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