static struct wpabuf * wifi_display_build_go_ie(struct p2p_group *group) { struct wpabuf *wfd_subelems, *wfd_ie; struct p2p_group_member *m; u8 *len; unsigned int count = 0; if (!group->p2p->wfd_ie_probe_resp) return NULL; wfd_subelems = wpabuf_alloc(wpabuf_len(group->p2p->wfd_ie_probe_resp) + group->num_members * 24 + 100); if (wfd_subelems == NULL) return NULL; if (group->p2p->wfd_dev_info) wpabuf_put_buf(wfd_subelems, group->p2p->wfd_dev_info); if (group->p2p->wfd_assoc_bssid) wpabuf_put_buf(wfd_subelems, group->p2p->wfd_assoc_bssid); if (group->p2p->wfd_coupled_sink_info) wpabuf_put_buf(wfd_subelems, group->p2p->wfd_coupled_sink_info); /* Build WFD Session Info */ wpabuf_put_u8(wfd_subelems, WFD_SUBELEM_SESSION_INFO); len = wpabuf_put(wfd_subelems, 2); m = group->members; while (m) { if (wifi_display_add_dev_info_descr(wfd_subelems, m)) count++; m = m->next; } if (count == 0) { /* No Wi-Fi Display clients - do not include subelement */ wfd_subelems->used -= 3; } else { WPA_PUT_BE16(len, (u8 *) wpabuf_put(wfd_subelems, 0) - len - 2); wpa_printf(MSG_DEBUG, "WFD: WFD Session Info: %u descriptors", count); } wfd_ie = wifi_display_encaps(wfd_subelems); wpabuf_free(wfd_subelems); return wfd_ie; }
static int wifi_display_update_wfd_ie(struct wpa_global *global) { struct wpabuf *ie, *buf; size_t len; wpa_printf(MSG_DEBUG, "WFD: Update WFD IE"); if (!global->wifi_display) { wpa_printf(MSG_DEBUG, "WFD: Wi-Fi Display disabled - do not " "include WFD IE"); p2p_set_wfd_ie_beacon(global->p2p, NULL); p2p_set_wfd_ie_probe_req(global->p2p, NULL); p2p_set_wfd_ie_probe_resp(global->p2p, NULL); p2p_set_wfd_ie_assoc_req(global->p2p, NULL); p2p_set_wfd_ie_invitation(global->p2p, NULL); p2p_set_wfd_ie_prov_disc(global->p2p, NULL); p2p_set_wfd_ie_go_neg(global->p2p, NULL); p2p_set_wfd_dev_info(global->p2p, NULL); p2p_set_wfd_assoc_bssid(global->p2p, NULL); p2p_set_wfd_coupled_sink_info(global->p2p, NULL); return 0; } p2p_set_wfd_dev_info(global->p2p, global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]); p2p_set_wfd_assoc_bssid( global->p2p, global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]); p2p_set_wfd_coupled_sink_info( global->p2p, global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]); /* * WFD IE is included in number of management frames. Two different * sets of subelements are included depending on the frame: * * Beacon, Probe Request, (Re)Association Request, GO Negotiation * Req/Resp/Conf: * WFD Device Info * [Associated BSSID] * [Coupled Sink Info] * * Probe Response, (Re)Association Response, P2P Invitation Req/Resp, * Provision Discovery Req/Resp: * same as above and also [WFD Session Info] */ len = 0; if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_DEVICE_INFO]); if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_ASSOCIATED_BSSID]); if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_COUPLED_SINK]); if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_SESSION_INFO]); buf = wpabuf_alloc(len); if (buf == NULL) return -1; if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]); if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]) wpabuf_put_buf(buf, global->wfd_subelem[ WFD_SUBELEM_ASSOCIATED_BSSID]); if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Beacon", ie); p2p_set_wfd_ie_beacon(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Request", ie); p2p_set_wfd_ie_probe_req(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for (Re)Association Request", ie); p2p_set_wfd_ie_assoc_req(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for GO Negotiation", ie); p2p_set_wfd_ie_go_neg(global->p2p, ie); if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Response", ie); p2p_set_wfd_ie_probe_resp(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for P2P Invitation", ie); p2p_set_wfd_ie_invitation(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Provision Discovery", ie); p2p_set_wfd_ie_prov_disc(global->p2p, ie); wpabuf_free(buf); return 0; }
static int wifi_display_update_wfd_ie(struct wpa_global *global) { struct wpabuf *ie, *buf; size_t len, plen; if (global->p2p == NULL) return 0; wpa_printf(MSG_DEBUG, "WFD: Update WFD IE"); if (!global->wifi_display) { wpa_printf(MSG_DEBUG, "WFD: Wi-Fi Display disabled - do not " "include WFD IE"); p2p_set_wfd_ie_beacon(global->p2p, NULL); p2p_set_wfd_ie_probe_req(global->p2p, NULL); p2p_set_wfd_ie_probe_resp(global->p2p, NULL); p2p_set_wfd_ie_assoc_req(global->p2p, NULL); p2p_set_wfd_ie_invitation(global->p2p, NULL); p2p_set_wfd_ie_prov_disc_req(global->p2p, NULL); p2p_set_wfd_ie_prov_disc_resp(global->p2p, NULL); p2p_set_wfd_ie_go_neg(global->p2p, NULL); p2p_set_wfd_dev_info(global->p2p, NULL); p2p_set_wfd_assoc_bssid(global->p2p, NULL); p2p_set_wfd_coupled_sink_info(global->p2p, NULL); return 0; } p2p_set_wfd_dev_info(global->p2p, global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]); p2p_set_wfd_assoc_bssid( global->p2p, global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]); p2p_set_wfd_coupled_sink_info( global->p2p, global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]); /* * WFD IE is included in number of management frames. Two different * sets of subelements are included depending on the frame: * * Beacon, (Re)Association Request, GO Negotiation Req/Resp/Conf, * Provision Discovery Req: * WFD Device Info * [Associated BSSID] * [Coupled Sink Info] * * Probe Request: * WFD Device Info * [Associated BSSID] * [Coupled Sink Info] * [WFD Extended Capability] * * Probe Response: * WFD Device Info * [Associated BSSID] * [Coupled Sink Info] * [WFD Extended Capability] * [WFD Session Info] * * (Re)Association Response, P2P Invitation Req/Resp, * Provision Discovery Resp: * WFD Device Info * [Associated BSSID] * [Coupled Sink Info] * [WFD Session Info] */ len = 0; if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_DEVICE_INFO]); if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_ASSOCIATED_BSSID]); if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_COUPLED_SINK]); if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]) len += wpabuf_len(global->wfd_subelem[ WFD_SUBELEM_SESSION_INFO]); if (global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]) len += wpabuf_len(global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]); buf = wpabuf_alloc(len); if (buf == NULL) return -1; if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]); if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]) wpabuf_put_buf(buf, global->wfd_subelem[ WFD_SUBELEM_ASSOCIATED_BSSID]); if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Beacon", ie); p2p_set_wfd_ie_beacon(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for (Re)Association Request", ie); p2p_set_wfd_ie_assoc_req(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for GO Negotiation", ie); p2p_set_wfd_ie_go_neg(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Provision Discovery " "Request", ie); p2p_set_wfd_ie_prov_disc_req(global->p2p, ie); plen = buf->used; if (global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Request", ie); p2p_set_wfd_ie_probe_req(global->p2p, ie); if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Response", ie); p2p_set_wfd_ie_probe_resp(global->p2p, ie); /* Remove WFD Extended Capability from buffer */ buf->used = plen; if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]) wpabuf_put_buf(buf, global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for P2P Invitation", ie); p2p_set_wfd_ie_invitation(global->p2p, ie); ie = wifi_display_encaps(buf); wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Provision Discovery " "Response", ie); p2p_set_wfd_ie_prov_disc_resp(global->p2p, ie); /* [ALPS00933997] [Need Patch] [Volunteer Patch] [Android 4.3 MR2 migration]wpa_supplicant_8 . wfd enhancement */ #ifdef CONFIG_MTK_P2P { const u8 *buf; P_WFD_ATTRI_HDR_T prWfdHdr; struct wfd_data_s *p_wfd_data_cmd; p_wfd_data_cmd = &global->wfd_data_cmd; p_wfd_data_cmd->WfdDevInfo = 0; p_wfd_data_cmd->WfdControlPort = 0; p_wfd_data_cmd->WfdMaximumTp = 0; p_wfd_data_cmd->WfdFlag &= ~WFD_FLAG_DEV_INFO_VALID; if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]) { P_WFD_ATTRI_WFD_DEV_INFO_T prWfdDevInfo = NULL; buf = wpabuf_head_u8(global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]); prWfdHdr = (P_WFD_ATTRI_HDR_T) buf; prWfdDevInfo = (P_WFD_ATTRI_WFD_DEV_INFO_T) (buf+WFD_ATTRI_HDR_LEN); wpa_printf(MSG_DEBUG, "wfd_id=%u len=%u " "wfd_info=0x%x " "wfd_ctrl_port=%u " "wfd_tp=%u\n", prWfdHdr->ucId, WPA_GET_BE16((u8 *)(&prWfdHdr->u2Length)), WPA_GET_BE16((u8 *)(&prWfdDevInfo->u2DevInfo)), WPA_GET_BE16((u8*)(&prWfdDevInfo->u2ControlPort)), WPA_GET_BE16((u8*)(&prWfdDevInfo->u2MaximumTp))); p_wfd_data_cmd->WfdDevInfo = WPA_GET_BE16((u8 *)(&prWfdDevInfo->u2DevInfo)); p_wfd_data_cmd->WfdControlPort = WPA_GET_BE16((u8*)(&prWfdDevInfo->u2ControlPort)); p_wfd_data_cmd->WfdMaximumTp = WPA_GET_BE16((u8*)(&prWfdDevInfo->u2MaximumTp)); p_wfd_data_cmd->WfdFlag |= WFD_FLAG_DEV_INFO_VALID; } if(global->p2p_init_wpa_s) { wpas_wfd_data_process(global->p2p_init_wpa_s, &global->wfd_data_cmd); wpa_drv_driver_cmd(global->p2p_init_wpa_s, "wfd_data_update", (char *)(&global->wfd_data), sizeof(struct wfd_data_s)); } } #endif /* CONFIG_MTK_P2P */ wpabuf_free(buf); return 0; }