]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/ctrl_iface.c
P2P: Add VHT parameter to P2P operations
[thirdparty/hostap.git] / wpa_supplicant / ctrl_iface.c
index 81ca37d759016c4a46572fbdd9af2ae0e394abb8..809ae0c2ef43670b86a7e9572004ab2fe24c7654 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant / Control interface (shared code for all backends)
- * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -50,7 +50,7 @@ static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
 
 static int pno_start(struct wpa_supplicant *wpa_s)
 {
-       int ret;
+       int ret, interval;
        size_t i, num_ssid;
        struct wpa_ssid *ssid;
        struct wpa_driver_scan_params params;
@@ -108,7 +108,10 @@ static int pno_start(struct wpa_supplicant *wpa_s)
        if (wpa_s->conf->filter_rssi)
                params.filter_rssi = wpa_s->conf->filter_rssi;
 
-       ret = wpa_drv_sched_scan(wpa_s, &params, 10 * 1000);
+       interval = wpa_s->conf->sched_scan_interval ?
+               wpa_s->conf->sched_scan_interval : 10;
+
+       ret = wpa_drv_sched_scan(wpa_s, &params, interval * 1000);
        os_free(params.filter_ssids);
        if (ret == 0)
                wpa_s->pno = 1;
@@ -1411,6 +1414,8 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
        char *pos, *end, tmp[30];
        int res, verbose, wps, ret;
 
+       if (os_strcmp(params, "-DRIVER") == 0)
+               return wpa_drv_status(wpa_s, buf, buflen);
        verbose = os_strcmp(params, "-VERBOSE") == 0;
        wps = os_strcmp(params, "-WPS") == 0;
        pos = buf;
@@ -1503,7 +1508,10 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
        }
 #ifdef CONFIG_SAE
        if (wpa_s->wpa_state >= WPA_ASSOCIATED &&
-           wpa_s->sme.sae.state == SAE_ACCEPTED && !wpa_s->ap_iface) {
+#ifdef CONFIG_AP
+           !wpa_s->ap_iface &&
+#endif /* CONFIG_AP */
+           wpa_s->sme.sae.state == SAE_ACCEPTED) {
                ret = os_snprintf(pos, end - pos, "sae_group=%d\n",
                                  wpa_s->sme.sae.group);
                if (ret < 0 || ret >= end - pos)
@@ -1557,16 +1565,21 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
                char *type;
 
                for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+                       size_t i;
+
                        if (wpa_s->current_ssid->parent_cred != cred)
                                continue;
                        if (!cred->domain)
                                continue;
 
-                       ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
-                                         cred->domain);
-                       if (ret < 0 || ret >= end - pos)
-                               return pos - buf;
-                       pos += ret;
+                       for (i = 0; i < cred->num_domain; i++) {
+                               ret = os_snprintf(pos, end - pos,
+                                                 "home_sp=%s\n",
+                                                 cred->domain[i]);
+                               if (ret < 0 || ret >= end - pos)
+                                       return pos - buf;
+                               pos += ret;
+                       }
 
                        if (wpa_s->current_bss == NULL ||
                            wpa_s->current_bss->anqp == NULL)
@@ -2008,6 +2021,8 @@ static int wpa_supplicant_ctrl_iface_scan_result(
        const u8 *ie, *ie2, *p2p;
 
        p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
+       if (!p2p)
+               p2p = wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE);
        if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
            os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
            0)
@@ -2438,7 +2453,7 @@ static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
                ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
                                  cred->id, cred->realm ? cred->realm : "",
                                  cred->username ? cred->username : "",
-                                 cred->domain ? cred->domain : "",
+                                 cred->domain ? cred->domain[0] : "",
                                  cred->imsi ? cred->imsi : "");
                if (ret < 0 || ret >= end - pos)
                        return pos - buf;
@@ -2523,9 +2538,16 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
                while (cred) {
                        prev = cred;
                        cred = cred->next;
-                       if (prev->domain &&
-                           os_strcmp(prev->domain, cmd + 8) == 0)
-                               wpas_ctrl_remove_cred(wpa_s, prev);
+                       if (prev->domain) {
+                               size_t i;
+                               for (i = 0; i < prev->num_domain; i++) {
+                                       if (os_strcmp(prev->domain[i], cmd + 8)
+                                           != 0)
+                                               continue;
+                                       wpas_ctrl_remove_cred(wpa_s, prev);
+                                       break;
+                               }
+                       }
                }
                return 0;
        }
@@ -3257,7 +3279,8 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                                return 0;
                        pos += ret;
                }
-               if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
+               if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
+                   wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
                        ret = os_snprintf(pos, end - pos, "[P2P]");
                        if (ret < 0 || ret >= end - pos)
                                return 0;
@@ -3665,12 +3688,12 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        int go_intent = -1;
        int freq = 0;
        int pd;
-       int ht40;
+       int ht40, vht;
 
        /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
         * [persistent|persistent=<network id>]
         * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
-        * [ht40] */
+        * [ht40] [vht] */
 
        if (hwaddr_aton(cmd, addr))
                return -1;
@@ -3698,7 +3721,9 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        auth = os_strstr(pos, " auth") != NULL;
        automatic = os_strstr(pos, " auto") != NULL;
        pd = os_strstr(pos, " provdisc") != NULL;
-       ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
+       vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
+       ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
+               vht;
 
        pos2 = os_strstr(pos, " go_intent=");
        if (pos2) {
@@ -3739,7 +3764,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, automatic, join,
                                   auth, go_intent, freq, persistent_id, pd,
-                                  ht40);
+                                  ht40, vht);
        if (new_pin == -2) {
                os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
                return 25;
@@ -4103,7 +4128,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        struct wpa_ssid *ssid;
        u8 *_peer = NULL, peer[ETH_ALEN];
        int freq = 0, pref_freq = 0;
-       int ht40;
+       int ht40, vht;
 
        id = atoi(cmd);
        pos = os_strstr(cmd, " peer=");
@@ -4137,9 +4162,12 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
                        return -1;
        }
 
-       ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
+       vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
+       ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
+               vht;
 
-       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, pref_freq);
+       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, vht,
+                              pref_freq);
 }
 
 
@@ -4186,7 +4214,8 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
 
 
 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
-                                        char *cmd, int freq, int ht40)
+                                        char *cmd, int freq, int ht40,
+                                        int vht)
 {
        int id;
        struct wpa_ssid *ssid;
@@ -4200,31 +4229,34 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, NULL);
+       return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, vht,
+                                            NULL, 0);
 }
 
 
 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
 {
-       int freq = 0, ht40;
+       int freq = 0, ht40, vht;
        char *pos;
 
        pos = os_strstr(cmd, "freq=");
        if (pos)
                freq = atoi(pos + 5);
 
-       ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
+       vht = (os_strstr(cmd, "vht") != NULL) || wpa_s->conf->p2p_go_vht;
+       ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
+               vht;
 
        if (os_strncmp(cmd, "persistent=", 11) == 0)
                return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq,
-                                                    ht40);
+                                                    ht40, vht);
        if (os_strcmp(cmd, "persistent") == 0 ||
            os_strncmp(cmd, "persistent ", 11) == 0)
-               return wpas_p2p_group_add(wpa_s, 1, freq, ht40);
+               return wpas_p2p_group_add(wpa_s, 1, freq, ht40, vht);
        if (os_strncmp(cmd, "freq=", 5) == 0)
-               return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
+               return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht);
        if (ht40)
-               return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
+               return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht);
 
        wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
                   cmd);
@@ -4327,48 +4359,21 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
 static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
                                  const char *param)
 {
-       struct wpa_freq_range *freq = NULL, *n;
-       unsigned int count = 0, i;
-       const char *pos, *pos2, *pos3;
+       unsigned int i;
 
        if (wpa_s->global->p2p == NULL)
                return -1;
 
-       /*
-        * param includes comma separated frequency range.
-        * For example: 2412-2432,2462,5000-6000
-        */
-       pos = param;
-       while (pos && pos[0]) {
-               n = os_realloc_array(freq, count + 1,
-                                    sizeof(struct wpa_freq_range));
-               if (n == NULL) {
-                       os_free(freq);
-                       return -1;
-               }
-               freq = n;
-               freq[count].min = atoi(pos);
-               pos2 = os_strchr(pos, '-');
-               pos3 = os_strchr(pos, ',');
-               if (pos2 && (!pos3 || pos2 < pos3)) {
-                       pos2++;
-                       freq[count].max = atoi(pos2);
-               } else
-                       freq[count].max = freq[count].min;
-               pos = pos3;
-               if (pos)
-                       pos++;
-               count++;
-       }
+       if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0)
+               return -1;
 
-       for (i = 0; i < count; i++) {
+       for (i = 0; i < wpa_s->global->p2p_disallow_freq.num; i++) {
+               struct wpa_freq_range *freq;
+               freq = &wpa_s->global->p2p_disallow_freq.range[i];
                wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
-                          freq[i].min, freq[i].max);
+                          freq->min, freq->max);
        }
 
-       os_free(wpa_s->global->p2p_disallow_freq);
-       wpa_s->global->p2p_disallow_freq = freq;
-       wpa_s->global->num_p2p_disallow_freq = count;
        wpas_p2p_update_channel_list(wpa_s);
        return 0;
 }
@@ -4559,6 +4564,11 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
                                        max_disc_int, max_disc_tu);
        }
 
+       if (os_strcmp(cmd, "per_sta_psk") == 0) {
+               wpa_s->global->p2p_per_sta_psk = !!atoi(param);
+               return 0;
+       }
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
                   cmd);
 
@@ -4624,6 +4634,25 @@ static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
        return wpas_p2p_ext_listen(wpa_s, period, interval);
 }
 
+
+static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+       const char *pos;
+       u8 peer[ETH_ALEN];
+       int iface_addr = 0;
+
+       pos = cmd;
+       if (os_strncmp(pos, "iface=", 6) == 0) {
+               iface_addr = 1;
+               pos += 6;
+       }
+       if (hwaddr_aton(pos, peer))
+               return -1;
+
+       wpas_p2p_remove_client(wpa_s, peer, iface_addr);
+       return 0;
+}
+
 #endif /* CONFIG_P2P */
 
 
@@ -5114,6 +5143,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
 #ifdef CONFIG_WPS
        wpas_wps_cancel(wpa_s);
 #endif /* CONFIG_WPS */
+       wpa_s->after_wps = 0;
+       wpa_s->known_wps_freq = 0;
 
 #ifdef CONFIG_TDLS_TESTING
        extern unsigned int tdls_testing;
@@ -5149,12 +5180,18 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+       eapol_sm_notify_ctrl_response(wpa_s->eapol);
+}
+
+
 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                                         char *buf, size_t *resp_len)
 {
        char *reply;
        const int reply_size = 4096;
-       int ctrl_rsp = 0;
        int reply_len;
 
        if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
@@ -5381,7 +5418,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpas_p2p_group_remove(wpa_s, buf + 17))
                        reply_len = -1;
        } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
-               if (wpas_p2p_group_add(wpa_s, 0, 0, 0))
+               if (wpas_p2p_group_add(wpa_s, 0, 0, 0, 0))
                        reply_len = -1;
        } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
                if (p2p_ctrl_group_add(wpa_s, buf + 14))
@@ -5445,6 +5482,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
                if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "P2P_REMOVE_CLIENT ", 18) == 0) {
+               if (p2p_ctrl_remove_client(wpa_s, buf + 18) < 0)
+                       reply_len = -1;
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_WIFI_DISPLAY
        } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) {
@@ -5490,8 +5530,14 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpa_supplicant_ctrl_iface_ctrl_rsp(
                            wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
                        reply_len = -1;
-               else
-                       ctrl_rsp = 1;
+               else {
+                       /*
+                        * Notify response from timeout to allow the control
+                        * interface response to be sent first.
+                        */
+                       eloop_register_timeout(0, 0, wpas_ctrl_eapol_response,
+                                              wpa_s, NULL);
+               }
        } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
                if (wpa_supplicant_reload_configuration(wpa_s))
                        reply_len = -1;
@@ -5532,6 +5578,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                             (wpa_s->wpa_state == WPA_COMPLETED))) {
                                wpa_s->normal_scans = 0;
                                wpa_s->scan_req = MANUAL_SCAN_REQ;
+                               wpa_s->after_wps = 0;
+                               wpa_s->known_wps_freq = 0;
                                wpa_supplicant_req_scan(wpa_s, 0, 0);
                        } else if (wpa_s->sched_scanning) {
                                wpa_printf(MSG_DEBUG, "Stop ongoing "
@@ -5689,9 +5737,6 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                reply_len = 5;
        }
 
-       if (ctrl_rsp)
-               eapol_sm_notify_ctrl_response(wpa_s->eapol);
-
        *resp_len = reply_len;
        return reply;
 }
@@ -5931,6 +5976,7 @@ static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global,
                "P2P_UNAUTHORIZE ",
                "P2P_PRESENCE_REQ ",
                "P2P_EXT_LISTEN ",
+               "P2P_REMOVE_CLIENT ",
                NULL
        };
        int found = 0;
@@ -5989,6 +6035,102 @@ static char * wpas_global_ctrl_iface_redir(struct wpa_global *global,
 }
 
 
+static int wpas_global_ctrl_iface_set(struct wpa_global *global, char *cmd)
+{
+       char *value;
+
+       value = os_strchr(cmd, ' ');
+       if (value == NULL)
+               return -1;
+       *value++ = '\0';
+
+       wpa_printf(MSG_DEBUG, "GLOBAL_CTRL_IFACE SET '%s'='%s'", cmd, value);
+
+#ifdef CONFIG_WIFI_DISPLAY
+       if (os_strcasecmp(cmd, "wifi_display") == 0) {
+               wifi_display_enable(global, !!atoi(value));
+               return 0;
+       }
+#endif /* CONFIG_WIFI_DISPLAY */
+
+       return -1;
+}
+
+
+#ifndef CONFIG_NO_CONFIG_WRITE
+static int wpas_global_ctrl_iface_save_config(struct wpa_global *global)
+{
+       int ret = 0;
+       struct wpa_supplicant *wpa_s;
+
+       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+               if (!wpa_s->conf->update_config) {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed to update configuration (update_config=0)");
+                       continue;
+               }
+
+               if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to update configuration");
+                       ret = 1;
+               } else {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration updated");
+               }
+       }
+
+       return ret;
+}
+#endif /* CONFIG_NO_CONFIG_WRITE */
+
+
+static int wpas_global_ctrl_iface_status(struct wpa_global *global,
+                                        char *buf, size_t buflen)
+{
+       char *pos, *end;
+       int ret;
+       struct wpa_supplicant *wpa_s;
+
+       pos = buf;
+       end = buf + buflen;
+
+#ifdef CONFIG_P2P
+       if (global->p2p && !global->p2p_disabled) {
+               ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
+                                 "\n"
+                                 "p2p_state=%s\n",
+                                 MAC2STR(global->p2p_dev_addr),
+                                 p2p_get_state_txt(global->p2p));
+               if (ret < 0 || ret >= end - pos)
+                       return pos - buf;
+               pos += ret;
+       } else if (global->p2p) {
+               ret = os_snprintf(pos, end - pos, "p2p_state=DISABLED\n");
+               if (ret < 0 || ret >= end - pos)
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_P2P */
+
+#ifdef CONFIG_WIFI_DISPLAY
+       ret = os_snprintf(pos, end - pos, "wifi_display=%d\n",
+                         !!global->wifi_display);
+       if (ret < 0 || ret >= end - pos)
+               return pos - buf;
+       pos += ret;
+#endif /* CONFIG_WIFI_DISPLAY */
+
+       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+               ret = os_snprintf(pos, end - pos, "ifname=%s\n"
+                                 "address=" MACSTR "\n",
+                                 wpa_s->ifname, MAC2STR(wpa_s->own_addr));
+               if (ret < 0 || ret >= end - pos)
+                       return pos - buf;
+               pos += ret;
+       }
+
+       return pos - buf;
+}
+
+
 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
                                                char *buf, size_t *resp_len)
 {
@@ -6046,6 +6188,17 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
                wpas_notify_suspend(global);
        } else if (os_strcmp(buf, "RESUME") == 0) {
                wpas_notify_resume(global);
+       } else if (os_strncmp(buf, "SET ", 4) == 0) {
+               if (wpas_global_ctrl_iface_set(global, buf + 4))
+                       reply_len = -1;
+#ifndef CONFIG_NO_CONFIG_WRITE
+       } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
+               if (wpas_global_ctrl_iface_save_config(global))
+                       reply_len = -1;
+#endif /* CONFIG_NO_CONFIG_WRITE */
+       } else if (os_strcmp(buf, "STATUS") == 0) {
+               reply_len = wpas_global_ctrl_iface_status(global, reply,
+                                                         reply_size);
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;