[9610][7885] wlbt :Revert setScanningMacOui support as feature and only pass VTS.
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / wifi_offload.cpp
1 #include <stdint.h>
2 #include <fcntl.h>
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>
11
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>
17
18 #include "nl80211_copy.h"
19 #include "sync.h"
20
21 #define LOG_TAG "WifiHAL"
22
23 #include <utils/Log.h>
24
25 #include "wifi_hal.h"
26 #include "common.h"
27 #include "cpp_bindings.h"
28
29 #ifndef SLSI_WLAN_UNIT_TEST
30 using namespace android;
31 #endif
32
33 typedef enum {
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;
41
42 typedef enum {
43 START_MKEEP_ALIVE,
44 STOP_MKEEP_ALIVE,
45 } GetCmdType;
46
47 ///////////////////////////////////////////////////////////////////////////////
48 class MKeepAliveCommand : public WifiCommand
49 {
50 u8 mIndex;
51 u8 *mIpPkt;
52 u16 mIpPktLen;
53 u8 *mSrcMacAddr;
54 u8 *mDstMacAddr;
55 u32 mPeriodMsec;
56 GetCmdType mType;
57
58 public:
59
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)
66 { }
67
68 // constructor for stop sending
69 MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
70 : WifiCommand(iface, 0), mIndex(index), mType(cmdType)
71 {
72 mIpPkt = NULL;
73 mIpPktLen = 0;
74 mSrcMacAddr = NULL;
75 mDstMacAddr = NULL;
76 mPeriodMsec = 0;
77 }
78
79 int createRequest(WifiRequest &request) {
80 int result;
81
82 switch (mType) {
83 case START_MKEEP_ALIVE:
84 {
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);
88 return result;
89 }
90
91 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
92
93 result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
94 if (result < 0) {
95 ALOGE("Failed to put id request; result = %d", result);
96 return result;
97 }
98
99 result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
100 if (result < 0) {
101 ALOGE("Failed to put ip pkt len request; result = %d", result);
102 return result;
103 }
104
105 result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
106 if (result < 0) {
107 ALOGE("Failed to put ip pkt request; result = %d", result);
108 return result;
109 }
110
111 result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
112 if (result < 0) {
113 ALOGE("Failed to put src mac address request; result = %d", result);
114 return result;
115 }
116
117 result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
118 if (result < 0) {
119 ALOGE("Failed to put dst mac address request; result = %d", result);
120 return result;
121 }
122
123 result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
124 if (result < 0) {
125 ALOGE("Failed to put period request; result = %d", result);
126 return result;
127 }
128
129 request.attr_end(data);
130 break;
131 }
132
133 case STOP_MKEEP_ALIVE:
134 {
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);
138 return result;
139 }
140
141 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
142
143 result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
144 if (result < 0) {
145 ALOGE("Failed to put id request; result = %d", result);
146 return result;
147 }
148
149 request.attr_end(data);
150 break;
151 }
152
153 default:
154 ALOGE("Unknown wifi keep alive command");
155 result = WIFI_ERROR_UNKNOWN;
156 }
157 return result;
158 }
159
160 int start() {
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);
166 return result;
167 }
168
169 result = requestResponse(request);
170 if (result != WIFI_SUCCESS) {
171 ALOGE("Failed to register keep alive response; result = %d", result);
172 }
173 return result;
174 }
175
176 virtual int handleResponse(WifiEvent& reply) {
177
178 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
179 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
180 return NL_SKIP;
181 }
182
183 switch (mType) {
184 case START_MKEEP_ALIVE:
185 case STOP_MKEEP_ALIVE:
186 break;
187
188 default:
189 ALOGW("Unknown mkeep_alive command");
190 }
191 return NL_OK;
192 }
193
194 virtual int handleEvent(WifiEvent& event) {
195 /* NO events! */
196 return NL_SKIP;
197 }
198 };
199
200
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)
204 {
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();
211 delete cmd;
212 return result;
213 } else {
214 ALOGE("Invalid mkeep_alive parameters");
215 return WIFI_ERROR_INVALID_ARGS;
216 }
217 }
218
219 /* API to stop sending mkeep_alive packet. */
220 wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
221 {
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();
225 delete cmd;
226 return result;
227 } else {
228 ALOGE("Invalid mkeep_alive parameters");
229 return WIFI_ERROR_INVALID_ARGS;
230 }
231 }