]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Override P2P_PEER group_capab with 0 if no matching BSS entry found
authorSunil Dutt <usdutt@qti.qualcomm.com>
Tue, 31 Jan 2017 18:57:06 +0000 (00:27 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 6 Feb 2017 10:17:12 +0000 (12:17 +0200)
Relying on the group_capab from the P2P peer information can result in
improper information on whether the peer is currently operating as a GO.
However, there is a known implementation in Android that does this.

To reduce issues from this misuse in upper layer to try to determine
whether a specific peer is operationg a group, override the group_capab
value in P2P_PEER output with 0 if there are no BSS entries with the
peer P2P Device as a GO. This is not a perfect information since there
may not have been a recent scan on all channels, but this results in
less issues than trying to decide between new group formation and
joining an existing group based on stale or incorrect information.

Since no upper layer application is really supposed to use the
group_capab field value in P2P_PEER command, this change should not
cause any impact for properly design components and the possibility of
regressions is limited to cases that are already known to work
incorrectly in number of identifiable cases.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wpa_supplicant/ctrl_iface.c

index e83df721d2a36eb4669501a891b0c8553d3505d5..fc5955bc1a7f392c66b5445e4a4dc27b13992d36 100644 (file)
@@ -6038,10 +6038,24 @@ static int p2p_ctrl_group_member(struct wpa_supplicant *wpa_s, const char *cmd,
 }
 
 
+static int wpas_find_p2p_dev_addr_bss(struct wpa_global *global,
+                                     const u8 *p2p_dev_addr)
+{
+       struct wpa_supplicant *wpa_s;
+
+       for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+               if (wpa_bss_get_p2p_dev_addr(wpa_s, p2p_dev_addr))
+                       return 1;
+       }
+
+       return 0;
+}
+
+
 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
                         char *buf, size_t buflen)
 {
-       u8 addr[ETH_ALEN], *addr_ptr;
+       u8 addr[ETH_ALEN], *addr_ptr, group_capab;
        int next, res;
        const struct p2p_peer_info *info;
        char *pos, *end;
@@ -6070,6 +6084,16 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
        info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
        if (info == NULL)
                return -1;
+       group_capab = info->group_capab;
+
+       if (group_capab &&
+           !wpas_find_p2p_dev_addr_bss(wpa_s->global, info->p2p_device_addr)) {
+               wpa_printf(MSG_DEBUG,
+                          "P2P: Could not find any BSS with p2p_dev_addr "
+                          MACSTR ", hence override group_capab from 0x%x to 0",
+                          MAC2STR(info->p2p_device_addr), group_capab);
+               group_capab = 0;
+       }
 
        pos = buf;
        end = buf + buflen;
@@ -6095,7 +6119,7 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
                          info->serial_number,
                          info->config_methods,
                          info->dev_capab,
-                         info->group_capab,
+                         group_capab,
                          info->level);
        if (os_snprintf_error(end - pos, res))
                return pos - buf;