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