static void p2ps_add_new_group_info(struct p2p_data *p2p, struct wpabuf *buf) { int found; u8 intended_addr[ETH_ALEN]; u8 ssid[SSID_MAX_LEN]; size_t ssid_len; int group_iface; if (!p2p->cfg->get_go_info) { return; } found = p2p->cfg->get_go_info(p2p->cfg->cb_ctx, intended_addr, ssid, &ssid_len, &group_iface); if (found) { p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, ssid, ssid_len); p2p_buf_add_intended_addr(buf, intended_addr); } else { if (!p2p->ssid_set) { p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len); p2p->ssid_set = 1; } /* Add pre-composed P2P Group ID */ p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid, p2p->ssid_len); if (group_iface) { p2p_buf_add_intended_addr(buf, p2p->intended_addr); } else { p2p_buf_add_intended_addr(buf, p2p->cfg->dev_addr); } } }
static void p2ps_add_new_group_info(struct p2p_data *p2p, struct p2p_device *dev, struct wpabuf *buf) { int found; u8 intended_addr[ETH_ALEN]; u8 ssid[SSID_MAX_LEN]; size_t ssid_len; int group_iface; unsigned int force_freq; if (!p2p->cfg->get_go_info) return; found = p2p->cfg->get_go_info( p2p->cfg->cb_ctx, intended_addr, ssid, &ssid_len, &group_iface, &force_freq); if (found) { if (force_freq > 0) { p2p->p2ps_prov->force_freq = force_freq; p2p->p2ps_prov->pref_freq = 0; if (dev) p2p_prepare_channel(p2p, dev, force_freq, 0, 0); } p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, ssid, ssid_len); if (group_iface) p2p_buf_add_intended_addr(buf, p2p->intended_addr); else p2p_buf_add_intended_addr(buf, intended_addr); } else { if (!p2p->ssid_set) { p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len); p2p->ssid_set = 1; } /* Add pre-composed P2P Group ID */ p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid, p2p->ssid_len); if (group_iface) p2p_buf_add_intended_addr( buf, p2p->intended_addr); else p2p_buf_add_intended_addr( buf, p2p->cfg->dev_addr); } }
static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, u8 dialog_token, u16 config_methods, struct p2p_device *go) { struct wpabuf *buf; u8 *len; buf = wpabuf_alloc(1000); if (buf == NULL) return NULL; p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); len = p2p_buf_add_ie_hdr(buf); p2p_buf_add_capability(buf, p2p->dev_capab, 0); p2p_buf_add_device_info(buf, p2p, NULL); if (go) { p2p_buf_add_group_id(buf, go->info.p2p_device_addr, go->oper_ssid, go->oper_ssid_len); } p2p_buf_update_ie_hdr(buf, len); /* WPS IE with Config Methods attribute */ p2p_build_wps_ie_config_methods(buf, config_methods); return buf; }
static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, u8 dialog_token, u16 config_methods, struct p2p_device *go) { struct wpabuf *buf; u8 *len; size_t extra = 0; #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_prov_disc_req) extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); len = p2p_buf_add_ie_hdr(buf); p2p_buf_add_capability(buf, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); p2p_buf_add_device_info(buf, p2p, NULL); if (go) { p2p_buf_add_group_id(buf, go->info.p2p_device_addr, go->oper_ssid, go->oper_ssid_len); } p2p_buf_update_ie_hdr(buf, len); /* WPS IE with Config Methods attribute */ p2p_build_wps_ie_config_methods(buf, config_methods); #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_prov_disc_req) wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); return buf; }
static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, struct p2p_device *peer, const u8 *go_dev_addr) { struct wpabuf *buf; u8 *len; const u8 *dev_addr; buf = wpabuf_alloc(1000); if (buf == NULL) return NULL; peer->dialog_token++; if (peer->dialog_token == 0) peer->dialog_token = 1; p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_REQ, peer->dialog_token); len = p2p_buf_add_ie_hdr(buf); if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent) p2p_buf_add_config_timeout(buf, 0, 0); else p2p_buf_add_config_timeout(buf, 100, 20); p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ? P2P_INVITATION_FLAGS_TYPE : 0); p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); if (p2p->inv_bssid_set) p2p_buf_add_group_bssid(buf, p2p->inv_bssid); p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); if (go_dev_addr) dev_addr = go_dev_addr; else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT) dev_addr = peer->info.p2p_device_addr; else dev_addr = p2p->cfg->dev_addr; p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len); p2p_buf_add_device_info(buf, p2p, peer); p2p_buf_update_ie_hdr(buf, len); return buf; }
static struct wpabuf * p2p_build_dev_disc_req(struct p2p_data *p2p, struct p2p_device *go, const u8 *dev_id) { struct wpabuf *buf; u8 *len; buf = wpabuf_alloc(100); if (buf == NULL) return NULL; go->dialog_token++; if (go->dialog_token == 0) go->dialog_token = 1; p2p_buf_add_public_action_hdr(buf, P2P_DEV_DISC_REQ, go->dialog_token); len = p2p_buf_add_ie_hdr(buf); p2p_buf_add_device_id(buf, dev_id); p2p_buf_add_group_id(buf, go->info.p2p_device_addr, go->oper_ssid, go->oper_ssid_len); p2p_buf_update_ie_hdr(buf, len); return buf; }
static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, int join) { struct wpabuf *buf; u8 *len; size_t extra = 0; u8 dialog_token = dev->dialog_token; u16 config_methods = dev->req_config_methods; struct p2p_device *go = join ? dev : NULL; u8 group_capab; #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_prov_disc_req) extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); if (p2p->p2ps_prov) extra += os_strlen(p2p->p2ps_prov->info) + 1 + sizeof(struct p2ps_provision); buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); len = p2p_buf_add_ie_hdr(buf); group_capab = 0; if (p2p->p2ps_prov) { group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP; group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN; if (p2p->cross_connect) group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; if (p2p->cfg->p2p_intra_bss) group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; } p2p_buf_add_capability(buf, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, group_capab); p2p_buf_add_device_info(buf, p2p, NULL); if (p2p->p2ps_prov) { p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods); } else if (go) { p2p_buf_add_group_id(buf, go->info.p2p_device_addr, go->oper_ssid, go->oper_ssid_len); } p2p_buf_update_ie_hdr(buf, len); /* WPS IE with Config Methods attribute */ p2p_build_wps_ie_config_methods(buf, config_methods); #ifdef CONFIG_WIFI_DISPLAY if (p2p->wfd_ie_prov_disc_req) wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); return buf; }
static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, struct p2p_device *peer, const u8 *go_dev_addr) { struct wpabuf *buf; u8 *len; const u8 *dev_addr; size_t extra = 0; #ifdef CONFIG_WIFI_DISPLAY struct wpabuf *wfd_ie = p2p->wfd_ie_invitation; if (wfd_ie && p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { size_t i; for (i = 0; i < p2p->num_groups; i++) { struct p2p_group *g = p2p->groups[i]; struct wpabuf *ie; ie = p2p_group_get_wfd_ie(g); if (ie) { wfd_ie = ie; break; } } } if (wfd_ie) extra = wpabuf_len(wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; peer->dialog_token++; if (peer->dialog_token == 0) peer->dialog_token = 1; p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_REQ, peer->dialog_token); len = p2p_buf_add_ie_hdr(buf); if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent) p2p_buf_add_config_timeout(buf, 0, 0); else p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ? P2P_INVITATION_FLAGS_TYPE : 0); p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); if (p2p->inv_bssid_set) p2p_buf_add_group_bssid(buf, p2p->inv_bssid); p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); if (go_dev_addr) dev_addr = go_dev_addr; else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT) dev_addr = peer->info.p2p_device_addr; else dev_addr = p2p->cfg->dev_addr; p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len); p2p_buf_add_device_info(buf, p2p, peer); p2p_buf_update_ie_hdr(buf, len); #ifdef CONFIG_WIFI_DISPLAY if (wfd_ie) wpabuf_put_buf(buf, wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ return buf; }
static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, struct p2p_device *peer, const u8 *go_dev_addr, int dev_pw_id) { struct wpabuf *buf; u8 *len; const u8 *dev_addr; size_t extra = 0; #ifdef CONFIG_WIFI_DISPLAY struct wpabuf *wfd_ie = p2p->wfd_ie_invitation; if (wfd_ie && p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { size_t i; for (i = 0; i < p2p->num_groups; i++) { struct p2p_group *g = p2p->groups[i]; struct wpabuf *ie; if (os_memcmp(p2p_group_get_interface_addr(g), p2p->inv_bssid, ETH_ALEN) != 0) continue; ie = p2p_group_get_wfd_ie(g); if (ie) { wfd_ie = ie; break; } } } if (wfd_ie) extra = wpabuf_len(wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]) extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]); buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; peer->dialog_token++; if (peer->dialog_token == 0) peer->dialog_token = 1; p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_REQ, peer->dialog_token); len = p2p_buf_add_ie_hdr(buf); if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent) p2p_buf_add_config_timeout(buf, 0, 0); else p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ? P2P_INVITATION_FLAGS_TYPE : 0); if (p2p->inv_role != P2P_INVITE_ROLE_CLIENT || !(peer->flags & P2P_DEV_NO_PREF_CHAN)) p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); if (p2p->inv_bssid_set) p2p_buf_add_group_bssid(buf, p2p->inv_bssid); p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); if (go_dev_addr) dev_addr = go_dev_addr; else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT) dev_addr = peer->info.p2p_device_addr; else dev_addr = p2p->cfg->dev_addr; p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len); p2p_buf_add_device_info(buf, p2p, peer); p2p_buf_update_ie_hdr(buf, len); p2p_buf_add_pref_channel_list(buf, p2p->pref_freq_list, p2p->num_pref_freq); #ifdef CONFIG_WIFI_DISPLAY if (wfd_ie) wpabuf_put_buf(buf, wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]) wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]); if (dev_pw_id >= 0) { /* WSC IE in Invitation Request for NFC static handover */ p2p_build_wps_ie(p2p, buf, dev_pw_id, 0); } return buf; }