]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Track non-P2P members in the group and set Group Limit bit
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 19 Oct 2010 15:10:28 +0000 (18:10 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 19 Oct 2010 15:10:28 +0000 (18:10 +0300)
The P2P group component is now tracking of associated stations
in the group and the Group Limit bit in the Group Capabilities
is updated based on whether there is room for new clients in
the group.

src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/p2p/p2p.h
src/p2p/p2p_group.c
wpa_supplicant/p2p_supplicant.c

index a6c546ca942c3f6813c924dde0ab00548741a40f..8b354494e74c2fb9ed58094a5c3566b9e1adb67c 100644 (file)
@@ -183,10 +183,8 @@ skip_wpa_check:
        ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
 
 #ifdef CONFIG_P2P
-       if (elems.p2p) {
-               p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
-                                     all_ies, all_ies_len);
-       }
+       p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
+                             all_ies, all_ies_len);
 #endif /* CONFIG_P2P */
 
        return 0;
index c73a794595db2bea77cfdfa739dde9e0d877c1a2..241240fca5317e8e70d420856a9b5504de6a021b 100644 (file)
@@ -781,17 +781,12 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
                sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
                                                          P2P_IE_VENDOR_TYPE);
 
-               if (p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
-                                         ies, ies_len) < 0) {
-                       wpa_printf(MSG_DEBUG, "P2P: Invalid P2P IE in "
-                                  "(Re)Association Request frame from "
-                                  MACSTR, MAC2STR(sta->addr));
-                       return WLAN_STATUS_UNSPECIFIED_FAILURE;
-               }
        } else {
                wpabuf_free(sta->p2p_ie);
                sta->p2p_ie = NULL;
        }
+
+       p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
 #endif /* CONFIG_P2P */
 
        return WLAN_STATUS_SUCCESS;
index d425eb7518e1d8045cfe02fd268bd97bf7bb78e4..108af5d4b78531637b4d6895109707a83ea11cff 100644 (file)
@@ -1014,6 +1014,11 @@ struct p2p_group_config {
         */
        u8 interface_addr[ETH_ALEN];
 
+       /**
+        * max_clients - Maximum number of clients in the group
+        */
+       unsigned int max_clients;
+
        /**
         * cb_ctx - Context to use with callback functions
         */
index 4ee84cdedf051ae375801bb632fc36f4057ba43f..22a1ca73cb79e67a47cbd628ee8eb039965e876c 100644 (file)
@@ -39,6 +39,7 @@ struct p2p_group {
        struct p2p_data *p2p;
        struct p2p_group_config *cfg;
        struct p2p_group_member *members;
+       unsigned int num_members;
        int group_formation;
        int beacon_update;
        struct wpabuf *noa;
@@ -89,6 +90,7 @@ static void p2p_group_free_members(struct p2p_group *group)
        struct p2p_group_member *m, *prev;
        m = group->members;
        group->members = NULL;
+       group->num_members = 0;
        while (m) {
                prev = m;
                m = m->next;
@@ -127,6 +129,8 @@ void p2p_group_deinit(struct p2p_group *group)
 
 static void p2p_client_info(struct wpabuf *ie, struct p2p_group_member *m)
 {
+       if (m->client_info == NULL)
+               return;
        if (wpabuf_tailroom(ie) < wpabuf_len(m->client_info) + 1)
                return;
        wpabuf_put_buf(ie, m->client_info);
@@ -150,6 +154,8 @@ static void p2p_group_add_common_ies(struct p2p_group *group,
                group_capab |= P2P_GROUP_CAPAB_GROUP_FORMATION;
        if (group->p2p->cross_connect)
                group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
+       if (group->num_members >= group->cfg->max_clients)
+               group_capab |= P2P_GROUP_CAPAB_GROUP_LIMIT;
        p2p_buf_add_capability(ie, dev_capab, group_capab);
 }
 
@@ -316,31 +322,21 @@ int p2p_group_notif_assoc(struct p2p_group *group, const u8 *addr,
                return -1;
        os_memcpy(m->addr, addr, ETH_ALEN);
        m->p2p_ie = ieee802_11_vendor_ie_concat(ie, len, P2P_IE_VENDOR_TYPE);
-       if (m->p2p_ie == NULL) {
-               p2p_group_free_member(m);
-               return -1;
-       }
-
-       m->client_info = p2p_build_client_info(addr, m->p2p_ie, &m->dev_capab,
-                                              m->dev_addr);
-       if (m->client_info == NULL) {
-               /*
-                * This can happen, e.g., when a P2P client connects to a P2P
-                * group using the infrastructure WLAN interface instead of
-                * P2P group interface. In that case, the P2P client may behave
-                * as if the GO would be a P2P Manager WLAN AP.
-                */
-               wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG,
-                       "P2P: Could not build Client Info from P2P IE - "
-                       "assume " MACSTR " is not a P2P client",
-                       MAC2STR(addr));
-               p2p_group_free_member(m);
-               return 0;
+       if (m->p2p_ie) {
+               m->client_info = p2p_build_client_info(addr, m->p2p_ie,
+                                                      &m->dev_capab,
+                                                      m->dev_addr);
        }
 
        m->next = group->members;
        group->members = m;
-
+       group->num_members++;
+       wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Add client " MACSTR
+               " to group (p2p=%d client_info=%d); num_members=%u/%u",
+               MAC2STR(addr), m->p2p_ie ? 1 : 0, m->client_info ? 1 : 0,
+               group->num_members, group->cfg->max_clients);
+       if (group->num_members == group->cfg->max_clients)
+               group->beacon_update = 1;
        p2p_group_update_ies(group);
 
        return 0;
@@ -392,6 +388,13 @@ void p2p_group_notif_disassoc(struct p2p_group *group, const u8 *addr)
                else
                        group->members = m->next;
                p2p_group_free_member(m);
+               group->num_members--;
+               wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Remove "
+                       "client " MACSTR " from group; num_members=%u/%u",
+                       MAC2STR(addr), group->num_members,
+                       group->cfg->max_clients);
+               if (group->num_members == group->cfg->max_clients - 1)
+                       group->beacon_update = 1;
                p2p_group_update_ies(group);
        }
 }
@@ -558,7 +561,7 @@ int p2p_group_go_discover(struct p2p_group *group, const u8 *dev_id,
        int freq;
 
        m = p2p_group_get_client(group, dev_id);
-       if (m == NULL) {
+       if (m == NULL || m->client_info == NULL) {
                wpa_printf(MSG_DEBUG, "P2P: Requested client was not in this "
                           "group " MACSTR,
                           MAC2STR(group->cfg->interface_addr));
@@ -612,7 +615,7 @@ u8 p2p_group_presence_req(struct p2p_group *group,
        int curr_noa_len;
 
        m = p2p_group_get_client_iface(group, client_interface_addr);
-       if (m == NULL) {
+       if (m == NULL || m->client_info == NULL) {
                wpa_printf(MSG_DEBUG, "P2P: Client was not in this group");
                return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
        }
index 950e5169024f3e79594fe5a6046d56a2c5932527..ab298f2b0be847db19805833b97185ffb7c81da6 100644 (file)
@@ -3014,6 +3014,11 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
 
        cfg->persistent_group = persistent_group;
        os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
+       if (wpa_s->max_stations &&
+           wpa_s->max_stations < wpa_s->conf->max_num_sta)
+               cfg->max_clients = wpa_s->max_stations;
+       else
+               cfg->max_clients = wpa_s->conf->max_num_sta;
        cfg->cb_ctx = wpa_s;
        cfg->ie_update = wpas_p2p_ie_update;