• 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 <netlink-types.h>
33 #include <net/if.h>
34 
35 #include "nl80211_copy.h"
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     mMsg = nlmsg_alloc();
559     if (mMsg != NULL) {
560         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
561                 hdrlen, flags, cmd, /* version = */ 0);
562         return WIFI_SUCCESS;
563     } else {
564         return WIFI_ERROR_OUT_OF_MEMORY;
565     }
566 }
567 
create(uint32_t id,int subcmd)568 int WifiRequest::create(uint32_t id, int subcmd) {
569     int res = create(NL80211_CMD_VENDOR);
570     if (res < 0) {
571         return res;
572     }
573 
574     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
575     if (res < 0) {
576         return res;
577     }
578 
579     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
580     if (res < 0) {
581         return res;
582     }
583 
584     if (mIface != -1) {
585         res = set_iface_id(mIface);
586     }
587 
588     return res;
589 }
590 
591 
no_seq_check(struct nl_msg * msg,void * arg)592 static int no_seq_check(struct nl_msg *msg, void *arg)
593 {
594     return NL_OK;
595 }
596 
requestResponse()597 int WifiCommand::requestResponse() {
598     int err = create();                 /* create the message */
599     if (err < 0) {
600         return err;
601     }
602 
603     return requestResponse(mMsg);
604 }
605 
requestResponse(WifiRequest & request)606 int WifiCommand::requestResponse(WifiRequest& request) {
607     int err = 0;
608 
609     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
610     if (!cb)
611         goto out;
612 
613     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
614     if (err < 0)
615         goto out;
616 
617     err = 1;
618 
619     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
620     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
621     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
622     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
623     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
624 
625     while (err > 0) {                   /* wait for reply */
626         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
627         if (res) {
628             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
629         }
630     }
631 out:
632     nl_cb_put(cb);
633     return err;
634 }
635 
requestEvent(int cmd)636 int WifiCommand::requestEvent(int cmd) {
637 
638     ALOGD("requesting event %d", cmd);
639 
640     int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
641     if (res < 0) {
642         return res;
643     }
644 
645     res = create();                                                 /* create the message */
646     if (res < 0)
647         goto out;
648 
649     ALOGD("waiting for response %d", cmd);
650 
651     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
652     if (res < 0)
653         goto out;
654 
655     ALOGD("waiting for event %d", cmd);
656     res = mCondition.wait();
657     if (res < 0)
658         goto out;
659 
660 out:
661     wifi_unregister_handler(wifiHandle(), cmd);
662     return res;
663 }
664 
requestVendorEvent(uint32_t id,int subcmd)665 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
666 
667     int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
668     if (res < 0) {
669         return res;
670     }
671 
672     res = create();                                                 /* create the message */
673     if (res < 0)
674         goto out;
675 
676     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
677     if (res < 0)
678         goto out;
679 
680     res = mCondition.wait();
681     if (res < 0)
682         goto out;
683 
684 out:
685     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
686     return res;
687 }
688 
689 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)690 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
691     // ALOGD("response_handler called");
692     WifiCommand *cmd = (WifiCommand *)arg;
693     WifiEvent reply(msg);
694     int res = reply.parse();
695     if (res < 0) {
696         ALOGE("Failed to parse reply message = %d", res);
697         return NL_SKIP;
698     } else {
699         reply.log();
700         return cmd->handleResponse(reply);
701     }
702 }
703 
event_handler(struct nl_msg * msg,void * arg)704 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
705     WifiCommand *cmd = (WifiCommand *)arg;
706     WifiEvent event(msg);
707     int res = event.parse();
708     if (res < 0) {
709         ALOGE("Failed to parse event = %d", res);
710         res = NL_SKIP;
711     } else {
712         res = cmd->handleEvent(event);
713     }
714 
715     cmd->mCondition.signal();
716     return res;
717 }
718 
719 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)720 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
721     // ALOGD("valid_handler called");
722      int *err = (int *)arg;
723     *err = 0;
724     return NL_SKIP;
725 }
726 
ack_handler(struct nl_msg * msg,void * arg)727 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
728     // ALOGD("ack_handler called");
729     int *err = (int *)arg;
730     *err = 0;
731     return NL_STOP;
732 }
733 
finish_handler(struct nl_msg * msg,void * arg)734 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
735     // ALOGD("finish_handler called");
736     int *ret = (int *)arg;
737     *ret = 0;
738     return NL_SKIP;
739 }
740 
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)741 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
742     int *ret = (int *)arg;
743     *ret = err->error;
744 
745     // ALOGD("error_handler received : %d", err->error);
746     return NL_SKIP;
747 }
748 
749 
WifiVendorCommand(wifi_handle handle,wifi_request_id id,u32 vendor_id,u32 subcmd)750 WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
751                                      wifi_request_id id,
752                                      u32 vendor_id,
753                                      u32 subcmd)
754         : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
755         mVendorData(NULL), mDataLen(0)
756 {
757     ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
758           this, mVendor_id, mSubcmd);
759 }
760 
~WifiVendorCommand()761 WifiVendorCommand::~WifiVendorCommand()
762 {
763     ALOGV("~WifiVendorCommand %p destroyed", this);
764     //mVendorData is not destroyed here. Assumption
765     //is that VendorData is specific to each Vendor and they
766     //are responsible for owning the same.
767 }
768 
769 // Override this method to parse reply and dig out data; save it
770 // in the corresponding object
handleResponse(WifiEvent & reply)771 int WifiVendorCommand::handleResponse(WifiEvent &reply)
772 {
773     ALOGI("WifiVendorCommand::handleResponse");
774     struct nlattr **tb = reply.attributes();
775     struct nlattr *attr = NULL;
776     struct genlmsghdr *gnlh = reply.header();
777 
778     if (gnlh->cmd == NL80211_CMD_VENDOR) {
779         if (tb[NL80211_ATTR_VENDOR_DATA]) {
780             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
781             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
782             ALOGD("%s: Vendor data len received:%d", __func__, mDataLen);
783         }
784     }
785     return NL_SKIP;
786 }
787 
788 // Override this method to parse event and dig out data;
789 // save it in the object
handleEvent(WifiEvent & event)790 int WifiVendorCommand::handleEvent(WifiEvent &event)
791 {
792     ALOGI("WifiVendorCommand::handleEvent");
793     struct nlattr **tb = event.attributes();
794     struct nlattr *attr = NULL;
795     struct genlmsghdr *gnlh = event.header();
796 
797     if (gnlh->cmd == NL80211_CMD_VENDOR) {
798         /* Vendor Event */
799         if (!tb[NL80211_ATTR_VENDOR_ID] ||
800             !tb[NL80211_ATTR_VENDOR_SUBCMD])
801             return NL_SKIP;
802 
803         mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
804         mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
805 
806         ALOGD("%s: Vendor event: vendor_id=0x%x subcmd=%u",
807               __func__, mVendor_id, mSubcmd);
808 
809         if (tb[NL80211_ATTR_VENDOR_DATA]) {
810             mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
811             mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
812             ALOGD("%s: Vendor data len received:%d", __func__, mDataLen);
813             hexdump(mVendorData, mDataLen);
814         }
815     }
816     return NL_SKIP;
817 }
818 
create()819 int WifiVendorCommand::create() {
820     int ifindex;
821     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
822     if (ret < 0) {
823         return ret;
824     }
825     // insert the oui in the msg
826     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
827     if (ret < 0)
828         goto out;
829 
830     // insert the subcmd in the msg
831     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
832     if (ret < 0)
833         goto out;
834 
835     //Insert the vendor specific data
836     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
837     hexdump(mVendorData, mDataLen);
838 
839     //insert the iface id to be "wlan0"
840     ifindex = if_nametoindex("wlan0");
841     ALOGE("%s ifindex obtained:%d",__func__,ifindex);
842     mMsg.set_iface_id(ifindex);
843 out:
844     return ret;
845 
846 }
847 
requestEvent()848 int WifiVendorCommand::requestEvent()
849 {
850     int res = requestVendorEvent(mVendor_id, mSubcmd);
851     return res;
852 
853 }
854 
put_u8(int attribute,uint8_t value)855 int WifiVendorCommand::put_u8(int attribute, uint8_t value)
856 {
857     return mMsg.put_u8(attribute, value);
858 }
859 
put_u16(int attribute,uint16_t value)860 int WifiVendorCommand::put_u16(int attribute, uint16_t value)
861 {
862     return mMsg.put_u16(attribute, value);
863 }
864 
put_u32(int attribute,uint32_t value)865 int WifiVendorCommand::put_u32(int attribute, uint32_t value)
866 {
867     return mMsg.put_u32(attribute, value);
868 }
869 
put_s32(int attribute,int value)870 int WifiVendorCommand::put_s32(int attribute, int value) {
871     return mMsg.put_s32(attribute, value);
872 }
873 
put_u64(int attribute,uint64_t value)874 int WifiVendorCommand::put_u64(int attribute, uint64_t value)
875 {
876     return mMsg.put_u64(attribute, value);
877 }
878 
put_string(int attribute,const char * value)879 int WifiVendorCommand::put_string(int attribute, const char *value)
880 {
881     return mMsg.put_string(attribute, value);
882 }
883 
put_addr(int attribute,mac_addr value)884 int WifiVendorCommand::put_addr(int attribute, mac_addr value)
885 {
886     return mMsg.put_addr(attribute, value);
887 }
888 
attr_start(int attribute)889 struct nlattr * WifiVendorCommand::attr_start(int attribute)
890 {
891     return mMsg.attr_start(attribute);
892 }
893 
attr_end(struct nlattr * attribute)894 void WifiVendorCommand::attr_end(struct nlattr *attribute)
895 {
896     return mMsg.attr_end(attribute);
897 }
898 
set_iface_id(const char * name)899 int WifiVendorCommand::set_iface_id(const char* name)
900 {
901     unsigned ifindex = if_nametoindex(name);
902     ALOGE("%s ifindex obtained:%d",__func__,ifindex);
903     return mMsg.set_iface_id(ifindex);
904 }
905 
put_bytes(int attribute,const char * data,int len)906 int WifiVendorCommand::put_bytes(int attribute, const char *data, int len)
907 {
908     return mMsg.put_bytes(attribute, data, len);
909 }
910