[7885]wlbt : Fix coverity issues (Critical and Major)
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / cpp_bindings.cpp
CommitLineData
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
26void 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
36static 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
145const 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
454void 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 }
7753f181
DD
495}
496
497const char *WifiEvent::get_cmdString() {
498 return cmdToString(get_cmd());
499}
500
501
502int WifiEvent::parse() {
503 if (mHeader != NULL) {
504 return WIFI_SUCCESS;
505 }
506 mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
507 int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
508 genlmsg_attrlen(mHeader, 0), NULL);
509
510 ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
511 return result;
512}
513
514int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
515 mMsg = nlmsg_alloc();
516 if (mMsg != NULL) {
517 genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
518 hdrlen, flags, cmd, /* version = */ 0);
519 return WIFI_SUCCESS;
520 } else {
521 return WIFI_ERROR_OUT_OF_MEMORY;
522 }
523}
524
525int WifiRequest::create(uint32_t id, int subcmd) {
526 int res = create(NL80211_CMD_VENDOR);
527 if (res < 0) {
528 return res;
529 }
530
531 res = put_u32(NL80211_ATTR_VENDOR_ID, id);
532 if (res < 0) {
533 return res;
534 }
535
536 res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
537 if (res < 0) {
538 return res;
539 }
540
541 if (mIface != -1) {
542 res = set_iface_id(mIface);
543 }
544
545 return res;
546}
547
548
549static int no_seq_check(struct nl_msg *msg, void *arg)
550{
551 return NL_OK;
552}
553
554int WifiCommand::requestResponse() {
555 int err = create(); /* create the message */
556 if (err < 0) {
557 return err;
558 }
559
560 return requestResponse(mMsg);
561}
562
563int WifiCommand::requestResponse(WifiRequest& request) {
564 int err = 0;
565
566 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
567 if (!cb)
568 goto out;
569
570 err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */
571 if (err < 0)
572 goto out;
573
574 err = 1;
575
576 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
577 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
578 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
579 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
580 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
581
582 while (err > 0) { /* wait for reply */
583 int res = nl_recvmsgs(mInfo->cmd_sock, cb);
584 if (res) {
585 ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
586 }
587 }
588out:
589 nl_cb_put(cb);
590 return err;
591}
592
593int WifiCommand::requestEvent(int cmd) {
594
595 ALOGD("requesting event %d", cmd);
596
597 int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
598 if (res < 0) {
599 return res;
600 }
601
602 res = create(); /* create the message */
603 if (res < 0)
604 goto out;
605
606 ALOGD("waiting for response %d", cmd);
607
608 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
609 if (res < 0)
610 goto out;
611
612 ALOGD("waiting for event %d", cmd);
613 res = mCondition.wait();
614 if (res < 0)
615 goto out;
616
617out:
618 wifi_unregister_handler(wifiHandle(), cmd);
619 return res;
620}
621
622int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
623
624 int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
625 if (res < 0) {
626 return res;
627 }
628
629 res = create(); /* create the message */
630 if (res < 0)
631 goto out;
632
633 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
634 if (res < 0)
635 goto out;
636
637 res = mCondition.wait();
638 if (res < 0)
639 goto out;
640
641out:
642 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
643 return res;
644}
645
646/* Event handlers */
647int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
7753f181
DD
648 WifiCommand *cmd = (WifiCommand *)arg;
649 WifiEvent reply(msg);
650 int res = reply.parse();
651 if (res < 0) {
652 ALOGE("Failed to parse reply message = %d", res);
653 return NL_SKIP;
654 } else {
655 // reply.log();
656 return cmd->handleResponse(reply);
657 }
658}
659
660int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
661 WifiCommand *cmd = (WifiCommand *)arg;
662 WifiEvent event(msg);
663 int res = event.parse();
664 if (res < 0) {
665 ALOGE("Failed to parse event = %d", res);
666 res = NL_SKIP;
667 } else {
668 res = cmd->handleEvent(event);
669 }
670
671 cmd->mCondition.signal();
672 return res;
673}
674
675/* Other event handlers */
676int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
7753f181
DD
677 int *err = (int *)arg;
678 *err = 0;
679 return NL_SKIP;
680}
681
682int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
7753f181
DD
683 int *err = (int *)arg;
684 *err = 0;
685 return NL_STOP;
686}
687
688int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
7753f181
DD
689 int *ret = (int *)arg;
690 *ret = 0;
691 return NL_SKIP;
692}
693
694int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
695 int *ret = (int *)arg;
696 *ret = err->error;
697
698 ALOGD("error_handler received : %d", err->error);
699 return NL_SKIP;
700}