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.
This commit is contained in:
parent
de979d8fc7
commit
3f4ce13fde
5 changed files with 40 additions and 34 deletions
|
@ -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);
|
||||
}
|
||||
#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,
|
||||
if (m->p2p_ie) {
|
||||
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;
|
||||
}
|
||||
|
||||
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…
Reference in a new issue