1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Portions copyright (C) 2017 Broadcom Limited
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29
30 #include <linux/pkt_sched.h>
31 #include <netlink/object-api.h>
32 #include <netlink/netlink.h>
33 #include <netlink/socket.h>
34 #include <netlink/handlers.h>
35
36 #include <ctype.h>
37 #include <errno.h>
38
39 #include "wifi_hal.h"
40 #include "common.h"
41 #include "cpp_bindings.h"
42
43 pthread_mutex_t ResponseMutex;
InitResponseLock()44 void InitResponseLock() {
45 pthread_mutex_init(&ResponseMutex, NULL);
46 }
47
DestroyResponseLock()48 void DestroyResponseLock()
49 {
50 pthread_mutex_destroy(&ResponseMutex);
51 }
52
appendFmt(char * buf,int & offset,const char * fmt,...)53 void appendFmt(char *buf, int &offset, const char *fmt, ...)
54 {
55 va_list params;
56 va_start(params, fmt);
57 offset += vsprintf(buf + offset, fmt, params);
58 va_end(params);
59 }
60
61 #define C2S(x) case x: return #x;
62
cmdToString(int cmd)63 static const char *cmdToString(int cmd)
64 {
65 switch (cmd) {
66 C2S(NL80211_CMD_UNSPEC)
67 C2S(NL80211_CMD_GET_WIPHY)
68 C2S(NL80211_CMD_SET_WIPHY)
69 C2S(NL80211_CMD_NEW_WIPHY)
70 C2S(NL80211_CMD_DEL_WIPHY)
71 C2S(NL80211_CMD_GET_INTERFACE)
72 C2S(NL80211_CMD_SET_INTERFACE)
73 C2S(NL80211_CMD_NEW_INTERFACE)
74 C2S(NL80211_CMD_DEL_INTERFACE)
75 C2S(NL80211_CMD_GET_KEY)
76 C2S(NL80211_CMD_SET_KEY)
77 C2S(NL80211_CMD_NEW_KEY)
78 C2S(NL80211_CMD_DEL_KEY)
79 C2S(NL80211_CMD_GET_BEACON)
80 C2S(NL80211_CMD_SET_BEACON)
81 C2S(NL80211_CMD_START_AP)
82 C2S(NL80211_CMD_STOP_AP)
83 C2S(NL80211_CMD_GET_STATION)
84 C2S(NL80211_CMD_SET_STATION)
85 C2S(NL80211_CMD_NEW_STATION)
86 C2S(NL80211_CMD_DEL_STATION)
87 C2S(NL80211_CMD_GET_MPATH)
88 C2S(NL80211_CMD_SET_MPATH)
89 C2S(NL80211_CMD_NEW_MPATH)
90 C2S(NL80211_CMD_DEL_MPATH)
91 C2S(NL80211_CMD_SET_BSS)
92 C2S(NL80211_CMD_SET_REG)
93 C2S(NL80211_CMD_REQ_SET_REG)
94 C2S(NL80211_CMD_GET_MESH_CONFIG)
95 C2S(NL80211_CMD_SET_MESH_CONFIG)
96 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
97 C2S(NL80211_CMD_GET_REG)
98 C2S(NL80211_CMD_GET_SCAN)
99 C2S(NL80211_CMD_TRIGGER_SCAN)
100 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
101 C2S(NL80211_CMD_SCAN_ABORTED)
102 C2S(NL80211_CMD_REG_CHANGE)
103 C2S(NL80211_CMD_AUTHENTICATE)
104 C2S(NL80211_CMD_ASSOCIATE)
105 C2S(NL80211_CMD_DEAUTHENTICATE)
106 C2S(NL80211_CMD_DISASSOCIATE)
107 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
108 C2S(NL80211_CMD_REG_BEACON_HINT)
109 C2S(NL80211_CMD_JOIN_IBSS)
110 C2S(NL80211_CMD_LEAVE_IBSS)
111 C2S(NL80211_CMD_TESTMODE)
112 C2S(NL80211_CMD_CONNECT)
113 C2S(NL80211_CMD_ROAM)
114 C2S(NL80211_CMD_DISCONNECT)
115 C2S(NL80211_CMD_SET_WIPHY_NETNS)
116 C2S(NL80211_CMD_GET_SURVEY)
117 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
118 C2S(NL80211_CMD_SET_PMKSA)
119 C2S(NL80211_CMD_DEL_PMKSA)
120 C2S(NL80211_CMD_FLUSH_PMKSA)
121 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
122 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
123 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
124 C2S(NL80211_CMD_REGISTER_FRAME)
125 C2S(NL80211_CMD_FRAME)
126 C2S(NL80211_CMD_FRAME_TX_STATUS)
127 C2S(NL80211_CMD_SET_POWER_SAVE)
128 C2S(NL80211_CMD_GET_POWER_SAVE)
129 C2S(NL80211_CMD_SET_CQM)
130 C2S(NL80211_CMD_NOTIFY_CQM)
131 C2S(NL80211_CMD_SET_CHANNEL)
132 C2S(NL80211_CMD_SET_WDS_PEER)
133 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
134 C2S(NL80211_CMD_JOIN_MESH)
135 C2S(NL80211_CMD_LEAVE_MESH)
136 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
137 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
138 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
139 C2S(NL80211_CMD_GET_WOWLAN)
140 C2S(NL80211_CMD_SET_WOWLAN)
141 C2S(NL80211_CMD_START_SCHED_SCAN)
142 C2S(NL80211_CMD_STOP_SCHED_SCAN)
143 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
144 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
145 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
146 C2S(NL80211_CMD_PMKSA_CANDIDATE)
147 C2S(NL80211_CMD_TDLS_OPER)
148 C2S(NL80211_CMD_TDLS_MGMT)
149 C2S(NL80211_CMD_UNEXPECTED_FRAME)
150 C2S(NL80211_CMD_PROBE_CLIENT)
151 C2S(NL80211_CMD_REGISTER_BEACONS)
152 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
153 C2S(NL80211_CMD_SET_NOACK_MAP)
154 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
155 C2S(NL80211_CMD_START_P2P_DEVICE)
156 C2S(NL80211_CMD_STOP_P2P_DEVICE)
157 C2S(NL80211_CMD_CONN_FAILED)
158 C2S(NL80211_CMD_SET_MCAST_RATE)
159 C2S(NL80211_CMD_SET_MAC_ACL)
160 C2S(NL80211_CMD_RADAR_DETECT)
161 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
162 C2S(NL80211_CMD_UPDATE_FT_IES)
163 C2S(NL80211_CMD_FT_EVENT)
164 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
165 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
166 C2S(NL80211_CMD_GET_COALESCE)
167 C2S(NL80211_CMD_SET_COALESCE)
168 C2S(NL80211_CMD_CHANNEL_SWITCH)
169 C2S(NL80211_CMD_VENDOR)
170 C2S(NL80211_CMD_SET_QOS_MAP)
171 default:
172 return "NL80211_CMD_UNKNOWN";
173 }
174 }
175
attributeToString(int attribute)176 const char *attributeToString(int attribute)
177 {
178 switch (attribute) {
179 C2S(NL80211_ATTR_UNSPEC)
180
181 C2S(NL80211_ATTR_WIPHY)
182 C2S(NL80211_ATTR_WIPHY_NAME)
183
184 C2S(NL80211_ATTR_IFINDEX)
185 C2S(NL80211_ATTR_IFNAME)
186 C2S(NL80211_ATTR_IFTYPE)
187
188 C2S(NL80211_ATTR_MAC)
189
190 C2S(NL80211_ATTR_KEY_DATA)
191 C2S(NL80211_ATTR_KEY_IDX)
192 C2S(NL80211_ATTR_KEY_CIPHER)
193 C2S(NL80211_ATTR_KEY_SEQ)
194 C2S(NL80211_ATTR_KEY_DEFAULT)
195
196 C2S(NL80211_ATTR_BEACON_INTERVAL)
197 C2S(NL80211_ATTR_DTIM_PERIOD)
198 C2S(NL80211_ATTR_BEACON_HEAD)
199 C2S(NL80211_ATTR_BEACON_TAIL)
200
201 C2S(NL80211_ATTR_STA_AID)
202 C2S(NL80211_ATTR_STA_FLAGS)
203 C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
204 C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
205 C2S(NL80211_ATTR_STA_VLAN)
206 C2S(NL80211_ATTR_STA_INFO)
207
208 C2S(NL80211_ATTR_WIPHY_BANDS)
209
210 C2S(NL80211_ATTR_MNTR_FLAGS)
211
212 C2S(NL80211_ATTR_MESH_ID)
213 C2S(NL80211_ATTR_STA_PLINK_ACTION)
214 C2S(NL80211_ATTR_MPATH_NEXT_HOP)
215 C2S(NL80211_ATTR_MPATH_INFO)
216
217 C2S(NL80211_ATTR_BSS_CTS_PROT)
218 C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
219 C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
220
221 C2S(NL80211_ATTR_HT_CAPABILITY)
222
223 C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
224
225 C2S(NL80211_ATTR_REG_ALPHA2)
226 C2S(NL80211_ATTR_REG_RULES)
227
228 C2S(NL80211_ATTR_MESH_CONFIG)
229
230 C2S(NL80211_ATTR_BSS_BASIC_RATES)
231
232 C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
233 C2S(NL80211_ATTR_WIPHY_FREQ)
234 C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
235
236 C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
237
238 C2S(NL80211_ATTR_MGMT_SUBTYPE)
239 C2S(NL80211_ATTR_IE)
240
241 C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
242
243 C2S(NL80211_ATTR_SCAN_FREQUENCIES)
244 C2S(NL80211_ATTR_SCAN_SSIDS)
245 C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
246 C2S(NL80211_ATTR_BSS)
247
248 C2S(NL80211_ATTR_REG_INITIATOR)
249 C2S(NL80211_ATTR_REG_TYPE)
250
251 C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
252
253 C2S(NL80211_ATTR_FRAME)
254 C2S(NL80211_ATTR_SSID)
255 C2S(NL80211_ATTR_AUTH_TYPE)
256 C2S(NL80211_ATTR_REASON_CODE)
257
258 C2S(NL80211_ATTR_KEY_TYPE)
259
260 C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
261 C2S(NL80211_ATTR_CIPHER_SUITES)
262
263 C2S(NL80211_ATTR_FREQ_BEFORE)
264 C2S(NL80211_ATTR_FREQ_AFTER)
265
266 C2S(NL80211_ATTR_FREQ_FIXED)
267
268
269 C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
270 C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
271 C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
272 C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
273
274 C2S(NL80211_ATTR_TIMED_OUT)
275
276 C2S(NL80211_ATTR_USE_MFP)
277
278 C2S(NL80211_ATTR_STA_FLAGS2)
279
280 C2S(NL80211_ATTR_CONTROL_PORT)
281
282 C2S(NL80211_ATTR_TESTDATA)
283
284 C2S(NL80211_ATTR_PRIVACY)
285
286 C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
287 C2S(NL80211_ATTR_STATUS_CODE)
288
289 C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
290 C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
291 C2S(NL80211_ATTR_WPA_VERSIONS)
292 C2S(NL80211_ATTR_AKM_SUITES)
293
294 C2S(NL80211_ATTR_REQ_IE)
295 C2S(NL80211_ATTR_RESP_IE)
296
297 C2S(NL80211_ATTR_PREV_BSSID)
298
299 C2S(NL80211_ATTR_KEY)
300 C2S(NL80211_ATTR_KEYS)
301
302 C2S(NL80211_ATTR_PID)
303
304 C2S(NL80211_ATTR_4ADDR)
305
306 C2S(NL80211_ATTR_SURVEY_INFO)
307
308 C2S(NL80211_ATTR_PMKID)
309 C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
310
311 C2S(NL80211_ATTR_DURATION)
312
313 C2S(NL80211_ATTR_COOKIE)
314
315 C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
316
317 C2S(NL80211_ATTR_TX_RATES)
318
319 C2S(NL80211_ATTR_FRAME_MATCH)
320
321 C2S(NL80211_ATTR_ACK)
322
323 C2S(NL80211_ATTR_PS_STATE)
324
325 C2S(NL80211_ATTR_CQM)
326
327 C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
328
329 C2S(NL80211_ATTR_AP_ISOLATE)
330
331 C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
332 C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
333
334 C2S(NL80211_ATTR_TX_FRAME_TYPES)
335 C2S(NL80211_ATTR_RX_FRAME_TYPES)
336 C2S(NL80211_ATTR_FRAME_TYPE)
337
338 C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
339 C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
340
341 C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
342
343 C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
344 C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
345
346 C2S(NL80211_ATTR_MCAST_RATE)
347
348 C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
349
350 C2S(NL80211_ATTR_BSS_HT_OPMODE)
351
352 C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
353
354 C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
355
356 C2S(NL80211_ATTR_MESH_SETUP)
357
358 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
359 C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
360
361 C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
362 C2S(NL80211_ATTR_STA_PLINK_STATE)
363
364 C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
365 C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
366
367 C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
368
369 C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
370 C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
371
372 C2S(NL80211_ATTR_REKEY_DATA)
373
374 C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
375 C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
376
377 C2S(NL80211_ATTR_SCAN_SUPP_RATES)
378
379 C2S(NL80211_ATTR_HIDDEN_SSID)
380
381 C2S(NL80211_ATTR_IE_PROBE_RESP)
382 C2S(NL80211_ATTR_IE_ASSOC_RESP)
383
384 C2S(NL80211_ATTR_STA_WME)
385 C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
386
387 C2S(NL80211_ATTR_ROAM_SUPPORT)
388
389 C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
390 C2S(NL80211_ATTR_MAX_MATCH_SETS)
391
392 C2S(NL80211_ATTR_PMKSA_CANDIDATE)
393
394 C2S(NL80211_ATTR_TX_NO_CCK_RATE)
395
396 C2S(NL80211_ATTR_TDLS_ACTION)
397 C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
398 C2S(NL80211_ATTR_TDLS_OPERATION)
399 C2S(NL80211_ATTR_TDLS_SUPPORT)
400 C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
401
402 C2S(NL80211_ATTR_DEVICE_AP_SME)
403
404 C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
405
406 C2S(NL80211_ATTR_FEATURE_FLAGS)
407
408 C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
409
410 C2S(NL80211_ATTR_PROBE_RESP)
411
412 C2S(NL80211_ATTR_DFS_REGION)
413
414 C2S(NL80211_ATTR_DISABLE_HT)
415 C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
416
417 C2S(NL80211_ATTR_NOACK_MAP)
418
419 C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
420
421 C2S(NL80211_ATTR_RX_SIGNAL_DBM)
422
423 C2S(NL80211_ATTR_BG_SCAN_PERIOD)
424
425 C2S(NL80211_ATTR_WDEV)
426
427 C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
428
429 C2S(NL80211_ATTR_CONN_FAILED_REASON)
430
431 C2S(NL80211_ATTR_SAE_DATA)
432
433 C2S(NL80211_ATTR_VHT_CAPABILITY)
434
435 C2S(NL80211_ATTR_SCAN_FLAGS)
436
437 C2S(NL80211_ATTR_CHANNEL_WIDTH)
438 C2S(NL80211_ATTR_CENTER_FREQ1)
439 C2S(NL80211_ATTR_CENTER_FREQ2)
440
441 C2S(NL80211_ATTR_P2P_CTWINDOW)
442 C2S(NL80211_ATTR_P2P_OPPPS)
443
444 C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
445
446 C2S(NL80211_ATTR_ACL_POLICY)
447
448 C2S(NL80211_ATTR_MAC_ADDRS)
449
450 C2S(NL80211_ATTR_MAC_ACL_MAX)
451
452 C2S(NL80211_ATTR_RADAR_EVENT)
453
454 C2S(NL80211_ATTR_EXT_CAPA)
455 C2S(NL80211_ATTR_EXT_CAPA_MASK)
456
457 C2S(NL80211_ATTR_STA_CAPABILITY)
458 C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
459
460 C2S(NL80211_ATTR_PROTOCOL_FEATURES)
461 C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
462
463 C2S(NL80211_ATTR_DISABLE_VHT)
464 C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
465
466 C2S(NL80211_ATTR_MDID)
467 C2S(NL80211_ATTR_IE_RIC)
468
469 C2S(NL80211_ATTR_CRIT_PROT_ID)
470 C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
471
472 C2S(NL80211_ATTR_PEER_AID)
473
474 C2S(NL80211_ATTR_COALESCE_RULE)
475
476 C2S(NL80211_ATTR_CH_SWITCH_COUNT)
477 C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
478 C2S(NL80211_ATTR_CSA_IES)
479 C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
480 C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
481
482 C2S(NL80211_ATTR_RXMGMT_FLAGS)
483
484 C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
485
486 C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
487
488 C2S(NL80211_ATTR_HANDLE_DFS)
489
490 C2S(NL80211_ATTR_SUPPORT_5_MHZ)
491 C2S(NL80211_ATTR_SUPPORT_10_MHZ)
492
493 C2S(NL80211_ATTR_OPMODE_NOTIF)
494
495 C2S(NL80211_ATTR_VENDOR_ID)
496 C2S(NL80211_ATTR_VENDOR_SUBCMD)
497 C2S(NL80211_ATTR_VENDOR_DATA)
498 C2S(NL80211_ATTR_VENDOR_EVENTS)
499
500 C2S(NL80211_ATTR_QOS_MAP)
501 default:
502 return "NL80211_ATTR_UNKNOWN";
503 }
504 }
505
log()506 void WifiEvent::log() {
507 parse();
508
509 byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
510 int len = genlmsg_attrlen(mHeader, 0);
511 ALOGD("cmd = %s, len = %d", get_cmdString(), len);
512 ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd());
513
514 for (int i = 0; i < len; i += 16) {
515 char line[81];
516 int linelen = min(16, len - i);
517 int offset = 0;
518 appendFmt(line, offset, "%02x", data[i]);
519 for (int j = 1; j < linelen; j++) {
520 appendFmt(line, offset, " %02x", data[i+j]);
521 }
522
523 for (int j = linelen; j < 16; j++) {
524 appendFmt(line, offset, " ");
525 }
526
527 line[23] = '-';
528
529 appendFmt(line, offset, " ");
530
531 for (int j = 0; j < linelen; j++) {
532 if (isprint(data[i+j])) {
533 appendFmt(line, offset, "%c", data[i+j]);
534 } else {
535 appendFmt(line, offset, "-");
536 }
537 }
538
539 ALOGD("%s", line);
540 }
541
542 for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) {
543 if (mAttributes[i] != NULL) {
544 ALOGD("found attribute %s", attributeToString(i));
545 }
546 }
547
548 ALOGD("-- End of message --");
549 }
550
get_cmdString()551 const char *WifiEvent::get_cmdString() {
552 return cmdToString(get_cmd());
553 }
554
555
parse()556 int WifiEvent::parse() {
557 if (mHeader != NULL) {
558 return WIFI_SUCCESS;
559 }
560 mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
561 int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
562 genlmsg_attrlen(mHeader, 0), NULL);
563
564 // ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
565 return result;
566 }
567
create(int family,uint8_t cmd,int flags,int hdrlen)568 int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
569
570 destroy();
571
572 mMsg = nlmsg_alloc();
573 if (mMsg != NULL) {
574 genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
575 hdrlen, flags, cmd, /* version = */ 0);
576 return WIFI_SUCCESS;
577 } else {
578 return WIFI_ERROR_OUT_OF_MEMORY;
579 }
580 }
581
create(uint32_t id,int subcmd)582 int WifiRequest::create(uint32_t id, int subcmd) {
583 int res = create(NL80211_CMD_VENDOR);
584 if (res < 0) {
585 return res;
586 }
587
588 res = put_u32(NL80211_ATTR_VENDOR_ID, id);
589 if (res < 0) {
590 return res;
591 }
592
593 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
594 if (res < 0) {
595 return res;
596 }
597
598 if (mIface != -1) {
599 res = set_iface_id(mIface);
600 }
601
602 return res;
603 }
604
605
no_seq_check(struct nl_msg * msg,void * arg)606 static int no_seq_check(struct nl_msg *msg, void *arg)
607 {
608 return NL_OK;
609 }
610
requestResponse()611 int WifiCommand::requestResponse() {
612 int err = create(); /* create the message */
613 if (err < 0) {
614 return err;
615 }
616
617 return requestResponse(mMsg);
618 }
619
requestResponse(WifiRequest & request)620 int WifiCommand::requestResponse(WifiRequest& request) {
621 pthread_mutex_lock(&ResponseMutex);
622 int err = 0, res = 0;
623
624 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
625 if (!cb)
626 goto out;
627
628 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */
629 if (err < 0)
630 goto out;
631
632 err = 1;
633
634 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
635 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
636 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
637 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
638 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
639
640 while (err > 0) { /* wait for reply */
641 int res = nl_recvmsgs(mInfo->cmd_sock, cb);
642 if (res) {
643 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
644 }
645 }
646 out:
647 nl_cb_put(cb);
648 pthread_mutex_unlock(&ResponseMutex);
649 return err;
650 }
651
requestEvent(int cmd)652 int WifiCommand::requestEvent(int cmd) {
653
654 ALOGD("requesting event %d", cmd);
655
656 int res = wifi_register_handler(wifiHandle(), cmd, 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 ALOGD("waiting for response %d", cmd);
666
667 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
668 if (res < 0)
669 goto out;
670
671 ALOGD("waiting for event %d", cmd);
672 res = mCondition.wait();
673 if (res < 0)
674 goto out;
675
676 out:
677 wifi_unregister_handler(wifiHandle(), cmd);
678 return res;
679 }
680
requestVendorEvent(uint32_t id,int subcmd)681 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
682
683 int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
684 if (res < 0) {
685 return res;
686 }
687
688 res = create(); /* create the message */
689 if (res < 0)
690 goto out;
691
692 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
693 if (res < 0)
694 goto out;
695
696 res = mCondition.wait();
697 if (res < 0)
698 goto out;
699
700 out:
701 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
702 return res;
703 }
704
705 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)706 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
707 // ALOGD("response_handler called");
708 WifiCommand *cmd = (WifiCommand *)arg;
709 WifiEvent reply(msg);
710 int res = reply.parse();
711 if (res < 0) {
712 ALOGE("Failed to parse reply message = %d", res);
713 return NL_SKIP;
714 } else {
715 // reply.log();
716 return cmd->handleResponse(reply);
717 }
718 }
719
event_handler(struct nl_msg * msg,void * arg)720 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
721 WifiCommand *cmd = (WifiCommand *)arg;
722 WifiEvent event(msg);
723 int res = event.parse();
724 if (res < 0) {
725 ALOGE("Failed to parse event = %d", res);
726 res = NL_SKIP;
727 } else {
728 res = cmd->handleEvent(event);
729 }
730
731 cmd->mCondition.signal();
732 return res;
733 }
734
735 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)736 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
737 // ALOGD("valid_handler called");
738 int *err = (int *)arg;
739 *err = 0;
740 return NL_SKIP;
741 }
742
ack_handler(struct nl_msg * msg,void * arg)743 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
744 // ALOGD("ack_handler called");
745 int *err = (int *)arg;
746 *err = 0;
747 return NL_STOP;
748 }
749
finish_handler(struct nl_msg * msg,void * arg)750 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
751 // ALOGD("finish_handler called");
752 int *ret = (int *)arg;
753 *ret = 0;
754 return NL_SKIP;
755 }
756
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)757 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
758 int *ret = (int *)arg;
759 *ret = err->error;
760
761 // ALOGD("error_handler received : %d", err->error);
762 return NL_SKIP;
763 }
764