nl80211: Ignore deauth/disassoc event during Connect reassociation
[mech_eap.git] / src / drivers / driver_nl80211_event.c
1 /*
2  * Driver interaction with Linux nl80211/cfg80211 - Event processing
3  * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5  * Copyright (c) 2009-2010, Atheros Communications
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10
11 #include "includes.h"
12 #include <netlink/genl/genl.h>
13
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "common/qca-vendor.h"
17 #include "common/qca-vendor-attr.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "driver_nl80211.h"
21
22
23 static const char * nl80211_command_to_string(enum nl80211_commands cmd)
24 {
25 #define C2S(x) case x: return #x;
26         switch (cmd) {
27         C2S(NL80211_CMD_UNSPEC)
28         C2S(NL80211_CMD_GET_WIPHY)
29         C2S(NL80211_CMD_SET_WIPHY)
30         C2S(NL80211_CMD_NEW_WIPHY)
31         C2S(NL80211_CMD_DEL_WIPHY)
32         C2S(NL80211_CMD_GET_INTERFACE)
33         C2S(NL80211_CMD_SET_INTERFACE)
34         C2S(NL80211_CMD_NEW_INTERFACE)
35         C2S(NL80211_CMD_DEL_INTERFACE)
36         C2S(NL80211_CMD_GET_KEY)
37         C2S(NL80211_CMD_SET_KEY)
38         C2S(NL80211_CMD_NEW_KEY)
39         C2S(NL80211_CMD_DEL_KEY)
40         C2S(NL80211_CMD_GET_BEACON)
41         C2S(NL80211_CMD_SET_BEACON)
42         C2S(NL80211_CMD_START_AP)
43         C2S(NL80211_CMD_STOP_AP)
44         C2S(NL80211_CMD_GET_STATION)
45         C2S(NL80211_CMD_SET_STATION)
46         C2S(NL80211_CMD_NEW_STATION)
47         C2S(NL80211_CMD_DEL_STATION)
48         C2S(NL80211_CMD_GET_MPATH)
49         C2S(NL80211_CMD_SET_MPATH)
50         C2S(NL80211_CMD_NEW_MPATH)
51         C2S(NL80211_CMD_DEL_MPATH)
52         C2S(NL80211_CMD_SET_BSS)
53         C2S(NL80211_CMD_SET_REG)
54         C2S(NL80211_CMD_REQ_SET_REG)
55         C2S(NL80211_CMD_GET_MESH_CONFIG)
56         C2S(NL80211_CMD_SET_MESH_CONFIG)
57         C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
58         C2S(NL80211_CMD_GET_REG)
59         C2S(NL80211_CMD_GET_SCAN)
60         C2S(NL80211_CMD_TRIGGER_SCAN)
61         C2S(NL80211_CMD_NEW_SCAN_RESULTS)
62         C2S(NL80211_CMD_SCAN_ABORTED)
63         C2S(NL80211_CMD_REG_CHANGE)
64         C2S(NL80211_CMD_AUTHENTICATE)
65         C2S(NL80211_CMD_ASSOCIATE)
66         C2S(NL80211_CMD_DEAUTHENTICATE)
67         C2S(NL80211_CMD_DISASSOCIATE)
68         C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
69         C2S(NL80211_CMD_REG_BEACON_HINT)
70         C2S(NL80211_CMD_JOIN_IBSS)
71         C2S(NL80211_CMD_LEAVE_IBSS)
72         C2S(NL80211_CMD_TESTMODE)
73         C2S(NL80211_CMD_CONNECT)
74         C2S(NL80211_CMD_ROAM)
75         C2S(NL80211_CMD_DISCONNECT)
76         C2S(NL80211_CMD_SET_WIPHY_NETNS)
77         C2S(NL80211_CMD_GET_SURVEY)
78         C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
79         C2S(NL80211_CMD_SET_PMKSA)
80         C2S(NL80211_CMD_DEL_PMKSA)
81         C2S(NL80211_CMD_FLUSH_PMKSA)
82         C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
83         C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
84         C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
85         C2S(NL80211_CMD_REGISTER_FRAME)
86         C2S(NL80211_CMD_FRAME)
87         C2S(NL80211_CMD_FRAME_TX_STATUS)
88         C2S(NL80211_CMD_SET_POWER_SAVE)
89         C2S(NL80211_CMD_GET_POWER_SAVE)
90         C2S(NL80211_CMD_SET_CQM)
91         C2S(NL80211_CMD_NOTIFY_CQM)
92         C2S(NL80211_CMD_SET_CHANNEL)
93         C2S(NL80211_CMD_SET_WDS_PEER)
94         C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
95         C2S(NL80211_CMD_JOIN_MESH)
96         C2S(NL80211_CMD_LEAVE_MESH)
97         C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
98         C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
99         C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
100         C2S(NL80211_CMD_GET_WOWLAN)
101         C2S(NL80211_CMD_SET_WOWLAN)
102         C2S(NL80211_CMD_START_SCHED_SCAN)
103         C2S(NL80211_CMD_STOP_SCHED_SCAN)
104         C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
105         C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
106         C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
107         C2S(NL80211_CMD_PMKSA_CANDIDATE)
108         C2S(NL80211_CMD_TDLS_OPER)
109         C2S(NL80211_CMD_TDLS_MGMT)
110         C2S(NL80211_CMD_UNEXPECTED_FRAME)
111         C2S(NL80211_CMD_PROBE_CLIENT)
112         C2S(NL80211_CMD_REGISTER_BEACONS)
113         C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
114         C2S(NL80211_CMD_SET_NOACK_MAP)
115         C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
116         C2S(NL80211_CMD_START_P2P_DEVICE)
117         C2S(NL80211_CMD_STOP_P2P_DEVICE)
118         C2S(NL80211_CMD_CONN_FAILED)
119         C2S(NL80211_CMD_SET_MCAST_RATE)
120         C2S(NL80211_CMD_SET_MAC_ACL)
121         C2S(NL80211_CMD_RADAR_DETECT)
122         C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
123         C2S(NL80211_CMD_UPDATE_FT_IES)
124         C2S(NL80211_CMD_FT_EVENT)
125         C2S(NL80211_CMD_CRIT_PROTOCOL_START)
126         C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
127         C2S(NL80211_CMD_GET_COALESCE)
128         C2S(NL80211_CMD_SET_COALESCE)
129         C2S(NL80211_CMD_CHANNEL_SWITCH)
130         C2S(NL80211_CMD_VENDOR)
131         C2S(NL80211_CMD_SET_QOS_MAP)
132         C2S(NL80211_CMD_ADD_TX_TS)
133         C2S(NL80211_CMD_DEL_TX_TS)
134         default:
135                 return "NL80211_CMD_UNKNOWN";
136         }
137 #undef C2S
138 }
139
140
141 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
142                             const u8 *frame, size_t len)
143 {
144         const struct ieee80211_mgmt *mgmt;
145         union wpa_event_data event;
146
147         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
148             drv->force_connect_cmd) {
149                 /*
150                  * Avoid reporting two association events that would confuse
151                  * the core code.
152                  */
153                 wpa_printf(MSG_DEBUG,
154                            "nl80211: Ignore auth event when using driver SME");
155                 return;
156         }
157
158         wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
159         mgmt = (const struct ieee80211_mgmt *) frame;
160         if (len < 24 + sizeof(mgmt->u.auth)) {
161                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
162                            "frame");
163                 return;
164         }
165
166         os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
167         os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
168         os_memset(&event, 0, sizeof(event));
169         os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
170         event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
171         event.auth.auth_transaction =
172                 le_to_host16(mgmt->u.auth.auth_transaction);
173         event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
174         if (len > 24 + sizeof(mgmt->u.auth)) {
175                 event.auth.ies = mgmt->u.auth.variable;
176                 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
177         }
178
179         wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
180 }
181
182
183 static void nl80211_parse_wmm_params(struct nlattr *wmm_attr,
184                                      struct wmm_params *wmm_params)
185 {
186         struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
187         static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
188                 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
189         };
190
191         if (!wmm_attr ||
192             nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
193                              wme_policy) ||
194             !wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
195                 return;
196
197         wmm_params->uapsd_queues =
198                 nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
199         wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
200 }
201
202
203 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
204                             const u8 *frame, size_t len, struct nlattr *wmm)
205 {
206         const struct ieee80211_mgmt *mgmt;
207         union wpa_event_data event;
208         u16 status;
209
210         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
211             drv->force_connect_cmd) {
212                 /*
213                  * Avoid reporting two association events that would confuse
214                  * the core code.
215                  */
216                 wpa_printf(MSG_DEBUG,
217                            "nl80211: Ignore assoc event when using driver SME");
218                 return;
219         }
220
221         wpa_printf(MSG_DEBUG, "nl80211: Associate event");
222         mgmt = (const struct ieee80211_mgmt *) frame;
223         if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
224                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
225                            "frame");
226                 return;
227         }
228
229         status = le_to_host16(mgmt->u.assoc_resp.status_code);
230         if (status != WLAN_STATUS_SUCCESS) {
231                 os_memset(&event, 0, sizeof(event));
232                 event.assoc_reject.bssid = mgmt->bssid;
233                 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
234                         event.assoc_reject.resp_ies =
235                                 (u8 *) mgmt->u.assoc_resp.variable;
236                         event.assoc_reject.resp_ies_len =
237                                 len - 24 - sizeof(mgmt->u.assoc_resp);
238                 }
239                 event.assoc_reject.status_code = status;
240
241                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
242                 return;
243         }
244
245         drv->associated = 1;
246         os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
247         os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
248
249         os_memset(&event, 0, sizeof(event));
250         if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
251                 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
252                 event.assoc_info.resp_ies_len =
253                         len - 24 - sizeof(mgmt->u.assoc_resp);
254         }
255
256         event.assoc_info.freq = drv->assoc_freq;
257
258         nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
259
260         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
261 }
262
263
264 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
265                                enum nl80211_commands cmd, struct nlattr *status,
266                                struct nlattr *addr, struct nlattr *req_ie,
267                                struct nlattr *resp_ie,
268                                struct nlattr *authorized,
269                                struct nlattr *key_replay_ctr,
270                                struct nlattr *ptk_kck,
271                                struct nlattr *ptk_kek,
272                                struct nlattr *subnet_status)
273 {
274         union wpa_event_data event;
275         const u8 *ssid;
276         u16 status_code;
277
278         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
279                 /*
280                  * Avoid reporting two association events that would confuse
281                  * the core code.
282                  */
283                 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
284                            "when using userspace SME", cmd);
285                 return;
286         }
287
288         drv->connect_reassoc = 0;
289
290         status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
291
292         if (cmd == NL80211_CMD_CONNECT) {
293                 wpa_printf(MSG_DEBUG,
294                            "nl80211: Connect event (status=%u ignore_next_local_disconnect=%d)",
295                            status_code, drv->ignore_next_local_disconnect);
296         } else if (cmd == NL80211_CMD_ROAM) {
297                 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
298         }
299
300         os_memset(&event, 0, sizeof(event));
301         if (cmd == NL80211_CMD_CONNECT && status_code != WLAN_STATUS_SUCCESS) {
302                 if (addr)
303                         event.assoc_reject.bssid = nla_data(addr);
304                 if (drv->ignore_next_local_disconnect) {
305                         drv->ignore_next_local_disconnect = 0;
306                         if (!event.assoc_reject.bssid ||
307                             (os_memcmp(event.assoc_reject.bssid,
308                                        drv->auth_attempt_bssid,
309                                        ETH_ALEN) != 0)) {
310                                 /*
311                                  * Ignore the event that came without a BSSID or
312                                  * for the old connection since this is likely
313                                  * not relevant to the new Connect command.
314                                  */
315                                 wpa_printf(MSG_DEBUG,
316                                            "nl80211: Ignore connection failure event triggered during reassociation");
317                                 return;
318                         }
319                 }
320                 if (resp_ie) {
321                         event.assoc_reject.resp_ies = nla_data(resp_ie);
322                         event.assoc_reject.resp_ies_len = nla_len(resp_ie);
323                 }
324                 event.assoc_reject.status_code = status_code;
325                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
326                 return;
327         }
328
329         drv->associated = 1;
330         if (addr) {
331                 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
332                 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
333         }
334
335         if (req_ie) {
336                 event.assoc_info.req_ies = nla_data(req_ie);
337                 event.assoc_info.req_ies_len = nla_len(req_ie);
338
339                 if (cmd == NL80211_CMD_ROAM) {
340                         ssid = get_ie(event.assoc_info.req_ies,
341                                       event.assoc_info.req_ies_len,
342                                       WLAN_EID_SSID);
343                         if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
344                                 drv->ssid_len = ssid[1];
345                                 os_memcpy(drv->ssid, ssid + 2, ssid[1]);
346                         }
347                 }
348         }
349         if (resp_ie) {
350                 event.assoc_info.resp_ies = nla_data(resp_ie);
351                 event.assoc_info.resp_ies_len = nla_len(resp_ie);
352         }
353
354         event.assoc_info.freq = nl80211_get_assoc_freq(drv);
355
356         if (authorized && nla_get_u8(authorized)) {
357                 event.assoc_info.authorized = 1;
358                 wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
359         }
360         if (key_replay_ctr) {
361                 event.assoc_info.key_replay_ctr = nla_data(key_replay_ctr);
362                 event.assoc_info.key_replay_ctr_len = nla_len(key_replay_ctr);
363         }
364         if (ptk_kck) {
365                 event.assoc_info.ptk_kck = nla_data(ptk_kck);
366                 event.assoc_info.ptk_kck_len = nla_len(ptk_kck);
367         }
368         if (ptk_kek) {
369                 event.assoc_info.ptk_kek = nla_data(ptk_kek);
370                 event.assoc_info.ptk_kek_len = nla_len(ptk_kek);
371         }
372
373         if (subnet_status) {
374                 /*
375                  * At least for now, this is only available from
376                  * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that
377                  * attribute has the same values 0, 1, 2 as are used in the
378                  * variable here, so no mapping between different values are
379                  * needed.
380                  */
381                 event.assoc_info.subnet_status = nla_get_u8(subnet_status);
382         }
383
384         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
385 }
386
387
388 static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
389                                   struct nlattr *reason, struct nlattr *addr,
390                                   struct nlattr *by_ap)
391 {
392         union wpa_event_data data;
393         unsigned int locally_generated = by_ap == NULL;
394
395         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
396                 /*
397                  * Avoid reporting two disassociation events that could
398                  * confuse the core code.
399                  */
400                 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
401                            "event when using userspace SME");
402                 return;
403         }
404
405         if (drv->ignore_next_local_disconnect) {
406                 drv->ignore_next_local_disconnect = 0;
407                 if (locally_generated) {
408                         wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
409                                    "event triggered during reassociation");
410                         return;
411                 }
412                 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
413                            "disconnect but got another disconnect "
414                            "event first");
415         }
416
417         wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
418         nl80211_mark_disconnected(drv);
419         os_memset(&data, 0, sizeof(data));
420         if (reason)
421                 data.deauth_info.reason_code = nla_get_u16(reason);
422         data.deauth_info.locally_generated = by_ap == NULL;
423         wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
424 }
425
426
427 static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
428 {
429         int freq1 = 0;
430
431         switch (convert2width(width)) {
432         case CHAN_WIDTH_20_NOHT:
433         case CHAN_WIDTH_20:
434                 return 0;
435         case CHAN_WIDTH_40:
436                 freq1 = cf1 - 10;
437                 break;
438         case CHAN_WIDTH_80:
439                 freq1 = cf1 - 30;
440                 break;
441         case CHAN_WIDTH_160:
442                 freq1 = cf1 - 70;
443                 break;
444         case CHAN_WIDTH_UNKNOWN:
445         case CHAN_WIDTH_80P80:
446                 /* FIXME: implement this */
447                 return 0;
448         }
449
450         return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
451 }
452
453
454 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
455                                  struct nlattr *ifindex, struct nlattr *freq,
456                                  struct nlattr *type, struct nlattr *bw,
457                                  struct nlattr *cf1, struct nlattr *cf2)
458 {
459         struct i802_bss *bss;
460         union wpa_event_data data;
461         int ht_enabled = 1;
462         int chan_offset = 0;
463         int ifidx;
464
465         wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
466
467         if (!freq)
468                 return;
469
470         ifidx = nla_get_u32(ifindex);
471         bss = get_bss_ifindex(drv, ifidx);
472         if (bss == NULL) {
473                 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
474                            ifidx);
475                 return;
476         }
477
478         if (type) {
479                 enum nl80211_channel_type ch_type = nla_get_u32(type);
480
481                 wpa_printf(MSG_DEBUG, "nl80211: Channel type: %d", ch_type);
482                 switch (ch_type) {
483                 case NL80211_CHAN_NO_HT:
484                         ht_enabled = 0;
485                         break;
486                 case NL80211_CHAN_HT20:
487                         break;
488                 case NL80211_CHAN_HT40PLUS:
489                         chan_offset = 1;
490                         break;
491                 case NL80211_CHAN_HT40MINUS:
492                         chan_offset = -1;
493                         break;
494                 }
495         } else if (bw && cf1) {
496                 /* This can happen for example with VHT80 ch switch */
497                 chan_offset = calculate_chan_offset(nla_get_u32(bw),
498                                                     nla_get_u32(freq),
499                                                     nla_get_u32(cf1),
500                                                     cf2 ? nla_get_u32(cf2) : 0);
501         } else {
502                 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
503         }
504
505         os_memset(&data, 0, sizeof(data));
506         data.ch_switch.freq = nla_get_u32(freq);
507         data.ch_switch.ht_enabled = ht_enabled;
508         data.ch_switch.ch_offset = chan_offset;
509         if (bw)
510                 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
511         if (cf1)
512                 data.ch_switch.cf1 = nla_get_u32(cf1);
513         if (cf2)
514                 data.ch_switch.cf2 = nla_get_u32(cf2);
515
516         bss->freq = data.ch_switch.freq;
517
518         wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
519 }
520
521
522 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
523                                enum nl80211_commands cmd, struct nlattr *addr)
524 {
525         union wpa_event_data event;
526         enum wpa_event_type ev;
527
528         if (nla_len(addr) != ETH_ALEN)
529                 return;
530
531         wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
532                    cmd, MAC2STR((u8 *) nla_data(addr)));
533
534         if (cmd == NL80211_CMD_AUTHENTICATE)
535                 ev = EVENT_AUTH_TIMED_OUT;
536         else if (cmd == NL80211_CMD_ASSOCIATE)
537                 ev = EVENT_ASSOC_TIMED_OUT;
538         else
539                 return;
540
541         os_memset(&event, 0, sizeof(event));
542         os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
543         wpa_supplicant_event(drv->ctx, ev, &event);
544 }
545
546
547 static void mlme_event_mgmt(struct i802_bss *bss,
548                             struct nlattr *freq, struct nlattr *sig,
549                             const u8 *frame, size_t len)
550 {
551         struct wpa_driver_nl80211_data *drv = bss->drv;
552         const struct ieee80211_mgmt *mgmt;
553         union wpa_event_data event;
554         u16 fc, stype;
555         int ssi_signal = 0;
556         int rx_freq = 0;
557
558         wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
559         mgmt = (const struct ieee80211_mgmt *) frame;
560         if (len < 24) {
561                 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
562                 return;
563         }
564
565         fc = le_to_host16(mgmt->frame_control);
566         stype = WLAN_FC_GET_STYPE(fc);
567
568         if (sig)
569                 ssi_signal = (s32) nla_get_u32(sig);
570
571         os_memset(&event, 0, sizeof(event));
572         if (freq) {
573                 event.rx_mgmt.freq = nla_get_u32(freq);
574                 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
575         }
576         wpa_printf(MSG_DEBUG,
577                    "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR
578                    " freq=%d ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u",
579                    MAC2STR(mgmt->da), MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
580                    rx_freq, ssi_signal, fc,
581                    le_to_host16(mgmt->seq_ctrl), stype, fc2str(fc),
582                    (unsigned int) len);
583         event.rx_mgmt.frame = frame;
584         event.rx_mgmt.frame_len = len;
585         event.rx_mgmt.ssi_signal = ssi_signal;
586         event.rx_mgmt.drv_priv = bss;
587         wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
588 }
589
590
591 static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
592                                       struct nlattr *cookie, const u8 *frame,
593                                       size_t len, struct nlattr *ack)
594 {
595         union wpa_event_data event;
596         const struct ieee80211_hdr *hdr;
597         u16 fc;
598
599         wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
600         if (!is_ap_interface(drv->nlmode)) {
601                 u64 cookie_val;
602
603                 if (!cookie)
604                         return;
605
606                 cookie_val = nla_get_u64(cookie);
607                 wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
608                            " cookie=0%llx%s (ack=%d)",
609                            (long long unsigned int) cookie_val,
610                            cookie_val == drv->send_action_cookie ?
611                            " (match)" : " (unknown)", ack != NULL);
612                 if (cookie_val != drv->send_action_cookie)
613                         return;
614         }
615
616         hdr = (const struct ieee80211_hdr *) frame;
617         fc = le_to_host16(hdr->frame_control);
618
619         os_memset(&event, 0, sizeof(event));
620         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
621         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
622         event.tx_status.dst = hdr->addr1;
623         event.tx_status.data = frame;
624         event.tx_status.data_len = len;
625         event.tx_status.ack = ack != NULL;
626         wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
627 }
628
629
630 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
631                                        enum wpa_event_type type,
632                                        const u8 *frame, size_t len)
633 {
634         const struct ieee80211_mgmt *mgmt;
635         union wpa_event_data event;
636         const u8 *bssid = NULL;
637         u16 reason_code = 0;
638
639         if (type == EVENT_DEAUTH)
640                 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
641         else
642                 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
643
644         mgmt = (const struct ieee80211_mgmt *) frame;
645         if (len >= 24) {
646                 bssid = mgmt->bssid;
647
648                 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
649                     !drv->associated &&
650                     os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
651                     os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
652                     os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
653                         /*
654                          * Avoid issues with some roaming cases where
655                          * disconnection event for the old AP may show up after
656                          * we have started connection with the new AP.
657                          * In case of locally generated event clear
658                          * ignore_next_local_deauth as well, to avoid next local
659                          * deauth event be wrongly ignored.
660                          */
661                         if (!os_memcmp(mgmt->sa, drv->first_bss->addr,
662                                        ETH_ALEN)) {
663                                 wpa_printf(MSG_DEBUG,
664                                            "nl80211: Received a locally generated deauth event. Clear ignore_next_local_deauth flag");
665                                 drv->ignore_next_local_deauth = 0;
666                         } else {
667                                 wpa_printf(MSG_DEBUG,
668                                            "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
669                                            MAC2STR(bssid),
670                                            MAC2STR(drv->auth_attempt_bssid));
671                         }
672                         return;
673                 }
674
675                 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
676                     drv->connect_reassoc && drv->associated &&
677                     os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0 &&
678                     os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0) {
679                         /*
680                          * Avoid issues with some roaming cases where
681                          * disconnection event for the old AP may show up after
682                          * we have started connection with the new AP.
683                          */
684                          wpa_printf(MSG_DEBUG,
685                                     "nl80211: Ignore deauth/disassoc event from old AP "
686                                     MACSTR
687                                     " when already connecting with " MACSTR,
688                                     MAC2STR(bssid),
689                                     MAC2STR(drv->auth_attempt_bssid));
690                         return;
691                 }
692
693                 if (drv->associated != 0 &&
694                     os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
695                     os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
696                         /*
697                          * We have presumably received this deauth as a
698                          * response to a clear_state_mismatch() outgoing
699                          * deauth.  Don't let it take us offline!
700                          */
701                         wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
702                                    "from Unknown BSSID " MACSTR " -- ignoring",
703                                    MAC2STR(bssid));
704                         return;
705                 }
706         }
707
708         nl80211_mark_disconnected(drv);
709         os_memset(&event, 0, sizeof(event));
710
711         /* Note: Same offset for Reason Code in both frame subtypes */
712         if (len >= 24 + sizeof(mgmt->u.deauth))
713                 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
714
715         if (type == EVENT_DISASSOC) {
716                 event.disassoc_info.locally_generated =
717                         !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
718                 event.disassoc_info.addr = bssid;
719                 event.disassoc_info.reason_code = reason_code;
720                 if (frame + len > mgmt->u.disassoc.variable) {
721                         event.disassoc_info.ie = mgmt->u.disassoc.variable;
722                         event.disassoc_info.ie_len = frame + len -
723                                 mgmt->u.disassoc.variable;
724                 }
725         } else {
726                 event.deauth_info.locally_generated =
727                         !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
728                 if (drv->ignore_deauth_event) {
729                         wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
730                         drv->ignore_deauth_event = 0;
731                         if (event.deauth_info.locally_generated)
732                                 drv->ignore_next_local_deauth = 0;
733                         return;
734                 }
735                 if (drv->ignore_next_local_deauth) {
736                         drv->ignore_next_local_deauth = 0;
737                         if (event.deauth_info.locally_generated) {
738                                 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
739                                 return;
740                         }
741                         wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
742                 }
743                 event.deauth_info.addr = bssid;
744                 event.deauth_info.reason_code = reason_code;
745                 if (frame + len > mgmt->u.deauth.variable) {
746                         event.deauth_info.ie = mgmt->u.deauth.variable;
747                         event.deauth_info.ie_len = frame + len -
748                                 mgmt->u.deauth.variable;
749                 }
750         }
751
752         wpa_supplicant_event(drv->ctx, type, &event);
753 }
754
755
756 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
757                                          enum wpa_event_type type,
758                                          const u8 *frame, size_t len)
759 {
760         const struct ieee80211_mgmt *mgmt;
761         union wpa_event_data event;
762         u16 reason_code = 0;
763
764         if (type == EVENT_UNPROT_DEAUTH)
765                 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
766         else
767                 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
768
769         if (len < 24)
770                 return;
771
772         mgmt = (const struct ieee80211_mgmt *) frame;
773
774         os_memset(&event, 0, sizeof(event));
775         /* Note: Same offset for Reason Code in both frame subtypes */
776         if (len >= 24 + sizeof(mgmt->u.deauth))
777                 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
778
779         if (type == EVENT_UNPROT_DISASSOC) {
780                 event.unprot_disassoc.sa = mgmt->sa;
781                 event.unprot_disassoc.da = mgmt->da;
782                 event.unprot_disassoc.reason_code = reason_code;
783         } else {
784                 event.unprot_deauth.sa = mgmt->sa;
785                 event.unprot_deauth.da = mgmt->da;
786                 event.unprot_deauth.reason_code = reason_code;
787         }
788
789         wpa_supplicant_event(drv->ctx, type, &event);
790 }
791
792
793 static void mlme_event(struct i802_bss *bss,
794                        enum nl80211_commands cmd, struct nlattr *frame,
795                        struct nlattr *addr, struct nlattr *timed_out,
796                        struct nlattr *freq, struct nlattr *ack,
797                        struct nlattr *cookie, struct nlattr *sig,
798                        struct nlattr *wmm)
799 {
800         struct wpa_driver_nl80211_data *drv = bss->drv;
801         const u8 *data;
802         size_t len;
803
804         if (timed_out && addr) {
805                 mlme_timeout_event(drv, cmd, addr);
806                 return;
807         }
808
809         if (frame == NULL) {
810                 wpa_printf(MSG_DEBUG,
811                            "nl80211: MLME event %d (%s) without frame data",
812                            cmd, nl80211_command_to_string(cmd));
813                 return;
814         }
815
816         data = nla_data(frame);
817         len = nla_len(frame);
818         if (len < 4 + 2 * ETH_ALEN) {
819                 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
820                            MACSTR ") - too short",
821                            cmd, nl80211_command_to_string(cmd), bss->ifname,
822                            MAC2STR(bss->addr));
823                 return;
824         }
825         wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
826                    ") A1=" MACSTR " A2=" MACSTR, cmd,
827                    nl80211_command_to_string(cmd), bss->ifname,
828                    MAC2STR(bss->addr), MAC2STR(data + 4),
829                    MAC2STR(data + 4 + ETH_ALEN));
830         if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
831             os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
832             os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
833                 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
834                            "for foreign address", bss->ifname);
835                 return;
836         }
837         wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
838                     nla_data(frame), nla_len(frame));
839
840         switch (cmd) {
841         case NL80211_CMD_AUTHENTICATE:
842                 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
843                 break;
844         case NL80211_CMD_ASSOCIATE:
845                 mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm);
846                 break;
847         case NL80211_CMD_DEAUTHENTICATE:
848                 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
849                                            nla_data(frame), nla_len(frame));
850                 break;
851         case NL80211_CMD_DISASSOCIATE:
852                 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
853                                            nla_data(frame), nla_len(frame));
854                 break;
855         case NL80211_CMD_FRAME:
856                 mlme_event_mgmt(bss, freq, sig, nla_data(frame),
857                                 nla_len(frame));
858                 break;
859         case NL80211_CMD_FRAME_TX_STATUS:
860                 mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
861                                           nla_len(frame), ack);
862                 break;
863         case NL80211_CMD_UNPROT_DEAUTHENTICATE:
864                 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
865                                              nla_data(frame), nla_len(frame));
866                 break;
867         case NL80211_CMD_UNPROT_DISASSOCIATE:
868                 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
869                                              nla_data(frame), nla_len(frame));
870                 break;
871         default:
872                 break;
873         }
874 }
875
876
877 static void mlme_event_michael_mic_failure(struct i802_bss *bss,
878                                            struct nlattr *tb[])
879 {
880         union wpa_event_data data;
881
882         wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
883         os_memset(&data, 0, sizeof(data));
884         if (tb[NL80211_ATTR_MAC]) {
885                 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
886                             nla_data(tb[NL80211_ATTR_MAC]),
887                             nla_len(tb[NL80211_ATTR_MAC]));
888                 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
889         }
890         if (tb[NL80211_ATTR_KEY_SEQ]) {
891                 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
892                             nla_data(tb[NL80211_ATTR_KEY_SEQ]),
893                             nla_len(tb[NL80211_ATTR_KEY_SEQ]));
894         }
895         if (tb[NL80211_ATTR_KEY_TYPE]) {
896                 enum nl80211_key_type key_type =
897                         nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
898                 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
899                 if (key_type == NL80211_KEYTYPE_PAIRWISE)
900                         data.michael_mic_failure.unicast = 1;
901         } else
902                 data.michael_mic_failure.unicast = 1;
903
904         if (tb[NL80211_ATTR_KEY_IDX]) {
905                 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
906                 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
907         }
908
909         wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
910 }
911
912
913 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
914                                  struct nlattr *tb[])
915 {
916         unsigned int freq;
917
918         if (tb[NL80211_ATTR_MAC] == NULL) {
919                 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
920                            "event");
921                 return;
922         }
923         os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
924
925         drv->associated = 1;
926         wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
927                    MAC2STR(drv->bssid));
928
929         freq = nl80211_get_assoc_freq(drv);
930         if (freq) {
931                 wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
932                            freq);
933                 drv->first_bss->freq = freq;
934         }
935
936         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
937 }
938
939
940 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
941                                          int cancel_event, struct nlattr *tb[])
942 {
943         unsigned int freq, chan_type, duration;
944         union wpa_event_data data;
945         u64 cookie;
946
947         if (tb[NL80211_ATTR_WIPHY_FREQ])
948                 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
949         else
950                 freq = 0;
951
952         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
953                 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
954         else
955                 chan_type = 0;
956
957         if (tb[NL80211_ATTR_DURATION])
958                 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
959         else
960                 duration = 0;
961
962         if (tb[NL80211_ATTR_COOKIE])
963                 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
964         else
965                 cookie = 0;
966
967         wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
968                    "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
969                    cancel_event, freq, chan_type, duration,
970                    (long long unsigned int) cookie,
971                    cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
972
973         if (cookie != drv->remain_on_chan_cookie)
974                 return; /* not for us */
975
976         if (cancel_event)
977                 drv->pending_remain_on_chan = 0;
978
979         os_memset(&data, 0, sizeof(data));
980         data.remain_on_channel.freq = freq;
981         data.remain_on_channel.duration = duration;
982         wpa_supplicant_event(drv->ctx, cancel_event ?
983                              EVENT_CANCEL_REMAIN_ON_CHANNEL :
984                              EVENT_REMAIN_ON_CHANNEL, &data);
985 }
986
987
988 static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
989                                 struct nlattr *tb[])
990 {
991         union wpa_event_data data;
992
993         os_memset(&data, 0, sizeof(data));
994
995         if (tb[NL80211_ATTR_IE]) {
996                 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
997                 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
998         }
999
1000         if (tb[NL80211_ATTR_IE_RIC]) {
1001                 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
1002                 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
1003         }
1004
1005         if (tb[NL80211_ATTR_MAC])
1006                 os_memcpy(data.ft_ies.target_ap,
1007                           nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1008
1009         wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
1010                    MAC2STR(data.ft_ies.target_ap));
1011
1012         wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
1013 }
1014
1015
1016 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
1017                             struct nlattr *tb[], int external_scan)
1018 {
1019         union wpa_event_data event;
1020         struct nlattr *nl;
1021         int rem;
1022         struct scan_info *info;
1023 #define MAX_REPORT_FREQS 50
1024         int freqs[MAX_REPORT_FREQS];
1025         int num_freqs = 0;
1026
1027         if (!external_scan && drv->scan_for_auth) {
1028                 drv->scan_for_auth = 0;
1029                 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
1030                            "cfg80211 BSS entry");
1031                 wpa_driver_nl80211_authenticate_retry(drv);
1032                 return;
1033         }
1034
1035         os_memset(&event, 0, sizeof(event));
1036         info = &event.scan_info;
1037         info->aborted = aborted;
1038         info->external_scan = external_scan;
1039         info->nl_scan_event = 1;
1040
1041         if (tb[NL80211_ATTR_SCAN_SSIDS]) {
1042                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
1043                         struct wpa_driver_scan_ssid *s =
1044                                 &info->ssids[info->num_ssids];
1045                         s->ssid = nla_data(nl);
1046                         s->ssid_len = nla_len(nl);
1047                         wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
1048                                    wpa_ssid_txt(s->ssid, s->ssid_len));
1049                         info->num_ssids++;
1050                         if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1051                                 break;
1052                 }
1053         }
1054         if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
1055                 char msg[300], *pos, *end;
1056                 int res;
1057
1058                 pos = msg;
1059                 end = pos + sizeof(msg);
1060                 *pos = '\0';
1061
1062                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
1063                 {
1064                         freqs[num_freqs] = nla_get_u32(nl);
1065                         res = os_snprintf(pos, end - pos, " %d",
1066                                           freqs[num_freqs]);
1067                         if (!os_snprintf_error(end - pos, res))
1068                                 pos += res;
1069                         num_freqs++;
1070                         if (num_freqs == MAX_REPORT_FREQS - 1)
1071                                 break;
1072                 }
1073                 info->freqs = freqs;
1074                 info->num_freqs = num_freqs;
1075                 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
1076                            msg);
1077         }
1078         wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1079 }
1080
1081
1082 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
1083                               struct nlattr *tb[])
1084 {
1085         static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
1086                 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
1087                 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
1088                 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
1089                 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
1090         };
1091         struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
1092         enum nl80211_cqm_rssi_threshold_event event;
1093         union wpa_event_data ed;
1094         struct wpa_signal_info sig;
1095         int res;
1096
1097         if (tb[NL80211_ATTR_CQM] == NULL ||
1098             nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
1099                              cqm_policy)) {
1100                 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
1101                 return;
1102         }
1103
1104         os_memset(&ed, 0, sizeof(ed));
1105
1106         if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
1107                 if (!tb[NL80211_ATTR_MAC])
1108                         return;
1109                 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
1110                           ETH_ALEN);
1111                 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
1112                 return;
1113         }
1114
1115         if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
1116                 return;
1117         event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
1118
1119         if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
1120                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1121                            "event: RSSI high");
1122                 ed.signal_change.above_threshold = 1;
1123         } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
1124                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1125                            "event: RSSI low");
1126                 ed.signal_change.above_threshold = 0;
1127         } else
1128                 return;
1129
1130         res = nl80211_get_link_signal(drv, &sig);
1131         if (res == 0) {
1132                 ed.signal_change.current_signal = sig.current_signal;
1133                 ed.signal_change.current_txrate = sig.current_txrate;
1134                 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
1135                            sig.current_signal, sig.current_txrate);
1136         }
1137
1138         res = nl80211_get_link_noise(drv, &sig);
1139         if (res == 0) {
1140                 ed.signal_change.current_noise = sig.current_noise;
1141                 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
1142                            sig.current_noise);
1143         }
1144
1145         wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
1146 }
1147
1148
1149 static void nl80211_new_peer_candidate(struct wpa_driver_nl80211_data *drv,
1150                                        struct nlattr **tb)
1151 {
1152         const u8 *addr;
1153         union wpa_event_data data;
1154
1155         if (drv->nlmode != NL80211_IFTYPE_MESH_POINT ||
1156             !tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
1157                 return;
1158
1159         addr = nla_data(tb[NL80211_ATTR_MAC]);
1160         wpa_printf(MSG_DEBUG, "nl80211: New peer candidate " MACSTR,
1161                    MAC2STR(addr));
1162
1163         os_memset(&data, 0, sizeof(data));
1164         data.mesh_peer.peer = addr;
1165         data.mesh_peer.ies = nla_data(tb[NL80211_ATTR_IE]);
1166         data.mesh_peer.ie_len = nla_len(tb[NL80211_ATTR_IE]);
1167         wpa_supplicant_event(drv->ctx, EVENT_NEW_PEER_CANDIDATE, &data);
1168 }
1169
1170
1171 static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
1172                                       struct i802_bss *bss,
1173                                       struct nlattr **tb)
1174 {
1175         u8 *addr;
1176         union wpa_event_data data;
1177
1178         if (tb[NL80211_ATTR_MAC] == NULL)
1179                 return;
1180         addr = nla_data(tb[NL80211_ATTR_MAC]);
1181         wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
1182
1183         if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1184                 u8 *ies = NULL;
1185                 size_t ies_len = 0;
1186                 if (tb[NL80211_ATTR_IE]) {
1187                         ies = nla_data(tb[NL80211_ATTR_IE]);
1188                         ies_len = nla_len(tb[NL80211_ATTR_IE]);
1189                 }
1190                 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
1191                 drv_event_assoc(bss->ctx, addr, ies, ies_len, 0);
1192                 return;
1193         }
1194
1195         if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1196                 return;
1197
1198         os_memset(&data, 0, sizeof(data));
1199         os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
1200         wpa_supplicant_event(bss->ctx, EVENT_IBSS_RSN_START, &data);
1201 }
1202
1203
1204 static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
1205                                       struct i802_bss *bss,
1206                                       struct nlattr **tb)
1207 {
1208         u8 *addr;
1209         union wpa_event_data data;
1210
1211         if (tb[NL80211_ATTR_MAC] == NULL)
1212                 return;
1213         addr = nla_data(tb[NL80211_ATTR_MAC]);
1214         wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
1215                    MAC2STR(addr));
1216
1217         if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1218                 drv_event_disassoc(bss->ctx, addr);
1219                 return;
1220         }
1221
1222         if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1223                 return;
1224
1225         os_memset(&data, 0, sizeof(data));
1226         os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
1227         wpa_supplicant_event(bss->ctx, EVENT_IBSS_PEER_LOST, &data);
1228 }
1229
1230
1231 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
1232                                         struct nlattr **tb)
1233 {
1234         struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
1235         static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
1236                 [NL80211_REKEY_DATA_KEK] = {
1237                         .minlen = NL80211_KEK_LEN,
1238                         .maxlen = NL80211_KEK_LEN,
1239                 },
1240                 [NL80211_REKEY_DATA_KCK] = {
1241                         .minlen = NL80211_KCK_LEN,
1242                         .maxlen = NL80211_KCK_LEN,
1243                 },
1244                 [NL80211_REKEY_DATA_REPLAY_CTR] = {
1245                         .minlen = NL80211_REPLAY_CTR_LEN,
1246                         .maxlen = NL80211_REPLAY_CTR_LEN,
1247                 },
1248         };
1249         union wpa_event_data data;
1250
1251         if (!tb[NL80211_ATTR_MAC] ||
1252             !tb[NL80211_ATTR_REKEY_DATA] ||
1253             nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
1254                              tb[NL80211_ATTR_REKEY_DATA], rekey_policy) ||
1255             !rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
1256                 return;
1257
1258         os_memset(&data, 0, sizeof(data));
1259         data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
1260         wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
1261                    MAC2STR(data.driver_gtk_rekey.bssid));
1262         data.driver_gtk_rekey.replay_ctr =
1263                 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
1264         wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
1265                     data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
1266         wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
1267 }
1268
1269
1270 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
1271                                           struct nlattr **tb)
1272 {
1273         struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
1274         static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
1275                 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
1276                 [NL80211_PMKSA_CANDIDATE_BSSID] = {
1277                         .minlen = ETH_ALEN,
1278                         .maxlen = ETH_ALEN,
1279                 },
1280                 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
1281         };
1282         union wpa_event_data data;
1283
1284         wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
1285
1286         if (!tb[NL80211_ATTR_PMKSA_CANDIDATE] ||
1287             nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
1288                              tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy) ||
1289             !cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
1290             !cand[NL80211_PMKSA_CANDIDATE_BSSID])
1291                 return;
1292
1293         os_memset(&data, 0, sizeof(data));
1294         os_memcpy(data.pmkid_candidate.bssid,
1295                   nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
1296         data.pmkid_candidate.index =
1297                 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
1298         data.pmkid_candidate.preauth =
1299                 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
1300         wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
1301 }
1302
1303
1304 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
1305                                        struct nlattr **tb)
1306 {
1307         union wpa_event_data data;
1308
1309         wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
1310
1311         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
1312                 return;
1313
1314         os_memset(&data, 0, sizeof(data));
1315         os_memcpy(data.client_poll.addr,
1316                   nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1317
1318         wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
1319 }
1320
1321
1322 static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
1323                                     struct nlattr **tb)
1324 {
1325         union wpa_event_data data;
1326
1327         wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
1328
1329         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
1330                 return;
1331
1332         os_memset(&data, 0, sizeof(data));
1333         os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1334         switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
1335         case NL80211_TDLS_SETUP:
1336                 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
1337                            MACSTR, MAC2STR(data.tdls.peer));
1338                 data.tdls.oper = TDLS_REQUEST_SETUP;
1339                 break;
1340         case NL80211_TDLS_TEARDOWN:
1341                 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
1342                            MACSTR, MAC2STR(data.tdls.peer));
1343                 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
1344                 break;
1345         case NL80211_TDLS_DISCOVERY_REQ:
1346                 wpa_printf(MSG_DEBUG,
1347                            "nl80211: TDLS discovery request for peer " MACSTR,
1348                            MAC2STR(data.tdls.peer));
1349                 data.tdls.oper = TDLS_REQUEST_DISCOVER;
1350                 break;
1351         default:
1352                 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
1353                            "event");
1354                 return;
1355         }
1356         if (tb[NL80211_ATTR_REASON_CODE]) {
1357                 data.tdls.reason_code =
1358                         nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
1359         }
1360
1361         wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
1362 }
1363
1364
1365 static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
1366                             struct nlattr **tb)
1367 {
1368         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
1369 }
1370
1371
1372 static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
1373                                          struct nlattr **tb)
1374 {
1375         union wpa_event_data data;
1376         u32 reason;
1377
1378         wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
1379
1380         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
1381                 return;
1382
1383         os_memset(&data, 0, sizeof(data));
1384         os_memcpy(data.connect_failed_reason.addr,
1385                   nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1386
1387         reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
1388         switch (reason) {
1389         case NL80211_CONN_FAIL_MAX_CLIENTS:
1390                 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
1391                 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
1392                 break;
1393         case NL80211_CONN_FAIL_BLOCKED_CLIENT:
1394                 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
1395                            " tried to connect",
1396                            MAC2STR(data.connect_failed_reason.addr));
1397                 data.connect_failed_reason.code = BLOCKED_CLIENT;
1398                 break;
1399         default:
1400                 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
1401                            "%u", reason);
1402                 return;
1403         }
1404
1405         wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
1406 }
1407
1408
1409 static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
1410                                 struct nlattr **tb)
1411 {
1412         union wpa_event_data data;
1413         enum nl80211_radar_event event_type;
1414
1415         if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
1416                 return;
1417
1418         os_memset(&data, 0, sizeof(data));
1419         data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1420         event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
1421
1422         /* Check HT params */
1423         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1424                 data.dfs_event.ht_enabled = 1;
1425                 data.dfs_event.chan_offset = 0;
1426
1427                 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
1428                 case NL80211_CHAN_NO_HT:
1429                         data.dfs_event.ht_enabled = 0;
1430                         break;
1431                 case NL80211_CHAN_HT20:
1432                         break;
1433                 case NL80211_CHAN_HT40PLUS:
1434                         data.dfs_event.chan_offset = 1;
1435                         break;
1436                 case NL80211_CHAN_HT40MINUS:
1437                         data.dfs_event.chan_offset = -1;
1438                         break;
1439                 }
1440         }
1441
1442         /* Get VHT params */
1443         if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1444                 data.dfs_event.chan_width =
1445                         convert2width(nla_get_u32(
1446                                               tb[NL80211_ATTR_CHANNEL_WIDTH]));
1447         if (tb[NL80211_ATTR_CENTER_FREQ1])
1448                 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1449         if (tb[NL80211_ATTR_CENTER_FREQ2])
1450                 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1451
1452         wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
1453                    data.dfs_event.freq, data.dfs_event.ht_enabled,
1454                    data.dfs_event.chan_offset, data.dfs_event.chan_width,
1455                    data.dfs_event.cf1, data.dfs_event.cf2);
1456
1457         switch (event_type) {
1458         case NL80211_RADAR_DETECTED:
1459                 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
1460                 break;
1461         case NL80211_RADAR_CAC_FINISHED:
1462                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
1463                 break;
1464         case NL80211_RADAR_CAC_ABORTED:
1465                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
1466                 break;
1467         case NL80211_RADAR_NOP_FINISHED:
1468                 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
1469                 break;
1470         default:
1471                 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
1472                            "received", event_type);
1473                 break;
1474         }
1475 }
1476
1477
1478 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
1479                                    int wds)
1480 {
1481         struct wpa_driver_nl80211_data *drv = bss->drv;
1482         union wpa_event_data event;
1483
1484         if (!tb[NL80211_ATTR_MAC])
1485                 return;
1486
1487         os_memset(&event, 0, sizeof(event));
1488         event.rx_from_unknown.bssid = bss->addr;
1489         event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
1490         event.rx_from_unknown.wds = wds;
1491
1492         wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
1493 }
1494
1495
1496 #ifdef CONFIG_DRIVER_NL80211_QCA
1497
1498 static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
1499                                    const u8 *data, size_t len)
1500 {
1501         u32 i, count;
1502         union wpa_event_data event;
1503         struct wpa_freq_range *range = NULL;
1504         const struct qca_avoid_freq_list *freq_range;
1505
1506         freq_range = (const struct qca_avoid_freq_list *) data;
1507         if (len < sizeof(freq_range->count))
1508                 return;
1509
1510         count = freq_range->count;
1511         if (len < sizeof(freq_range->count) +
1512             count * sizeof(struct qca_avoid_freq_range)) {
1513                 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
1514                            (unsigned int) len);
1515                 return;
1516         }
1517
1518         if (count > 0) {
1519                 range = os_calloc(count, sizeof(struct wpa_freq_range));
1520                 if (range == NULL)
1521                         return;
1522         }
1523
1524         os_memset(&event, 0, sizeof(event));
1525         for (i = 0; i < count; i++) {
1526                 unsigned int idx = event.freq_range.num;
1527                 range[idx].min = freq_range->range[i].start_freq;
1528                 range[idx].max = freq_range->range[i].end_freq;
1529                 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
1530                            range[idx].min, range[idx].max);
1531                 if (range[idx].min > range[idx].max) {
1532                         wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
1533                         continue;
1534                 }
1535                 event.freq_range.num++;
1536         }
1537         event.freq_range.range = range;
1538
1539         wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
1540
1541         os_free(range);
1542 }
1543
1544
1545 static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
1546 {
1547         switch (hw_mode) {
1548         case QCA_ACS_MODE_IEEE80211B:
1549                 return HOSTAPD_MODE_IEEE80211B;
1550         case QCA_ACS_MODE_IEEE80211G:
1551                 return HOSTAPD_MODE_IEEE80211G;
1552         case QCA_ACS_MODE_IEEE80211A:
1553                 return HOSTAPD_MODE_IEEE80211A;
1554         case QCA_ACS_MODE_IEEE80211AD:
1555                 return HOSTAPD_MODE_IEEE80211AD;
1556         case QCA_ACS_MODE_IEEE80211ANY:
1557                 return HOSTAPD_MODE_IEEE80211ANY;
1558         default:
1559                 return NUM_HOSTAPD_MODES;
1560         }
1561 }
1562
1563
1564 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
1565                                    const u8 *data, size_t len)
1566 {
1567         struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
1568         union wpa_event_data event;
1569
1570         wpa_printf(MSG_DEBUG,
1571                    "nl80211: ACS channel selection vendor event received");
1572
1573         if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
1574                       (struct nlattr *) data, len, NULL) ||
1575             !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] ||
1576             !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL])
1577                 return;
1578
1579         os_memset(&event, 0, sizeof(event));
1580         event.acs_selected_channels.pri_channel =
1581                 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
1582         event.acs_selected_channels.sec_channel =
1583                 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
1584         if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
1585                 event.acs_selected_channels.vht_seg0_center_ch =
1586                         nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
1587         if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
1588                 event.acs_selected_channels.vht_seg1_center_ch =
1589                         nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
1590         if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
1591                 event.acs_selected_channels.ch_width =
1592                         nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
1593         if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
1594                 u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
1595
1596                 event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
1597                 if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
1598                     event.acs_selected_channels.hw_mode ==
1599                     HOSTAPD_MODE_IEEE80211ANY) {
1600                         wpa_printf(MSG_DEBUG,
1601                                    "nl80211: Invalid hw_mode %d in ACS selection event",
1602                                    hw_mode);
1603                         return;
1604                 }
1605         }
1606
1607         wpa_printf(MSG_INFO,
1608                    "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
1609                    event.acs_selected_channels.pri_channel,
1610                    event.acs_selected_channels.sec_channel,
1611                    event.acs_selected_channels.ch_width,
1612                    event.acs_selected_channels.vht_seg0_center_ch,
1613                    event.acs_selected_channels.vht_seg1_center_ch,
1614                    event.acs_selected_channels.hw_mode);
1615
1616         /* Ignore ACS channel list check for backwards compatibility */
1617
1618         wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
1619 }
1620
1621
1622 static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
1623                                       const u8 *data, size_t len)
1624 {
1625         struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1];
1626         u8 *bssid;
1627
1628         wpa_printf(MSG_DEBUG,
1629                    "nl80211: Key management roam+auth vendor event received");
1630
1631         if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX,
1632                       (struct nlattr *) data, len, NULL) ||
1633             !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] ||
1634             nla_len(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN ||
1635             !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE] ||
1636             !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] ||
1637             !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED])
1638                 return;
1639
1640         bssid = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]);
1641         wpa_printf(MSG_DEBUG, "  * roam BSSID " MACSTR, MAC2STR(bssid));
1642
1643         mlme_event_connect(drv, NL80211_CMD_ROAM, NULL,
1644                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
1645                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
1646                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
1647                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
1648                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
1649                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
1650                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK],
1651                            tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS]);
1652 }
1653
1654
1655 static void qca_nl80211_dfs_offload_radar_event(
1656         struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
1657 {
1658         union wpa_event_data data;
1659         struct nlattr *tb[NL80211_ATTR_MAX + 1];
1660
1661         wpa_printf(MSG_DEBUG,
1662                    "nl80211: DFS offload radar vendor event received");
1663
1664         if (nla_parse(tb, NL80211_ATTR_MAX,
1665                       (struct nlattr *) msg, length, NULL))
1666                 return;
1667
1668         if (!tb[NL80211_ATTR_WIPHY_FREQ]) {
1669                 wpa_printf(MSG_INFO,
1670                            "nl80211: Error parsing WIPHY_FREQ in FS offload radar vendor event");
1671                 return;
1672         }
1673
1674         os_memset(&data, 0, sizeof(data));
1675         data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1676
1677         wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz",
1678                    data.dfs_event.freq);
1679
1680         /* Check HT params */
1681         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1682                 data.dfs_event.ht_enabled = 1;
1683                 data.dfs_event.chan_offset = 0;
1684
1685                 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
1686                 case NL80211_CHAN_NO_HT:
1687                         data.dfs_event.ht_enabled = 0;
1688                         break;
1689                 case NL80211_CHAN_HT20:
1690                         break;
1691                 case NL80211_CHAN_HT40PLUS:
1692                         data.dfs_event.chan_offset = 1;
1693                         break;
1694                 case NL80211_CHAN_HT40MINUS:
1695                         data.dfs_event.chan_offset = -1;
1696                         break;
1697                 }
1698         }
1699
1700         /* Get VHT params */
1701         if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1702                 data.dfs_event.chan_width =
1703                         convert2width(nla_get_u32(
1704                                               tb[NL80211_ATTR_CHANNEL_WIDTH]));
1705         if (tb[NL80211_ATTR_CENTER_FREQ1])
1706                 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1707         if (tb[NL80211_ATTR_CENTER_FREQ2])
1708                 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1709
1710         wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, "
1711                     "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
1712                     data.dfs_event.freq, data.dfs_event.ht_enabled,
1713                     data.dfs_event.chan_offset, data.dfs_event.chan_width,
1714                     data.dfs_event.cf1, data.dfs_event.cf2);
1715
1716         switch (subcmd) {
1717         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
1718                 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
1719                 break;
1720         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
1721                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
1722                 break;
1723         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
1724                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
1725                 break;
1726         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
1727                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
1728                 break;
1729         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
1730                 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
1731                 break;
1732         default:
1733                 wpa_printf(MSG_DEBUG,
1734                            "nl80211: Unknown DFS offload radar event %d received",
1735                            subcmd);
1736                 break;
1737         }
1738 }
1739
1740
1741 static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
1742                                            u8 *data, size_t len)
1743 {
1744         struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1745         u64 cookie = 0;
1746         union wpa_event_data event;
1747         struct scan_info *info;
1748
1749         if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
1750                       (struct nlattr *) data, len, NULL) ||
1751             !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
1752                 return;
1753
1754         cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1755         if (cookie != drv->vendor_scan_cookie) {
1756                 /* External scan trigger event, ignore */
1757                 return;
1758         }
1759
1760         /* Cookie match, own scan */
1761         os_memset(&event, 0, sizeof(event));
1762         info = &event.scan_info;
1763         info->external_scan = 0;
1764         info->nl_scan_event = 0;
1765
1766         drv->scan_state = SCAN_STARTED;
1767         wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
1768 }
1769
1770
1771 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
1772                                    int aborted, struct nlattr *tb[],
1773                                    int external_scan)
1774 {
1775         union wpa_event_data event;
1776         struct nlattr *nl;
1777         int rem;
1778         struct scan_info *info;
1779         int freqs[MAX_REPORT_FREQS];
1780         int num_freqs = 0;
1781
1782         os_memset(&event, 0, sizeof(event));
1783         info = &event.scan_info;
1784         info->aborted = aborted;
1785         info->external_scan = external_scan;
1786
1787         if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
1788                 nla_for_each_nested(nl,
1789                                     tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], rem) {
1790                         struct wpa_driver_scan_ssid *s =
1791                                 &info->ssids[info->num_ssids];
1792                         s->ssid = nla_data(nl);
1793                         s->ssid_len = nla_len(nl);
1794                         wpa_printf(MSG_DEBUG,
1795                                    "nl80211: Scan probed for SSID '%s'",
1796                                    wpa_ssid_txt(s->ssid, s->ssid_len));
1797                         info->num_ssids++;
1798                         if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1799                                 break;
1800                 }
1801         }
1802
1803         if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1804                 char msg[300], *pos, *end;
1805                 int res;
1806
1807                 pos = msg;
1808                 end = pos + sizeof(msg);
1809                 *pos = '\0';
1810
1811                 nla_for_each_nested(nl,
1812                                     tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
1813                                     rem) {
1814                         freqs[num_freqs] = nla_get_u32(nl);
1815                         res = os_snprintf(pos, end - pos, " %d",
1816                                           freqs[num_freqs]);
1817                         if (!os_snprintf_error(end - pos, res))
1818                                 pos += res;
1819                         num_freqs++;
1820                         if (num_freqs == MAX_REPORT_FREQS - 1)
1821                                 break;
1822                 }
1823
1824                 info->freqs = freqs;
1825                 info->num_freqs = num_freqs;
1826                 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
1827                            msg);
1828         }
1829         wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1830 }
1831
1832
1833 static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
1834                                         u8 *data, size_t len)
1835 {
1836         struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1837         u64 cookie = 0;
1838         enum scan_status status;
1839         int external_scan;
1840
1841         if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
1842                       (struct nlattr *) data, len, NULL) ||
1843             !tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS] ||
1844             !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
1845                 return;
1846
1847         status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS]);
1848         if (status >= VENDOR_SCAN_STATUS_MAX)
1849                 return; /* invalid status */
1850
1851         cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1852         if (cookie != drv->vendor_scan_cookie) {
1853                 /* Event from an external scan, get scan results */
1854                 external_scan = 1;
1855         } else {
1856                 external_scan = 0;
1857                 if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
1858                         drv->scan_state = SCAN_COMPLETED;
1859                 else
1860                         drv->scan_state = SCAN_ABORTED;
1861
1862                 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1863                                      drv->ctx);
1864                 drv->vendor_scan_cookie = 0;
1865                 drv->last_scan_cmd = 0;
1866         }
1867
1868         send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
1869                                external_scan);
1870 }
1871
1872 #endif /* CONFIG_DRIVER_NL80211_QCA */
1873
1874
1875 static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
1876                                      u32 subcmd, u8 *data, size_t len)
1877 {
1878         switch (subcmd) {
1879         case QCA_NL80211_VENDOR_SUBCMD_TEST:
1880                 wpa_hexdump(MSG_DEBUG, "nl80211: QCA test event", data, len);
1881                 break;
1882 #ifdef CONFIG_DRIVER_NL80211_QCA
1883         case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
1884                 qca_nl80211_avoid_freq(drv, data, len);
1885                 break;
1886         case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
1887                 qca_nl80211_key_mgmt_auth(drv, data, len);
1888                 break;
1889         case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
1890                 qca_nl80211_acs_select_ch(drv, data, len);
1891                 break;
1892         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
1893         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
1894         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
1895         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
1896         case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
1897                 qca_nl80211_dfs_offload_radar_event(drv, subcmd, data, len);
1898                 break;
1899         case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
1900                 qca_nl80211_scan_trigger_event(drv, data, len);
1901                 break;
1902         case QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE:
1903                 qca_nl80211_scan_done_event(drv, data, len);
1904                 break;
1905 #endif /* CONFIG_DRIVER_NL80211_QCA */
1906         default:
1907                 wpa_printf(MSG_DEBUG,
1908                            "nl80211: Ignore unsupported QCA vendor event %u",
1909                            subcmd);
1910                 break;
1911         }
1912 }
1913
1914
1915 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
1916                                  struct nlattr **tb)
1917 {
1918         u32 vendor_id, subcmd, wiphy = 0;
1919         int wiphy_idx;
1920         u8 *data = NULL;
1921         size_t len = 0;
1922
1923         if (!tb[NL80211_ATTR_VENDOR_ID] ||
1924             !tb[NL80211_ATTR_VENDOR_SUBCMD])
1925                 return;
1926
1927         vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
1928         subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
1929
1930         if (tb[NL80211_ATTR_WIPHY])
1931                 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1932
1933         wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
1934                    wiphy, vendor_id, subcmd);
1935
1936         if (tb[NL80211_ATTR_VENDOR_DATA]) {
1937                 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
1938                 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
1939                 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
1940         }
1941
1942         wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
1943         if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
1944                 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
1945                            wiphy, wiphy_idx);
1946                 return;
1947         }
1948
1949         switch (vendor_id) {
1950         case OUI_QCA:
1951                 nl80211_vendor_event_qca(drv, subcmd, data, len);
1952                 break;
1953         default:
1954                 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
1955                 break;
1956         }
1957 }
1958
1959
1960 static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
1961                                      struct nlattr *tb[])
1962 {
1963         union wpa_event_data data;
1964         enum nl80211_reg_initiator init;
1965
1966         wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
1967
1968         if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
1969                 return;
1970
1971         os_memset(&data, 0, sizeof(data));
1972         init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
1973         wpa_printf(MSG_DEBUG, " * initiator=%d", init);
1974         switch (init) {
1975         case NL80211_REGDOM_SET_BY_CORE:
1976                 data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
1977                 break;
1978         case NL80211_REGDOM_SET_BY_USER:
1979                 data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
1980                 break;
1981         case NL80211_REGDOM_SET_BY_DRIVER:
1982                 data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
1983                 break;
1984         case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1985                 data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
1986                 break;
1987         }
1988
1989         if (tb[NL80211_ATTR_REG_TYPE]) {
1990                 enum nl80211_reg_type type;
1991                 type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
1992                 wpa_printf(MSG_DEBUG, " * type=%d", type);
1993                 switch (type) {
1994                 case NL80211_REGDOM_TYPE_COUNTRY:
1995                         data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
1996                         break;
1997                 case NL80211_REGDOM_TYPE_WORLD:
1998                         data.channel_list_changed.type = REGDOM_TYPE_WORLD;
1999                         break;
2000                 case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
2001                         data.channel_list_changed.type =
2002                                 REGDOM_TYPE_CUSTOM_WORLD;
2003                         break;
2004                 case NL80211_REGDOM_TYPE_INTERSECTION:
2005                         data.channel_list_changed.type =
2006                                 REGDOM_TYPE_INTERSECTION;
2007                         break;
2008                 }
2009         }
2010
2011         if (tb[NL80211_ATTR_REG_ALPHA2]) {
2012                 os_strlcpy(data.channel_list_changed.alpha2,
2013                            nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
2014                            sizeof(data.channel_list_changed.alpha2));
2015                 wpa_printf(MSG_DEBUG, " * alpha2=%s",
2016                            data.channel_list_changed.alpha2);
2017         }
2018
2019         wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2020 }
2021
2022
2023 static void do_process_drv_event(struct i802_bss *bss, int cmd,
2024                                  struct nlattr **tb)
2025 {
2026         struct wpa_driver_nl80211_data *drv = bss->drv;
2027         union wpa_event_data data;
2028         int external_scan_event = 0;
2029
2030         wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2031                    cmd, nl80211_command_to_string(cmd), bss->ifname);
2032
2033         if (cmd == NL80211_CMD_ROAM &&
2034             (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
2035                 /*
2036                  * Device will use roam+auth vendor event to indicate
2037                  * roaming, so ignore the regular roam event.
2038                  */
2039                 wpa_printf(MSG_DEBUG,
2040                            "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
2041                            cmd);
2042                 return;
2043         }
2044
2045         if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
2046             (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
2047              cmd == NL80211_CMD_SCAN_ABORTED)) {
2048                 wpa_driver_nl80211_set_mode(drv->first_bss,
2049                                             drv->ap_scan_as_station);
2050                 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
2051         }
2052
2053         switch (cmd) {
2054         case NL80211_CMD_TRIGGER_SCAN:
2055                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
2056                 drv->scan_state = SCAN_STARTED;
2057                 if (drv->scan_for_auth) {
2058                         /*
2059                          * Cannot indicate EVENT_SCAN_STARTED here since we skip
2060                          * EVENT_SCAN_RESULTS in scan_for_auth case and the
2061                          * upper layer implementation could get confused about
2062                          * scanning state.
2063                          */
2064                         wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
2065                         break;
2066                 }
2067                 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
2068                 break;
2069         case NL80211_CMD_START_SCHED_SCAN:
2070                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
2071                 drv->scan_state = SCHED_SCAN_STARTED;
2072                 break;
2073         case NL80211_CMD_SCHED_SCAN_STOPPED:
2074                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
2075                 drv->scan_state = SCHED_SCAN_STOPPED;
2076                 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
2077                 break;
2078         case NL80211_CMD_NEW_SCAN_RESULTS:
2079                 wpa_dbg(drv->ctx, MSG_DEBUG,
2080                         "nl80211: New scan results available");
2081                 drv->scan_complete_events = 1;
2082                 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
2083                         drv->scan_state = SCAN_COMPLETED;
2084                         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
2085                                              drv, drv->ctx);
2086                         drv->last_scan_cmd = 0;
2087                 } else {
2088                         external_scan_event = 1;
2089                 }
2090                 send_scan_event(drv, 0, tb, external_scan_event);
2091                 break;
2092         case NL80211_CMD_SCHED_SCAN_RESULTS:
2093                 wpa_dbg(drv->ctx, MSG_DEBUG,
2094                         "nl80211: New sched scan results available");
2095                 drv->scan_state = SCHED_SCAN_RESULTS;
2096                 send_scan_event(drv, 0, tb, 0);
2097                 break;
2098         case NL80211_CMD_SCAN_ABORTED:
2099                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
2100                 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
2101                         drv->scan_state = SCAN_ABORTED;
2102                         /*
2103                          * Need to indicate that scan results are available in
2104                          * order not to make wpa_supplicant stop its scanning.
2105                          */
2106                         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
2107                                              drv, drv->ctx);
2108                         drv->last_scan_cmd = 0;
2109                 } else {
2110                         external_scan_event = 1;
2111                 }
2112                 send_scan_event(drv, 1, tb, external_scan_event);
2113                 break;
2114         case NL80211_CMD_AUTHENTICATE:
2115         case NL80211_CMD_ASSOCIATE:
2116         case NL80211_CMD_DEAUTHENTICATE:
2117         case NL80211_CMD_DISASSOCIATE:
2118         case NL80211_CMD_FRAME_TX_STATUS:
2119         case NL80211_CMD_UNPROT_DEAUTHENTICATE:
2120         case NL80211_CMD_UNPROT_DISASSOCIATE:
2121                 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
2122                            tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
2123                            tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
2124                            tb[NL80211_ATTR_COOKIE],
2125                            tb[NL80211_ATTR_RX_SIGNAL_DBM],
2126                            tb[NL80211_ATTR_STA_WME]);
2127                 break;
2128         case NL80211_CMD_CONNECT:
2129         case NL80211_CMD_ROAM:
2130                 mlme_event_connect(drv, cmd,
2131                                    tb[NL80211_ATTR_STATUS_CODE],
2132                                    tb[NL80211_ATTR_MAC],
2133                                    tb[NL80211_ATTR_REQ_IE],
2134                                    tb[NL80211_ATTR_RESP_IE],
2135                                    NULL, NULL, NULL, NULL, NULL);
2136                 break;
2137         case NL80211_CMD_CH_SWITCH_NOTIFY:
2138                 mlme_event_ch_switch(drv,
2139                                      tb[NL80211_ATTR_IFINDEX],
2140                                      tb[NL80211_ATTR_WIPHY_FREQ],
2141                                      tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2142                                      tb[NL80211_ATTR_CHANNEL_WIDTH],
2143                                      tb[NL80211_ATTR_CENTER_FREQ1],
2144                                      tb[NL80211_ATTR_CENTER_FREQ2]);
2145                 break;
2146         case NL80211_CMD_DISCONNECT:
2147                 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
2148                                       tb[NL80211_ATTR_MAC],
2149                                       tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
2150                 break;
2151         case NL80211_CMD_MICHAEL_MIC_FAILURE:
2152                 mlme_event_michael_mic_failure(bss, tb);
2153                 break;
2154         case NL80211_CMD_JOIN_IBSS:
2155                 mlme_event_join_ibss(drv, tb);
2156                 break;
2157         case NL80211_CMD_REMAIN_ON_CHANNEL:
2158                 mlme_event_remain_on_channel(drv, 0, tb);
2159                 break;
2160         case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
2161                 mlme_event_remain_on_channel(drv, 1, tb);
2162                 break;
2163         case NL80211_CMD_NOTIFY_CQM:
2164                 nl80211_cqm_event(drv, tb);
2165                 break;
2166         case NL80211_CMD_REG_CHANGE:
2167                 nl80211_reg_change_event(drv, tb);
2168                 break;
2169         case NL80211_CMD_REG_BEACON_HINT:
2170                 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
2171                 os_memset(&data, 0, sizeof(data));
2172                 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
2173                 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
2174                                      &data);
2175                 break;
2176         case NL80211_CMD_NEW_STATION:
2177                 nl80211_new_station_event(drv, bss, tb);
2178                 break;
2179         case NL80211_CMD_DEL_STATION:
2180                 nl80211_del_station_event(drv, bss, tb);
2181                 break;
2182         case NL80211_CMD_SET_REKEY_OFFLOAD:
2183                 nl80211_rekey_offload_event(drv, tb);
2184                 break;
2185         case NL80211_CMD_PMKSA_CANDIDATE:
2186                 nl80211_pmksa_candidate_event(drv, tb);
2187                 break;
2188         case NL80211_CMD_PROBE_CLIENT:
2189                 nl80211_client_probe_event(drv, tb);
2190                 break;
2191         case NL80211_CMD_TDLS_OPER:
2192                 nl80211_tdls_oper_event(drv, tb);
2193                 break;
2194         case NL80211_CMD_CONN_FAILED:
2195                 nl80211_connect_failed_event(drv, tb);
2196                 break;
2197         case NL80211_CMD_FT_EVENT:
2198                 mlme_event_ft_event(drv, tb);
2199                 break;
2200         case NL80211_CMD_RADAR_DETECT:
2201                 nl80211_radar_event(drv, tb);
2202                 break;
2203         case NL80211_CMD_STOP_AP:
2204                 nl80211_stop_ap(drv, tb);
2205                 break;
2206         case NL80211_CMD_VENDOR:
2207                 nl80211_vendor_event(drv, tb);
2208                 break;
2209         case NL80211_CMD_NEW_PEER_CANDIDATE:
2210                 nl80211_new_peer_candidate(drv, tb);
2211                 break;
2212         default:
2213                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
2214                         "(cmd=%d)", cmd);
2215                 break;
2216         }
2217 }
2218
2219
2220 int process_global_event(struct nl_msg *msg, void *arg)
2221 {
2222         struct nl80211_global *global = arg;
2223         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2224         struct nlattr *tb[NL80211_ATTR_MAX + 1];
2225         struct wpa_driver_nl80211_data *drv, *tmp;
2226         int ifidx = -1;
2227         struct i802_bss *bss;
2228         u64 wdev_id = 0;
2229         int wdev_id_set = 0;
2230
2231         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2232                   genlmsg_attrlen(gnlh, 0), NULL);
2233
2234         if (tb[NL80211_ATTR_IFINDEX])
2235                 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2236         else if (tb[NL80211_ATTR_WDEV]) {
2237                 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
2238                 wdev_id_set = 1;
2239         }
2240
2241         dl_list_for_each_safe(drv, tmp, &global->interfaces,
2242                               struct wpa_driver_nl80211_data, list) {
2243                 for (bss = drv->first_bss; bss; bss = bss->next) {
2244                         if ((ifidx == -1 && !wdev_id_set) ||
2245                             ifidx == bss->ifindex ||
2246                             (wdev_id_set && bss->wdev_id_set &&
2247                              wdev_id == bss->wdev_id)) {
2248                                 do_process_drv_event(bss, gnlh->cmd, tb);
2249                                 return NL_SKIP;
2250                         }
2251                 }
2252                 wpa_printf(MSG_DEBUG,
2253                            "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d wdev 0x%llx)",
2254                            gnlh->cmd, ifidx, (long long unsigned int) wdev_id);
2255         }
2256
2257         return NL_SKIP;
2258 }
2259
2260
2261 int process_bss_event(struct nl_msg *msg, void *arg)
2262 {
2263         struct i802_bss *bss = arg;
2264         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2265         struct nlattr *tb[NL80211_ATTR_MAX + 1];
2266
2267         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2268                   genlmsg_attrlen(gnlh, 0), NULL);
2269
2270         wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
2271                    gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
2272                    bss->ifname);
2273
2274         switch (gnlh->cmd) {
2275         case NL80211_CMD_FRAME:
2276         case NL80211_CMD_FRAME_TX_STATUS:
2277                 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
2278                            tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
2279                            tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
2280                            tb[NL80211_ATTR_COOKIE],
2281                            tb[NL80211_ATTR_RX_SIGNAL_DBM],
2282                            tb[NL80211_ATTR_STA_WME]);
2283                 break;
2284         case NL80211_CMD_UNEXPECTED_FRAME:
2285                 nl80211_spurious_frame(bss, tb, 0);
2286                 break;
2287         case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
2288                 nl80211_spurious_frame(bss, tb, 1);
2289                 break;
2290         default:
2291                 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
2292                            "(cmd=%d)", gnlh->cmd);
2293                 break;
2294         }
2295
2296         return NL_SKIP;
2297 }