Include previous BSSID in connection request to indicate reassociation
[mech_eap.git] / wpa_supplicant / events.c
index 00e4c04..1483ad4 100644 (file)
@@ -574,6 +574,16 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                                "   skip RSN IE - no mgmt frame protection enabled but AP requires it");
                        break;
                }
+#ifdef CONFIG_MBO
+               if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
+                   wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND) &&
+                   wpas_get_ssid_pmf(wpa_s, ssid) !=
+                   NO_MGMT_FRAME_PROTECTION) {
+                       wpa_dbg(wpa_s, MSG_DEBUG,
+                               "   skip RSN IE - no mgmt frame protection enabled on MBO AP");
+                       break;
+               }
+#endif /* CONFIG_MBO */
 
                wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on RSN IE");
                return 1;
@@ -816,10 +826,10 @@ static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
 }
 
 
-static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
-                                           int i, struct wpa_bss *bss,
-                                           struct wpa_ssid *group,
-                                           int only_first_ssid)
+struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
+                                    int i, struct wpa_bss *bss,
+                                    struct wpa_ssid *group,
+                                    int only_first_ssid)
 {
        u8 wpa_ie_len, rsn_ie_len;
        int wpa;
@@ -1974,6 +1984,8 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
                }
                if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
                     (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
+                   (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
+                    (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
                    (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
                        if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
                                break;
@@ -2746,6 +2758,13 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
                }
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_MATCH_IFACE
+               if (wpa_s->matched) {
+                       wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
+                       break;
+               }
+#endif /* CONFIG_MATCH_IFACE */
+
 #ifdef CONFIG_TERMINATE_ONLASTIF
                /* check if last interface */
                if (!any_interfaces(wpa_s->global->ifaces))
@@ -3333,6 +3352,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
            event != EVENT_INTERFACE_ENABLED &&
            event != EVENT_INTERFACE_STATUS &&
+           event != EVENT_SCAN_RESULTS &&
            event != EVENT_SCHED_SCAN_STOPPED) {
                wpa_dbg(wpa_s, MSG_DEBUG,
                        "Ignore event %s (%d) while interface is disabled",
@@ -3419,6 +3439,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                }
                break;
        case EVENT_SCAN_RESULTS:
+               if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+                       wpa_s->scan_res_handler = NULL;
+                       wpa_s->own_scan_running = 0;
+                       wpa_s->radio->external_scan_running = 0;
+                       wpa_s->last_scan_req = NORMAL_SCAN_REQ;
+                       break;
+               }
+
                if (!(data && data->scan_info.external_scan) &&
                    os_reltime_initialized(&wpa_s->scan_start_time)) {
                        struct os_reltime now, diff;
@@ -3482,6 +3510,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
                                "status_code=%u",
                                data->assoc_reject.status_code);
+               wpa_s->assoc_status_code = data->assoc_reject.status_code;
+               wpas_notify_assoc_status_code(wpa_s);
                if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
                        sme_event_assoc_reject(wpa_s, data);
                else {
@@ -3917,7 +3947,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        case EVENT_SCHED_SCAN_STOPPED:
                wpa_s->pno = 0;
                wpa_s->sched_scanning = 0;
-               resched = wpa_s->scanning;
+               resched = wpa_s->scanning && wpas_scan_scheduled(wpa_s);
                wpa_supplicant_notify_scanning(wpa_s, 0);
 
                if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
@@ -3985,3 +4015,43 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                break;
        }
 }
+
+
+void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
+                                union wpa_event_data *data)
+{
+       struct wpa_supplicant *wpa_s;
+
+       if (event != EVENT_INTERFACE_STATUS)
+               return;
+
+       wpa_s = wpa_supplicant_get_iface(ctx, data->interface_status.ifname);
+       if (wpa_s && wpa_s->driver->get_ifindex) {
+               unsigned int ifindex;
+
+               ifindex = wpa_s->driver->get_ifindex(wpa_s->drv_priv);
+               if (ifindex != data->interface_status.ifindex) {
+                       wpa_dbg(wpa_s, MSG_DEBUG,
+                               "interface status ifindex %d mismatch (%d)",
+                               ifindex, data->interface_status.ifindex);
+                       return;
+               }
+       }
+#ifdef CONFIG_MATCH_IFACE
+       else if (data->interface_status.ievent == EVENT_INTERFACE_ADDED) {
+               struct wpa_interface *wpa_i;
+
+               wpa_i = wpa_supplicant_match_iface(
+                       ctx, data->interface_status.ifname);
+               if (!wpa_i)
+                       return;
+               wpa_s = wpa_supplicant_add_iface(ctx, wpa_i, NULL);
+               os_free(wpa_i);
+               if (wpa_s)
+                       wpa_s->matched = 1;
+       }
+#endif /* CONFIG_MATCH_IFACE */
+
+       if (wpa_s)
+               wpa_supplicant_event(wpa_s, event, data);
+}