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;
struct p2p_group_member *m, *prev;
m = group->members;
group->members = NULL;
+ group->num_members = 0;
while (m) {
prev = m;
m = m->next;
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);
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);
}
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;
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);
}
}
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));
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;
}