• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdint.h>
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <netlink/genl/genl.h>
21 #include <netlink/genl/family.h>
22 #include <netlink/genl/ctrl.h>
23 #include <linux/rtnetlink.h>
24 #include <netpacket/packet.h>
25 #include <linux/filter.h>
26 #include <linux/errqueue.h>
27 
28 #include <linux/pkt_sched.h>
29 #include <netlink/object-api.h>
30 #include <netlink/netlink.h>
31 #include <netlink/socket.h>
32 #include <net/if.h>
33 
34 #include "nl80211_copy.h"
35 #include <ctype.h>
36 
37 #include <hardware_legacy/wifi_hal.h>
38 #include "common.h"
39 #include "cpp_bindings.h"
40 #include "vendor_definitions.h"
41 
appendFmt(char * buf,size_t buf_len,int & offset,const char * fmt,...)42 void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...)
43 {
44     va_list params;
45     va_start(params, fmt);
46     offset += vsnprintf(buf + offset, buf_len - 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 
501     for (int i = 0; i < len; i += 16) {
502         char line[81];
503         int linelen = min(16, len - i);
504         int offset = 0;
505         appendFmt(line, sizeof(line), offset, "%02x", data[i]);
506         for (int j = 1; j < linelen; j++) {
507             appendFmt(line, sizeof(line), offset, " %02x", data[i+j]);
508         }
509 
510         for (int j = linelen; j < 16; j++) {
511             appendFmt(line, sizeof(line), offset, "   ");
512         }
513 
514         line[23] = '-';
515 
516         appendFmt(line, sizeof(line), offset, "  ");
517 
518         for (int j = 0; j < linelen; j++) {
519             if (isprint(data[i+j])) {
520                 appendFmt(line, sizeof(line), offset, "%c", data[i+j]);
521             } else {
522                 appendFmt(line, sizeof(line), offset, "-");
523             }
524         }
525 
526     }
527 
528 }
529 
get_cmdString()530 const char *WifiEvent::get_cmdString() {
531     return cmdToString(get_cmd());
532 }
533 
534 
parse()535 int WifiEvent::parse() {
536     if (mHeader != NULL) {
537         return WIFI_SUCCESS;
538     }
539     mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
540     int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
541           genlmsg_attrlen(mHeader, 0), NULL);
542 
543     return result;
544 }
545 
create(int family,uint8_t cmd,int flags,int hdrlen)546 wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
547 
548     destroy();
549 
550     mMsg = nlmsg_alloc();
551     if (mMsg != NULL) {
552         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
553                 hdrlen, flags, cmd, /* version = */ 0);
554         return WIFI_SUCCESS;
555     } else {
556         return WIFI_ERROR_OUT_OF_MEMORY;
557     }
558 }
559 
create(uint32_t id,int subcmd)560 wifi_error WifiRequest::create(uint32_t id, int subcmd) {
561     wifi_error res = create(NL80211_CMD_VENDOR);
562     if (res != WIFI_SUCCESS)
563         return res;
564 
565     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
566     if (res != WIFI_SUCCESS)
567         return res;
568 
569     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
570     if (res != WIFI_SUCCESS)
571         return res;
572 
573     if (mIface != -1)
574         res = set_iface_id(mIface);
575 
576     return res;
577 }
578 
579 
no_seq_check(struct nl_msg * msg,void * arg)580 static int no_seq_check(struct nl_msg *msg, void *arg)
581 {
582     return NL_OK;
583 }
584 
requestResponse()585 wifi_error WifiCommand::requestResponse()
586 {
587     wifi_error err = create();                 /* create the message */
588     if (err != WIFI_SUCCESS)
589         return err;
590 
591     return requestResponse(mMsg);
592 }
593 
requestResponse(WifiRequest & request)594 wifi_error WifiCommand::requestResponse(WifiRequest& request)
595 {
596     int err = 0;
597 
598     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
599     if (!cb)
600         goto out;
601 
602     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
603     if (err < 0)
604         goto out;
605 
606     err = 1;
607 
608     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
609     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
610     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
611     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
612     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
613 
614     while (err > 0) {                   /* wait for reply */
615         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
616         if (res) {
617             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res);
618         }
619     }
620 out:
621     nl_cb_put(cb);
622     mMsg.destroy();
623     return mapKernelErrortoWifiHalError(err);
624 }
625 
requestEvent(int cmd)626 wifi_error WifiCommand::requestEvent(int cmd)
627 {
628 
629     int status;
630     wifi_error res = wifi_register_handler(wifiHandle(), cmd, event_handler,
631                                            this);
632     if (res != WIFI_SUCCESS)
633         return res;
634 
635     res = create();                                                 /* create the message */
636     if (res != WIFI_SUCCESS)
637         goto out;
638 
639     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
640     if (status < 0) {
641         res = mapKernelErrortoWifiHalError(status);
642         goto out;
643     }
644 
645     res = mCondition.wait();
646     if (res != WIFI_SUCCESS)
647         goto out;
648 
649 out:
650     wifi_unregister_handler(wifiHandle(), cmd);
651     return res;
652 }
653 
requestVendorEvent(uint32_t id,int subcmd)654 wifi_error WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
655     int status;
656     wifi_error res = wifi_register_vendor_handler(wifiHandle(), id, subcmd,
657                                                   event_handler, this);
658     if (res != WIFI_SUCCESS)
659         return res;
660 
661     res = create();                                                 /* create the message */
662     if (res != WIFI_SUCCESS)
663         goto out;
664 
665     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
666     if (status < 0) {
667         res = mapKernelErrortoWifiHalError(status);
668         goto out;
669     }
670 
671     res = mCondition.wait();
672     if (res != WIFI_SUCCESS)
673         goto out;
674 
675 out:
676     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
677     return res;
678 }
679 
680 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)681 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
682     WifiCommand *cmd = (WifiCommand *)arg;
683     WifiEvent reply(msg);
684     int res = reply.parse();
685     if (res < 0) {
686         ALOGE("Failed to parse reply message = %d", res);
687         return NL_SKIP;
688     } else {
689         // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */
690         return cmd->handleResponse(reply);
691     }
692 }
693 
event_handler(struct nl_msg * msg,void * arg)694 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
695     WifiCommand *cmd = (WifiCommand *)arg;
696     WifiEvent event(msg);
697     int res = event.parse();
698     if (res < 0) {
699         ALOGE("Failed to parse event = %d", res);
700         res = NL_SKIP;
701     } else {
702         res = cmd->handleEvent(event);
703     }
704 
705     cmd->mCondition.signal();
706     return res;
707 }
708 
709 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)710 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
711      int *err = (int *)arg;
712     *err = 0;
713     return NL_SKIP;
714 }
715 
ack_handler(struct nl_msg * msg,void * arg)716 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
717     int *err = (int *)arg;
718     *err = 0;
719     return NL_STOP;
720 }
721 
finish_handler(struct nl_msg * msg,void * arg)722 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
723     int *ret = (int *)arg;
724     *ret = 0;
725     return NL_SKIP;
726 }
727 
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)728 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
729     int *ret = (int *)arg;
730     *ret = err->error;
731 
732     return NL_SKIP;
733 }
734 
735 
WifiVendorCommand(wifi_handle handle,wifi_request_id id,u32 vendor_id,u32 subcmd)736 WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
737                                      wifi_request_id id,
738                                      u32 vendor_id,
739                                      u32 subcmd)
740         : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
741         mVendorData(NULL), mDataLen(0)
742 {
743     ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
744           this, mVendor_id, mSubcmd);
745 }
746 
~WifiVendorCommand()747 WifiVendorCommand::~WifiVendorCommand()
748 {
749     //ALOGV("~WifiVendorCommand %p destroyed", this);
750     //mVendorData is not destroyed here. Assumption
751     //is that VendorData is specific to each Vendor and they
752     //are responsible for owning the same.
753 }
754 
755 // Override this method to parse reply and dig out data; save it
756 // in the corresponding object
handleResponse(WifiEvent & reply)757 int WifiVendorCommand::handleResponse(WifiEvent &reply)
758 {
759     struct nlattr **tb = reply.attributes();
760     struct genlmsghdr *gnlh = reply.header();
761 
762     if (gnlh->cmd == NL80211_CMD_VENDOR) {
763         if (tb[NL80211_ATTR_VENDOR_DATA]) {
764             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
765             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
766         }
767     }
768     return NL_SKIP;
769 }
770 
771 // Override this method to parse event and dig out data;
772 // save it in the object
handleEvent(WifiEvent & event)773 int WifiVendorCommand::handleEvent(WifiEvent &event)
774 {
775     struct nlattr **tb = event.attributes();
776     struct genlmsghdr *gnlh = event.header();
777 
778     if (gnlh->cmd == NL80211_CMD_VENDOR) {
779         /* Vendor Event */
780         if (!tb[NL80211_ATTR_VENDOR_ID] ||
781             !tb[NL80211_ATTR_VENDOR_SUBCMD])
782             return NL_SKIP;
783 
784         mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
785         mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
786 
787         ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u",
788               __FUNCTION__, mVendor_id, mSubcmd);
789 
790         if (tb[NL80211_ATTR_VENDOR_DATA]) {
791             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
792             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
793             ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen);
794             hexdump(mVendorData, mDataLen);
795         }
796     }
797     return NL_SKIP;
798 }
799 
create()800 wifi_error WifiVendorCommand::create() {
801     int ifindex;
802     wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
803     if (ret != WIFI_SUCCESS)
804         return ret;
805 
806     // insert the oui in the msg
807     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
808     if (ret != WIFI_SUCCESS)
809         goto out;
810 
811     // insert the subcmd in the msg
812     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
813     if (ret != WIFI_SUCCESS)
814         goto out;
815 
816     //Insert the vendor specific data
817     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
818     if (ret != WIFI_SUCCESS)
819         goto out;
820     hexdump(mVendorData, mDataLen);
821 
822     //insert the iface id to be "wlan0"
823     ifindex = if_nametoindex("wlan0");
824     ret = mMsg.set_iface_id(ifindex);
825 out:
826     return ret;
827 }
828 
requestResponse()829 wifi_error WifiVendorCommand::requestResponse()
830 {
831     return WifiCommand::requestResponse(mMsg);
832 }
833 
requestEvent()834 wifi_error WifiVendorCommand::requestEvent()
835 {
836     wifi_error res = requestVendorEvent(mVendor_id, mSubcmd);
837     return res;
838 }
839 
put_u8(int attribute,uint8_t value)840 wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value)
841 {
842     return mMsg.put_u8(attribute, value);
843 }
844 
put_u16(int attribute,uint16_t value)845 wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value)
846 {
847     return mMsg.put_u16(attribute, value);
848 }
849 
put_u32(int attribute,uint32_t value)850 wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value)
851 {
852     return mMsg.put_u32(attribute, value);
853 }
854 
put_u64(int attribute,uint64_t value)855 wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value)
856 {
857     return mMsg.put_u64(attribute, value);
858 }
859 
put_s8(int attribute,s8 value)860 wifi_error WifiVendorCommand::put_s8(int attribute, s8 value)
861 {
862     return mMsg.put_s8(attribute, value);
863 }
864 
put_s16(int attribute,s16 value)865 wifi_error WifiVendorCommand::put_s16(int attribute, s16 value)
866 {
867     return mMsg.put_s16(attribute, value);
868 }
869 
put_s32(int attribute,s32 value)870 wifi_error WifiVendorCommand::put_s32(int attribute, s32 value)
871 {
872     return mMsg.put_s32(attribute, value);
873 }
874 
put_s64(int attribute,s64 value)875 wifi_error WifiVendorCommand::put_s64(int attribute, s64 value)
876 {
877     return mMsg.put_s64(attribute, value);
878 }
879 
put_flag(int attribute)880 wifi_error WifiVendorCommand::put_flag(int attribute)
881 {
882     return mMsg.put_flag(attribute);
883 }
884 
get_u8(const struct nlattr * nla)885 u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
886 {
887     return mMsg.get_u8(nla);
888 }
889 
get_u16(const struct nlattr * nla)890 u16 WifiVendorCommand::get_u16(const struct nlattr *nla)
891 {
892     return mMsg.get_u16(nla);
893 }
894 
get_u32(const struct nlattr * nla)895 u32 WifiVendorCommand::get_u32(const struct nlattr *nla)
896 {
897     return mMsg.get_u32(nla);
898 }
899 
get_u64(const struct nlattr * nla)900 u64 WifiVendorCommand::get_u64(const struct nlattr *nla)
901 {
902     return mMsg.get_u64(nla);
903 }
904 
get_s8(const struct nlattr * nla)905 s8 WifiVendorCommand::get_s8(const struct nlattr *nla)
906 {
907     return mMsg.get_s8(nla);
908 }
909 
get_s16(const struct nlattr * nla)910 s16 WifiVendorCommand::get_s16(const struct nlattr *nla)
911 {
912     return mMsg.get_s16(nla);
913 }
914 
get_s32(const struct nlattr * nla)915 s32 WifiVendorCommand::get_s32(const struct nlattr *nla)
916 {
917     return mMsg.get_s32(nla);
918 }
919 
get_s64(const struct nlattr * nla)920 s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
921 {
922     return mMsg.get_s64(nla);
923 }
924 
put_string(int attribute,const char * value)925 wifi_error WifiVendorCommand::put_string(int attribute, const char *value)
926 {
927     return mMsg.put_string(attribute, value);
928 }
929 
put_addr(int attribute,mac_addr value)930 wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value)
931 {
932     return mMsg.put_addr(attribute, value);
933 }
934 
attr_start(int attribute)935 struct nlattr * WifiVendorCommand::attr_start(int attribute)
936 {
937     return mMsg.attr_start(attribute);
938 }
939 
attr_end(struct nlattr * attribute)940 void WifiVendorCommand::attr_end(struct nlattr *attribute)
941 {
942     return mMsg.attr_end(attribute);
943 }
944 
set_iface_id(const char * name)945 wifi_error WifiVendorCommand::set_iface_id(const char* name)
946 {
947     unsigned ifindex = if_nametoindex(name);
948     return mMsg.set_iface_id(ifindex);
949 }
950 
put_bytes(int attribute,const char * data,int len)951 wifi_error WifiVendorCommand::put_bytes(int attribute,
952                                         const char *data,
953                                         int len)
954 {
955     return mMsg.put_bytes(attribute, data, len);
956 }
957 
get_mac_addr(struct nlattr ** tb_vendor,int attribute,mac_addr addr)958 wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor,
959                                        int attribute,
960                                        mac_addr addr)
961 {
962     if (!tb_vendor[attribute]) {
963         ALOGE("Failed to get attribute : %d", attribute);
964         return WIFI_ERROR_INVALID_ARGS;
965     }
966     if (!addr) {
967         ALOGE("addr is NULL");
968         return WIFI_ERROR_INVALID_ARGS;
969     }
970 
971     if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) {
972         ALOGE("Invalid mac addr lenght\n");
973         return WIFI_ERROR_INVALID_ARGS;
974     }
975 
976     memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]),
977                  nla_len(tb_vendor[attribute]));
978 
979     return WIFI_SUCCESS;
980 }
981 
initialize_vendor_cmd(wifi_interface_handle iface,wifi_request_id id,u32 subcmd,WifiVendorCommand ** vCommand)982 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
983                                  wifi_request_id id,
984                                  u32 subcmd,
985                                  WifiVendorCommand **vCommand)
986 {
987     wifi_error ret;
988     interface_info *ifaceInfo = getIfaceInfo(iface);
989     wifi_handle wifiHandle = getWifiHandle(iface);
990 
991     if (vCommand == NULL) {
992         ALOGE("%s: Error vCommand NULL", __FUNCTION__);
993         return WIFI_ERROR_INVALID_ARGS;
994     }
995 
996     *vCommand = new WifiVendorCommand(wifiHandle, id,
997                                       OUI_QCA,
998                                       subcmd);
999     if (*vCommand == NULL) {
1000         ALOGE("%s: Object creation failed", __FUNCTION__);
1001         return WIFI_ERROR_OUT_OF_MEMORY;
1002     }
1003 
1004     /* Create the message */
1005     ret = (*vCommand)->create();
1006     if (ret != WIFI_SUCCESS)
1007         goto cleanup;
1008 
1009     ret = (*vCommand)->set_iface_id(ifaceInfo->name);
1010     if (ret != WIFI_SUCCESS)
1011         goto cleanup;
1012 
1013     return WIFI_SUCCESS;
1014 
1015 cleanup:
1016     delete *vCommand;
1017     return ret;
1018 }
1019