Allow SCAN command to specify scan_ssid=1 SSIDs
[mech_eap.git] / wpa_supplicant / ctrl_iface.c
index 9bf03e3..244fd2d 100644 (file)
@@ -584,6 +584,13 @@ static int wpa_supplicant_ctrl_iface_tdls_teardown(
        u8 peer[ETH_ALEN];
        int ret;
 
+       if (os_strcmp(addr, "*") == 0) {
+               /* remove everyone */
+               wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN *");
+               wpa_tdls_teardown_peers(wpa_s->wpa);
+               return 0;
+       }
+
        if (hwaddr_aton(addr, peer)) {
                wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
                           "address '%s'", addr);
@@ -2204,17 +2211,43 @@ static int wpa_supplicant_ctrl_iface_scan_result(
                        return -1;
                pos += ret;
        }
-       if (bss->caps & IEEE80211_CAP_IBSS) {
-               ret = os_snprintf(pos, end - pos, "[IBSS]");
+       if (bss_is_dmg(bss)) {
+               const char *s;
+               ret = os_snprintf(pos, end - pos, "[DMG]");
                if (ret < 0 || ret >= end - pos)
                        return -1;
                pos += ret;
-       }
-       if (bss->caps & IEEE80211_CAP_ESS) {
-               ret = os_snprintf(pos, end - pos, "[ESS]");
+               switch (bss->caps & IEEE80211_CAP_DMG_MASK) {
+               case IEEE80211_CAP_DMG_IBSS:
+                       s = "[IBSS]";
+                       break;
+               case IEEE80211_CAP_DMG_AP:
+                       s = "[ESS]";
+                       break;
+               case IEEE80211_CAP_DMG_PBSS:
+                       s = "[PBSS]";
+                       break;
+               default:
+                       s = "";
+                       break;
+               }
+               ret = os_snprintf(pos, end - pos, "%s", s);
                if (ret < 0 || ret >= end - pos)
                        return -1;
                pos += ret;
+       } else {
+               if (bss->caps & IEEE80211_CAP_IBSS) {
+                       ret = os_snprintf(pos, end - pos, "[IBSS]");
+                       if (ret < 0 || ret >= end - pos)
+                               return -1;
+                       pos += ret;
+               }
+               if (bss->caps & IEEE80211_CAP_ESS) {
+                       ret = os_snprintf(pos, end - pos, "[ESS]");
+                       if (ret < 0 || ret >= end - pos)
+                               return -1;
+                       pos += ret;
+               }
        }
        if (p2p) {
                ret = os_snprintf(pos, end - pos, "[P2P]");
@@ -3544,17 +3577,43 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                                return 0;
                        pos += ret;
                }
-               if (bss->caps & IEEE80211_CAP_IBSS) {
-                       ret = os_snprintf(pos, end - pos, "[IBSS]");
+               if (bss_is_dmg(bss)) {
+                       const char *s;
+                       ret = os_snprintf(pos, end - pos, "[DMG]");
                        if (ret < 0 || ret >= end - pos)
                                return 0;
                        pos += ret;
-               }
-               if (bss->caps & IEEE80211_CAP_ESS) {
-                       ret = os_snprintf(pos, end - pos, "[ESS]");
+                       switch (bss->caps & IEEE80211_CAP_DMG_MASK) {
+                       case IEEE80211_CAP_DMG_IBSS:
+                               s = "[IBSS]";
+                               break;
+                       case IEEE80211_CAP_DMG_AP:
+                               s = "[ESS]";
+                               break;
+                       case IEEE80211_CAP_DMG_PBSS:
+                               s = "[PBSS]";
+                               break;
+                       default:
+                               s = "";
+                               break;
+                       }
+                       ret = os_snprintf(pos, end - pos, "%s", s);
                        if (ret < 0 || ret >= end - pos)
                                return 0;
                        pos += ret;
+               } else {
+                       if (bss->caps & IEEE80211_CAP_IBSS) {
+                               ret = os_snprintf(pos, end - pos, "[IBSS]");
+                               if (ret < 0 || ret >= end - pos)
+                                       return 0;
+                               pos += ret;
+                       }
+                       if (bss->caps & IEEE80211_CAP_ESS) {
+                               ret = os_snprintf(pos, end - pos, "[ESS]");
+                               if (ret < 0 || ret >= end - pos)
+                                       return 0;
+                               pos += ret;
+                       }
                }
                if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
                    wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
@@ -4708,7 +4767,7 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 
        if (os_strcmp(cmd, "listen_channel") == 0) {
                return p2p_set_listen_channel(wpa_s->global->p2p, 81,
-                                             atoi(param));
+                                             atoi(param), 1);
        }
 
        if (os_strcmp(cmd, "ssid_postfix") == 0) {
@@ -5316,7 +5375,7 @@ static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s,
        if (len == 0 && cred && cred->realm)
                return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm);
 
-       if (len % 1)
+       if (len & 1)
                return -1;
        len /= 2;
        buf = os_malloc(len);
@@ -5756,8 +5815,8 @@ static void wpas_ctrl_radio_work_timeout(void *eloop_ctx, void *timeout_ctx)
                "Timing out external radio work %u (%s)",
                ework->id, work->type);
        wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_TIMEOUT "%u", ework->id);
-       os_free(ework);
        radio_work_done(work);
+       os_free(ework);
 }
 
 
@@ -5899,8 +5958,8 @@ void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s)
                if (work->started)
                        eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
                                             work, NULL);
-               os_free(ework);
                radio_work_done(work);
+               os_free(ework);
        }
 }
 
@@ -5927,6 +5986,25 @@ static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val)
 }
 
 
+static int scan_id_list_parse(struct wpa_supplicant *wpa_s, const char *value)
+{
+       const char *pos = value;
+
+       while (pos) {
+               if (*pos == ' ' || *pos == '\0')
+                       break;
+               if (wpa_s->scan_id_count == MAX_SCAN_ID)
+                       return -1;
+               wpa_s->scan_id[wpa_s->scan_id_count++] = atoi(pos);
+               pos = os_strchr(pos, ',');
+               if (pos)
+                       pos++;
+       }
+
+       return 0;
+}
+
+
 static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
                           char *reply, int reply_size, int *reply_len)
 {
@@ -5940,6 +6018,7 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
        wpa_s->manual_scan_passive = 0;
        wpa_s->manual_scan_use_id = 0;
        wpa_s->manual_scan_only_new = 0;
+       wpa_s->scan_id_count = 0;
 
        if (params) {
                if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
@@ -5962,6 +6041,12 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
                pos = os_strstr(params, "only_new=1");
                if (pos)
                        wpa_s->manual_scan_only_new = 1;
+
+               pos = os_strstr(params, "scan_id=");
+               if (pos && scan_id_list_parse(wpa_s, pos + 8) < 0) {
+                       *reply_len = -1;
+                       return;
+               }
        } else {
                os_free(wpa_s->manual_scan_freqs);
                wpa_s->manual_scan_freqs = NULL;