Merge branch 'moonshot' of ssh://moonshot.suchdamage.org:822/srv/git/libeap into...
[libeap.git] / wpa_supplicant / ap.c
index f638186..ea57540 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "utils/common.h"
 #include "common/ieee802_11_defs.h"
+#include "common/wpa_ctrl.h"
 #include "ap/hostapd.h"
 #include "ap/ap_config.h"
 #ifdef NEED_AP_MLME
@@ -37,6 +38,7 @@
 #include "driver_i.h"
 #include "p2p_supplicant.h"
 #include "ap.h"
+#include "ap/sta_info.h"
 
 
 static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
@@ -160,14 +162,21 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
                bss->config_methods = os_strdup(wpa_s->conf->config_methods);
        if (wpa_s->conf->device_type)
                bss->device_type = os_strdup(wpa_s->conf->device_type);
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
        if (wpa_s->conf->device_name) {
                bss->device_name = os_strdup(wpa_s->conf->device_name);
                bss->friendly_name = os_strdup(wpa_s->conf->device_name);
        }
-#endif /* CONFIG_P2P */
+       if (wpa_s->conf->manufacturer)
+               bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
+       if (wpa_s->conf->model_name)
+               bss->model_name = os_strdup(wpa_s->conf->model_name);
+       if (wpa_s->conf->model_number)
+               bss->model_number = os_strdup(wpa_s->conf->model_number);
+       if (wpa_s->conf->serial_number)
+               bss->serial_number = os_strdup(wpa_s->conf->serial_number);
+       os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
+       os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
+#endif /* CONFIG_WPS */
 
        return 0;
 }
@@ -192,6 +201,26 @@ static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
 }
 
 
+static void ap_wps_event_cb(void *ctx, enum wps_event event,
+                           union wps_event_data *data)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       if (event == WPS_EV_FAIL && wpa_s->parent && wpa_s->parent != wpa_s) {
+               struct wps_event_fail *fail = &data->fail;
+
+               /*
+                * src/ap/wps_hostapd.c has already sent this on the main
+                * interface, so only send on the parent interface here if
+                * needed.
+                */
+               wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+                       "msg=%d config_error=%d",
+                       fail->msg, fail->config_error);
+       }
+}
+
+
 static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
 {
 #ifdef CONFIG_P2P
@@ -294,6 +323,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
        if (ssid->mode == WPAS_MODE_P2P_GO ||
            ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
                params.p2p = 1;
+       wpa_drv_set_intra_bss(wpa_s, wpa_s->conf->p2p_intra_bss);
 #endif /* CONFIG_P2P */
 
        if (wpa_s->parent->set_ap_uapsd)
@@ -357,6 +387,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
                                             ap_probe_req_rx, wpa_s);
                hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
                hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
+               hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
+               hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
 #ifdef CONFIG_P2P
                hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
                hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(
@@ -395,7 +427,8 @@ void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
 
        wpa_s->current_ssid = NULL;
 #ifdef CONFIG_P2P
-       wpa_s->ap_iface->bss[0]->p2p_group = NULL;
+       if (wpa_s->ap_iface->bss)
+               wpa_s->ap_iface->bss[0]->p2p_group = NULL;
        wpas_p2p_group_deinit(wpa_s);
 #endif /* CONFIG_P2P */
        hostapd_interface_deinit(wpa_s->ap_iface);
@@ -469,6 +502,51 @@ int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid)
 }
 
 
+static int wpa_supplicant_ap_wps_sta_cancel(struct hostapd_data *hapd,
+                                           struct sta_info *sta, void *ctx)
+{
+       if (sta && (sta->flags & WLAN_STA_WPS)) {
+               ap_sta_deauthenticate(hapd, sta,
+                                     WLAN_REASON_PREV_AUTH_NOT_VALID);
+               wpa_printf(MSG_DEBUG, "WPS: %s: Deauth sta=" MACSTR,
+                          __func__, MAC2STR(sta->addr));
+               return 1;
+       }
+
+       return 0;
+}
+
+
+int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
+{
+       struct wps_registrar *reg;
+       int reg_sel = 0, wps_sta = 0;
+
+       if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
+               return -1;
+
+       reg = wpa_s->ap_iface->bss[0]->wps->registrar;
+       reg_sel = wps_registrar_wps_cancel(reg);
+       wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
+                                 wpa_supplicant_ap_wps_sta_cancel, NULL);
+
+       if (!reg_sel && !wps_sta) {
+               wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
+                          "time");
+               return -1;
+       }
+
+       /*
+        * There are 2 cases to return wps cancel as success:
+        * 1. When wps cancel was initiated but no connection has been
+        *    established with client yet.
+        * 2. Client is in the middle of exchanging WPS messages.
+        */
+
+       return 0;
+}
+
+
 int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
                              const char *pin, char *buf, size_t buflen)
 {