FST: Integration into wpa_supplicant
authorAnton Nayshtut <qca_antonn@qca.qualcomm.com>
Sun, 16 Nov 2014 15:28:53 +0000 (17:28 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 16 Jul 2015 15:26:15 +0000 (18:26 +0300)
This commit integrates the FST into the wpa_supplicant.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wpa_supplicant/events.c
wpa_supplicant/main.c
wpa_supplicant/notify.c
wpa_supplicant/scan.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index aa171ef..92abb25 100644 (file)
@@ -2000,6 +2000,19 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
        if (wpa_found || rsn_found)
                wpa_s->ap_ies_from_associnfo = 1;
 
+#ifdef CONFIG_FST
+       wpabuf_free(wpa_s->received_mb_ies);
+       wpa_s->received_mb_ies = NULL;
+       if (wpa_s->fst) {
+               struct mb_ies_info mb_ies;
+
+               wpa_printf(MSG_DEBUG, "Looking for MB IE");
+               if (!mb_ies_info_by_ies(&mb_ies, data->assoc_info.resp_ies,
+                                       data->assoc_info.resp_ies_len))
+                       wpa_s->received_mb_ies = mb_ies_by_info(&mb_ies);
+       }
+#endif /* CONFIG_FST */
+
        if (wpa_s->assoc_freq && data->assoc_info.freq &&
            wpa_s->assoc_freq != data->assoc_info.freq) {
                wpa_printf(MSG_DEBUG, "Operating frequency changed from "
index 1c93306..d5d47e1 100644 (file)
@@ -12,6 +12,7 @@
 #endif /* __linux__ */
 
 #include "common.h"
+#include "fst/fst.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "p2p_supplicant.h"
@@ -309,6 +310,17 @@ int main(int argc, char *argv[])
                           "wpa_supplicant");
        }
 
+       if (fst_global_init()) {
+               wpa_printf(MSG_ERROR, "Failed to initialize FST");
+               exitcode = -1;
+               goto out;
+       }
+
+#if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE)
+       if (!fst_global_add_ctrl(fst_ctrl_cli))
+               wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl");
+#endif
+
        for (i = 0; exitcode == 0 && i < iface_count; i++) {
                struct wpa_supplicant *wpa_s;
 
@@ -334,6 +346,8 @@ int main(int argc, char *argv[])
 
        wpa_supplicant_deinit(global);
 
+       fst_global_deinit();
+
 out:
        wpa_supplicant_fd_workaround(0);
        os_free(ifaces);
index 822db74..aa8c214 100644 (file)
@@ -17,6 +17,7 @@
 #include "dbus/dbus_old.h"
 #include "dbus/dbus_new.h"
 #include "rsn_supp/wpa.h"
+#include "fst/fst.h"
 #include "driver_i.h"
 #include "scan.h"
 #include "p2p_supplicant.h"
@@ -88,6 +89,16 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
        /* notify the new DBus API */
        wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
 
+#ifdef CONFIG_FST
+       if (wpa_s->fst && !is_zero_ether_addr(wpa_s->bssid)) {
+               if (new_state == WPA_COMPLETED)
+                       fst_notify_peer_connected(wpa_s->fst, wpa_s->bssid);
+               else if (old_state >= WPA_ASSOCIATED &&
+                        new_state < WPA_ASSOCIATED)
+                       fst_notify_peer_disconnected(wpa_s->fst, wpa_s->bssid);
+       }
+#endif /* CONFIG_FST */
+
        if (new_state == WPA_COMPLETED)
                wpas_p2p_notif_connected(wpa_s);
        else if (old_state >= WPA_ASSOCIATED && new_state < WPA_ASSOCIATED)
index 70cfa36..8d0d1a5 100644 (file)
@@ -485,6 +485,12 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
                wpas_hs20_add_indication(extra_ie, -1);
 #endif /* CONFIG_HS20 */
 
+#ifdef CONFIG_FST
+       if (wpa_s->fst_ies &&
+           wpabuf_resize(&extra_ie, wpabuf_len(wpa_s->fst_ies)) == 0)
+               wpabuf_put_buf(extra_ie, wpa_s->fst_ies);
+#endif /* CONFIG_FST */
+
        return extra_ie;
 }
 
index a472feb..d945db7 100644 (file)
@@ -438,6 +438,21 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_HS20 */
 
+#ifdef CONFIG_FST
+       if (wpa_s->fst_ies) {
+               int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
+
+               if (wpa_s->sme.assoc_req_ie_len + fst_ies_len <=
+                   sizeof(wpa_s->sme.assoc_req_ie)) {
+                       os_memcpy(wpa_s->sme.assoc_req_ie +
+                                 wpa_s->sme.assoc_req_ie_len,
+                                 wpabuf_head(wpa_s->fst_ies),
+                                 fst_ies_len);
+                       wpa_s->sme.assoc_req_ie_len += fst_ies_len;
+               }
+       }
+#endif /* CONFIG_FST */
+
        ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
                                             sizeof(ext_capab));
        if (ext_capab_len > 0) {
index 8fba938..d6b9642 100644 (file)
@@ -35,6 +35,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/hw_features_common.h"
 #include "p2p/p2p.h"
+#include "fst/fst.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
@@ -2188,6 +2189,18 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
                }
        }
 
+#ifdef CONFIG_FST
+       if (wpa_s->fst_ies) {
+               int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
+
+               if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
+                       os_memcpy(wpa_ie + wpa_ie_len,
+                                 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
+                       wpa_ie_len += fst_ies_len;
+               }
+       }
+#endif /* CONFIG_FST */
+
        wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
        use_crypt = 1;
        cipher_pairwise = wpa_s->pairwise_cipher;
@@ -3700,6 +3713,123 @@ int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
 }
 
 
+#ifdef CONFIG_FST
+
+static const u8 * wpas_fst_get_bssid_cb(void *ctx)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       return (is_zero_ether_addr(wpa_s->bssid) ||
+               wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
+}
+
+
+static void wpas_fst_get_channel_info_cb(void *ctx,
+                                        enum hostapd_hw_mode *hw_mode,
+                                        u8 *channel)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       if (wpa_s->current_bss) {
+               *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
+                                                 channel);
+       } else if (wpa_s->hw.num_modes) {
+               *hw_mode = wpa_s->hw.modes[0].mode;
+       } else {
+               WPA_ASSERT(0);
+               *hw_mode = 0;
+       }
+}
+
+
+static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       *modes = wpa_s->hw.modes;
+       return wpa_s->hw.num_modes;
+}
+
+
+static void wpas_fst_set_ies_cb(void *ctx, struct wpabuf *fst_ies)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       wpa_s->fst_ies = fst_ies;
+}
+
+
+static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
+       return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+                                         wpa_s->own_addr, wpa_s->bssid,
+                                         wpabuf_head(data), wpabuf_len(data),
+                                  0);
+}
+
+
+static struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
+       return wpa_s->received_mb_ies;
+}
+
+
+static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
+                                    const u8 *buf, size_t size)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+       struct mb_ies_info info;
+
+       WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
+
+       if (!mb_ies_info_by_ies(&info, buf, size)) {
+               wpabuf_free(wpa_s->received_mb_ies);
+               wpa_s->received_mb_ies = mb_ies_by_info(&info);
+       }
+}
+
+
+const u8 * wpas_fst_get_peer_first(void *ctx, struct fst_get_peer_ctx **get_ctx,
+                                  Boolean mb_only)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       *get_ctx = NULL;
+       if (!is_zero_ether_addr(wpa_s->bssid))
+               return (wpa_s->received_mb_ies || !mb_only) ?
+                       wpa_s->bssid : NULL;
+       return NULL;
+}
+
+
+const u8 * wpas_fst_get_peer_next(void *ctx, struct fst_get_peer_ctx **get_ctx,
+                                 Boolean mb_only)
+{
+       return NULL;
+}
+
+void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
+                                      struct fst_wpa_obj *iface_obj)
+{
+       iface_obj->ctx              = wpa_s;
+       iface_obj->get_bssid        = wpas_fst_get_bssid_cb;
+       iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
+       iface_obj->get_hw_modes     = wpas_fst_get_hw_modes;
+       iface_obj->set_ies          = wpas_fst_set_ies_cb;
+       iface_obj->send_action      = wpas_fst_send_action_cb;
+       iface_obj->get_mb_ie        = wpas_fst_get_mb_ie_cb;
+       iface_obj->update_mb_ie     = wpas_fst_update_mb_ie_cb;
+       iface_obj->get_peer_first   = wpas_fst_get_peer_first;
+       iface_obj->get_peer_next    = wpas_fst_get_peer_next;
+}
+#endif /* CONFIG_FST */
+
 static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
                                    const struct wpa_driver_capa *capa)
 {
@@ -4238,6 +4368,28 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
+#ifdef CONFIG_FST
+       if (wpa_s->conf->fst_group_id) {
+               struct fst_iface_cfg cfg;
+               struct fst_wpa_obj iface_obj;
+
+               fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
+               os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
+                          sizeof(cfg.group_id));
+               cfg.priority = wpa_s->conf->fst_priority;
+               cfg.llt = wpa_s->conf->fst_llt;
+
+               wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
+                                       &iface_obj, &cfg);
+               if (!wpa_s->fst) {
+                       wpa_msg(wpa_s, MSG_ERROR,
+                               "FST: Cannot attach iface %s to group %s",
+                               wpa_s->ifname, cfg.group_id);
+                       return -1;
+               }
+       }
+#endif /* CONFIG_FST */
+
        if (wpas_wps_init(wpa_s))
                return -1;
 
@@ -4346,6 +4498,17 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
        wpas_ctrl_radio_work_flush(wpa_s);
        radio_remove_interface(wpa_s);
 
+#ifdef CONFIG_FST
+       if (wpa_s->fst) {
+               fst_detach(wpa_s->fst);
+               wpa_s->fst = NULL;
+       }
+       if (wpa_s->received_mb_ies) {
+               wpabuf_free(wpa_s->received_mb_ies);
+               wpa_s->received_mb_ies = NULL;
+       }
+#endif /* CONFIG_FST */
+
        if (wpa_s->drv_priv)
                wpa_drv_deinit(wpa_s);
 
index dd5b245..1338e17 100644 (file)
@@ -977,6 +977,12 @@ struct wpa_supplicant {
        u8 last_tspecs_count;
 
        struct rrm_data rrm;
+
+#ifdef CONFIG_FST
+       struct fst_iface *fst;
+       struct wpabuf *fst_ies;
+       struct wpabuf *received_mb_ies;
+#endif /* CONFIG_FST */
 };
 
 
@@ -1149,4 +1155,14 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
                           int *freq_array, unsigned int len);
 
 void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
+
+#ifdef CONFIG_FST
+
+struct fst_wpa_obj;
+
+void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
+                                      struct fst_wpa_obj *iface_obj);
+
+#endif /* CONFIG_FST */
+
 #endif /* WPA_SUPPLICANT_I_H */