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