3 #include <sys/socket.h>
4 #include <netlink/genl/genl.h>
5 #include <netlink/genl/family.h>
6 #include <netlink/genl/ctrl.h>
7 #include <linux/rtnetlink.h>
8 #include <netpacket/packet.h>
9 #include <linux/filter.h>
10 #include <linux/errqueue.h>
12 #include <linux/pkt_sched.h>
13 #include <netlink/object-api.h>
14 #include <netlink/netlink.h>
15 #include <netlink/socket.h>
16 #include <netlink/types.h>
18 #include "nl80211_copy.h"
21 #define LOG_TAG "WifiHAL"
23 #include <utils/Log.h>
27 #include "cpp_bindings.h"
29 #ifndef SLSI_WLAN_UNIT_TEST
30 using namespace android
;
34 MKEEP_ALIVE_ATTRIBUTE_ID
,
35 MKEEP_ALIVE_ATTRIBUTE_IP_PKT
,
36 MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN
,
37 MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR
,
38 MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR
,
39 MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
40 } WIFI_MKEEP_ALIVE_ATTRIBUTE
;
47 ///////////////////////////////////////////////////////////////////////////////
48 class MKeepAliveCommand
: public WifiCommand
60 // constructor for start sending
61 MKeepAliveCommand(wifi_interface_handle iface
, u8 index
, u8
*ip_packet
, u16 ip_packet_len
,
62 u8
*src_mac_addr
, u8
*dst_mac_addr
, u32 period_msec
, GetCmdType cmdType
)
63 : WifiCommand(iface
, 0), mIndex(index
), mIpPkt(ip_packet
),
64 mIpPktLen(ip_packet_len
), mSrcMacAddr(src_mac_addr
), mDstMacAddr(dst_mac_addr
),
65 mPeriodMsec(period_msec
), mType(cmdType
)
68 // constructor for stop sending
69 MKeepAliveCommand(wifi_interface_handle iface
, u8 index
, GetCmdType cmdType
)
70 : WifiCommand(iface
, 0), mIndex(index
), mType(cmdType
)
79 int createRequest(WifiRequest
&request
) {
83 case START_MKEEP_ALIVE
:
85 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD
);
86 if (result
!= WIFI_SUCCESS
) {
87 ALOGE("Failed to create start keep alive request; result = %d", result
);
91 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
93 result
= request
.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID
, mIndex
);
95 ALOGE("Failed to put id request; result = %d", result
);
99 result
= request
.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN
, mIpPktLen
);
101 ALOGE("Failed to put ip pkt len request; result = %d", result
);
105 result
= request
.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT
, (u8
*)mIpPkt
, mIpPktLen
);
107 ALOGE("Failed to put ip pkt request; result = %d", result
);
111 result
= request
.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR
, mSrcMacAddr
);
113 ALOGE("Failed to put src mac address request; result = %d", result
);
117 result
= request
.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR
, mDstMacAddr
);
119 ALOGE("Failed to put dst mac address request; result = %d", result
);
123 result
= request
.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
, mPeriodMsec
);
125 ALOGE("Failed to put period request; result = %d", result
);
129 request
.attr_end(data
);
133 case STOP_MKEEP_ALIVE
:
135 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD
);
136 if (result
!= WIFI_SUCCESS
) {
137 ALOGE("Failed to create stop keep alive request; result = %d", result
);
141 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
143 result
= request
.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID
, mIndex
);
145 ALOGE("Failed to put id request; result = %d", result
);
149 request
.attr_end(data
);
154 ALOGE("Unknown wifi keep alive command");
155 result
= WIFI_ERROR_UNKNOWN
;
161 ALOGD("Start mkeep_alive command");
162 WifiRequest
request(familyId(), ifaceId());
163 int result
= createRequest(request
);
164 if (result
!= WIFI_SUCCESS
) {
165 ALOGE("Failed to create keep alive request; result = %d", result
);
169 result
= requestResponse(request
);
170 if (result
!= WIFI_SUCCESS
) {
171 ALOGE("Failed to register keep alive response; result = %d", result
);
176 virtual int handleResponse(WifiEvent
& reply
) {
178 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
179 ALOGD("Ignoring reply with cmd = %d", reply
.get_cmd());
184 case START_MKEEP_ALIVE
:
185 case STOP_MKEEP_ALIVE
:
189 ALOGW("Unknown mkeep_alive command");
194 virtual int handleEvent(WifiEvent
& event
) {
201 /* API to send specified mkeep_alive packet periodically. */
202 wifi_error
wifi_start_sending_offloaded_packet(wifi_request_id index
, wifi_interface_handle iface
,
203 u8
*ip_packet
, u16 ip_packet_len
, u8
*src_mac_addr
, u8
*dst_mac_addr
, u32 period_msec
)
205 if ((index
> 0 && index
<= N_AVAIL_ID
) && (ip_packet
!= NULL
) && (src_mac_addr
!= NULL
)
206 && (dst_mac_addr
!= NULL
) && (period_msec
> 0)
207 && (ip_packet_len
<= MKEEP_ALIVE_IP_PKT_MAX
)) {
208 MKeepAliveCommand
*cmd
= new MKeepAliveCommand(iface
, index
, ip_packet
, ip_packet_len
,
209 src_mac_addr
, dst_mac_addr
, period_msec
, START_MKEEP_ALIVE
);
210 wifi_error result
= (wifi_error
)cmd
->start();
214 ALOGE("Invalid mkeep_alive parameters");
215 return WIFI_ERROR_INVALID_ARGS
;
219 /* API to stop sending mkeep_alive packet. */
220 wifi_error
wifi_stop_sending_offloaded_packet(wifi_request_id index
, wifi_interface_handle iface
)
222 if (index
> 0 && index
<= N_AVAIL_ID
) {
223 MKeepAliveCommand
*cmd
= new MKeepAliveCommand(iface
, index
, STOP_MKEEP_ALIVE
);
224 wifi_error result
= (wifi_error
)cmd
->start();
228 ALOGE("Invalid mkeep_alive parameters");
229 return WIFI_ERROR_INVALID_ARGS
;