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