Commit | Line | Data |
---|---|---|
7753f181 DD |
1 | |
2 | #include <stdint.h> | |
3 | #include <fcntl.h> | |
4 | #include <sys/socket.h> | |
5 | #include <netlink/genl/genl.h> | |
6 | #include <netlink/genl/family.h> | |
7 | #include <netlink/genl/ctrl.h> | |
8 | #include <linux/rtnetlink.h> | |
9 | #include <netpacket/packet.h> | |
10 | #include <linux/filter.h> | |
11 | #include <linux/errqueue.h> | |
12 | ||
13 | #include <linux/pkt_sched.h> | |
14 | #include <netlink/object-api.h> | |
15 | #include <netlink/netlink.h> | |
16 | #include <netlink/socket.h> | |
17 | #include <netlink/handlers.h> | |
18 | #include <stdarg.h> | |
19 | ||
20 | #include <ctype.h> | |
21 | ||
22 | #include "wifi_hal.h" | |
23 | #include "common.h" | |
24 | #include "cpp_bindings.h" | |
25 | ||
26 | void appendFmt(char *buf, int &offset, const char *fmt, ...) | |
27 | { | |
28 | va_list params; | |
29 | va_start(params, fmt); | |
30 | offset += vsprintf(buf + offset, fmt, params); | |
31 | va_end(params); | |
32 | } | |
33 | ||
34 | #define C2S(x) case x: return #x; | |
35 | ||
36 | static const char *cmdToString(int cmd) | |
37 | { | |
38 | switch (cmd) { | |
39 | C2S(NL80211_CMD_UNSPEC) | |
40 | C2S(NL80211_CMD_GET_WIPHY) | |
41 | C2S(NL80211_CMD_SET_WIPHY) | |
42 | C2S(NL80211_CMD_NEW_WIPHY) | |
43 | C2S(NL80211_CMD_DEL_WIPHY) | |
44 | C2S(NL80211_CMD_GET_INTERFACE) | |
45 | C2S(NL80211_CMD_SET_INTERFACE) | |
46 | C2S(NL80211_CMD_NEW_INTERFACE) | |
47 | C2S(NL80211_CMD_DEL_INTERFACE) | |
48 | C2S(NL80211_CMD_GET_KEY) | |
49 | C2S(NL80211_CMD_SET_KEY) | |
50 | C2S(NL80211_CMD_NEW_KEY) | |
51 | C2S(NL80211_CMD_DEL_KEY) | |
52 | C2S(NL80211_CMD_GET_BEACON) | |
53 | C2S(NL80211_CMD_SET_BEACON) | |
54 | C2S(NL80211_CMD_START_AP) | |
55 | C2S(NL80211_CMD_STOP_AP) | |
56 | C2S(NL80211_CMD_GET_STATION) | |
57 | C2S(NL80211_CMD_SET_STATION) | |
58 | C2S(NL80211_CMD_NEW_STATION) | |
59 | C2S(NL80211_CMD_DEL_STATION) | |
60 | C2S(NL80211_CMD_GET_MPATH) | |
61 | C2S(NL80211_CMD_SET_MPATH) | |
62 | C2S(NL80211_CMD_NEW_MPATH) | |
63 | C2S(NL80211_CMD_DEL_MPATH) | |
64 | C2S(NL80211_CMD_SET_BSS) | |
65 | C2S(NL80211_CMD_SET_REG) | |
66 | C2S(NL80211_CMD_REQ_SET_REG) | |
67 | C2S(NL80211_CMD_GET_MESH_CONFIG) | |
68 | C2S(NL80211_CMD_SET_MESH_CONFIG) | |
69 | C2S(NL80211_CMD_SET_MGMT_EXTRA_IE) | |
70 | C2S(NL80211_CMD_GET_REG) | |
71 | C2S(NL80211_CMD_GET_SCAN) | |
72 | C2S(NL80211_CMD_TRIGGER_SCAN) | |
73 | C2S(NL80211_CMD_NEW_SCAN_RESULTS) | |
74 | C2S(NL80211_CMD_SCAN_ABORTED) | |
75 | C2S(NL80211_CMD_REG_CHANGE) | |
76 | C2S(NL80211_CMD_AUTHENTICATE) | |
77 | C2S(NL80211_CMD_ASSOCIATE) | |
78 | C2S(NL80211_CMD_DEAUTHENTICATE) | |
79 | C2S(NL80211_CMD_DISASSOCIATE) | |
80 | C2S(NL80211_CMD_MICHAEL_MIC_FAILURE) | |
81 | C2S(NL80211_CMD_REG_BEACON_HINT) | |
82 | C2S(NL80211_CMD_JOIN_IBSS) | |
83 | C2S(NL80211_CMD_LEAVE_IBSS) | |
84 | C2S(NL80211_CMD_TESTMODE) | |
85 | C2S(NL80211_CMD_CONNECT) | |
86 | C2S(NL80211_CMD_ROAM) | |
87 | C2S(NL80211_CMD_DISCONNECT) | |
88 | C2S(NL80211_CMD_SET_WIPHY_NETNS) | |
89 | C2S(NL80211_CMD_GET_SURVEY) | |
90 | C2S(NL80211_CMD_NEW_SURVEY_RESULTS) | |
91 | C2S(NL80211_CMD_SET_PMKSA) | |
92 | C2S(NL80211_CMD_DEL_PMKSA) | |
93 | C2S(NL80211_CMD_FLUSH_PMKSA) | |
94 | C2S(NL80211_CMD_REMAIN_ON_CHANNEL) | |
95 | C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL) | |
96 | C2S(NL80211_CMD_SET_TX_BITRATE_MASK) | |
97 | C2S(NL80211_CMD_REGISTER_FRAME) | |
98 | C2S(NL80211_CMD_FRAME) | |
99 | C2S(NL80211_CMD_FRAME_TX_STATUS) | |
100 | C2S(NL80211_CMD_SET_POWER_SAVE) | |
101 | C2S(NL80211_CMD_GET_POWER_SAVE) | |
102 | C2S(NL80211_CMD_SET_CQM) | |
103 | C2S(NL80211_CMD_NOTIFY_CQM) | |
104 | C2S(NL80211_CMD_SET_CHANNEL) | |
105 | C2S(NL80211_CMD_SET_WDS_PEER) | |
106 | C2S(NL80211_CMD_FRAME_WAIT_CANCEL) | |
107 | C2S(NL80211_CMD_JOIN_MESH) | |
108 | C2S(NL80211_CMD_LEAVE_MESH) | |
109 | C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE) | |
110 | C2S(NL80211_CMD_UNPROT_DISASSOCIATE) | |
111 | C2S(NL80211_CMD_NEW_PEER_CANDIDATE) | |
112 | C2S(NL80211_CMD_GET_WOWLAN) | |
113 | C2S(NL80211_CMD_SET_WOWLAN) | |
114 | C2S(NL80211_CMD_START_SCHED_SCAN) | |
115 | C2S(NL80211_CMD_STOP_SCHED_SCAN) | |
116 | C2S(NL80211_CMD_SCHED_SCAN_RESULTS) | |
117 | C2S(NL80211_CMD_SCHED_SCAN_STOPPED) | |
118 | C2S(NL80211_CMD_SET_REKEY_OFFLOAD) | |
119 | C2S(NL80211_CMD_PMKSA_CANDIDATE) | |
120 | C2S(NL80211_CMD_TDLS_OPER) | |
121 | C2S(NL80211_CMD_TDLS_MGMT) | |
122 | C2S(NL80211_CMD_UNEXPECTED_FRAME) | |
123 | C2S(NL80211_CMD_PROBE_CLIENT) | |
124 | C2S(NL80211_CMD_REGISTER_BEACONS) | |
125 | C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME) | |
126 | C2S(NL80211_CMD_SET_NOACK_MAP) | |
127 | C2S(NL80211_CMD_CH_SWITCH_NOTIFY) | |
128 | C2S(NL80211_CMD_START_P2P_DEVICE) | |
129 | C2S(NL80211_CMD_STOP_P2P_DEVICE) | |
130 | C2S(NL80211_CMD_CONN_FAILED) | |
131 | C2S(NL80211_CMD_SET_MCAST_RATE) | |
132 | C2S(NL80211_CMD_SET_MAC_ACL) | |
133 | C2S(NL80211_CMD_RADAR_DETECT) | |
134 | C2S(NL80211_CMD_GET_PROTOCOL_FEATURES) | |
135 | C2S(NL80211_CMD_UPDATE_FT_IES) | |
136 | C2S(NL80211_CMD_FT_EVENT) | |
137 | C2S(NL80211_CMD_CRIT_PROTOCOL_START) | |
138 | C2S(NL80211_CMD_CRIT_PROTOCOL_STOP) | |
139 | C2S(NL80211_CMD_VENDOR) | |
140 | default: | |
141 | return "NL80211_CMD_UNKNOWN"; | |
142 | } | |
143 | } | |
144 | ||
145 | const char *attributeToString(int attribute) | |
146 | { | |
147 | switch (attribute) { | |
148 | C2S(NL80211_ATTR_UNSPEC) | |
149 | ||
150 | C2S(NL80211_ATTR_WIPHY) | |
151 | C2S(NL80211_ATTR_WIPHY_NAME) | |
152 | ||
153 | C2S(NL80211_ATTR_IFINDEX) | |
154 | C2S(NL80211_ATTR_IFNAME) | |
155 | C2S(NL80211_ATTR_IFTYPE) | |
156 | ||
157 | C2S(NL80211_ATTR_MAC) | |
158 | ||
159 | C2S(NL80211_ATTR_KEY_DATA) | |
160 | C2S(NL80211_ATTR_KEY_IDX) | |
161 | C2S(NL80211_ATTR_KEY_CIPHER) | |
162 | C2S(NL80211_ATTR_KEY_SEQ) | |
163 | C2S(NL80211_ATTR_KEY_DEFAULT) | |
164 | ||
165 | C2S(NL80211_ATTR_BEACON_INTERVAL) | |
166 | C2S(NL80211_ATTR_DTIM_PERIOD) | |
167 | C2S(NL80211_ATTR_BEACON_HEAD) | |
168 | C2S(NL80211_ATTR_BEACON_TAIL) | |
169 | ||
170 | C2S(NL80211_ATTR_STA_AID) | |
171 | C2S(NL80211_ATTR_STA_FLAGS) | |
172 | C2S(NL80211_ATTR_STA_LISTEN_INTERVAL) | |
173 | C2S(NL80211_ATTR_STA_SUPPORTED_RATES) | |
174 | C2S(NL80211_ATTR_STA_VLAN) | |
175 | C2S(NL80211_ATTR_STA_INFO) | |
176 | ||
177 | C2S(NL80211_ATTR_WIPHY_BANDS) | |
178 | ||
179 | C2S(NL80211_ATTR_MNTR_FLAGS) | |
180 | ||
181 | C2S(NL80211_ATTR_MESH_ID) | |
182 | C2S(NL80211_ATTR_STA_PLINK_ACTION) | |
183 | C2S(NL80211_ATTR_MPATH_NEXT_HOP) | |
184 | C2S(NL80211_ATTR_MPATH_INFO) | |
185 | ||
186 | C2S(NL80211_ATTR_BSS_CTS_PROT) | |
187 | C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE) | |
188 | C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME) | |
189 | ||
190 | C2S(NL80211_ATTR_HT_CAPABILITY) | |
191 | ||
192 | C2S(NL80211_ATTR_SUPPORTED_IFTYPES) | |
193 | ||
194 | C2S(NL80211_ATTR_REG_ALPHA2) | |
195 | C2S(NL80211_ATTR_REG_RULES) | |
196 | ||
197 | C2S(NL80211_ATTR_MESH_CONFIG) | |
198 | ||
199 | C2S(NL80211_ATTR_BSS_BASIC_RATES) | |
200 | ||
201 | C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS) | |
202 | C2S(NL80211_ATTR_WIPHY_FREQ) | |
203 | C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE) | |
204 | ||
205 | C2S(NL80211_ATTR_KEY_DEFAULT_MGMT) | |
206 | ||
207 | C2S(NL80211_ATTR_MGMT_SUBTYPE) | |
208 | C2S(NL80211_ATTR_IE) | |
209 | ||
210 | C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS) | |
211 | ||
212 | C2S(NL80211_ATTR_SCAN_FREQUENCIES) | |
213 | C2S(NL80211_ATTR_SCAN_SSIDS) | |
214 | C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */ | |
215 | C2S(NL80211_ATTR_BSS) | |
216 | ||
217 | C2S(NL80211_ATTR_REG_INITIATOR) | |
218 | C2S(NL80211_ATTR_REG_TYPE) | |
219 | ||
220 | C2S(NL80211_ATTR_SUPPORTED_COMMANDS) | |
221 | ||
222 | C2S(NL80211_ATTR_FRAME) | |
223 | C2S(NL80211_ATTR_SSID) | |
224 | C2S(NL80211_ATTR_AUTH_TYPE) | |
225 | C2S(NL80211_ATTR_REASON_CODE) | |
226 | ||
227 | C2S(NL80211_ATTR_KEY_TYPE) | |
228 | ||
229 | C2S(NL80211_ATTR_MAX_SCAN_IE_LEN) | |
230 | C2S(NL80211_ATTR_CIPHER_SUITES) | |
231 | ||
232 | C2S(NL80211_ATTR_FREQ_BEFORE) | |
233 | C2S(NL80211_ATTR_FREQ_AFTER) | |
234 | ||
235 | C2S(NL80211_ATTR_FREQ_FIXED) | |
236 | ||
237 | ||
238 | C2S(NL80211_ATTR_WIPHY_RETRY_SHORT) | |
239 | C2S(NL80211_ATTR_WIPHY_RETRY_LONG) | |
240 | C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD) | |
241 | C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD) | |
242 | ||
243 | C2S(NL80211_ATTR_TIMED_OUT) | |
244 | ||
245 | C2S(NL80211_ATTR_USE_MFP) | |
246 | ||
247 | C2S(NL80211_ATTR_STA_FLAGS2) | |
248 | ||
249 | C2S(NL80211_ATTR_CONTROL_PORT) | |
250 | ||
251 | C2S(NL80211_ATTR_TESTDATA) | |
252 | ||
253 | C2S(NL80211_ATTR_PRIVACY) | |
254 | ||
255 | C2S(NL80211_ATTR_DISCONNECTED_BY_AP) | |
256 | C2S(NL80211_ATTR_STATUS_CODE) | |
257 | ||
258 | C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE) | |
259 | C2S(NL80211_ATTR_CIPHER_SUITE_GROUP) | |
260 | C2S(NL80211_ATTR_WPA_VERSIONS) | |
261 | C2S(NL80211_ATTR_AKM_SUITES) | |
262 | ||
263 | C2S(NL80211_ATTR_REQ_IE) | |
264 | C2S(NL80211_ATTR_RESP_IE) | |
265 | ||
266 | C2S(NL80211_ATTR_PREV_BSSID) | |
267 | ||
268 | C2S(NL80211_ATTR_KEY) | |
269 | C2S(NL80211_ATTR_KEYS) | |
270 | ||
271 | C2S(NL80211_ATTR_PID) | |
272 | ||
273 | C2S(NL80211_ATTR_4ADDR) | |
274 | ||
275 | C2S(NL80211_ATTR_SURVEY_INFO) | |
276 | ||
277 | C2S(NL80211_ATTR_PMKID) | |
278 | C2S(NL80211_ATTR_MAX_NUM_PMKIDS) | |
279 | ||
280 | C2S(NL80211_ATTR_DURATION) | |
281 | ||
282 | C2S(NL80211_ATTR_COOKIE) | |
283 | ||
284 | C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS) | |
285 | ||
286 | C2S(NL80211_ATTR_TX_RATES) | |
287 | ||
288 | C2S(NL80211_ATTR_FRAME_MATCH) | |
289 | ||
290 | C2S(NL80211_ATTR_ACK) | |
291 | ||
292 | C2S(NL80211_ATTR_PS_STATE) | |
293 | ||
294 | C2S(NL80211_ATTR_CQM) | |
295 | ||
296 | C2S(NL80211_ATTR_LOCAL_STATE_CHANGE) | |
297 | ||
298 | C2S(NL80211_ATTR_AP_ISOLATE) | |
299 | ||
300 | C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING) | |
301 | C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL) | |
302 | ||
303 | C2S(NL80211_ATTR_TX_FRAME_TYPES) | |
304 | C2S(NL80211_ATTR_RX_FRAME_TYPES) | |
305 | C2S(NL80211_ATTR_FRAME_TYPE) | |
306 | ||
307 | C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE) | |
308 | C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT) | |
309 | ||
310 | C2S(NL80211_ATTR_SUPPORT_IBSS_RSN) | |
311 | ||
312 | C2S(NL80211_ATTR_WIPHY_ANTENNA_TX) | |
313 | C2S(NL80211_ATTR_WIPHY_ANTENNA_RX) | |
314 | ||
315 | C2S(NL80211_ATTR_MCAST_RATE) | |
316 | ||
317 | C2S(NL80211_ATTR_OFFCHANNEL_TX_OK) | |
318 | ||
319 | C2S(NL80211_ATTR_BSS_HT_OPMODE) | |
320 | ||
321 | C2S(NL80211_ATTR_KEY_DEFAULT_TYPES) | |
322 | ||
323 | C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION) | |
324 | ||
325 | C2S(NL80211_ATTR_MESH_SETUP) | |
326 | ||
327 | C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX) | |
328 | C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX) | |
329 | ||
330 | C2S(NL80211_ATTR_SUPPORT_MESH_AUTH) | |
331 | C2S(NL80211_ATTR_STA_PLINK_STATE) | |
332 | ||
333 | C2S(NL80211_ATTR_WOWLAN_TRIGGERS) | |
334 | C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED) | |
335 | ||
336 | C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL) | |
337 | ||
338 | C2S(NL80211_ATTR_INTERFACE_COMBINATIONS) | |
339 | C2S(NL80211_ATTR_SOFTWARE_IFTYPES) | |
340 | ||
341 | C2S(NL80211_ATTR_REKEY_DATA) | |
342 | ||
343 | C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS) | |
344 | C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN) | |
345 | ||
346 | C2S(NL80211_ATTR_SCAN_SUPP_RATES) | |
347 | ||
348 | C2S(NL80211_ATTR_HIDDEN_SSID) | |
349 | ||
350 | C2S(NL80211_ATTR_IE_PROBE_RESP) | |
351 | C2S(NL80211_ATTR_IE_ASSOC_RESP) | |
352 | ||
353 | C2S(NL80211_ATTR_STA_WME) | |
354 | C2S(NL80211_ATTR_SUPPORT_AP_UAPSD) | |
355 | ||
356 | C2S(NL80211_ATTR_ROAM_SUPPORT) | |
357 | ||
358 | C2S(NL80211_ATTR_SCHED_SCAN_MATCH) | |
359 | C2S(NL80211_ATTR_MAX_MATCH_SETS) | |
360 | ||
361 | C2S(NL80211_ATTR_PMKSA_CANDIDATE) | |
362 | ||
363 | C2S(NL80211_ATTR_TX_NO_CCK_RATE) | |
364 | ||
365 | C2S(NL80211_ATTR_TDLS_ACTION) | |
366 | C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN) | |
367 | C2S(NL80211_ATTR_TDLS_OPERATION) | |
368 | C2S(NL80211_ATTR_TDLS_SUPPORT) | |
369 | C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP) | |
370 | ||
371 | C2S(NL80211_ATTR_DEVICE_AP_SME) | |
372 | ||
373 | C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK) | |
374 | ||
375 | C2S(NL80211_ATTR_FEATURE_FLAGS) | |
376 | ||
377 | C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD) | |
378 | ||
379 | C2S(NL80211_ATTR_PROBE_RESP) | |
380 | ||
381 | C2S(NL80211_ATTR_DFS_REGION) | |
382 | ||
383 | C2S(NL80211_ATTR_DISABLE_HT) | |
384 | C2S(NL80211_ATTR_HT_CAPABILITY_MASK) | |
385 | ||
386 | C2S(NL80211_ATTR_NOACK_MAP) | |
387 | ||
388 | C2S(NL80211_ATTR_INACTIVITY_TIMEOUT) | |
389 | ||
390 | C2S(NL80211_ATTR_RX_SIGNAL_DBM) | |
391 | ||
392 | C2S(NL80211_ATTR_BG_SCAN_PERIOD) | |
393 | ||
394 | C2S(NL80211_ATTR_WDEV) | |
395 | ||
396 | C2S(NL80211_ATTR_USER_REG_HINT_TYPE) | |
397 | ||
398 | C2S(NL80211_ATTR_CONN_FAILED_REASON) | |
399 | ||
400 | C2S(NL80211_ATTR_SAE_DATA) | |
401 | ||
402 | C2S(NL80211_ATTR_VHT_CAPABILITY) | |
403 | ||
404 | C2S(NL80211_ATTR_SCAN_FLAGS) | |
405 | ||
406 | C2S(NL80211_ATTR_CHANNEL_WIDTH) | |
407 | C2S(NL80211_ATTR_CENTER_FREQ1) | |
408 | C2S(NL80211_ATTR_CENTER_FREQ2) | |
409 | ||
410 | C2S(NL80211_ATTR_P2P_CTWINDOW) | |
411 | C2S(NL80211_ATTR_P2P_OPPPS) | |
412 | ||
413 | C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE) | |
414 | ||
415 | C2S(NL80211_ATTR_ACL_POLICY) | |
416 | ||
417 | C2S(NL80211_ATTR_MAC_ADDRS) | |
418 | ||
419 | C2S(NL80211_ATTR_MAC_ACL_MAX) | |
420 | ||
421 | C2S(NL80211_ATTR_RADAR_EVENT) | |
422 | ||
423 | C2S(NL80211_ATTR_EXT_CAPA) | |
424 | C2S(NL80211_ATTR_EXT_CAPA_MASK) | |
425 | ||
426 | C2S(NL80211_ATTR_STA_CAPABILITY) | |
427 | C2S(NL80211_ATTR_STA_EXT_CAPABILITY) | |
428 | ||
429 | C2S(NL80211_ATTR_PROTOCOL_FEATURES) | |
430 | C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP) | |
431 | ||
432 | C2S(NL80211_ATTR_DISABLE_VHT) | |
433 | C2S(NL80211_ATTR_VHT_CAPABILITY_MASK) | |
434 | ||
435 | C2S(NL80211_ATTR_MDID) | |
436 | C2S(NL80211_ATTR_IE_RIC) | |
437 | ||
438 | C2S(NL80211_ATTR_CRIT_PROT_ID) | |
439 | C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION) | |
440 | ||
441 | C2S(NL80211_ATTR_PEER_AID) | |
442 | ||
443 | ||
444 | //S(NL80211_ATTR_VENDOR_ID) | |
445 | C2S(NL80211_ATTR_VENDOR_SUBCMD) | |
446 | C2S(NL80211_ATTR_VENDOR_DATA) | |
447 | C2S(NL80211_ATTR_VENDOR_EVENTS) | |
448 | ||
449 | default: | |
450 | return "NL80211_ATTR_UNKNOWN"; | |
451 | } | |
452 | } | |
453 | ||
454 | void WifiEvent::log() { | |
455 | parse(); | |
456 | ||
457 | byte *data = (byte *)genlmsg_attrdata(mHeader, 0); | |
458 | int len = genlmsg_attrlen(mHeader, 0); | |
459 | ALOGD("cmd = %s, len = %d", get_cmdString(), len); | |
460 | ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd()); | |
461 | ||
462 | for (int i = 0; i < len; i += 16) { | |
463 | char line[81]; | |
464 | int linelen = min(16, len - i); | |
465 | int offset = 0; | |
466 | appendFmt(line, offset, "%02x", data[i]); | |
467 | for (int j = 1; j < linelen; j++) { | |
468 | appendFmt(line, offset, " %02x", data[i+j]); | |
469 | } | |
470 | ||
471 | for (int j = linelen; j < 16; j++) { | |
472 | appendFmt(line, offset, " "); | |
473 | } | |
474 | ||
475 | line[23] = '-'; | |
476 | ||
477 | appendFmt(line, offset, " "); | |
478 | ||
479 | for (int j = 0; j < linelen; j++) { | |
480 | if (isprint(data[i+j])) { | |
481 | appendFmt(line, offset, "%c", data[i+j]); | |
482 | } else { | |
483 | appendFmt(line, offset, "-"); | |
484 | } | |
485 | } | |
486 | ||
487 | ALOGD("%s", line); | |
488 | } | |
489 | ||
490 | for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) { | |
491 | if (mAttributes[i] != NULL) { | |
492 | ALOGD("found attribute %s", attributeToString(i)); | |
493 | } | |
494 | } | |
495 | ||
496 | ALOGD("-- End of message --"); | |
497 | } | |
498 | ||
499 | const char *WifiEvent::get_cmdString() { | |
500 | return cmdToString(get_cmd()); | |
501 | } | |
502 | ||
503 | ||
504 | int WifiEvent::parse() { | |
505 | if (mHeader != NULL) { | |
506 | return WIFI_SUCCESS; | |
507 | } | |
508 | mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg)); | |
509 | int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0), | |
510 | genlmsg_attrlen(mHeader, 0), NULL); | |
511 | ||
512 | ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len); | |
513 | return result; | |
514 | } | |
515 | ||
516 | int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) { | |
517 | mMsg = nlmsg_alloc(); | |
518 | if (mMsg != NULL) { | |
519 | genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family, | |
520 | hdrlen, flags, cmd, /* version = */ 0); | |
521 | return WIFI_SUCCESS; | |
522 | } else { | |
523 | return WIFI_ERROR_OUT_OF_MEMORY; | |
524 | } | |
525 | } | |
526 | ||
527 | int WifiRequest::create(uint32_t id, int subcmd) { | |
528 | int res = create(NL80211_CMD_VENDOR); | |
529 | if (res < 0) { | |
530 | return res; | |
531 | } | |
532 | ||
533 | res = put_u32(NL80211_ATTR_VENDOR_ID, id); | |
534 | if (res < 0) { | |
535 | return res; | |
536 | } | |
537 | ||
538 | res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd); | |
539 | if (res < 0) { | |
540 | return res; | |
541 | } | |
542 | ||
543 | if (mIface != -1) { | |
544 | res = set_iface_id(mIface); | |
545 | } | |
546 | ||
547 | return res; | |
548 | } | |
549 | ||
550 | ||
551 | static int no_seq_check(struct nl_msg *msg, void *arg) | |
552 | { | |
553 | return NL_OK; | |
554 | } | |
555 | ||
556 | int WifiCommand::requestResponse() { | |
557 | int err = create(); /* create the message */ | |
558 | if (err < 0) { | |
559 | return err; | |
560 | } | |
561 | ||
562 | return requestResponse(mMsg); | |
563 | } | |
564 | ||
565 | int WifiCommand::requestResponse(WifiRequest& request) { | |
566 | int err = 0; | |
567 | ||
568 | struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); | |
569 | if (!cb) | |
570 | goto out; | |
571 | ||
572 | err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */ | |
573 | if (err < 0) | |
574 | goto out; | |
575 | ||
576 | err = 1; | |
577 | ||
578 | nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); | |
579 | nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); | |
580 | nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); | |
581 | nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); | |
582 | nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this); | |
583 | ||
584 | while (err > 0) { /* wait for reply */ | |
585 | int res = nl_recvmsgs(mInfo->cmd_sock, cb); | |
586 | if (res) { | |
587 | ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res); | |
588 | } | |
589 | } | |
590 | out: | |
591 | nl_cb_put(cb); | |
592 | return err; | |
593 | } | |
594 | ||
595 | int WifiCommand::requestEvent(int cmd) { | |
596 | ||
597 | ALOGD("requesting event %d", cmd); | |
598 | ||
599 | int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this); | |
600 | if (res < 0) { | |
601 | return res; | |
602 | } | |
603 | ||
604 | res = create(); /* create the message */ | |
605 | if (res < 0) | |
606 | goto out; | |
607 | ||
608 | ALOGD("waiting for response %d", cmd); | |
609 | ||
610 | res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ | |
611 | if (res < 0) | |
612 | goto out; | |
613 | ||
614 | ALOGD("waiting for event %d", cmd); | |
615 | res = mCondition.wait(); | |
616 | if (res < 0) | |
617 | goto out; | |
618 | ||
619 | out: | |
620 | wifi_unregister_handler(wifiHandle(), cmd); | |
621 | return res; | |
622 | } | |
623 | ||
624 | int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { | |
625 | ||
626 | int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this); | |
627 | if (res < 0) { | |
628 | return res; | |
629 | } | |
630 | ||
631 | res = create(); /* create the message */ | |
632 | if (res < 0) | |
633 | goto out; | |
634 | ||
635 | res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ | |
636 | if (res < 0) | |
637 | goto out; | |
638 | ||
639 | res = mCondition.wait(); | |
640 | if (res < 0) | |
641 | goto out; | |
642 | ||
643 | out: | |
644 | wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); | |
645 | return res; | |
646 | } | |
647 | ||
648 | /* Event handlers */ | |
649 | int WifiCommand::response_handler(struct nl_msg *msg, void *arg) { | |
650 | ALOGD("response_handler called"); | |
651 | WifiCommand *cmd = (WifiCommand *)arg; | |
652 | WifiEvent reply(msg); | |
653 | int res = reply.parse(); | |
654 | if (res < 0) { | |
655 | ALOGE("Failed to parse reply message = %d", res); | |
656 | return NL_SKIP; | |
657 | } else { | |
658 | // reply.log(); | |
659 | return cmd->handleResponse(reply); | |
660 | } | |
661 | } | |
662 | ||
663 | int WifiCommand::event_handler(struct nl_msg *msg, void *arg) { | |
664 | WifiCommand *cmd = (WifiCommand *)arg; | |
665 | WifiEvent event(msg); | |
666 | int res = event.parse(); | |
667 | if (res < 0) { | |
668 | ALOGE("Failed to parse event = %d", res); | |
669 | res = NL_SKIP; | |
670 | } else { | |
671 | res = cmd->handleEvent(event); | |
672 | } | |
673 | ||
674 | cmd->mCondition.signal(); | |
675 | return res; | |
676 | } | |
677 | ||
678 | /* Other event handlers */ | |
679 | int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) { | |
680 | ALOGD("valid_handler called"); | |
681 | int *err = (int *)arg; | |
682 | *err = 0; | |
683 | return NL_SKIP; | |
684 | } | |
685 | ||
686 | int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) { | |
687 | ALOGD("ack_handler called"); | |
688 | int *err = (int *)arg; | |
689 | *err = 0; | |
690 | return NL_STOP; | |
691 | } | |
692 | ||
693 | int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) { | |
694 | ALOGD("finish_handler called"); | |
695 | int *ret = (int *)arg; | |
696 | *ret = 0; | |
697 | return NL_SKIP; | |
698 | } | |
699 | ||
700 | int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { | |
701 | int *ret = (int *)arg; | |
702 | *ret = err->error; | |
703 | ||
704 | ALOGD("error_handler received : %d", err->error); | |
705 | return NL_SKIP; | |
706 | } |