Moving Wifi HAL to hardware
[android/platform/hardware/broadcom/wlan.git] / bcmdhd / wifi_hal / cpp_bindings.cpp
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-types.h>
18
19 #include "nl80211_copy.h"
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_GET_COALESCE)
140         C2S(NL80211_CMD_SET_COALESCE)
141         C2S(NL80211_CMD_CHANNEL_SWITCH)
142         C2S(NL80211_CMD_VENDOR)
143         C2S(NL80211_CMD_SET_QOS_MAP)
144         default:
145                 return "NL80211_CMD_UNKNOWN";
146         }
147 }
148
149 const char *attributeToString(int attribute)
150 {
151     switch (attribute) {
152         C2S(NL80211_ATTR_UNSPEC)
153
154         C2S(NL80211_ATTR_WIPHY)
155         C2S(NL80211_ATTR_WIPHY_NAME)
156
157         C2S(NL80211_ATTR_IFINDEX)
158         C2S(NL80211_ATTR_IFNAME)
159         C2S(NL80211_ATTR_IFTYPE)
160
161         C2S(NL80211_ATTR_MAC)
162
163         C2S(NL80211_ATTR_KEY_DATA)
164         C2S(NL80211_ATTR_KEY_IDX)
165         C2S(NL80211_ATTR_KEY_CIPHER)
166         C2S(NL80211_ATTR_KEY_SEQ)
167         C2S(NL80211_ATTR_KEY_DEFAULT)
168
169         C2S(NL80211_ATTR_BEACON_INTERVAL)
170         C2S(NL80211_ATTR_DTIM_PERIOD)
171         C2S(NL80211_ATTR_BEACON_HEAD)
172         C2S(NL80211_ATTR_BEACON_TAIL)
173
174         C2S(NL80211_ATTR_STA_AID)
175         C2S(NL80211_ATTR_STA_FLAGS)
176         C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
177         C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
178         C2S(NL80211_ATTR_STA_VLAN)
179         C2S(NL80211_ATTR_STA_INFO)
180
181         C2S(NL80211_ATTR_WIPHY_BANDS)
182
183         C2S(NL80211_ATTR_MNTR_FLAGS)
184
185         C2S(NL80211_ATTR_MESH_ID)
186         C2S(NL80211_ATTR_STA_PLINK_ACTION)
187         C2S(NL80211_ATTR_MPATH_NEXT_HOP)
188         C2S(NL80211_ATTR_MPATH_INFO)
189
190         C2S(NL80211_ATTR_BSS_CTS_PROT)
191         C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
192         C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
193
194         C2S(NL80211_ATTR_HT_CAPABILITY)
195
196         C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
197
198         C2S(NL80211_ATTR_REG_ALPHA2)
199         C2S(NL80211_ATTR_REG_RULES)
200
201         C2S(NL80211_ATTR_MESH_CONFIG)
202
203         C2S(NL80211_ATTR_BSS_BASIC_RATES)
204
205         C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
206         C2S(NL80211_ATTR_WIPHY_FREQ)
207         C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
208
209         C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
210
211         C2S(NL80211_ATTR_MGMT_SUBTYPE)
212         C2S(NL80211_ATTR_IE)
213
214         C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
215
216         C2S(NL80211_ATTR_SCAN_FREQUENCIES)
217         C2S(NL80211_ATTR_SCAN_SSIDS)
218         C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
219         C2S(NL80211_ATTR_BSS)
220
221         C2S(NL80211_ATTR_REG_INITIATOR)
222         C2S(NL80211_ATTR_REG_TYPE)
223
224         C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
225
226         C2S(NL80211_ATTR_FRAME)
227         C2S(NL80211_ATTR_SSID)
228         C2S(NL80211_ATTR_AUTH_TYPE)
229         C2S(NL80211_ATTR_REASON_CODE)
230
231         C2S(NL80211_ATTR_KEY_TYPE)
232
233         C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
234         C2S(NL80211_ATTR_CIPHER_SUITES)
235
236         C2S(NL80211_ATTR_FREQ_BEFORE)
237         C2S(NL80211_ATTR_FREQ_AFTER)
238
239         C2S(NL80211_ATTR_FREQ_FIXED)
240
241
242         C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
243         C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
244         C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
245         C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
246
247         C2S(NL80211_ATTR_TIMED_OUT)
248
249         C2S(NL80211_ATTR_USE_MFP)
250
251         C2S(NL80211_ATTR_STA_FLAGS2)
252
253         C2S(NL80211_ATTR_CONTROL_PORT)
254
255         C2S(NL80211_ATTR_TESTDATA)
256
257         C2S(NL80211_ATTR_PRIVACY)
258
259         C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
260         C2S(NL80211_ATTR_STATUS_CODE)
261
262         C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
263         C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
264         C2S(NL80211_ATTR_WPA_VERSIONS)
265         C2S(NL80211_ATTR_AKM_SUITES)
266
267         C2S(NL80211_ATTR_REQ_IE)
268         C2S(NL80211_ATTR_RESP_IE)
269
270         C2S(NL80211_ATTR_PREV_BSSID)
271
272         C2S(NL80211_ATTR_KEY)
273         C2S(NL80211_ATTR_KEYS)
274
275         C2S(NL80211_ATTR_PID)
276
277         C2S(NL80211_ATTR_4ADDR)
278
279         C2S(NL80211_ATTR_SURVEY_INFO)
280
281         C2S(NL80211_ATTR_PMKID)
282         C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
283
284         C2S(NL80211_ATTR_DURATION)
285
286         C2S(NL80211_ATTR_COOKIE)
287
288         C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
289
290         C2S(NL80211_ATTR_TX_RATES)
291
292         C2S(NL80211_ATTR_FRAME_MATCH)
293
294         C2S(NL80211_ATTR_ACK)
295
296         C2S(NL80211_ATTR_PS_STATE)
297
298         C2S(NL80211_ATTR_CQM)
299
300         C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
301
302         C2S(NL80211_ATTR_AP_ISOLATE)
303
304         C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
305         C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
306
307         C2S(NL80211_ATTR_TX_FRAME_TYPES)
308         C2S(NL80211_ATTR_RX_FRAME_TYPES)
309         C2S(NL80211_ATTR_FRAME_TYPE)
310
311         C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
312         C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
313
314         C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
315
316         C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
317         C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
318
319         C2S(NL80211_ATTR_MCAST_RATE)
320
321         C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
322
323         C2S(NL80211_ATTR_BSS_HT_OPMODE)
324
325         C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
326
327         C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
328
329         C2S(NL80211_ATTR_MESH_SETUP)
330
331         C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
332         C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
333
334         C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
335         C2S(NL80211_ATTR_STA_PLINK_STATE)
336
337         C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
338         C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
339
340         C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
341
342         C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
343         C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
344
345         C2S(NL80211_ATTR_REKEY_DATA)
346
347         C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
348         C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
349
350         C2S(NL80211_ATTR_SCAN_SUPP_RATES)
351
352         C2S(NL80211_ATTR_HIDDEN_SSID)
353
354         C2S(NL80211_ATTR_IE_PROBE_RESP)
355         C2S(NL80211_ATTR_IE_ASSOC_RESP)
356
357         C2S(NL80211_ATTR_STA_WME)
358         C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
359
360         C2S(NL80211_ATTR_ROAM_SUPPORT)
361
362         C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
363         C2S(NL80211_ATTR_MAX_MATCH_SETS)
364
365         C2S(NL80211_ATTR_PMKSA_CANDIDATE)
366
367         C2S(NL80211_ATTR_TX_NO_CCK_RATE)
368
369         C2S(NL80211_ATTR_TDLS_ACTION)
370         C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
371         C2S(NL80211_ATTR_TDLS_OPERATION)
372         C2S(NL80211_ATTR_TDLS_SUPPORT)
373         C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
374
375         C2S(NL80211_ATTR_DEVICE_AP_SME)
376
377         C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
378
379         C2S(NL80211_ATTR_FEATURE_FLAGS)
380
381         C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
382
383         C2S(NL80211_ATTR_PROBE_RESP)
384
385         C2S(NL80211_ATTR_DFS_REGION)
386
387         C2S(NL80211_ATTR_DISABLE_HT)
388         C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
389
390         C2S(NL80211_ATTR_NOACK_MAP)
391
392         C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
393
394         C2S(NL80211_ATTR_RX_SIGNAL_DBM)
395
396         C2S(NL80211_ATTR_BG_SCAN_PERIOD)
397
398         C2S(NL80211_ATTR_WDEV)
399
400         C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
401
402         C2S(NL80211_ATTR_CONN_FAILED_REASON)
403
404         C2S(NL80211_ATTR_SAE_DATA)
405
406         C2S(NL80211_ATTR_VHT_CAPABILITY)
407
408         C2S(NL80211_ATTR_SCAN_FLAGS)
409
410         C2S(NL80211_ATTR_CHANNEL_WIDTH)
411         C2S(NL80211_ATTR_CENTER_FREQ1)
412         C2S(NL80211_ATTR_CENTER_FREQ2)
413
414         C2S(NL80211_ATTR_P2P_CTWINDOW)
415         C2S(NL80211_ATTR_P2P_OPPPS)
416
417         C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
418
419         C2S(NL80211_ATTR_ACL_POLICY)
420
421         C2S(NL80211_ATTR_MAC_ADDRS)
422
423         C2S(NL80211_ATTR_MAC_ACL_MAX)
424
425         C2S(NL80211_ATTR_RADAR_EVENT)
426
427         C2S(NL80211_ATTR_EXT_CAPA)
428         C2S(NL80211_ATTR_EXT_CAPA_MASK)
429
430         C2S(NL80211_ATTR_STA_CAPABILITY)
431         C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
432
433         C2S(NL80211_ATTR_PROTOCOL_FEATURES)
434         C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
435
436         C2S(NL80211_ATTR_DISABLE_VHT)
437         C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
438
439         C2S(NL80211_ATTR_MDID)
440         C2S(NL80211_ATTR_IE_RIC)
441
442         C2S(NL80211_ATTR_CRIT_PROT_ID)
443         C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
444
445         C2S(NL80211_ATTR_PEER_AID)
446
447         C2S(NL80211_ATTR_COALESCE_RULE)
448
449         C2S(NL80211_ATTR_CH_SWITCH_COUNT)
450         C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
451         C2S(NL80211_ATTR_CSA_IES)
452         C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
453         C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
454
455         C2S(NL80211_ATTR_RXMGMT_FLAGS)
456
457         C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
458
459         C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
460
461         C2S(NL80211_ATTR_HANDLE_DFS)
462
463         C2S(NL80211_ATTR_SUPPORT_5_MHZ)
464         C2S(NL80211_ATTR_SUPPORT_10_MHZ)
465
466         C2S(NL80211_ATTR_OPMODE_NOTIF)
467
468         C2S(NL80211_ATTR_VENDOR_ID)
469         C2S(NL80211_ATTR_VENDOR_SUBCMD)
470         C2S(NL80211_ATTR_VENDOR_DATA)
471         C2S(NL80211_ATTR_VENDOR_EVENTS)
472
473         C2S(NL80211_ATTR_QOS_MAP)
474     default:
475         return "NL80211_ATTR_UNKNOWN";
476     }
477 }
478
479 void WifiEvent::log() {
480     parse();
481
482     byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
483     int len = genlmsg_attrlen(mHeader, 0);
484     ALOGD("cmd = %s, len = %d", get_cmdString(), len);
485     ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd());
486
487     for (int i = 0; i < len; i += 16) {
488         char line[81];
489         int linelen = min(16, len - i);
490         int offset = 0;
491         appendFmt(line, offset, "%02x", data[i]);
492         for (int j = 1; j < linelen; j++) {
493             appendFmt(line, offset, " %02x", data[i+j]);
494         }
495
496         for (int j = linelen; j < 16; j++) {
497             appendFmt(line, offset, "   ");
498         }
499
500         line[23] = '-';
501
502         appendFmt(line, offset, "  ");
503
504         for (int j = 0; j < linelen; j++) {
505             if (isprint(data[i+j])) {
506                 appendFmt(line, offset, "%c", data[i+j]);
507             } else {
508                 appendFmt(line, offset, "-");
509             }
510         }
511
512         ALOGD("%s", line);
513     }
514
515     for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) {
516         if (mAttributes[i] != NULL) {
517             ALOGD("found attribute %s", attributeToString(i));
518         }
519     }
520
521     ALOGD("-- End of message --");
522 }
523
524 const char *WifiEvent::get_cmdString() {
525     return cmdToString(get_cmd());
526 }
527
528
529 int WifiEvent::parse() {
530     if (mHeader != NULL) {
531         return WIFI_SUCCESS;
532     }
533     mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
534     int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
535           genlmsg_attrlen(mHeader, 0), NULL);
536
537     // ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
538     return result;
539 }
540
541 int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
542     mMsg = nlmsg_alloc();
543     if (mMsg != NULL) {
544         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
545                 hdrlen, flags, cmd, /* version = */ 0);
546         return WIFI_SUCCESS;
547     } else {
548         return WIFI_ERROR_OUT_OF_MEMORY;
549     }
550 }
551
552 int WifiRequest::create(uint32_t id, int subcmd) {
553     int res = create(NL80211_CMD_VENDOR);
554     if (res < 0) {
555         return res;
556     }
557
558     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
559     if (res < 0) {
560         return res;
561     }
562
563     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
564     if (res < 0) {
565         return res;
566     }
567
568     if (mIface != -1) {
569         res = set_iface_id(mIface);
570     }
571
572     return res;
573 }
574
575
576 static int no_seq_check(struct nl_msg *msg, void *arg)
577 {
578         return NL_OK;
579 }
580
581 int WifiCommand::requestResponse() {
582     int err = create();                 /* create the message */
583     if (err < 0) {
584         return err;
585     }
586
587     return requestResponse(mMsg);
588 }
589
590 int WifiCommand::requestResponse(WifiRequest& request) {
591     int err = 0;
592
593     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
594     if (!cb)
595         goto out;
596
597     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
598     if (err < 0)
599         goto out;
600
601     err = 1;
602
603     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
604     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
605     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
606     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
607     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
608
609     while (err > 0) {                   /* wait for reply */
610         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
611         if (res) {
612             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
613         }
614     }
615 out:
616     nl_cb_put(cb);
617     return err;
618 }
619
620 int WifiCommand::requestEvent(int cmd) {
621
622     ALOGD("requesting event %d", cmd);
623
624     int res = wifi_register_handler(wifiHandle(), cmd, 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     ALOGD("waiting for response %d", cmd);
634
635     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
636     if (res < 0)
637         goto out;
638
639     ALOGD("waiting for event %d", cmd);
640     res = mCondition.wait();
641     if (res < 0)
642         goto out;
643
644 out:
645     wifi_unregister_handler(wifiHandle(), cmd);
646     return res;
647 }
648
649 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
650
651     int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
652     if (res < 0) {
653         return res;
654     }
655
656     res = create();                                                 /* create the message */
657     if (res < 0)
658         goto out;
659
660     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
661     if (res < 0)
662         goto out;
663
664     res = mCondition.wait();
665     if (res < 0)
666         goto out;
667
668 out:
669     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
670     return res;
671 }
672
673 /* Event handlers */
674 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
675     // ALOGD("response_handler called");
676     WifiCommand *cmd = (WifiCommand *)arg;
677     WifiEvent reply(msg);
678     int res = reply.parse();
679     if (res < 0) {
680         ALOGE("Failed to parse reply message = %d", res);
681         return NL_SKIP;
682     } else {
683         reply.log();
684         return cmd->handleResponse(reply);
685     }
686 }
687
688 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
689     WifiCommand *cmd = (WifiCommand *)arg;
690     WifiEvent event(msg);
691     int res = event.parse();
692     if (res < 0) {
693         ALOGE("Failed to parse event = %d", res);
694         res = NL_SKIP;
695     } else {
696         res = cmd->handleEvent(event);
697     }
698
699     cmd->mCondition.signal();
700     return res;
701 }
702
703 /* Other event handlers */
704 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
705     // ALOGD("valid_handler called");
706     int *err = (int *)arg;
707     *err = 0;
708     return NL_SKIP;
709 }
710
711 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
712     // ALOGD("ack_handler called");
713     int *err = (int *)arg;
714     *err = 0;
715     return NL_STOP;
716 }
717
718 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
719     // ALOGD("finish_handler called");
720     int *ret = (int *)arg;
721     *ret = 0;
722     return NL_SKIP;
723 }
724
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     // ALOGD("error_handler received : %d", err->error);
730     return NL_SKIP;
731 }