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[offload]"
23 #include <utils/Log.h>
27 #include "cpp_bindings.h"
30 MKEEP_ALIVE_ATTRIBUTE_ID
,
31 MKEEP_ALIVE_ATTRIBUTE_IP_PKT
,
32 MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN
,
33 MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR
,
34 MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR
,
35 MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
36 } WIFI_MKEEP_ALIVE_ATTRIBUTE
;
43 ///////////////////////////////////////////////////////////////////////////////
44 class MKeepAliveCommand
: public WifiCommand
56 // constructor for start sending
57 MKeepAliveCommand(wifi_interface_handle iface
, u8 index
, u8
*ip_packet
, u16 ip_packet_len
,
58 u8
*src_mac_addr
, u8
*dst_mac_addr
, u32 period_msec
, GetCmdType cmdType
)
59 : WifiCommand(iface
, 0), mIndex(index
), mIpPkt(ip_packet
),
60 mIpPktLen(ip_packet_len
), mSrcMacAddr(src_mac_addr
), mDstMacAddr(dst_mac_addr
),
61 mPeriodMsec(period_msec
), mType(cmdType
)
64 // constructor for stop sending
65 MKeepAliveCommand(wifi_interface_handle iface
, u8 index
, GetCmdType cmdType
)
66 : WifiCommand(iface
, 0), mIndex(index
), mType(cmdType
)
75 int createRequest(WifiRequest
&request
) {
79 case START_MKEEP_ALIVE
:
81 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD
);
82 if (result
!= WIFI_SUCCESS
) {
83 ALOGE("Failed to create start keep alive request; result = %d", result
);
87 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
89 result
= request
.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID
, mIndex
);
91 ALOGE("Failed to put id request; result = %d", result
);
95 result
= request
.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN
, mIpPktLen
);
97 ALOGE("Failed to put ip pkt len request; result = %d", result
);
101 result
= request
.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT
, (u8
*)mIpPkt
, mIpPktLen
);
103 ALOGE("Failed to put ip pkt request; result = %d", result
);
107 result
= request
.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR
, mSrcMacAddr
);
109 ALOGE("Failed to put src mac address request; result = %d", result
);
113 result
= request
.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR
, mDstMacAddr
);
115 ALOGE("Failed to put dst mac address request; result = %d", result
);
119 result
= request
.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
, mPeriodMsec
);
121 ALOGE("Failed to put period request; result = %d", result
);
125 request
.attr_end(data
);
129 case STOP_MKEEP_ALIVE
:
131 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD
);
132 if (result
!= WIFI_SUCCESS
) {
133 ALOGE("Failed to create stop keep alive request; result = %d", result
);
137 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
139 result
= request
.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID
, mIndex
);
141 ALOGE("Failed to put id request; result = %d", result
);
145 request
.attr_end(data
);
150 ALOGE("Unknown wifi keep alive command");
151 result
= WIFI_ERROR_UNKNOWN
;
157 ALOGD("Start mkeep_alive command");
158 WifiRequest
request(familyId(), ifaceId());
159 int result
= createRequest(request
);
160 if (result
!= WIFI_SUCCESS
) {
161 ALOGE("Failed to create keep alive request; result = %d", result
);
165 result
= requestResponse(request
);
166 if (result
!= WIFI_SUCCESS
) {
167 ALOGE("Failed to register keep alive response; result = %d", result
);
172 virtual int handleResponse(WifiEvent
& reply
) {
174 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
175 ALOGD("Ignoring reply with cmd = %d", reply
.get_cmd());
180 case START_MKEEP_ALIVE
:
181 case STOP_MKEEP_ALIVE
:
185 ALOGW("Unknown mkeep_alive command");
190 virtual int handleEvent(WifiEvent
& event
) {
197 /* API to send specified mkeep_alive packet periodically. */
198 wifi_error
wifi_start_sending_offloaded_packet(wifi_request_id index
, wifi_interface_handle iface
,
199 u16 ether_type
, u8
*ip_packet
, u16 ip_packet_len
, u8
*src_mac_addr
, u8
*dst_mac_addr
,
202 if ((index
> 0 && index
<= N_AVAIL_ID
) && (ip_packet
!= NULL
) && (src_mac_addr
!= NULL
)
203 && (dst_mac_addr
!= NULL
) && (period_msec
> 0)
204 && (ip_packet_len
<= MKEEP_ALIVE_IP_PKT_MAX
)) {
205 MKeepAliveCommand
*cmd
= new MKeepAliveCommand(iface
, index
, ip_packet
, ip_packet_len
,
206 src_mac_addr
, dst_mac_addr
, period_msec
, START_MKEEP_ALIVE
);
207 wifi_error result
= (wifi_error
)cmd
->start();
211 ALOGE("Invalid mkeep_alive parameters");
212 return WIFI_ERROR_INVALID_ARGS
;
216 /* API to stop sending mkeep_alive packet. */
217 wifi_error
wifi_stop_sending_offloaded_packet(wifi_request_id index
, wifi_interface_handle iface
)
219 if (index
> 0 && index
<= N_AVAIL_ID
) {
220 MKeepAliveCommand
*cmd
= new MKeepAliveCommand(iface
, index
, STOP_MKEEP_ALIVE
);
221 wifi_error result
= (wifi_error
)cmd
->start();
225 ALOGE("Invalid mkeep_alive parameters");
226 return WIFI_ERROR_INVALID_ARGS
;