P2P: Track non-P2P members in the group and set Group Limit bit

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.
master
Jouni Malinen 14 years ago committed by Jouni Malinen
parent de979d8fc7
commit 3f4ce13fde

@ -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;

@ -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;

@ -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
*/

@ -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;
}

@ -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;

Loading…
Cancel
Save