1 /*
2  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3  *
4  * Not a Contribution
5  */
6 
7 /*
8  * Copyright (C) 2014 The Android Open Source Project
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22 
23 #include <stdint.h>
24 #include <fcntl.h>
25 #include <sys/socket.h>
26 #include <netlink/genl/genl.h>
27 #include <netlink/genl/family.h>
28 #include <netlink/genl/ctrl.h>
29 #include <linux/rtnetlink.h>
30 #include <netpacket/packet.h>
31 #include <linux/filter.h>
32 #include <linux/errqueue.h>
33 
34 #include <linux/pkt_sched.h>
35 #include <netlink/object-api.h>
36 #include <netlink/netlink.h>
37 #include <netlink/socket.h>
38 #include <net/if.h>
39 
40 #include "nl80211_copy.h"
41 #include <ctype.h>
42 
43 #include <hardware_legacy/wifi_hal.h>
44 #include "common.h"
45 #include "cpp_bindings.h"
46 #include "vendor_definitions.h"
47 
appendFmt(char * buf,size_t buf_len,int & offset,const char * fmt,...)48 void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...)
49 {
50     va_list params;
51     va_start(params, fmt);
52     offset += vsnprintf(buf + offset, buf_len - offset, fmt, params);
53     va_end(params);
54 }
55 
56 #define C2S(x)  case x: return #x;
57 
cmdToString(int cmd)58 static const char *cmdToString(int cmd)
59 {
60     switch (cmd) {
61     C2S(NL80211_CMD_UNSPEC)
62     C2S(NL80211_CMD_GET_WIPHY)
63     C2S(NL80211_CMD_SET_WIPHY)
64     C2S(NL80211_CMD_NEW_WIPHY)
65     C2S(NL80211_CMD_DEL_WIPHY)
66     C2S(NL80211_CMD_GET_INTERFACE)
67     C2S(NL80211_CMD_SET_INTERFACE)
68     C2S(NL80211_CMD_NEW_INTERFACE)
69     C2S(NL80211_CMD_DEL_INTERFACE)
70     C2S(NL80211_CMD_GET_KEY)
71     C2S(NL80211_CMD_SET_KEY)
72     C2S(NL80211_CMD_NEW_KEY)
73     C2S(NL80211_CMD_DEL_KEY)
74     C2S(NL80211_CMD_GET_BEACON)
75     C2S(NL80211_CMD_SET_BEACON)
76     C2S(NL80211_CMD_START_AP)
77     C2S(NL80211_CMD_STOP_AP)
78     C2S(NL80211_CMD_GET_STATION)
79     C2S(NL80211_CMD_SET_STATION)
80     C2S(NL80211_CMD_NEW_STATION)
81     C2S(NL80211_CMD_DEL_STATION)
82     C2S(NL80211_CMD_GET_MPATH)
83     C2S(NL80211_CMD_SET_MPATH)
84     C2S(NL80211_CMD_NEW_MPATH)
85     C2S(NL80211_CMD_DEL_MPATH)
86     C2S(NL80211_CMD_SET_BSS)
87     C2S(NL80211_CMD_SET_REG)
88     C2S(NL80211_CMD_REQ_SET_REG)
89     C2S(NL80211_CMD_GET_MESH_CONFIG)
90     C2S(NL80211_CMD_SET_MESH_CONFIG)
91     C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
92     C2S(NL80211_CMD_GET_REG)
93     C2S(NL80211_CMD_GET_SCAN)
94     C2S(NL80211_CMD_TRIGGER_SCAN)
95     C2S(NL80211_CMD_NEW_SCAN_RESULTS)
96     C2S(NL80211_CMD_SCAN_ABORTED)
97     C2S(NL80211_CMD_REG_CHANGE)
98     C2S(NL80211_CMD_AUTHENTICATE)
99     C2S(NL80211_CMD_ASSOCIATE)
100     C2S(NL80211_CMD_DEAUTHENTICATE)
101     C2S(NL80211_CMD_DISASSOCIATE)
102     C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
103     C2S(NL80211_CMD_REG_BEACON_HINT)
104     C2S(NL80211_CMD_JOIN_IBSS)
105     C2S(NL80211_CMD_LEAVE_IBSS)
106     C2S(NL80211_CMD_TESTMODE)
107     C2S(NL80211_CMD_CONNECT)
108     C2S(NL80211_CMD_ROAM)
109     C2S(NL80211_CMD_DISCONNECT)
110     C2S(NL80211_CMD_SET_WIPHY_NETNS)
111     C2S(NL80211_CMD_GET_SURVEY)
112     C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
113     C2S(NL80211_CMD_SET_PMKSA)
114     C2S(NL80211_CMD_DEL_PMKSA)
115     C2S(NL80211_CMD_FLUSH_PMKSA)
116     C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
117     C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
118     C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
119     C2S(NL80211_CMD_REGISTER_FRAME)
120     C2S(NL80211_CMD_FRAME)
121     C2S(NL80211_CMD_FRAME_TX_STATUS)
122     C2S(NL80211_CMD_SET_POWER_SAVE)
123     C2S(NL80211_CMD_GET_POWER_SAVE)
124     C2S(NL80211_CMD_SET_CQM)
125     C2S(NL80211_CMD_NOTIFY_CQM)
126     C2S(NL80211_CMD_SET_CHANNEL)
127     C2S(NL80211_CMD_SET_WDS_PEER)
128     C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
129     C2S(NL80211_CMD_JOIN_MESH)
130     C2S(NL80211_CMD_LEAVE_MESH)
131     C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
132     C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
133     C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
134     C2S(NL80211_CMD_GET_WOWLAN)
135     C2S(NL80211_CMD_SET_WOWLAN)
136     C2S(NL80211_CMD_START_SCHED_SCAN)
137     C2S(NL80211_CMD_STOP_SCHED_SCAN)
138     C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
139     C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
140     C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
141     C2S(NL80211_CMD_PMKSA_CANDIDATE)
142     C2S(NL80211_CMD_TDLS_OPER)
143     C2S(NL80211_CMD_TDLS_MGMT)
144     C2S(NL80211_CMD_UNEXPECTED_FRAME)
145     C2S(NL80211_CMD_PROBE_CLIENT)
146     C2S(NL80211_CMD_REGISTER_BEACONS)
147     C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
148     C2S(NL80211_CMD_SET_NOACK_MAP)
149     C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
150     C2S(NL80211_CMD_START_P2P_DEVICE)
151     C2S(NL80211_CMD_STOP_P2P_DEVICE)
152     C2S(NL80211_CMD_CONN_FAILED)
153     C2S(NL80211_CMD_SET_MCAST_RATE)
154     C2S(NL80211_CMD_SET_MAC_ACL)
155     C2S(NL80211_CMD_RADAR_DETECT)
156     C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
157     C2S(NL80211_CMD_UPDATE_FT_IES)
158     C2S(NL80211_CMD_FT_EVENT)
159     C2S(NL80211_CMD_CRIT_PROTOCOL_START)
160     C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
161     C2S(NL80211_CMD_GET_COALESCE)
162     C2S(NL80211_CMD_SET_COALESCE)
163     C2S(NL80211_CMD_CHANNEL_SWITCH)
164     C2S(NL80211_CMD_VENDOR)
165     C2S(NL80211_CMD_SET_QOS_MAP)
166     default:
167         return "NL80211_CMD_UNKNOWN";
168     }
169 }
170 
attributeToString(int attribute)171 const char *attributeToString(int attribute)
172 {
173     switch (attribute) {
174     C2S(NL80211_ATTR_UNSPEC)
175 
176     C2S(NL80211_ATTR_WIPHY)
177     C2S(NL80211_ATTR_WIPHY_NAME)
178 
179     C2S(NL80211_ATTR_IFINDEX)
180     C2S(NL80211_ATTR_IFNAME)
181     C2S(NL80211_ATTR_IFTYPE)
182 
183     C2S(NL80211_ATTR_MAC)
184 
185     C2S(NL80211_ATTR_KEY_DATA)
186     C2S(NL80211_ATTR_KEY_IDX)
187     C2S(NL80211_ATTR_KEY_CIPHER)
188     C2S(NL80211_ATTR_KEY_SEQ)
189     C2S(NL80211_ATTR_KEY_DEFAULT)
190 
191     C2S(NL80211_ATTR_BEACON_INTERVAL)
192     C2S(NL80211_ATTR_DTIM_PERIOD)
193     C2S(NL80211_ATTR_BEACON_HEAD)
194     C2S(NL80211_ATTR_BEACON_TAIL)
195 
196     C2S(NL80211_ATTR_STA_AID)
197     C2S(NL80211_ATTR_STA_FLAGS)
198     C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
199     C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
200     C2S(NL80211_ATTR_STA_VLAN)
201     C2S(NL80211_ATTR_STA_INFO)
202 
203     C2S(NL80211_ATTR_WIPHY_BANDS)
204 
205     C2S(NL80211_ATTR_MNTR_FLAGS)
206 
207     C2S(NL80211_ATTR_MESH_ID)
208     C2S(NL80211_ATTR_STA_PLINK_ACTION)
209     C2S(NL80211_ATTR_MPATH_NEXT_HOP)
210     C2S(NL80211_ATTR_MPATH_INFO)
211 
212     C2S(NL80211_ATTR_BSS_CTS_PROT)
213     C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
214     C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
215 
216     C2S(NL80211_ATTR_HT_CAPABILITY)
217 
218     C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
219 
220     C2S(NL80211_ATTR_REG_ALPHA2)
221     C2S(NL80211_ATTR_REG_RULES)
222 
223     C2S(NL80211_ATTR_MESH_CONFIG)
224 
225     C2S(NL80211_ATTR_BSS_BASIC_RATES)
226 
227     C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
228     C2S(NL80211_ATTR_WIPHY_FREQ)
229     C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
230 
231     C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
232 
233     C2S(NL80211_ATTR_MGMT_SUBTYPE)
234     C2S(NL80211_ATTR_IE)
235 
236     C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
237 
238     C2S(NL80211_ATTR_SCAN_FREQUENCIES)
239     C2S(NL80211_ATTR_SCAN_SSIDS)
240     C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
241     C2S(NL80211_ATTR_BSS)
242 
243     C2S(NL80211_ATTR_REG_INITIATOR)
244     C2S(NL80211_ATTR_REG_TYPE)
245 
246     C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
247 
248     C2S(NL80211_ATTR_FRAME)
249     C2S(NL80211_ATTR_SSID)
250     C2S(NL80211_ATTR_AUTH_TYPE)
251     C2S(NL80211_ATTR_REASON_CODE)
252 
253     C2S(NL80211_ATTR_KEY_TYPE)
254 
255     C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
256     C2S(NL80211_ATTR_CIPHER_SUITES)
257 
258     C2S(NL80211_ATTR_FREQ_BEFORE)
259     C2S(NL80211_ATTR_FREQ_AFTER)
260 
261     C2S(NL80211_ATTR_FREQ_FIXED)
262 
263 
264     C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
265     C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
266     C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
267     C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
268 
269     C2S(NL80211_ATTR_TIMED_OUT)
270 
271     C2S(NL80211_ATTR_USE_MFP)
272 
273     C2S(NL80211_ATTR_STA_FLAGS2)
274 
275     C2S(NL80211_ATTR_CONTROL_PORT)
276 
277     C2S(NL80211_ATTR_TESTDATA)
278 
279     C2S(NL80211_ATTR_PRIVACY)
280 
281     C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
282     C2S(NL80211_ATTR_STATUS_CODE)
283 
284     C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
285     C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
286     C2S(NL80211_ATTR_WPA_VERSIONS)
287     C2S(NL80211_ATTR_AKM_SUITES)
288 
289     C2S(NL80211_ATTR_REQ_IE)
290     C2S(NL80211_ATTR_RESP_IE)
291 
292     C2S(NL80211_ATTR_PREV_BSSID)
293 
294     C2S(NL80211_ATTR_KEY)
295     C2S(NL80211_ATTR_KEYS)
296 
297     C2S(NL80211_ATTR_PID)
298 
299     C2S(NL80211_ATTR_4ADDR)
300 
301     C2S(NL80211_ATTR_SURVEY_INFO)
302 
303     C2S(NL80211_ATTR_PMKID)
304     C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
305 
306     C2S(NL80211_ATTR_DURATION)
307 
308     C2S(NL80211_ATTR_COOKIE)
309 
310     C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
311 
312     C2S(NL80211_ATTR_TX_RATES)
313 
314     C2S(NL80211_ATTR_FRAME_MATCH)
315 
316     C2S(NL80211_ATTR_ACK)
317 
318     C2S(NL80211_ATTR_PS_STATE)
319 
320     C2S(NL80211_ATTR_CQM)
321 
322     C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
323 
324     C2S(NL80211_ATTR_AP_ISOLATE)
325 
326     C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
327     C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
328 
329     C2S(NL80211_ATTR_TX_FRAME_TYPES)
330     C2S(NL80211_ATTR_RX_FRAME_TYPES)
331     C2S(NL80211_ATTR_FRAME_TYPE)
332 
333     C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
334     C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
335 
336     C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
337 
338     C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
339     C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
340 
341     C2S(NL80211_ATTR_MCAST_RATE)
342 
343     C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
344 
345     C2S(NL80211_ATTR_BSS_HT_OPMODE)
346 
347     C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
348 
349     C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
350 
351     C2S(NL80211_ATTR_MESH_SETUP)
352 
353     C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
354     C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
355 
356     C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
357     C2S(NL80211_ATTR_STA_PLINK_STATE)
358 
359     C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
360     C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
361 
362     C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
363 
364     C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
365     C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
366 
367     C2S(NL80211_ATTR_REKEY_DATA)
368 
369     C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
370     C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
371 
372     C2S(NL80211_ATTR_SCAN_SUPP_RATES)
373 
374     C2S(NL80211_ATTR_HIDDEN_SSID)
375 
376     C2S(NL80211_ATTR_IE_PROBE_RESP)
377     C2S(NL80211_ATTR_IE_ASSOC_RESP)
378 
379     C2S(NL80211_ATTR_STA_WME)
380     C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
381 
382     C2S(NL80211_ATTR_ROAM_SUPPORT)
383 
384     C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
385     C2S(NL80211_ATTR_MAX_MATCH_SETS)
386 
387     C2S(NL80211_ATTR_PMKSA_CANDIDATE)
388 
389     C2S(NL80211_ATTR_TX_NO_CCK_RATE)
390 
391     C2S(NL80211_ATTR_TDLS_ACTION)
392     C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
393     C2S(NL80211_ATTR_TDLS_OPERATION)
394     C2S(NL80211_ATTR_TDLS_SUPPORT)
395     C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
396 
397     C2S(NL80211_ATTR_DEVICE_AP_SME)
398 
399     C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
400 
401     C2S(NL80211_ATTR_FEATURE_FLAGS)
402 
403     C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
404 
405     C2S(NL80211_ATTR_PROBE_RESP)
406 
407     C2S(NL80211_ATTR_DFS_REGION)
408 
409     C2S(NL80211_ATTR_DISABLE_HT)
410     C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
411 
412     C2S(NL80211_ATTR_NOACK_MAP)
413 
414     C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
415 
416     C2S(NL80211_ATTR_RX_SIGNAL_DBM)
417 
418     C2S(NL80211_ATTR_BG_SCAN_PERIOD)
419 
420     C2S(NL80211_ATTR_WDEV)
421 
422     C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
423 
424     C2S(NL80211_ATTR_CONN_FAILED_REASON)
425 
426     C2S(NL80211_ATTR_SAE_DATA)
427 
428     C2S(NL80211_ATTR_VHT_CAPABILITY)
429 
430     C2S(NL80211_ATTR_SCAN_FLAGS)
431 
432     C2S(NL80211_ATTR_CHANNEL_WIDTH)
433     C2S(NL80211_ATTR_CENTER_FREQ1)
434     C2S(NL80211_ATTR_CENTER_FREQ2)
435 
436     C2S(NL80211_ATTR_P2P_CTWINDOW)
437     C2S(NL80211_ATTR_P2P_OPPPS)
438 
439     C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
440 
441     C2S(NL80211_ATTR_ACL_POLICY)
442 
443     C2S(NL80211_ATTR_MAC_ADDRS)
444 
445     C2S(NL80211_ATTR_MAC_ACL_MAX)
446 
447     C2S(NL80211_ATTR_RADAR_EVENT)
448 
449     C2S(NL80211_ATTR_EXT_CAPA)
450     C2S(NL80211_ATTR_EXT_CAPA_MASK)
451 
452     C2S(NL80211_ATTR_STA_CAPABILITY)
453     C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
454 
455     C2S(NL80211_ATTR_PROTOCOL_FEATURES)
456     C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
457 
458     C2S(NL80211_ATTR_DISABLE_VHT)
459     C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
460 
461     C2S(NL80211_ATTR_MDID)
462     C2S(NL80211_ATTR_IE_RIC)
463 
464     C2S(NL80211_ATTR_CRIT_PROT_ID)
465     C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
466 
467     C2S(NL80211_ATTR_PEER_AID)
468 
469     C2S(NL80211_ATTR_COALESCE_RULE)
470 
471     C2S(NL80211_ATTR_CH_SWITCH_COUNT)
472     C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
473     C2S(NL80211_ATTR_CSA_IES)
474     C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
475     C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
476 
477     C2S(NL80211_ATTR_RXMGMT_FLAGS)
478 
479     C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
480 
481     C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
482 
483     C2S(NL80211_ATTR_HANDLE_DFS)
484 
485     C2S(NL80211_ATTR_SUPPORT_5_MHZ)
486     C2S(NL80211_ATTR_SUPPORT_10_MHZ)
487 
488     C2S(NL80211_ATTR_OPMODE_NOTIF)
489 
490     C2S(NL80211_ATTR_VENDOR_ID)
491     C2S(NL80211_ATTR_VENDOR_SUBCMD)
492     C2S(NL80211_ATTR_VENDOR_DATA)
493     C2S(NL80211_ATTR_VENDOR_EVENTS)
494 
495     C2S(NL80211_ATTR_QOS_MAP)
496     default:
497         return "NL80211_ATTR_UNKNOWN";
498     }
499 }
500 
log()501 void WifiEvent::log() {
502     parse();
503 
504     byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
505     int len = genlmsg_attrlen(mHeader, 0);
506 
507     for (int i = 0; i < len; i += 16) {
508         char line[81];
509         int linelen = min(16, len - i);
510         int offset = 0;
511         appendFmt(line, sizeof(line), offset, "%02x", data[i]);
512         for (int j = 1; j < linelen; j++) {
513             appendFmt(line, sizeof(line), offset, " %02x", data[i+j]);
514         }
515 
516         for (int j = linelen; j < 16; j++) {
517             appendFmt(line, sizeof(line), offset, "   ");
518         }
519 
520         line[23] = '-';
521 
522         appendFmt(line, sizeof(line), offset, "  ");
523 
524         for (int j = 0; j < linelen; j++) {
525             if (isprint(data[i+j])) {
526                 appendFmt(line, sizeof(line), offset, "%c", data[i+j]);
527             } else {
528                 appendFmt(line, sizeof(line), offset, "-");
529             }
530         }
531 
532     }
533 
534 }
535 
get_cmdString()536 const char *WifiEvent::get_cmdString() {
537     return cmdToString(get_cmd());
538 }
539 
540 
parse()541 int WifiEvent::parse() {
542     if (mHeader != NULL) {
543         return WIFI_SUCCESS;
544     }
545     mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
546     int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
547           genlmsg_attrlen(mHeader, 0), NULL);
548 
549     return result;
550 }
551 
create(int family,uint8_t cmd,int flags,int hdrlen)552 wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
553 
554     destroy();
555 
556     mMsg = nlmsg_alloc();
557     if (mMsg != NULL) {
558         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
559                 hdrlen, flags, cmd, /* version = */ 0);
560         return WIFI_SUCCESS;
561     } else {
562         return WIFI_ERROR_OUT_OF_MEMORY;
563     }
564 }
565 
create(uint32_t id,int subcmd)566 wifi_error WifiRequest::create(uint32_t id, int subcmd) {
567     wifi_error res = create(NL80211_CMD_VENDOR);
568     if (res != WIFI_SUCCESS)
569         return res;
570 
571     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
572     if (res != WIFI_SUCCESS)
573         return res;
574 
575     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
576     if (res != WIFI_SUCCESS)
577         return res;
578 
579     if (mIface != -1)
580         res = set_iface_id(mIface);
581 
582     return res;
583 }
584 
585 
no_seq_check(struct nl_msg * msg,void * arg)586 static int no_seq_check(struct nl_msg *msg, void *arg)
587 {
588     return NL_OK;
589 }
590 
requestResponse()591 wifi_error WifiCommand::requestResponse()
592 {
593     wifi_error err = create();                 /* create the message */
594     if (err != WIFI_SUCCESS)
595         return err;
596 
597     return requestResponse(mMsg);
598 }
599 
requestResponse(WifiRequest & request)600 wifi_error WifiCommand::requestResponse(WifiRequest& request)
601 {
602     int err = 0;
603 
604     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
605     if (!cb)
606         goto out;
607 
608     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
609     if (err < 0)
610         goto out;
611 
612     err = 1;
613 
614     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
615     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
616     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
617     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
618     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
619 
620     while (err > 0) {                   /* wait for reply */
621         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
622         if (res) {
623             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res);
624         }
625     }
626 out:
627     nl_cb_put(cb);
628     mMsg.destroy();
629     return mapKernelErrortoWifiHalError(err);
630 }
631 
requestEvent(int cmd)632 wifi_error WifiCommand::requestEvent(int cmd)
633 {
634 
635     int status;
636     wifi_error res = wifi_register_handler(wifiHandle(), cmd, event_handler,
637                                            this);
638     if (res != WIFI_SUCCESS)
639         return res;
640 
641     res = create();                                                 /* create the message */
642     if (res != WIFI_SUCCESS)
643         goto out;
644 
645     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
646     if (status < 0) {
647         res = mapKernelErrortoWifiHalError(status);
648         goto out;
649     }
650 
651     res = mCondition.wait();
652     if (res != WIFI_SUCCESS)
653         goto out;
654 
655 out:
656     wifi_unregister_handler(wifiHandle(), cmd);
657     return res;
658 }
659 
requestVendorEvent(uint32_t id,int subcmd)660 wifi_error WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
661     int status;
662     wifi_error res = wifi_register_vendor_handler(wifiHandle(), id, subcmd,
663                                                   event_handler, this);
664     if (res != WIFI_SUCCESS)
665         return res;
666 
667     res = create();                                                 /* create the message */
668     if (res != WIFI_SUCCESS)
669         goto out;
670 
671     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
672     if (status < 0) {
673         res = mapKernelErrortoWifiHalError(status);
674         goto out;
675     }
676 
677     res = mCondition.wait();
678     if (res != WIFI_SUCCESS)
679         goto out;
680 
681 out:
682     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
683     return res;
684 }
685 
686 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)687 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
688     WifiCommand *cmd = (WifiCommand *)arg;
689     WifiEvent reply(msg);
690     int res = reply.parse();
691     if (res < 0) {
692         ALOGE("Failed to parse reply message = %d", res);
693         return NL_SKIP;
694     } else {
695         // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */
696         return cmd->handleResponse(reply);
697     }
698 }
699 
event_handler(struct nl_msg * msg,void * arg)700 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
701     WifiCommand *cmd = (WifiCommand *)arg;
702     WifiEvent event(msg);
703     int res = event.parse();
704     if (res < 0) {
705         ALOGE("Failed to parse event = %d", res);
706         res = NL_SKIP;
707     } else {
708         res = cmd->handleEvent(event);
709     }
710 
711     cmd->mCondition.signal();
712     return res;
713 }
714 
715 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)716 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
717      int *err = (int *)arg;
718     *err = 0;
719     return NL_SKIP;
720 }
721 
ack_handler(struct nl_msg * msg,void * arg)722 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
723     int *err = (int *)arg;
724     *err = 0;
725     return NL_STOP;
726 }
727 
finish_handler(struct nl_msg * msg,void * arg)728 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
729     int *ret = (int *)arg;
730     *ret = 0;
731     return NL_SKIP;
732 }
733 
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)734 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
735     int *ret = (int *)arg;
736     *ret = err->error;
737 
738     return NL_SKIP;
739 }
740 
741 
WifiVendorCommand(wifi_handle handle,wifi_request_id id,u32 vendor_id,u32 subcmd)742 WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
743                                      wifi_request_id id,
744                                      u32 vendor_id,
745                                      u32 subcmd)
746         : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
747         mVendorData(NULL), mDataLen(0)
748 {
749     ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
750           this, mVendor_id, mSubcmd);
751 }
752 
~WifiVendorCommand()753 WifiVendorCommand::~WifiVendorCommand()
754 {
755     //ALOGV("~WifiVendorCommand %p destroyed", this);
756     //mVendorData is not destroyed here. Assumption
757     //is that VendorData is specific to each Vendor and they
758     //are responsible for owning the same.
759 }
760 
761 // Override this method to parse reply and dig out data; save it
762 // in the corresponding object
handleResponse(WifiEvent & reply)763 int WifiVendorCommand::handleResponse(WifiEvent &reply)
764 {
765     struct nlattr **tb = reply.attributes();
766     struct genlmsghdr *gnlh = reply.header();
767 
768     if (gnlh->cmd == NL80211_CMD_VENDOR) {
769         if (tb[NL80211_ATTR_VENDOR_DATA]) {
770             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
771             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
772         }
773     }
774     return NL_SKIP;
775 }
776 
777 // Override this method to parse event and dig out data;
778 // save it in the object
handleEvent(WifiEvent & event)779 int WifiVendorCommand::handleEvent(WifiEvent &event)
780 {
781     struct nlattr **tb = event.attributes();
782     struct genlmsghdr *gnlh = event.header();
783 
784     if (gnlh->cmd == NL80211_CMD_VENDOR) {
785         /* Vendor Event */
786         if (!tb[NL80211_ATTR_VENDOR_ID] ||
787             !tb[NL80211_ATTR_VENDOR_SUBCMD])
788             return NL_SKIP;
789 
790         mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
791         mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
792 
793         ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u",
794               __FUNCTION__, mVendor_id, mSubcmd);
795 
796         if (tb[NL80211_ATTR_VENDOR_DATA]) {
797             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
798             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
799             ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen);
800             hexdump(mVendorData, mDataLen);
801         }
802     }
803     return NL_SKIP;
804 }
805 
create()806 wifi_error WifiVendorCommand::create() {
807     int ifindex;
808     wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
809     if (ret != WIFI_SUCCESS)
810         return ret;
811 
812     // insert the oui in the msg
813     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
814     if (ret != WIFI_SUCCESS)
815         goto out;
816 
817     // insert the subcmd in the msg
818     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
819     if (ret != WIFI_SUCCESS)
820         goto out;
821 
822     //Insert the vendor specific data
823     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
824     if (ret != WIFI_SUCCESS)
825         goto out;
826     hexdump(mVendorData, mDataLen);
827 
828     //insert the iface id to be "wlan0"
829     ifindex = if_nametoindex("wlan0");
830     ret = mMsg.set_iface_id(ifindex);
831 out:
832     return ret;
833 }
834 
requestResponse()835 wifi_error WifiVendorCommand::requestResponse()
836 {
837     return WifiCommand::requestResponse(mMsg);
838 }
839 
requestEvent()840 wifi_error WifiVendorCommand::requestEvent()
841 {
842     wifi_error res = requestVendorEvent(mVendor_id, mSubcmd);
843     return res;
844 }
845 
put_u8(int attribute,uint8_t value)846 wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value)
847 {
848     return mMsg.put_u8(attribute, value);
849 }
850 
put_u16(int attribute,uint16_t value)851 wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value)
852 {
853     return mMsg.put_u16(attribute, value);
854 }
855 
put_u32(int attribute,uint32_t value)856 wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value)
857 {
858     return mMsg.put_u32(attribute, value);
859 }
860 
put_u64(int attribute,uint64_t value)861 wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value)
862 {
863     return mMsg.put_u64(attribute, value);
864 }
865 
put_s8(int attribute,s8 value)866 wifi_error WifiVendorCommand::put_s8(int attribute, s8 value)
867 {
868     return mMsg.put_s8(attribute, value);
869 }
870 
put_s16(int attribute,s16 value)871 wifi_error WifiVendorCommand::put_s16(int attribute, s16 value)
872 {
873     return mMsg.put_s16(attribute, value);
874 }
875 
put_s32(int attribute,s32 value)876 wifi_error WifiVendorCommand::put_s32(int attribute, s32 value)
877 {
878     return mMsg.put_s32(attribute, value);
879 }
880 
put_s64(int attribute,s64 value)881 wifi_error WifiVendorCommand::put_s64(int attribute, s64 value)
882 {
883     return mMsg.put_s64(attribute, value);
884 }
885 
put_flag(int attribute)886 wifi_error WifiVendorCommand::put_flag(int attribute)
887 {
888     return mMsg.put_flag(attribute);
889 }
890 
get_u8(const struct nlattr * nla)891 u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
892 {
893     return mMsg.get_u8(nla);
894 }
895 
get_u16(const struct nlattr * nla)896 u16 WifiVendorCommand::get_u16(const struct nlattr *nla)
897 {
898     return mMsg.get_u16(nla);
899 }
900 
get_u32(const struct nlattr * nla)901 u32 WifiVendorCommand::get_u32(const struct nlattr *nla)
902 {
903     return mMsg.get_u32(nla);
904 }
905 
get_u64(const struct nlattr * nla)906 u64 WifiVendorCommand::get_u64(const struct nlattr *nla)
907 {
908     return mMsg.get_u64(nla);
909 }
910 
get_s8(const struct nlattr * nla)911 s8 WifiVendorCommand::get_s8(const struct nlattr *nla)
912 {
913     return mMsg.get_s8(nla);
914 }
915 
get_s16(const struct nlattr * nla)916 s16 WifiVendorCommand::get_s16(const struct nlattr *nla)
917 {
918     return mMsg.get_s16(nla);
919 }
920 
get_s32(const struct nlattr * nla)921 s32 WifiVendorCommand::get_s32(const struct nlattr *nla)
922 {
923     return mMsg.get_s32(nla);
924 }
925 
get_s64(const struct nlattr * nla)926 s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
927 {
928     return mMsg.get_s64(nla);
929 }
930 
put_ipv6_addr(int attribute,uint8_t value[16])931 wifi_error WifiVendorCommand::put_ipv6_addr(int attribute, uint8_t value[16])
932 {
933     return mMsg.put_ipv6_addr(attribute, value);
934 }
935 
put_string(int attribute,const char * value)936 wifi_error WifiVendorCommand::put_string(int attribute, const char *value)
937 {
938     return mMsg.put_string(attribute, value);
939 }
940 
put_addr(int attribute,mac_addr value)941 wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value)
942 {
943     return mMsg.put_addr(attribute, value);
944 }
945 
attr_start(int attribute)946 struct nlattr * WifiVendorCommand::attr_start(int attribute)
947 {
948     return mMsg.attr_start(attribute);
949 }
950 
attr_end(struct nlattr * attribute)951 void WifiVendorCommand::attr_end(struct nlattr *attribute)
952 {
953     return mMsg.attr_end(attribute);
954 }
955 
set_iface_id(const char * name)956 wifi_error WifiVendorCommand::set_iface_id(const char* name)
957 {
958     unsigned ifindex = if_nametoindex(name);
959     return mMsg.set_iface_id(ifindex);
960 }
961 
put_bytes(int attribute,const char * data,int len)962 wifi_error WifiVendorCommand::put_bytes(int attribute,
963                                         const char *data,
964                                         int len)
965 {
966     return mMsg.put_bytes(attribute, data, len);
967 }
968 
get_mac_addr(struct nlattr ** tb_vendor,int attribute,mac_addr addr)969 wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor,
970                                        int attribute,
971                                        mac_addr addr)
972 {
973     if (!tb_vendor[attribute]) {
974         ALOGE("Failed to get attribute : %d", attribute);
975         return WIFI_ERROR_INVALID_ARGS;
976     }
977     if (!addr) {
978         ALOGE("addr is NULL");
979         return WIFI_ERROR_INVALID_ARGS;
980     }
981 
982     if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) {
983         ALOGE("Invalid mac addr lenght\n");
984         return WIFI_ERROR_INVALID_ARGS;
985     }
986 
987     memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]),
988                  nla_len(tb_vendor[attribute]));
989 
990     return WIFI_SUCCESS;
991 }
992 
initialize_vendor_cmd(wifi_interface_handle iface,wifi_request_id id,u32 subcmd,WifiVendorCommand ** vCommand)993 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
994                                  wifi_request_id id,
995                                  u32 subcmd,
996                                  WifiVendorCommand **vCommand)
997 {
998     wifi_error ret;
999     interface_info *ifaceInfo = getIfaceInfo(iface);
1000     wifi_handle wifiHandle = getWifiHandle(iface);
1001 
1002     if (vCommand == NULL) {
1003         ALOGE("%s: Error vCommand NULL", __FUNCTION__);
1004         return WIFI_ERROR_INVALID_ARGS;
1005     }
1006 
1007     *vCommand = new WifiVendorCommand(wifiHandle, id,
1008                                       OUI_QCA,
1009                                       subcmd);
1010     if (*vCommand == NULL) {
1011         ALOGE("%s: Object creation failed", __FUNCTION__);
1012         return WIFI_ERROR_OUT_OF_MEMORY;
1013     }
1014 
1015     /* Create the message */
1016     ret = (*vCommand)->create();
1017     if (ret != WIFI_SUCCESS)
1018         goto cleanup;
1019 
1020     ret = (*vCommand)->set_iface_id(ifaceInfo->name);
1021     if (ret != WIFI_SUCCESS)
1022         goto cleanup;
1023 
1024     return WIFI_SUCCESS;
1025 
1026 cleanup:
1027     delete *vCommand;
1028     return ret;
1029 }
1030