[RFC] nl80211: allow Android P2P functionality
Johannes Berg
johannes
Tue Apr 23 05:47:43 PDT 2013
From: Johannes Berg <johannes.berg at intel.com>
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.
Change-Id: Ia558cf847e0753b9c77056deee3acc618a63755f
Signed-hostap: Johannes Berg <johannes.berg at intel.com>
---
src/drivers/driver_nl80211.c | 50 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3b0dba4..7b14219 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -537,6 +537,7 @@ static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
struct wiphy_idx_data {
int wiphy_idx;
+ enum nl80211_iftype nlmode;
};
@@ -552,6 +553,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;
}
@@ -580,6 +584,30 @@ nla_put_failure:
}
+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;
+}
+
+
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
struct nl80211_wiphy_data *w)
{
@@ -3623,11 +3651,23 @@ 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)) {
--
1.8.0
More information about the Hostap
mailing list