mesh: Write close reason from Mesh Peering Close to debug log
[mech_eap.git] / wpa_supplicant / events.c
index 833f5a0..b7a3bc0 100644 (file)
@@ -281,6 +281,11 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
        wpa_supplicant_ap_deinit(wpa_s);
 #endif /* CONFIG_AP */
 
+#ifdef CONFIG_HS20
+       /* Clear possibly configured frame filters */
+       wpa_drv_configure_frame_filters(wpa_s, 0);
+#endif /* CONFIG_HS20 */
+
        if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
                return;
 
@@ -589,6 +594,14 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                return 1;
        }
 
+#ifdef CONFIG_IEEE80211W
+       if (wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "   skip - MFP Required but network not MFP Capable");
+               return 0;
+       }
+#endif /* CONFIG_IEEE80211W */
+
        wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
        while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
                proto_match++;
@@ -1006,7 +1019,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        continue;
                }
 
-               if (ssid->pbss != bss_is_pbss(bss)) {
+               if (ssid->pbss != 2 && ssid->pbss != bss_is_pbss(bss)) {
                        wpa_dbg(wpa_s, MSG_DEBUG, "   skip - PBSS mismatch (ssid %d bss %d)",
                                ssid->pbss, bss_is_pbss(bss));
                        continue;
@@ -1346,6 +1359,7 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
        struct wpa_bss *current_bss = NULL;
 #ifndef CONFIG_NO_ROAMING
        int min_diff;
+       int to_5ghz;
 #endif /* CONFIG_NO_ROAMING */
 
        if (wpa_s->reassociate)
@@ -1401,7 +1415,10 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
                return 1;
        }
 
-       if (current_bss->level < 0 && current_bss->level > selected->level) {
+       to_5ghz = selected->freq > 4000 && current_bss->freq < 4000;
+
+       if (current_bss->level < 0 &&
+           current_bss->level > selected->level + to_5ghz * 2) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
                        "signal level");
                return 0;
@@ -1420,6 +1437,13 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
                else
                        min_diff = 5;
        }
+       if (to_5ghz) {
+               /* Make it easier to move to 5 GHz band */
+               if (min_diff > 2)
+                       min_diff -= 2;
+               else
+                       min_diff = 0;
+       }
        if (abs(current_bss->level - selected->level) < min_diff) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference "
                        "in signal level");
@@ -2758,6 +2782,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))
@@ -3143,7 +3174,16 @@ static void wpa_supplicant_update_channel_list(
 {
        struct wpa_supplicant *ifs;
 
-       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
+       /*
+        * To allow backwards compatibility with higher level layers that
+        * assumed the REGDOM_CHANGE event is sent over the initially added
+        * interface. Find the highest parent of this interface and use it to
+        * send the event.
+        */
+       for (ifs = wpa_s; ifs->parent && ifs != ifs->parent; ifs = ifs->parent)
+               ;
+
+       wpa_msg(ifs, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
                reg_init_str(info->initiator), reg_type_str(info->type),
                info->alpha2[0] ? " alpha2=" : "",
                info->alpha2[0] ? info->alpha2 : "");
@@ -3256,6 +3296,14 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_INTERWORKING */
 
        if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
+           payload[0] == WLAN_RRM_RADIO_MEASUREMENT_REQUEST) {
+               wpas_rrm_handle_radio_measurement_request(wpa_s, mgmt->sa,
+                                                         payload + 1,
+                                                         plen - 1);
+               return;
+       }
+
+       if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
            payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
                wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1);
                return;
@@ -3496,13 +3544,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
        case EVENT_ASSOC_REJECT:
                if (data->assoc_reject.bssid)
                        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-                               "bssid=" MACSTR " status_code=%u",
+                               "bssid=" MACSTR " status_code=%u%s",
                                MAC2STR(data->assoc_reject.bssid),
-                               data->assoc_reject.status_code);
+                               data->assoc_reject.status_code,
+                               data->assoc_reject.timed_out ? " timeout" : "");
                else
                        wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-                               "status_code=%u",
-                               data->assoc_reject.status_code);
+                               "status_code=%u%s",
+                               data->assoc_reject.status_code,
+                               data->assoc_reject.timed_out ? " timeout" : "");
                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)
@@ -3560,17 +3610,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #endif /* CONFIG_AP */
 #ifdef CONFIG_OFFCHANNEL
                wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
-                       MACSTR, MAC2STR(wpa_s->parent->pending_action_dst));
+                       MACSTR, MAC2STR(wpa_s->p2pdev->pending_action_dst));
                /*
                 * Catch TX status events for Action frames we sent via group
-                * interface in GO mode.
+                * interface in GO mode, or via standalone AP interface.
+                * Note, wpa_s->p2pdev will be the same as wpa_s->parent,
+                * except when the primary interface is used as a GO interface
+                * (for drivers which do not have group interface concurrency)
                 */
                if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
                    data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
-                   os_memcmp(wpa_s->parent->pending_action_dst,
+                   os_memcmp(wpa_s->p2pdev->pending_action_dst,
                              data->tx_status.dst, ETH_ALEN) == 0) {
                        offchannel_send_action_tx_status(
-                               wpa_s->parent, data->tx_status.dst,
+                               wpa_s->p2pdev, data->tx_status.dst,
                                data->tx_status.data,
                                data->tx_status.data_len,
                                data->tx_status.ack ?
@@ -3616,6 +3669,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                if (!data || !wpa_s->current_ssid)
                        break;
 
+               wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH
+                       "freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d",
+                       data->ch_switch.freq,
+                       data->ch_switch.ht_enabled,
+                       data->ch_switch.ch_offset,
+                       channel_width_to_string(data->ch_switch.ch_width),
+                       data->ch_switch.cf1,
+                       data->ch_switch.cf2);
+
                wpa_s->assoc_freq = data->ch_switch.freq;
                wpa_s->current_ssid->frequency = data->ch_switch.freq;
 
@@ -3688,12 +3750,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #endif /* CONFIG_AP */
 #ifdef CONFIG_P2P
                        if (stype == WLAN_FC_STYPE_PROBE_REQ &&
-                           data->rx_mgmt.frame_len > 24) {
+                           data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
                                const u8 *src = mgmt->sa;
-                               const u8 *ie = mgmt->u.probe_req.variable;
-                               size_t ie_len = data->rx_mgmt.frame_len -
-                                       (mgmt->u.probe_req.variable -
-                                        data->rx_mgmt.frame);
+                               const u8 *ie;
+                               size_t ie_len;
+
+                               ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
+                               ie_len = data->rx_mgmt.frame_len -
+                                       IEEE80211_HDRLEN;
                                wpas_p2p_probe_req_rx(
                                        wpa_s, src, mgmt->da,
                                        mgmt->bssid, ie, ie_len,
@@ -3733,11 +3797,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                }
 
                if (stype == WLAN_FC_STYPE_PROBE_REQ &&
-                   data->rx_mgmt.frame_len > 24) {
-                       const u8 *ie = mgmt->u.probe_req.variable;
-                       size_t ie_len = data->rx_mgmt.frame_len -
-                               (mgmt->u.probe_req.variable -
-                                data->rx_mgmt.frame);
+                   data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
+                       const u8 *ie;
+                       size_t ie_len;
+
+                       ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
+                       ie_len = data->rx_mgmt.frame_len - IEEE80211_HDRLEN;
 
                        wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
                                         mgmt->bssid, ie, ie_len,
@@ -3938,7 +4003,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                         data->driver_gtk_rekey.replay_ctr);
                break;
        case EVENT_SCHED_SCAN_STOPPED:
-               wpa_s->pno = 0;
                wpa_s->sched_scanning = 0;
                resched = wpa_s->scanning && wpas_scan_scheduled(wpa_s);
                wpa_supplicant_notify_scanning(wpa_s, 0);
@@ -4030,6 +4094,20 @@ void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
                        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);