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