]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Allow Android P2P functionality
authorJohannes Berg <johannes.berg@intel.com>
Tue, 25 Jun 2013 10:38:03 +0000 (13:38 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 25 Jun 2013 10:38:03 +0000 (13:38 +0300)
To support Android the kernel may have a "p2p0" netdev for a P2P Device
even though this isn't very useful, but Android requires a netdev. To
support this in the supplicant, if the interface mode is P2P_DEVICE,
re-set it to the same instead of STATION mode.

Note that this is only possible with a kernel that creates a
netdev for the P2P Device wdev.

Signed-hostap: Johannes Berg <johannes.berg@intel.com>

src/drivers/driver_nl80211.c

index a9a9c4aac018dc2e453a0964893030326081afa3..b85f36b4f61839becf12b8be7ebe4d572e72049c 100644 (file)
@@ -668,6 +668,7 @@ static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
 
 struct wiphy_idx_data {
        int wiphy_idx;
+       enum nl80211_iftype nlmode;
 };
 
 
@@ -683,6 +684,9 @@ static int netdev_info_handler(struct nl_msg *msg, void *arg)
        if (tb[NL80211_ATTR_WIPHY])
                info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
 
+       if (tb[NL80211_ATTR_IFTYPE])
+               info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
+
        return NL_SKIP;
 }
 
@@ -711,6 +715,32 @@ nla_put_failure:
 }
 
 
+#ifndef HOSTAPD
+static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
+{
+       struct nl_msg *msg;
+       struct wiphy_idx_data data = {
+               .wiphy_idx = -1,
+       };
+
+       msg = nlmsg_alloc();
+       if (!msg)
+               return -1;
+
+       nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
+
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
+
+       if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
+               return data.nlmode;
+       msg = NULL;
+nla_put_failure:
+       nlmsg_free(msg);
+       return NL80211_IFTYPE_UNSPECIFIED;
+}
+#endif /* HOSTAPD */
+
+
 static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
                                    struct nl80211_wiphy_data *w)
 {
@@ -3890,11 +3920,22 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
         * dynamically added interface (e.g., P2P) that was already configured
         * with proper iftype.
         */
-       if (drv->ifindex != drv->global->if_add_ifindex &&
-           wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION) < 0) {
-               wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to "
-                          "use managed mode");
-               return -1;
+       if (drv->ifindex != drv->global->if_add_ifindex) {
+               enum nl80211_iftype nlmode;
+
+               nlmode = nl80211_get_ifmode(bss);
+               if (nlmode != NL80211_IFTYPE_P2P_DEVICE)
+                       nlmode = NL80211_IFTYPE_STATION;
+
+               if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
+                       wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to use %s mode",
+                                  nlmode == NL80211_IFTYPE_STATION ?
+                                  "managed" : "P2P-Device");
+                       return -1;
+               }
+
+               /* Always use managed mode internally, even for P2P Device */
+               drv->nlmode = NL80211_IFTYPE_STATION;
        }
 
        if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {