nl80211: Support vendor scan together with normal scan
[mech_eap.git] / src / drivers / driver_nl80211_event.c
index 647280c..5f2811c 100644 (file)
@@ -968,7 +968,7 @@ static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
 
 
 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
-                           struct nlattr *tb[])
+                           struct nlattr *tb[], int external_scan)
 {
        union wpa_event_data event;
        struct nlattr *nl;
@@ -978,7 +978,7 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
        int freqs[MAX_REPORT_FREQS];
        int num_freqs = 0;
 
-       if (drv->scan_for_auth) {
+       if (!external_scan && drv->scan_for_auth) {
                drv->scan_for_auth = 0;
                wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
                           "cfg80211 BSS entry");
@@ -989,6 +989,8 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
        os_memset(&event, 0, sizeof(event));
        info = &event.scan_info;
        info->aborted = aborted;
+       info->external_scan = external_scan;
+       info->nl_scan_event = 1;
 
        if (tb[NL80211_ATTR_SCAN_SSIDS]) {
                nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
@@ -1691,6 +1693,8 @@ static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
 {
        struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
        u64 cookie = 0;
+       union wpa_event_data event;
+       struct scan_info *info;
 
        if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
                      (struct nlattr *) data, len, NULL) ||
@@ -1703,13 +1707,20 @@ static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
                return;
        }
 
+       /* Cookie match, own scan */
+       os_memset(&event, 0, sizeof(event));
+       info = &event.scan_info;
+       info->external_scan = 0;
+       info->nl_scan_event = 0;
+
        drv->scan_state = SCAN_STARTED;
-       wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
+       wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
 }
 
 
 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
-                                  int aborted, struct nlattr *tb[])
+                                  int aborted, struct nlattr *tb[],
+                                  int external_scan)
 {
        union wpa_event_data event;
        struct nlattr *nl;
@@ -1721,6 +1732,7 @@ static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
        os_memset(&event, 0, sizeof(event));
        info = &event.scan_info;
        info->aborted = aborted;
+       info->external_scan = external_scan;
 
        if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
                nla_for_each_nested(nl,
@@ -1774,6 +1786,7 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
        struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
        u64 cookie = 0;
        enum scan_status status;
+       int external_scan;
 
        if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
                      (struct nlattr *) data, len, NULL) ||
@@ -1788,7 +1801,9 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
        cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
        if (cookie != drv->vendor_scan_cookie) {
                /* Event from an external scan, get scan results */
+               external_scan = 1;
        } else {
+               external_scan = 0;
                if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
                        drv->scan_state = SCAN_COMPLETED;
                else
@@ -1797,9 +1812,11 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
                eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
                                     drv->ctx);
                drv->vendor_scan_cookie = 0;
+               drv->last_scan_cmd = 0;
        }
 
-       send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb);
+       send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
+                              external_scan);
 }
 
 
@@ -1954,6 +1971,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
        union wpa_event_data data;
+       int external_scan_event = 0;
 
        wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
                   cmd, nl80211_command_to_string(cmd), bss->ifname);
@@ -2006,28 +2024,38 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
        case NL80211_CMD_NEW_SCAN_RESULTS:
                wpa_dbg(drv->ctx, MSG_DEBUG,
                        "nl80211: New scan results available");
-               drv->scan_state = SCAN_COMPLETED;
                drv->scan_complete_events = 1;
-               eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
-                                    drv->ctx);
-               send_scan_event(drv, 0, tb);
+               if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
+                       drv->scan_state = SCAN_COMPLETED;
+                       eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
+                                            drv, drv->ctx);
+                       drv->last_scan_cmd = 0;
+               } else {
+                       external_scan_event = 1;
+               }
+               send_scan_event(drv, 0, tb, external_scan_event);
                break;
        case NL80211_CMD_SCHED_SCAN_RESULTS:
                wpa_dbg(drv->ctx, MSG_DEBUG,
                        "nl80211: New sched scan results available");
                drv->scan_state = SCHED_SCAN_RESULTS;
-               send_scan_event(drv, 0, tb);
+               send_scan_event(drv, 0, tb, 0);
                break;
        case NL80211_CMD_SCAN_ABORTED:
                wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
-               drv->scan_state = SCAN_ABORTED;
-               /*
-                * Need to indicate that scan results are available in order
-                * not to make wpa_supplicant stop its scanning.
-                */
-               eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
-                                    drv->ctx);
-               send_scan_event(drv, 1, tb);
+               if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
+                       drv->scan_state = SCAN_ABORTED;
+                       /*
+                        * Need to indicate that scan results are available in
+                        * order not to make wpa_supplicant stop its scanning.
+                        */
+                       eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
+                                            drv, drv->ctx);
+                       drv->last_scan_cmd = 0;
+               } else {
+                       external_scan_event = 1;
+               }
+               send_scan_event(drv, 1, tb, external_scan_event);
                break;
        case NL80211_CMD_AUTHENTICATE:
        case NL80211_CMD_ASSOCIATE: