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 "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 int 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 int WifiRequest::create(uint32_t id, int subcmd) {
561 int res = create(NL80211_CMD_VENDOR);
562 if (res < 0) {
563 return res;
564 }
565
566 res = put_u32(NL80211_ATTR_VENDOR_ID, id);
567 if (res < 0) {
568 return res;
569 }
570
571 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
572 if (res < 0) {
573 return res;
574 }
575
576 if (mIface != -1) {
577 res = set_iface_id(mIface);
578 }
579
580 return res;
581 }
582
583
no_seq_check(struct nl_msg * msg,void * arg)584 static int no_seq_check(struct nl_msg *msg, void *arg)
585 {
586 return NL_OK;
587 }
588
requestResponse()589 int WifiCommand::requestResponse() {
590 int err = create(); /* create the message */
591 if (err < 0) {
592 return err;
593 }
594
595 return requestResponse(mMsg);
596 }
597
requestResponse(WifiRequest & request)598 int WifiCommand::requestResponse(WifiRequest& request) {
599 int err = 0;
600
601 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
602 if (!cb)
603 goto out;
604
605 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */
606 if (err < 0)
607 goto out;
608
609 err = 1;
610
611 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
612 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
613 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
614 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
615 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
616
617 while (err > 0) { /* wait for reply */
618 int res = nl_recvmsgs(mInfo->cmd_sock, cb);
619 if (res) {
620 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res);
621 }
622 }
623 out:
624 nl_cb_put(cb);
625 mMsg.destroy();
626 return err;
627 }
628
requestEvent(int cmd)629 int WifiCommand::requestEvent(int cmd) {
630
631 int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
632 if (res < 0) {
633 return res;
634 }
635
636 res = create(); /* create the message */
637 if (res < 0)
638 goto out;
639
640 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
641 if (res < 0)
642 goto out;
643
644 res = mCondition.wait();
645 if (res < 0)
646 goto out;
647
648 out:
649 wifi_unregister_handler(wifiHandle(), cmd);
650 return res;
651 }
652
requestVendorEvent(uint32_t id,int subcmd)653 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
654
655 int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
656 if (res < 0) {
657 return res;
658 }
659
660 res = create(); /* create the message */
661 if (res < 0)
662 goto out;
663
664 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
665 if (res < 0)
666 goto out;
667
668 res = mCondition.wait();
669 if (res < 0)
670 goto out;
671
672 out:
673 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
674 return res;
675 }
676
677 /* Event handlers */
response_handler(struct nl_msg * msg,void * arg)678 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
679 WifiCommand *cmd = (WifiCommand *)arg;
680 WifiEvent reply(msg);
681 int res = reply.parse();
682 if (res < 0) {
683 ALOGE("Failed to parse reply message = %d", res);
684 return NL_SKIP;
685 } else {
686 // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */
687 return cmd->handleResponse(reply);
688 }
689 }
690
event_handler(struct nl_msg * msg,void * arg)691 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
692 WifiCommand *cmd = (WifiCommand *)arg;
693 WifiEvent event(msg);
694 int res = event.parse();
695 if (res < 0) {
696 ALOGE("Failed to parse event = %d", res);
697 res = NL_SKIP;
698 } else {
699 res = cmd->handleEvent(event);
700 }
701
702 cmd->mCondition.signal();
703 return res;
704 }
705
706 /* Other event handlers */
valid_handler(struct nl_msg * msg,void * arg)707 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
708 int *err = (int *)arg;
709 *err = 0;
710 return NL_SKIP;
711 }
712
ack_handler(struct nl_msg * msg,void * arg)713 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
714 int *err = (int *)arg;
715 *err = 0;
716 return NL_STOP;
717 }
718
finish_handler(struct nl_msg * msg,void * arg)719 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
720 int *ret = (int *)arg;
721 *ret = 0;
722 return NL_SKIP;
723 }
724
error_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)725 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
726 int *ret = (int *)arg;
727 *ret = err->error;
728
729 return NL_SKIP;
730 }
731
732
WifiVendorCommand(wifi_handle handle,wifi_request_id id,u32 vendor_id,u32 subcmd)733 WifiVendorCommand::WifiVendorCommand(wifi_handle handle,
734 wifi_request_id id,
735 u32 vendor_id,
736 u32 subcmd)
737 : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd),
738 mVendorData(NULL), mDataLen(0)
739 {
740 ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u",
741 this, mVendor_id, mSubcmd);
742 }
743
~WifiVendorCommand()744 WifiVendorCommand::~WifiVendorCommand()
745 {
746 //ALOGV("~WifiVendorCommand %p destroyed", this);
747 //mVendorData is not destroyed here. Assumption
748 //is that VendorData is specific to each Vendor and they
749 //are responsible for owning the same.
750 }
751
752 // Override this method to parse reply and dig out data; save it
753 // in the corresponding object
handleResponse(WifiEvent & reply)754 int WifiVendorCommand::handleResponse(WifiEvent &reply)
755 {
756 struct nlattr **tb = reply.attributes();
757 struct genlmsghdr *gnlh = reply.header();
758
759 if (gnlh->cmd == NL80211_CMD_VENDOR) {
760 if (tb[NL80211_ATTR_VENDOR_DATA]) {
761 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
762 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
763 }
764 }
765 return NL_SKIP;
766 }
767
768 // Override this method to parse event and dig out data;
769 // save it in the object
handleEvent(WifiEvent & event)770 int WifiVendorCommand::handleEvent(WifiEvent &event)
771 {
772 struct nlattr **tb = event.attributes();
773 struct genlmsghdr *gnlh = event.header();
774
775 if (gnlh->cmd == NL80211_CMD_VENDOR) {
776 /* Vendor Event */
777 if (!tb[NL80211_ATTR_VENDOR_ID] ||
778 !tb[NL80211_ATTR_VENDOR_SUBCMD])
779 return NL_SKIP;
780
781 mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
782 mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
783
784 ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u",
785 __FUNCTION__, mVendor_id, mSubcmd);
786
787 if (tb[NL80211_ATTR_VENDOR_DATA]) {
788 mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
789 mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
790 ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen);
791 hexdump(mVendorData, mDataLen);
792 }
793 }
794 return NL_SKIP;
795 }
796
create()797 int WifiVendorCommand::create() {
798 int ifindex;
799 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
800 if (ret < 0) {
801 return ret;
802 }
803 // insert the oui in the msg
804 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
805 if (ret < 0)
806 goto out;
807
808 // insert the subcmd in the msg
809 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
810 if (ret < 0)
811 goto out;
812
813 //Insert the vendor specific data
814 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
815 hexdump(mVendorData, mDataLen);
816
817 //insert the iface id to be "wlan0"
818 ifindex = if_nametoindex("wlan0");
819 mMsg.set_iface_id(ifindex);
820 out:
821 return ret;
822
823 }
824
requestResponse()825 int WifiVendorCommand::requestResponse()
826 {
827 return WifiCommand::requestResponse(mMsg);
828 }
829
requestEvent()830 int WifiVendorCommand::requestEvent()
831 {
832 int res = requestVendorEvent(mVendor_id, mSubcmd);
833 return res;
834
835 }
836
put_u8(int attribute,uint8_t value)837 int WifiVendorCommand::put_u8(int attribute, uint8_t value)
838 {
839 return mMsg.put_u8(attribute, value);
840 }
841
put_u16(int attribute,uint16_t value)842 int WifiVendorCommand::put_u16(int attribute, uint16_t value)
843 {
844 return mMsg.put_u16(attribute, value);
845 }
846
put_u32(int attribute,uint32_t value)847 int WifiVendorCommand::put_u32(int attribute, uint32_t value)
848 {
849 return mMsg.put_u32(attribute, value);
850 }
851
put_u64(int attribute,uint64_t value)852 int WifiVendorCommand::put_u64(int attribute, uint64_t value)
853 {
854 return mMsg.put_u64(attribute, value);
855 }
856
put_s8(int attribute,s8 value)857 int WifiVendorCommand::put_s8(int attribute, s8 value)
858 {
859 return mMsg.put_s8(attribute, value);
860 }
861
put_s16(int attribute,s16 value)862 int WifiVendorCommand::put_s16(int attribute, s16 value)
863 {
864 return mMsg.put_s16(attribute, value);
865 }
866
put_s32(int attribute,s32 value)867 int WifiVendorCommand::put_s32(int attribute, s32 value) {
868 return mMsg.put_s32(attribute, value);
869 }
870
put_s64(int attribute,s64 value)871 int WifiVendorCommand::put_s64(int attribute, s64 value)
872 {
873 return mMsg.put_s64(attribute, value);
874 }
875
get_u8(const struct nlattr * nla)876 u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
877 {
878 return mMsg.get_u8(nla);
879 }
880
get_u16(const struct nlattr * nla)881 u16 WifiVendorCommand::get_u16(const struct nlattr *nla)
882 {
883 return mMsg.get_u16(nla);
884 }
885
get_u32(const struct nlattr * nla)886 u32 WifiVendorCommand::get_u32(const struct nlattr *nla)
887 {
888 return mMsg.get_u32(nla);
889 }
890
get_u64(const struct nlattr * nla)891 u64 WifiVendorCommand::get_u64(const struct nlattr *nla)
892 {
893 return mMsg.get_u64(nla);
894 }
895
get_s8(const struct nlattr * nla)896 s8 WifiVendorCommand::get_s8(const struct nlattr *nla)
897 {
898 return mMsg.get_s8(nla);
899 }
900
get_s16(const struct nlattr * nla)901 s16 WifiVendorCommand::get_s16(const struct nlattr *nla)
902 {
903 return mMsg.get_s16(nla);
904 }
905
get_s32(const struct nlattr * nla)906 s32 WifiVendorCommand::get_s32(const struct nlattr *nla)
907 {
908 return mMsg.get_s32(nla);
909 }
910
get_s64(const struct nlattr * nla)911 s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
912 {
913 return mMsg.get_s64(nla);
914 }
915
put_string(int attribute,const char * value)916 int WifiVendorCommand::put_string(int attribute, const char *value)
917 {
918 return mMsg.put_string(attribute, value);
919 }
920
put_addr(int attribute,mac_addr value)921 int WifiVendorCommand::put_addr(int attribute, mac_addr value)
922 {
923 return mMsg.put_addr(attribute, value);
924 }
925
attr_start(int attribute)926 struct nlattr * WifiVendorCommand::attr_start(int attribute)
927 {
928 return mMsg.attr_start(attribute);
929 }
930
attr_end(struct nlattr * attribute)931 void WifiVendorCommand::attr_end(struct nlattr *attribute)
932 {
933 return mMsg.attr_end(attribute);
934 }
935
set_iface_id(const char * name)936 int WifiVendorCommand::set_iface_id(const char* name)
937 {
938 unsigned ifindex = if_nametoindex(name);
939 return mMsg.set_iface_id(ifindex);
940 }
941
put_bytes(int attribute,const char * data,int len)942 int WifiVendorCommand::put_bytes(int attribute, const char *data, int len)
943 {
944 return mMsg.put_bytes(attribute, data, len);
945 }
946
get_mac_addr(struct nlattr ** tb_vendor,int attribute,mac_addr addr)947 wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor,
948 int attribute,
949 mac_addr addr)
950 {
951 if (!tb_vendor[attribute]) {
952 ALOGE("Failed to get attribute : %d", attribute);
953 return WIFI_ERROR_INVALID_ARGS;
954 }
955 if (!addr) {
956 ALOGE("addr is NULL");
957 return WIFI_ERROR_INVALID_ARGS;
958 }
959
960 if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) {
961 ALOGE("Invalid mac addr lenght\n");
962 return WIFI_ERROR_INVALID_ARGS;
963 }
964
965 memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]),
966 nla_len(tb_vendor[attribute]));
967
968 return WIFI_SUCCESS;
969 }
970
initialize_vendor_cmd(wifi_interface_handle iface,wifi_request_id id,u32 subcmd,WifiVendorCommand ** vCommand)971 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
972 wifi_request_id id,
973 u32 subcmd,
974 WifiVendorCommand **vCommand)
975 {
976 int ret = 0;
977 interface_info *ifaceInfo = getIfaceInfo(iface);
978 wifi_handle wifiHandle = getWifiHandle(iface);
979
980 if (vCommand == NULL) {
981 ALOGE("%s: Error vCommand NULL", __FUNCTION__);
982 return WIFI_ERROR_INVALID_ARGS;
983 }
984
985 *vCommand = new WifiVendorCommand(wifiHandle, id,
986 OUI_QCA,
987 subcmd);
988 if (*vCommand == NULL) {
989 ALOGE("%s: Object creation failed", __FUNCTION__);
990 return WIFI_ERROR_OUT_OF_MEMORY;
991 }
992
993 /* Create the message */
994 ret = (*vCommand)->create();
995 if (ret < 0)
996 goto cleanup;
997
998 ret = (*vCommand)->set_iface_id(ifaceInfo->name);
999 if (ret < 0)
1000 goto cleanup;
1001
1002 return WIFI_SUCCESS;
1003
1004 cleanup:
1005 delete *vCommand;
1006 return (wifi_error)ret;
1007 }
1008