New driver capability info: max number of scan SSIDs
authorJouni Malinen <jouni.malinen@atheros.com>
Thu, 12 Feb 2009 19:49:57 +0000 (21:49 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 12 Feb 2009 20:05:32 +0000 (22:05 +0200)
The driver wrappers can now inform wpa_supplicant how many SSIDs can
be used in a single scan request (i.e., send multiple Probe Requests
per channel). This value is not yet used, but it can eventually be used
to allow a new scan command to specify multiple SSIDs to speed up
scan_ssid=1 operations. In addition, a warning could be printed if
scan_ssid=1 is used with a driver that does not support it
(max_scan_ssids=0).

src/drivers/driver.h
src/drivers/driver_nl80211.c
src/drivers/driver_test.c
src/drivers/driver_wext.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index d3bda18..5927e49 100644 (file)
@@ -322,6 +322,8 @@ struct wpa_driver_capa {
  * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
 #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008
        unsigned int flags;
+
+       int max_scan_ssids;
 };
 
 
index 35de073..cc8fdb7 100644 (file)
@@ -1402,6 +1402,62 @@ static int wpa_driver_nl80211_create_monitor_interface(
 #endif /* CONFIG_CLIENT_MLME */
 
 
+struct wiphy_info_data {
+       int max_scan_ssids;
+};
+
+
+static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+{
+       struct nlattr *tb[NL80211_ATTR_MAX + 1];
+       struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+       struct wiphy_info_data *info = arg;
+
+       nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+                 genlmsg_attrlen(gnlh, 0), NULL);
+
+       if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
+               info->max_scan_ssids =
+                       nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
+
+       return NL_SKIP;
+}
+
+
+static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
+                                      struct wiphy_info_data *info)
+{
+       struct nl_msg *msg;
+
+       os_memset(info, 0, sizeof(*info));
+       msg = nlmsg_alloc();
+       if (!msg)
+               return -1;
+
+       genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+                   0, NL80211_CMD_GET_WIPHY, 0);
+
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+
+       if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
+               return 0;
+       msg = NULL;
+nla_put_failure:
+       nlmsg_free(msg);
+       return -1;
+}
+
+
+static void wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
+{
+       struct wiphy_info_data info;
+       if (wpa_driver_nl80211_get_info(drv, &info))
+               return;
+       drv->has_capability = 1;
+       drv->capa.max_scan_ssids = info.max_scan_ssids;
+}
+
+
 /**
  * wpa_driver_nl80211_init - Initialize nl80211 driver interface
  * @ctx: context to be used when calling wpa_supplicant functions,
@@ -1550,6 +1606,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 
        drv->ifindex = if_nametoindex(drv->ifname);
 
+       wpa_driver_nl80211_capa(drv);
+
        wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
 }
 
index 49b2160..f0d3b43 100644 (file)
@@ -1016,6 +1016,7 @@ static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
                WPA_DRIVER_AUTH_LEAP;
        if (drv->use_mlme)
                capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
+       capa->max_scan_ssids = 10;
 
        return 0;
 }
index 8c2daa8..bc2137b 100644 (file)
@@ -1608,6 +1608,7 @@ static int wpa_driver_wext_get_range(void *priv)
                        drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
                if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
                        drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+               drv->capa.max_scan_ssids = 1;
 
                wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
                           "flags 0x%x",
index 56b4fd5..6eb0eec 100644 (file)
@@ -1898,6 +1898,7 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s)
                }
                if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
                        wpa_s->driver_4way_handshake = 1;
+               wpa_s->max_scan_ssids = capa.max_scan_ssids;
        }
 
 #ifdef CONFIG_IBSS_RSN
index b49f23a..1af64d2 100644 (file)
@@ -351,6 +351,7 @@ struct wpa_supplicant {
        struct wpa_client_mlme mlme;
        int use_client_mlme;
        int driver_4way_handshake;
+       int max_scan_ssids;
 
        int pending_mic_error_report;
        int pending_mic_error_pairwise;