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 
542     destroy();
543 
544     mMsg = nlmsg_alloc();
545     if (mMsg != NULL) {
546         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
547                 hdrlen, flags, cmd, /* version = */ 0);
548         return WIFI_SUCCESS;
549     } else {
550         return WIFI_ERROR_OUT_OF_MEMORY;
551     }
552 }
553 
create(uint32_t id,int subcmd)554 int WifiRequest::create(uint32_t id, int subcmd) {
555     int res = create(NL80211_CMD_VENDOR);
556     if (res < 0) {
557         return res;
558     }
559 
560     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
561     if (res < 0) {
562         return res;
563     }
564 
565     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
566     if (res < 0) {
567         return res;
568     }
569 
570     if (mIface != -1) {
571         res = set_iface_id(mIface);
572     }
573 
574     return res;
575 }
576 
577 
no_seq_check(struct nl_msg * msg,void * arg)578 static int no_seq_check(struct nl_msg *msg, void *arg)
579 {
580 	return NL_OK;
581 }
582 
requestResponse()583 int WifiCommand::requestResponse() {
584     int err = create();                 /* create the message */
585     if (err < 0) {
586         return err;
587     }
588 
589     return requestResponse(mMsg);
590 }
591 
requestResponse(WifiRequest & request)592 int WifiCommand::requestResponse(WifiRequest& request) {
593     int err = 0;
594 
595     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
596     if (!cb)
597         goto out;
598 
599     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
600     if (err < 0)
601         goto out;
602 
603     err = 1;
604 
605     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
606     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
607     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
608     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
609     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
610 
611     while (err > 0) {                   /* wait for reply */
612         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
613         if (res) {
614             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
615         }
616     }
617 out:
618     nl_cb_put(cb);
619     return err;
620 }
621 
requestEvent(int cmd)622 int WifiCommand::requestEvent(int cmd) {
623 
624     ALOGD("requesting event %d", cmd);
625 
626     int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
627     if (res < 0) {
628         return res;
629     }
630 
631     res = create();                                                 /* create the message */
632     if (res < 0)
633         goto out;
634 
635     ALOGD("waiting for response %d", cmd);
636 
637     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
638     if (res < 0)
639         goto out;
640 
641     ALOGD("waiting for event %d", cmd);
642     res = mCondition.wait();
643     if (res < 0)
644         goto out;
645 
646 out:
647     wifi_unregister_handler(wifiHandle(), cmd);
648     return res;
649 }
650 
requestVendorEvent(uint32_t id,int subcmd)651 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
652 
653     int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
654     if (res < 0) {
655         return res;
656     }
657 
658     res = create();                                                 /* create the message */
659     if (res < 0)
660         goto out;
661 
662     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
663     if (res < 0)
664         goto out;
665 
666     res = mCondition.wait();
667     if (res < 0)
668         goto out;
669 
670 out:
671     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
672     return res;
673 }
674 
675 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)676 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
677     // ALOGD("response_handler called");
678     WifiCommand *cmd = (WifiCommand *)arg;
679     WifiEvent reply(msg);
680     int res = reply.parse();
681     if (res < 0) {
682         ALOGE("Failed to parse reply message = %d", res);
683         return NL_SKIP;
684     } else {
685         // reply.log();
686         return cmd->handleResponse(reply);
687     }
688 }
689 
event_handler(struct nl_msg * msg,void * arg)690 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
691     WifiCommand *cmd = (WifiCommand *)arg;
692     WifiEvent event(msg);
693     int res = event.parse();
694     if (res < 0) {
695         ALOGE("Failed to parse event = %d", res);
696         res = NL_SKIP;
697     } else {
698         res = cmd->handleEvent(event);
699     }
700 
701     cmd->mCondition.signal();
702     return res;
703 }
704 
705 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)706 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
707     // ALOGD("valid_handler called");
708     int *err = (int *)arg;
709     *err = 0;
710     return NL_SKIP;
711 }
712 
ack_handler(struct nl_msg * msg,void * arg)713 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
714     // ALOGD("ack_handler called");
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     // ALOGD("finish_handler called");
722     int *ret = (int *)arg;
723     *ret = 0;
724     return NL_SKIP;
725 }
726 
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)727 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
728     int *ret = (int *)arg;
729     *ret = err->error;
730 
731     // ALOGD("error_handler received : %d", err->error);
732     return NL_SKIP;
733 }
734