1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <netlink/genl/genl.h>
21 #include <netlink/genl/family.h>
22 #include <netlink/genl/ctrl.h>
23 #include <linux/rtnetlink.h>
24 #include <netpacket/packet.h>
25 #include <linux/filter.h>
26 #include <linux/errqueue.h>
27
28 #include <linux/pkt_sched.h>
29 #include <netlink/object-api.h>
30 #include <netlink/netlink.h>
31 #include <netlink/socket.h>
32 #include <netlink-types.h>
33 #include <net/if.h>
34
35 #include "nl80211_copy.h"
36 #include <ctype.h>
37
38 #include "wifi_hal.h"
39 #include "common.h"
40 #include "cpp_bindings.h"
41 #include "qca-vendor.h"
42
appendFmt(char * buf,size_t buf_len,int & offset,const char * fmt,...)43 void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...)
44 {
45 va_list params;
46 va_start(params, fmt);
47 offset += vsnprintf(buf + offset, buf_len - offset, fmt, params);
48 va_end(params);
49 }
50
51 #define C2S(x) case x: return #x;
52
cmdToString(int cmd)53 static const char *cmdToString(int cmd)
54 {
55 switch (cmd) {
56 C2S(NL80211_CMD_UNSPEC)
57 C2S(NL80211_CMD_GET_WIPHY)
58 C2S(NL80211_CMD_SET_WIPHY)
59 C2S(NL80211_CMD_NEW_WIPHY)
60 C2S(NL80211_CMD_DEL_WIPHY)
61 C2S(NL80211_CMD_GET_INTERFACE)
62 C2S(NL80211_CMD_SET_INTERFACE)
63 C2S(NL80211_CMD_NEW_INTERFACE)
64 C2S(NL80211_CMD_DEL_INTERFACE)
65 C2S(NL80211_CMD_GET_KEY)
66 C2S(NL80211_CMD_SET_KEY)
67 C2S(NL80211_CMD_NEW_KEY)
68 C2S(NL80211_CMD_DEL_KEY)
69 C2S(NL80211_CMD_GET_BEACON)
70 C2S(NL80211_CMD_SET_BEACON)
71 C2S(NL80211_CMD_START_AP)
72 C2S(NL80211_CMD_STOP_AP)
73 C2S(NL80211_CMD_GET_STATION)
74 C2S(NL80211_CMD_SET_STATION)
75 C2S(NL80211_CMD_NEW_STATION)
76 C2S(NL80211_CMD_DEL_STATION)
77 C2S(NL80211_CMD_GET_MPATH)
78 C2S(NL80211_CMD_SET_MPATH)
79 C2S(NL80211_CMD_NEW_MPATH)
80 C2S(NL80211_CMD_DEL_MPATH)
81 C2S(NL80211_CMD_SET_BSS)
82 C2S(NL80211_CMD_SET_REG)
83 C2S(NL80211_CMD_REQ_SET_REG)
84 C2S(NL80211_CMD_GET_MESH_CONFIG)
85 C2S(NL80211_CMD_SET_MESH_CONFIG)
86 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
87 C2S(NL80211_CMD_GET_REG)
88 C2S(NL80211_CMD_GET_SCAN)
89 C2S(NL80211_CMD_TRIGGER_SCAN)
90 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
91 C2S(NL80211_CMD_SCAN_ABORTED)
92 C2S(NL80211_CMD_REG_CHANGE)
93 C2S(NL80211_CMD_AUTHENTICATE)
94 C2S(NL80211_CMD_ASSOCIATE)
95 C2S(NL80211_CMD_DEAUTHENTICATE)
96 C2S(NL80211_CMD_DISASSOCIATE)
97 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
98 C2S(NL80211_CMD_REG_BEACON_HINT)
99 C2S(NL80211_CMD_JOIN_IBSS)
100 C2S(NL80211_CMD_LEAVE_IBSS)
101 C2S(NL80211_CMD_TESTMODE)
102 C2S(NL80211_CMD_CONNECT)
103 C2S(NL80211_CMD_ROAM)
104 C2S(NL80211_CMD_DISCONNECT)
105 C2S(NL80211_CMD_SET_WIPHY_NETNS)
106 C2S(NL80211_CMD_GET_SURVEY)
107 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
108 C2S(NL80211_CMD_SET_PMKSA)
109 C2S(NL80211_CMD_DEL_PMKSA)
110 C2S(NL80211_CMD_FLUSH_PMKSA)
111 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
112 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
113 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
114 C2S(NL80211_CMD_REGISTER_FRAME)
115 C2S(NL80211_CMD_FRAME)
116 C2S(NL80211_CMD_FRAME_TX_STATUS)
117 C2S(NL80211_CMD_SET_POWER_SAVE)
118 C2S(NL80211_CMD_GET_POWER_SAVE)
119 C2S(NL80211_CMD_SET_CQM)
120 C2S(NL80211_CMD_NOTIFY_CQM)
121 C2S(NL80211_CMD_SET_CHANNEL)
122 C2S(NL80211_CMD_SET_WDS_PEER)
123 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
124 C2S(NL80211_CMD_JOIN_MESH)
125 C2S(NL80211_CMD_LEAVE_MESH)
126 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
127 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
128 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
129 C2S(NL80211_CMD_GET_WOWLAN)
130 C2S(NL80211_CMD_SET_WOWLAN)
131 C2S(NL80211_CMD_START_SCHED_SCAN)
132 C2S(NL80211_CMD_STOP_SCHED_SCAN)
133 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
134 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
135 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
136 C2S(NL80211_CMD_PMKSA_CANDIDATE)
137 C2S(NL80211_CMD_TDLS_OPER)
138 C2S(NL80211_CMD_TDLS_MGMT)
139 C2S(NL80211_CMD_UNEXPECTED_FRAME)
140 C2S(NL80211_CMD_PROBE_CLIENT)
141 C2S(NL80211_CMD_REGISTER_BEACONS)
142 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
143 C2S(NL80211_CMD_SET_NOACK_MAP)
144 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
145 C2S(NL80211_CMD_START_P2P_DEVICE)
146 C2S(NL80211_CMD_STOP_P2P_DEVICE)
147 C2S(NL80211_CMD_CONN_FAILED)
148 C2S(NL80211_CMD_SET_MCAST_RATE)
149 C2S(NL80211_CMD_SET_MAC_ACL)
150 C2S(NL80211_CMD_RADAR_DETECT)
151 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
152 C2S(NL80211_CMD_UPDATE_FT_IES)
153 C2S(NL80211_CMD_FT_EVENT)
154 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
155 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
156 C2S(NL80211_CMD_GET_COALESCE)
157 C2S(NL80211_CMD_SET_COALESCE)
158 C2S(NL80211_CMD_CHANNEL_SWITCH)
159 C2S(NL80211_CMD_VENDOR)
160 C2S(NL80211_CMD_SET_QOS_MAP)
161 default:
162 return "NL80211_CMD_UNKNOWN";
163 }
164 }
165
attributeToString(int attribute)166 const char *attributeToString(int attribute)
167 {
168 switch (attribute) {
169 C2S(NL80211_ATTR_UNSPEC)
170
171 C2S(NL80211_ATTR_WIPHY)
172 C2S(NL80211_ATTR_WIPHY_NAME)
173
174 C2S(NL80211_ATTR_IFINDEX)
175 C2S(NL80211_ATTR_IFNAME)
176 C2S(NL80211_ATTR_IFTYPE)
177
178 C2S(NL80211_ATTR_MAC)
179
180 C2S(NL80211_ATTR_KEY_DATA)
181 C2S(NL80211_ATTR_KEY_IDX)
182 C2S(NL80211_ATTR_KEY_CIPHER)
183 C2S(NL80211_ATTR_KEY_SEQ)
184 C2S(NL80211_ATTR_KEY_DEFAULT)
185
186 C2S(NL80211_ATTR_BEACON_INTERVAL)
187 C2S(NL80211_ATTR_DTIM_PERIOD)
188 C2S(NL80211_ATTR_BEACON_HEAD)
189 C2S(NL80211_ATTR_BEACON_TAIL)
190
191 C2S(NL80211_ATTR_STA_AID)
192 C2S(NL80211_ATTR_STA_FLAGS)
193 C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
194 C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
195 C2S(NL80211_ATTR_STA_VLAN)
196 C2S(NL80211_ATTR_STA_INFO)
197
198 C2S(NL80211_ATTR_WIPHY_BANDS)
199
200 C2S(NL80211_ATTR_MNTR_FLAGS)
201
202 C2S(NL80211_ATTR_MESH_ID)
203 C2S(NL80211_ATTR_STA_PLINK_ACTION)
204 C2S(NL80211_ATTR_MPATH_NEXT_HOP)
205 C2S(NL80211_ATTR_MPATH_INFO)
206
207 C2S(NL80211_ATTR_BSS_CTS_PROT)
208 C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
209 C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
210
211 C2S(NL80211_ATTR_HT_CAPABILITY)
212
213 C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
214
215 C2S(NL80211_ATTR_REG_ALPHA2)
216 C2S(NL80211_ATTR_REG_RULES)
217
218 C2S(NL80211_ATTR_MESH_CONFIG)
219
220 C2S(NL80211_ATTR_BSS_BASIC_RATES)
221
222 C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
223 C2S(NL80211_ATTR_WIPHY_FREQ)
224 C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
225
226 C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
227
228 C2S(NL80211_ATTR_MGMT_SUBTYPE)
229 C2S(NL80211_ATTR_IE)
230
231 C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
232
233 C2S(NL80211_ATTR_SCAN_FREQUENCIES)
234 C2S(NL80211_ATTR_SCAN_SSIDS)
235 C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
236 C2S(NL80211_ATTR_BSS)
237
238 C2S(NL80211_ATTR_REG_INITIATOR)
239 C2S(NL80211_ATTR_REG_TYPE)
240
241 C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
242
243 C2S(NL80211_ATTR_FRAME)
244 C2S(NL80211_ATTR_SSID)
245 C2S(NL80211_ATTR_AUTH_TYPE)
246 C2S(NL80211_ATTR_REASON_CODE)
247
248 C2S(NL80211_ATTR_KEY_TYPE)
249
250 C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
251 C2S(NL80211_ATTR_CIPHER_SUITES)
252
253 C2S(NL80211_ATTR_FREQ_BEFORE)
254 C2S(NL80211_ATTR_FREQ_AFTER)
255
256 C2S(NL80211_ATTR_FREQ_FIXED)
257
258
259 C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
260 C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
261 C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
262 C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
263
264 C2S(NL80211_ATTR_TIMED_OUT)
265
266 C2S(NL80211_ATTR_USE_MFP)
267
268 C2S(NL80211_ATTR_STA_FLAGS2)
269
270 C2S(NL80211_ATTR_CONTROL_PORT)
271
272 C2S(NL80211_ATTR_TESTDATA)
273
274 C2S(NL80211_ATTR_PRIVACY)
275
276 C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
277 C2S(NL80211_ATTR_STATUS_CODE)
278
279 C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
280 C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
281 C2S(NL80211_ATTR_WPA_VERSIONS)
282 C2S(NL80211_ATTR_AKM_SUITES)
283
284 C2S(NL80211_ATTR_REQ_IE)
285 C2S(NL80211_ATTR_RESP_IE)
286
287 C2S(NL80211_ATTR_PREV_BSSID)
288
289 C2S(NL80211_ATTR_KEY)
290 C2S(NL80211_ATTR_KEYS)
291
292 C2S(NL80211_ATTR_PID)
293
294 C2S(NL80211_ATTR_4ADDR)
295
296 C2S(NL80211_ATTR_SURVEY_INFO)
297
298 C2S(NL80211_ATTR_PMKID)
299 C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
300
301 C2S(NL80211_ATTR_DURATION)
302
303 C2S(NL80211_ATTR_COOKIE)
304
305 C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
306
307 C2S(NL80211_ATTR_TX_RATES)
308
309 C2S(NL80211_ATTR_FRAME_MATCH)
310
311 C2S(NL80211_ATTR_ACK)
312
313 C2S(NL80211_ATTR_PS_STATE)
314
315 C2S(NL80211_ATTR_CQM)
316
317 C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
318
319 C2S(NL80211_ATTR_AP_ISOLATE)
320
321 C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
322 C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
323
324 C2S(NL80211_ATTR_TX_FRAME_TYPES)
325 C2S(NL80211_ATTR_RX_FRAME_TYPES)
326 C2S(NL80211_ATTR_FRAME_TYPE)
327
328 C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
329 C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
330
331 C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
332
333 C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
334 C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
335
336 C2S(NL80211_ATTR_MCAST_RATE)
337
338 C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
339
340 C2S(NL80211_ATTR_BSS_HT_OPMODE)
341
342 C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
343
344 C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
345
346 C2S(NL80211_ATTR_MESH_SETUP)
347
348 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
349 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
350
351 C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
352 C2S(NL80211_ATTR_STA_PLINK_STATE)
353
354 C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
355 C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
356
357 C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
358
359 C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
360 C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
361
362 C2S(NL80211_ATTR_REKEY_DATA)
363
364 C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
365 C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
366
367 C2S(NL80211_ATTR_SCAN_SUPP_RATES)
368
369 C2S(NL80211_ATTR_HIDDEN_SSID)
370
371 C2S(NL80211_ATTR_IE_PROBE_RESP)
372 C2S(NL80211_ATTR_IE_ASSOC_RESP)
373
374 C2S(NL80211_ATTR_STA_WME)
375 C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
376
377 C2S(NL80211_ATTR_ROAM_SUPPORT)
378
379 C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
380 C2S(NL80211_ATTR_MAX_MATCH_SETS)
381
382 C2S(NL80211_ATTR_PMKSA_CANDIDATE)
383
384 C2S(NL80211_ATTR_TX_NO_CCK_RATE)
385
386 C2S(NL80211_ATTR_TDLS_ACTION)
387 C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
388 C2S(NL80211_ATTR_TDLS_OPERATION)
389 C2S(NL80211_ATTR_TDLS_SUPPORT)
390 C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
391
392 C2S(NL80211_ATTR_DEVICE_AP_SME)
393
394 C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
395
396 C2S(NL80211_ATTR_FEATURE_FLAGS)
397
398 C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
399
400 C2S(NL80211_ATTR_PROBE_RESP)
401
402 C2S(NL80211_ATTR_DFS_REGION)
403
404 C2S(NL80211_ATTR_DISABLE_HT)
405 C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
406
407 C2S(NL80211_ATTR_NOACK_MAP)
408
409 C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
410
411 C2S(NL80211_ATTR_RX_SIGNAL_DBM)
412
413 C2S(NL80211_ATTR_BG_SCAN_PERIOD)
414
415 C2S(NL80211_ATTR_WDEV)
416
417 C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
418
419 C2S(NL80211_ATTR_CONN_FAILED_REASON)
420
421 C2S(NL80211_ATTR_SAE_DATA)
422
423 C2S(NL80211_ATTR_VHT_CAPABILITY)
424
425 C2S(NL80211_ATTR_SCAN_FLAGS)
426
427 C2S(NL80211_ATTR_CHANNEL_WIDTH)
428 C2S(NL80211_ATTR_CENTER_FREQ1)
429 C2S(NL80211_ATTR_CENTER_FREQ2)
430
431 C2S(NL80211_ATTR_P2P_CTWINDOW)
432 C2S(NL80211_ATTR_P2P_OPPPS)
433
434 C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
435
436 C2S(NL80211_ATTR_ACL_POLICY)
437
438 C2S(NL80211_ATTR_MAC_ADDRS)
439
440 C2S(NL80211_ATTR_MAC_ACL_MAX)
441
442 C2S(NL80211_ATTR_RADAR_EVENT)
443
444 C2S(NL80211_ATTR_EXT_CAPA)
445 C2S(NL80211_ATTR_EXT_CAPA_MASK)
446
447 C2S(NL80211_ATTR_STA_CAPABILITY)
448 C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
449
450 C2S(NL80211_ATTR_PROTOCOL_FEATURES)
451 C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
452
453 C2S(NL80211_ATTR_DISABLE_VHT)
454 C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
455
456 C2S(NL80211_ATTR_MDID)
457 C2S(NL80211_ATTR_IE_RIC)
458
459 C2S(NL80211_ATTR_CRIT_PROT_ID)
460 C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
461
462 C2S(NL80211_ATTR_PEER_AID)
463
464 C2S(NL80211_ATTR_COALESCE_RULE)
465
466 C2S(NL80211_ATTR_CH_SWITCH_COUNT)
467 C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
468 C2S(NL80211_ATTR_CSA_IES)
469 C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
470 C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
471
472 C2S(NL80211_ATTR_RXMGMT_FLAGS)
473
474 C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
475
476 C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
477
478 C2S(NL80211_ATTR_HANDLE_DFS)
479
480 C2S(NL80211_ATTR_SUPPORT_5_MHZ)
481 C2S(NL80211_ATTR_SUPPORT_10_MHZ)
482
483 C2S(NL80211_ATTR_OPMODE_NOTIF)
484
485 C2S(NL80211_ATTR_VENDOR_ID)
486 C2S(NL80211_ATTR_VENDOR_SUBCMD)
487 C2S(NL80211_ATTR_VENDOR_DATA)
488 C2S(NL80211_ATTR_VENDOR_EVENTS)
489
490 C2S(NL80211_ATTR_QOS_MAP)
491 default:
492 return "NL80211_ATTR_UNKNOWN";
493 }
494 }
495
log()496 void WifiEvent::log() {
497 parse();
498
499 byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
500 int len = genlmsg_attrlen(mHeader, 0);
501
502 for (int i = 0; i < len; i += 16) {
503 char line[81];
504 int linelen = min(16, len - i);
505 int offset = 0;
506 appendFmt(line, sizeof(line), offset, "%02x", data[i]);
507 for (int j = 1; j < linelen; j++) {
508 appendFmt(line, sizeof(line), offset, " %02x", data[i+j]);
509 }
510
511 for (int j = linelen; j < 16; j++) {
512 appendFmt(line, sizeof(line), offset, " ");
513 }
514
515 line[23] = '-';
516
517 appendFmt(line, sizeof(line), offset, " ");
518
519 for (int j = 0; j < linelen; j++) {
520 if (isprint(data[i+j])) {
521 appendFmt(line, sizeof(line), offset, "%c", data[i+j]);
522 } else {
523 appendFmt(line, sizeof(line), offset, "-");
524 }
525 }
526
527 }
528
529 }
530
get_cmdString()531 const char *WifiEvent::get_cmdString() {
532 return cmdToString(get_cmd());
533 }
534
535
parse()536 int WifiEvent::parse() {
537 if (mHeader != NULL) {
538 return WIFI_SUCCESS;
539 }
540 mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
541 int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
542 genlmsg_attrlen(mHeader, 0), NULL);
543
544 return result;
545 }
546
create(int family,uint8_t cmd,int flags,int hdrlen)547 int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
548
549 destroy();
550
551 mMsg = nlmsg_alloc();
552 if (mMsg != NULL) {
553 genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
554 hdrlen, flags, cmd, /* version = */ 0);
555 return WIFI_SUCCESS;
556 } else {
557 return WIFI_ERROR_OUT_OF_MEMORY;
558 }
559 }
560
create(uint32_t id,int subcmd)561 int WifiRequest::create(uint32_t id, int subcmd) {
562 int res = create(NL80211_CMD_VENDOR);
563 if (res < 0) {
564 return res;
565 }
566
567 res = put_u32(NL80211_ATTR_VENDOR_ID, id);
568 if (res < 0) {
569 return res;
570 }
571
572 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
573 if (res < 0) {
574 return res;
575 }
576
577 if (mIface != -1) {
578 res = set_iface_id(mIface);
579 }
580
581 return res;
582 }
583
584
no_seq_check(struct nl_msg * msg,void * arg)585 static int no_seq_check(struct nl_msg *msg, void *arg)
586 {
587 return NL_OK;
588 }
589
requestResponse()590 int WifiCommand::requestResponse() {
591 int err = create(); /* create the message */
592 if (err < 0) {
593 return err;
594 }
595
596 return requestResponse(mMsg);
597 }
598
requestResponse(WifiRequest & request)599 int WifiCommand::requestResponse(WifiRequest& request) {
600 int err = 0;
601
602 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
603 if (!cb)
604 goto out;
605
606 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */
607 if (err < 0)
608 goto out;
609
610 err = 1;
611
612 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
613 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
614 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
615 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
616 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
617
618 while (err > 0) { /* wait for reply */
619 int res = nl_recvmsgs(mInfo->cmd_sock, cb);
620 if (res) {
621 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res);
622 }
623 }
624 out:
625 nl_cb_put(cb);
626 mMsg.destroy();
627 return err;
628 }
629
requestEvent(int cmd)630 int WifiCommand::requestEvent(int cmd) {
631
632 int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
633 if (res < 0) {
634 return res;
635 }
636
637 res = create(); /* create the message */
638 if (res < 0)
639 goto out;
640
641 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
642 if (res < 0)
643 goto out;
644
645 res = mCondition.wait();
646 if (res < 0)
647 goto out;
648
649 out:
650 wifi_unregister_handler(wifiHandle(), cmd);
651 return res;
652 }
653
requestVendorEvent(uint32_t id,int subcmd)654 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
655
656 int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
657 if (res < 0) {
658 return res;
659 }
660
661 res = create(); /* create the message */
662 if (res < 0)
663 goto out;
664
665 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
666 if (res < 0)
667 goto out;
668
669 res = mCondition.wait();
670 if (res < 0)
671 goto out;
672
673 out:
674 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
675 return res;
676 }
677
678 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)679 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
680 WifiCommand *cmd = (WifiCommand *)arg;
681 WifiEvent reply(msg);
682 int res = reply.parse();
683 if (res < 0) {
684 ALOGE("Failed to parse reply message = %d", res);
685 return NL_SKIP;
686 } else {
687 // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */
688 return cmd->handleResponse(reply);
689 }
690 }
691
event_handler(struct nl_msg * msg,void * arg)692 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
693 WifiCommand *cmd = (WifiCommand *)arg;
694 WifiEvent event(msg);
695 int res = event.parse();
696 if (res < 0) {
697 ALOGE("Failed to parse event = %d", res);
698 res = NL_SKIP;
699 } else {
700 res = cmd->handleEvent(event);
701 }
702
703 cmd->mCondition.signal();
704 return res;
705 }
706
707 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)708 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
709 int *err = (int *)arg;
710 *err = 0;
711 return NL_SKIP;
712 }
713
ack_handler(struct nl_msg * msg,void * arg)714 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
715 int *err = (int *)arg;
716 *err = 0;
717 return NL_STOP;
718 }
719
finish_handler(struct nl_msg * msg,void * arg)720 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
721 int *ret = (int *)arg;
722 *ret = 0;
723 return NL_SKIP;
724 }
725
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)726 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
727 int *ret = (int *)arg;
728 *ret = err->error;
729
730 return NL_SKIP;
731 }
732
733
WifiVendorCommand(wifi_handle handle,wifi_request_id id,u32 vendor_id,u32 subcmd)734 WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
735 wifi_request_id id,
736 u32 vendor_id,
737 u32 subcmd)
738 : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
739 mVendorData(NULL), mDataLen(0)
740 {
741 ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
742 this, mVendor_id, mSubcmd);
743 }
744
~WifiVendorCommand()745 WifiVendorCommand::~WifiVendorCommand()
746 {
747 //ALOGV("~WifiVendorCommand %p destroyed", this);
748 //mVendorData is not destroyed here. Assumption
749 //is that VendorData is specific to each Vendor and they
750 //are responsible for owning the same.
751 }
752
753 // Override this method to parse reply and dig out data; save it
754 // in the corresponding object
handleResponse(WifiEvent & reply)755 int WifiVendorCommand::handleResponse(WifiEvent &reply)
756 {
757 struct nlattr **tb = reply.attributes();
758 struct nlattr *attr = NULL;
759 struct genlmsghdr *gnlh = reply.header();
760
761 if (gnlh->cmd == NL80211_CMD_VENDOR) {
762 if (tb[NL80211_ATTR_VENDOR_DATA]) {
763 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
764 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
765 }
766 }
767 return NL_SKIP;
768 }
769
770 // Override this method to parse event and dig out data;
771 // save it in the object
handleEvent(WifiEvent & event)772 int WifiVendorCommand::handleEvent(WifiEvent &event)
773 {
774 struct nlattr **tb = event.attributes();
775 struct nlattr *attr = NULL;
776 struct genlmsghdr *gnlh = event.header();
777
778 if (gnlh->cmd == NL80211_CMD_VENDOR) {
779 /* Vendor Event */
780 if (!tb[NL80211_ATTR_VENDOR_ID] ||
781 !tb[NL80211_ATTR_VENDOR_SUBCMD])
782 return NL_SKIP;
783
784 mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
785 mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
786
787 ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u",
788 __FUNCTION__, mVendor_id, mSubcmd);
789
790 if (tb[NL80211_ATTR_VENDOR_DATA]) {
791 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
792 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
793 ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen);
794 hexdump(mVendorData, mDataLen);
795 }
796 }
797 return NL_SKIP;
798 }
799
create()800 int WifiVendorCommand::create() {
801 int ifindex;
802 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
803 if (ret < 0) {
804 return ret;
805 }
806 // insert the oui in the msg
807 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
808 if (ret < 0)
809 goto out;
810
811 // insert the subcmd in the msg
812 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
813 if (ret < 0)
814 goto out;
815
816 //Insert the vendor specific data
817 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
818 hexdump(mVendorData, mDataLen);
819
820 //insert the iface id to be "wlan0"
821 ifindex = if_nametoindex("wlan0");
822 mMsg.set_iface_id(ifindex);
823 out:
824 return ret;
825
826 }
827
requestResponse()828 int WifiVendorCommand::requestResponse()
829 {
830 return WifiCommand::requestResponse(mMsg);
831 }
832
requestEvent()833 int WifiVendorCommand::requestEvent()
834 {
835 int res = requestVendorEvent(mVendor_id, mSubcmd);
836 return res;
837
838 }
839
put_u8(int attribute,uint8_t value)840 int WifiVendorCommand::put_u8(int attribute, uint8_t value)
841 {
842 return mMsg.put_u8(attribute, value);
843 }
844
put_u16(int attribute,uint16_t value)845 int WifiVendorCommand::put_u16(int attribute, uint16_t value)
846 {
847 return mMsg.put_u16(attribute, value);
848 }
849
put_u32(int attribute,uint32_t value)850 int WifiVendorCommand::put_u32(int attribute, uint32_t value)
851 {
852 return mMsg.put_u32(attribute, value);
853 }
854
put_u64(int attribute,uint64_t value)855 int WifiVendorCommand::put_u64(int attribute, uint64_t value)
856 {
857 return mMsg.put_u64(attribute, value);
858 }
859
put_s8(int attribute,s8 value)860 int WifiVendorCommand::put_s8(int attribute, s8 value)
861 {
862 return mMsg.put_s8(attribute, value);
863 }
864
put_s16(int attribute,s16 value)865 int WifiVendorCommand::put_s16(int attribute, s16 value)
866 {
867 return mMsg.put_s16(attribute, value);
868 }
869
put_s32(int attribute,s32 value)870 int WifiVendorCommand::put_s32(int attribute, s32 value) {
871 return mMsg.put_s32(attribute, value);
872 }
873
put_s64(int attribute,s64 value)874 int WifiVendorCommand::put_s64(int attribute, s64 value)
875 {
876 return mMsg.put_s64(attribute, value);
877 }
878
get_u8(const struct nlattr * nla)879 u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
880 {
881 return mMsg.get_u8(nla);
882 }
883
get_u16(const struct nlattr * nla)884 u16 WifiVendorCommand::get_u16(const struct nlattr *nla)
885 {
886 return mMsg.get_u16(nla);
887 }
888
get_u32(const struct nlattr * nla)889 u32 WifiVendorCommand::get_u32(const struct nlattr *nla)
890 {
891 return mMsg.get_u32(nla);
892 }
893
get_u64(const struct nlattr * nla)894 u64 WifiVendorCommand::get_u64(const struct nlattr *nla)
895 {
896 return mMsg.get_u64(nla);
897 }
898
get_s8(const struct nlattr * nla)899 s8 WifiVendorCommand::get_s8(const struct nlattr *nla)
900 {
901 return mMsg.get_s8(nla);
902 }
903
get_s16(const struct nlattr * nla)904 s16 WifiVendorCommand::get_s16(const struct nlattr *nla)
905 {
906 return mMsg.get_s16(nla);
907 }
908
get_s32(const struct nlattr * nla)909 s32 WifiVendorCommand::get_s32(const struct nlattr *nla)
910 {
911 return mMsg.get_s32(nla);
912 }
913
get_s64(const struct nlattr * nla)914 s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
915 {
916 return mMsg.get_s64(nla);
917 }
918
put_string(int attribute,const char * value)919 int WifiVendorCommand::put_string(int attribute, const char *value)
920 {
921 return mMsg.put_string(attribute, value);
922 }
923
put_addr(int attribute,mac_addr value)924 int WifiVendorCommand::put_addr(int attribute, mac_addr value)
925 {
926 return mMsg.put_addr(attribute, value);
927 }
928
attr_start(int attribute)929 struct nlattr * WifiVendorCommand::attr_start(int attribute)
930 {
931 return mMsg.attr_start(attribute);
932 }
933
attr_end(struct nlattr * attribute)934 void WifiVendorCommand::attr_end(struct nlattr *attribute)
935 {
936 return mMsg.attr_end(attribute);
937 }
938
set_iface_id(const char * name)939 int WifiVendorCommand::set_iface_id(const char* name)
940 {
941 unsigned ifindex = if_nametoindex(name);
942 return mMsg.set_iface_id(ifindex);
943 }
944
put_bytes(int attribute,const char * data,int len)945 int WifiVendorCommand::put_bytes(int attribute, const char *data, int len)
946 {
947 return mMsg.put_bytes(attribute, data, len);
948 }
949
get_mac_addr(struct nlattr ** tb_vendor,int attribute,mac_addr addr)950 wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor,
951 int attribute,
952 mac_addr addr)
953 {
954 if (!tb_vendor[attribute]) {
955 ALOGE("Failed to get attribute : %d", attribute);
956 return WIFI_ERROR_INVALID_ARGS;
957 }
958 if (!addr) {
959 ALOGE("addr is NULL");
960 return WIFI_ERROR_INVALID_ARGS;
961 }
962
963 if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) {
964 ALOGE("Invalid mac addr lenght\n");
965 return WIFI_ERROR_INVALID_ARGS;
966 }
967
968 memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]),
969 nla_len(tb_vendor[attribute]));
970 return WIFI_SUCCESS;
971 }
972
initialize_vendor_cmd(wifi_interface_handle iface,wifi_request_id id,u32 subcmd,WifiVendorCommand ** vCommand)973 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
974 wifi_request_id id,
975 u32 subcmd,
976 WifiVendorCommand **vCommand)
977 {
978 int ret = 0;
979 interface_info *ifaceInfo = getIfaceInfo(iface);
980 wifi_handle wifiHandle = getWifiHandle(iface);
981
982 if (vCommand == NULL) {
983 ALOGE("%s: Error vCommand NULL", __FUNCTION__);
984 return WIFI_ERROR_INVALID_ARGS;
985 }
986
987 *vCommand = new WifiVendorCommand(wifiHandle, id,
988 OUI_QCA,
989 subcmd);
990 if (*vCommand == NULL) {
991 ALOGE("%s: Object creation failed", __FUNCTION__);
992 return WIFI_ERROR_OUT_OF_MEMORY;
993 }
994
995 /* Create the message */
996 ret = (*vCommand)->create();
997 if (ret < 0)
998 goto cleanup;
999
1000 ret = (*vCommand)->set_iface_id(ifaceInfo->name);
1001 if (ret < 0)
1002 goto cleanup;
1003
1004 return WIFI_SUCCESS;
1005
1006 cleanup:
1007 delete *vCommand;
1008 return (wifi_error)ret;
1009 }
1010