Lines Matching +full:switch +full:- +full:freq +full:- +full:select
2 * Wi-Fi Direct - P2P provision discovery
3 * Copyright (c) 2009-2010, Atheros Communications
54 if (!p2p->cfg->get_go_info) in p2ps_add_new_group_info()
57 found = p2p->cfg->get_go_info( in p2ps_add_new_group_info()
58 p2p->cfg->cb_ctx, intended_addr, ssid, in p2ps_add_new_group_info()
62 p2p->p2ps_prov->force_freq = force_freq; in p2ps_add_new_group_info()
63 p2p->p2ps_prov->pref_freq = 0; in p2ps_add_new_group_info()
68 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, in p2ps_add_new_group_info()
72 p2p_buf_add_intended_addr(buf, p2p->intended_addr); in p2ps_add_new_group_info()
76 if (!p2p->ssid_set) { in p2ps_add_new_group_info()
77 p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len); in p2ps_add_new_group_info()
78 p2p->ssid_set = 1; in p2ps_add_new_group_info()
81 /* Add pre-composed P2P Group ID */ in p2ps_add_new_group_info()
82 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, in p2ps_add_new_group_info()
83 p2p->ssid, p2p->ssid_len); in p2ps_add_new_group_info()
87 buf, p2p->intended_addr); in p2ps_add_new_group_info()
90 buf, p2p->cfg->dev_addr); in p2ps_add_new_group_info()
98 struct p2ps_provision *prov = p2p->p2ps_prov; in p2ps_add_pd_req_attrs()
99 struct p2ps_feature_capab fcap = { prov->cpt_mask, 0 }; in p2ps_add_pd_req_attrs()
105 int follow_on_req_fail = prov->status >= 0 && in p2ps_add_pd_req_attrs()
106 prov->status != P2P_SC_SUCCESS_DEFERRED; in p2ps_add_pd_req_attrs()
110 (prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW))) in p2ps_add_pd_req_attrs()
113 if (prov->status >= 0) in p2ps_add_pd_req_attrs()
114 p2p_buf_add_status(buf, (u8) prov->status); in p2ps_add_pd_req_attrs()
116 prov->method = config_methods; in p2ps_add_pd_req_attrs()
119 if (p2p->cfg->get_persistent_group) { in p2ps_add_pd_req_attrs()
120 shared_group = p2p->cfg->get_persistent_group( in p2ps_add_pd_req_attrs()
121 p2p->cfg->cb_ctx, dev->info.p2p_device_addr, in p2ps_add_pd_req_attrs()
127 (prov->conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_NEW))) { in p2ps_add_pd_req_attrs()
132 p2p, dev->info.p2p_device_addr); in p2ps_add_pd_req_attrs()
133 p2p_buf_add_channel_list(buf, p2p->cfg->country, in p2ps_add_pd_req_attrs()
134 &p2p->channels, is_6ghz_capab); in p2ps_add_pd_req_attrs()
138 (prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW))) in p2ps_add_pd_req_attrs()
139 p2p_buf_add_operating_channel(buf, p2p->cfg->country, in p2ps_add_pd_req_attrs()
140 p2p->op_reg_class, in p2ps_add_pd_req_attrs()
141 p2p->op_channel); in p2ps_add_pd_req_attrs()
144 if (prov->status < 0 && prov->info[0]) in p2ps_add_pd_req_attrs()
145 p2p_buf_add_session_info(buf, prov->info); in p2ps_add_pd_req_attrs()
148 p2p_buf_add_connection_capability(buf, prov->conncap); in p2ps_add_pd_req_attrs()
150 p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac); in p2ps_add_pd_req_attrs()
153 if (shared_group || prov->conncap == P2PS_SETUP_NEW || in p2ps_add_pd_req_attrs()
154 prov->conncap == in p2ps_add_pd_req_attrs()
156 prov->conncap == in p2ps_add_pd_req_attrs()
159 p2p_buf_add_config_timeout(buf, p2p->go_timeout, in p2ps_add_pd_req_attrs()
160 p2p->client_timeout); in p2ps_add_pd_req_attrs()
163 p2p_buf_add_listen_channel(buf, p2p->cfg->country, in p2ps_add_pd_req_attrs()
164 p2p->cfg->reg_class, in p2ps_add_pd_req_attrs()
165 p2p->cfg->channel); in p2ps_add_pd_req_attrs()
168 p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac); in p2ps_add_pd_req_attrs()
176 if ((prov->conncap == P2PS_SETUP_NONE || in p2ps_add_pd_req_attrs()
177 prov->conncap == P2PS_SETUP_CLIENT) && in p2ps_add_pd_req_attrs()
191 u8 dialog_token = dev->dialog_token; in p2p_build_prov_disc_req()
192 u16 config_methods = dev->req_config_methods; in p2p_build_prov_disc_req()
197 if (p2p->wfd_ie_prov_disc_req) in p2p_build_prov_disc_req()
198 extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); in p2p_build_prov_disc_req()
201 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) in p2p_build_prov_disc_req()
202 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); in p2p_build_prov_disc_req()
204 if (p2p->p2ps_prov) in p2p_build_prov_disc_req()
205 extra += os_strlen(p2p->p2ps_prov->info) + 1 + in p2p_build_prov_disc_req()
217 if (p2p->p2ps_prov) { in p2p_build_prov_disc_req()
220 if (p2p->cross_connect) in p2p_build_prov_disc_req()
222 if (p2p->cfg->p2p_intra_bss) in p2p_build_prov_disc_req()
225 p2p_buf_add_capability(buf, p2p->dev_capab & in p2p_build_prov_disc_req()
229 if (p2p->p2ps_prov) { in p2p_build_prov_disc_req()
232 p2p_buf_add_group_id(buf, go->info.p2p_device_addr, in p2p_build_prov_disc_req()
233 go->oper_ssid, go->oper_ssid_len); in p2p_build_prov_disc_req()
241 if (p2p->wfd_ie_prov_disc_req) in p2p_build_prov_disc_req()
242 wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); in p2p_build_prov_disc_req()
245 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) in p2p_build_prov_disc_req()
246 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); in p2p_build_prov_disc_req()
270 struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp; in p2p_build_prov_disc_resp()
273 for (i = 0; i < p2p->num_groups; i++) { in p2p_build_prov_disc_resp()
274 struct p2p_group *g = p2p->groups[i]; in p2p_build_prov_disc_resp()
290 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) in p2p_build_prov_disc_resp()
291 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); in p2p_build_prov_disc_resp()
300 if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) { in p2p_build_prov_disc_resp()
302 struct p2ps_provision *prov = p2p->p2ps_prov; in p2p_build_prov_disc_resp()
308 conncap = prov->conncap; in p2p_build_prov_disc_resp()
310 if (!status && prov->status != -1) in p2p_build_prov_disc_resp()
311 status = prov->status; in p2p_build_prov_disc_resp()
316 if (p2p->cross_connect) in p2p_build_prov_disc_resp()
318 if (p2p->cfg->p2p_intra_bss) in p2p_build_prov_disc_resp()
320 p2p_buf_add_capability(buf, p2p->dev_capab & in p2p_build_prov_disc_resp()
325 if (persist_ssid && p2p->cfg->get_persistent_group && dev && in p2p_build_prov_disc_resp()
333 persist = p2p->cfg->get_persistent_group( in p2p_build_prov_disc_resp()
334 p2p->cfg->cb_ctx, in p2p_build_prov_disc_resp()
335 dev->info.p2p_device_addr, in p2p_build_prov_disc_resp()
352 if (p2p->op_reg_class && p2p->op_channel) in p2p_build_prov_disc_resp()
354 buf, p2p->cfg->country, in p2p_build_prov_disc_resp()
355 p2p->op_reg_class, in p2p_build_prov_disc_resp()
356 p2p->op_channel); in p2p_build_prov_disc_resp()
359 buf, p2p->cfg->country, in p2p_build_prov_disc_resp()
360 p2p->cfg->op_reg_class, in p2p_build_prov_disc_resp()
361 p2p->cfg->op_channel); in p2p_build_prov_disc_resp()
370 p2p, dev->info.p2p_device_addr); in p2p_build_prov_disc_resp()
371 p2p_buf_add_channel_list(buf, p2p->cfg->country, in p2p_build_prov_disc_resp()
372 &p2p->channels, is_6ghz_capab); in p2p_build_prov_disc_resp()
378 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac); in p2p_build_prov_disc_resp()
382 p2p_buf_add_config_timeout(buf, p2p->go_timeout, in p2p_build_prov_disc_resp()
383 p2p->client_timeout); in p2p_build_prov_disc_resp()
385 p2p_buf_add_session_id(buf, prov->session_id, in p2p_build_prov_disc_resp()
386 prov->session_mac); in p2p_build_prov_disc_resp()
395 if (p2p->p2ps_prov) in p2p_build_prov_disc_resp()
397 p2p->p2ps_prov->adv_mac); in p2p_build_prov_disc_resp()
410 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) in p2p_build_prov_disc_resp()
411 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); in p2p_build_prov_disc_resp()
423 if (!p2p->p2ps_prov) { in p2ps_setup_p2ps_prov()
424 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1); in p2ps_setup_p2ps_prov()
425 if (!p2p->p2ps_prov) in p2ps_setup_p2ps_prov()
426 return -1; in p2ps_setup_p2ps_prov()
428 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1); in p2ps_setup_p2ps_prov()
431 tmp = p2p->p2ps_prov; in p2ps_setup_p2ps_prov()
432 tmp->adv_id = adv_id; in p2ps_setup_p2ps_prov()
433 tmp->session_id = session_id; in p2ps_setup_p2ps_prov()
434 tmp->method = method; in p2ps_setup_p2ps_prov()
435 os_memcpy(tmp->session_mac, session_mac, ETH_ALEN); in p2ps_setup_p2ps_prov()
436 os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN); in p2ps_setup_p2ps_prov()
437 tmp->info[0] = '\0'; in p2ps_setup_p2ps_prov()
468 if ((_val) && !msg->_attr) { \ in p2ps_validate_pd_req()
470 return -1; \ in p2ps_validate_pd_req()
484 * and related attributes for follow-on PD Request with a status in p2ps_validate_pd_req()
487 if (msg->status && *msg->status != P2P_SC_SUCCESS_DEFERRED) in p2ps_validate_pd_req()
502 if (msg->feature_cap_len < sizeof(struct p2ps_feature_capab)) { in p2ps_validate_pd_req()
504 return -1; in p2ps_validate_pd_req()
507 switch (*msg->conn_cap) { in p2ps_validate_pd_req()
541 return -1; in p2ps_validate_pd_req()
544 if (msg->persistent_dev) { in p2ps_validate_pd_req()
547 if (ether_addr_equal(msg->persistent_dev, addr)) { in p2ps_validate_pd_req()
571 int freq; in p2p_process_prov_disc_req() local
594 " with config methods 0x%x (freq=%d)", in p2p_process_prov_disc_req()
599 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { in p2p_process_prov_disc_req()
603 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1, in p2p_process_prov_disc_req()
618 wpabuf_free(dev->info.wfd_subelems); in p2p_process_prov_disc_req()
619 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); in p2p_process_prov_disc_req()
632 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */ in p2p_process_prov_disc_req()
636 for (i = 0; i < p2p->num_groups; i++) { in p2p_process_prov_disc_req()
638 p2p->groups[i], in p2p_process_prov_disc_req()
642 if (i == p2p->num_groups) { in p2p_process_prov_disc_req()
644 "PD request for unknown P2P Group ID - reject"); in p2p_process_prov_disc_req()
673 * request or in a follow-on PD request with the status in p2p_process_prov_disc_req()
689 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | in p2p_process_prov_disc_req()
696 dev->flags |= P2P_DEV_PD_PEER_KEYPAD; in p2p_process_prov_disc_req()
702 dev->flags |= P2P_DEV_PD_PEER_DISPLAY; in p2p_process_prov_disc_req()
707 dev->flags |= P2P_DEV_PD_PEER_P2PS; in p2p_process_prov_disc_req()
712 if (p2p->cfg->remove_stale_groups) { in p2p_process_prov_disc_req()
713 p2p->cfg->remove_stale_groups( in p2p_process_prov_disc_req()
714 p2p->cfg->cb_ctx, dev->info.p2p_device_addr, in p2p_process_prov_disc_req()
733 if (!ether_addr_equal(p2p->cfg->dev_addr, msg.adv_mac)) { in p2p_process_prov_disc_req()
748 auto_accept = p2ps_adv->auto_accept; in p2p_process_prov_disc_req()
749 conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx, in p2p_process_prov_disc_req()
759 resp_fcap.cpt = p2ps_own_preferred_cpt(p2ps_adv->cpt_priority, in p2p_process_prov_disc_req()
760 req_fcap->cpt); in p2p_process_prov_disc_req()
763 p2ps_adv->cpt_mask, req_fcap->cpt, resp_fcap.cpt); in p2p_process_prov_disc_req()
769 } else if (p2ps_adv->config_methods && in p2p_process_prov_disc_req()
771 p2ps_adv->config_methods)) { in p2p_process_prov_disc_req()
774 p2ps_adv->config_methods, in p2p_process_prov_disc_req()
777 } else if (!p2ps_adv->state) { in p2p_process_prov_disc_req()
786 p2p_dbg(p2p, "Keypad - always defer"); in p2p_process_prov_disc_req()
793 p2p_peer_channels_check(p2p, &p2p->channels, dev, in p2p_process_prov_disc_req()
797 "No common channels - force deferred flow"); in p2p_process_prov_disc_req()
811 if (dev->channels.reg_classes == 0 || in p2p_process_prov_disc_req()
812 !p2p_channels_includes(&dev->channels, in p2p_process_prov_disc_req()
815 struct p2p_channels *ch = &dev->channels; in p2p_process_prov_disc_req()
818 ch->reg_class[0].reg_class = in p2p_process_prov_disc_req()
820 ch->reg_class[0].channel[0] = in p2p_process_prov_disc_req()
822 ch->reg_class[0].channels = 1; in p2p_process_prov_disc_req()
823 ch->reg_classes = 1; in p2p_process_prov_disc_req()
826 p2p_channels_intersect(&p2p->channels, &dev->channels, in p2p_process_prov_disc_req()
831 "No common channels - force deferred flow"); in p2p_process_prov_disc_req()
846 tmp = p2p->p2ps_prov; in p2p_process_prov_disc_req()
847 tmp->force_freq = forced_freq; in p2p_process_prov_disc_req()
848 tmp->pref_freq = pref_freq; in p2p_process_prov_disc_req()
850 tmp->conncap = conncap; in p2p_process_prov_disc_req()
851 tmp->status = P2P_SC_SUCCESS; in p2p_process_prov_disc_req()
853 tmp->conncap = auto_accept; in p2p_process_prov_disc_req()
854 tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; in p2p_process_prov_disc_req()
863 (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) { in p2p_process_prov_disc_req()
877 tmp = p2p->p2ps_prov; in p2p_process_prov_disc_req()
879 tmp->status = reject; in p2p_process_prov_disc_req()
882 /* Not a P2PS Follow-on PD */ in p2p_process_prov_disc_req()
891 if (*msg.status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov) in p2p_process_prov_disc_req()
894 if (p2p->p2ps_prov->adv_id != adv_id || in p2p_process_prov_disc_req()
895 !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg.adv_mac)) { in p2p_process_prov_disc_req()
897 "P2PS Follow-on PD with mismatch Advertisement ID/MAC"); in p2p_process_prov_disc_req()
901 if (p2p->p2ps_prov->session_id != session_id || in p2p_process_prov_disc_req()
902 !ether_addr_equal(p2p->p2ps_prov->session_mac, msg.session_mac)) { in p2p_process_prov_disc_req()
903 p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Session ID/MAC"); in p2p_process_prov_disc_req()
907 method = p2p->p2ps_prov->method; in p2p_process_prov_disc_req()
909 conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx, in p2p_process_prov_disc_req()
911 p2p->p2ps_prov->conncap, in p2p_process_prov_disc_req()
912 &p2p->p2ps_prov->force_freq, in p2p_process_prov_disc_req()
913 &p2p->p2ps_prov->pref_freq); in p2p_process_prov_disc_req()
915 resp_fcap.cpt = p2ps_own_preferred_cpt(p2p->p2ps_prov->cpt_priority, in p2p_process_prov_disc_req()
916 req_fcap->cpt); in p2p_process_prov_disc_req()
919 p2p->p2ps_prov->cpt_mask, req_fcap->cpt, resp_fcap.cpt); in p2p_process_prov_disc_req()
921 p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq, in p2p_process_prov_disc_req()
922 p2p->p2ps_prov->pref_freq, 0); in p2p_process_prov_disc_req()
946 p2p_peer_channels_check(p2p, &p2p->channels, dev, in p2p_process_prov_disc_req()
950 "No common channels in Follow-On Provision Discovery Request"); in p2p_process_prov_disc_req()
956 dev->oper_freq = 0; in p2p_process_prov_disc_req()
961 dev->oper_freq = in p2p_process_prov_disc_req()
970 p2p->p2ps_prov->status = reject; in p2p_process_prov_disc_req()
971 p2p->p2ps_prov->conncap = conncap; in p2p_process_prov_disc_req()
981 * Send PD Response for an initial PD Request or for follow-on in p2p_process_prov_disc_req()
998 freq = rx_freq; in p2p_process_prov_disc_req()
1000 freq = p2p_channel_to_freq(p2p->cfg->reg_class, in p2p_process_prov_disc_req()
1001 p2p->cfg->channel); in p2p_process_prov_disc_req()
1002 if (freq < 0) { in p2p_process_prov_disc_req()
1008 p2p->pending_action_state = P2P_PENDING_PD_RESPONSE; in p2p_process_prov_disc_req()
1009 if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, in p2p_process_prov_disc_req()
1010 p2p->cfg->dev_addr, in p2p_process_prov_disc_req()
1015 p2p->send_action_in_progress = 1; in p2p_process_prov_disc_req()
1025 freq = 0; in p2p_process_prov_disc_req()
1027 freq = p2p_channel_to_freq(p2p->op_reg_class, in p2p_process_prov_disc_req()
1028 p2p->op_channel); in p2p_process_prov_disc_req()
1029 if (freq < 0) in p2p_process_prov_disc_req()
1030 freq = 0; in p2p_process_prov_disc_req()
1033 if (!p2p->cfg->p2ps_prov_complete) { in p2p_process_prov_disc_req()
1038 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject, in p2p_process_prov_disc_req()
1043 0, 0, NULL, NULL, 0, freq, in p2p_process_prov_disc_req()
1046 p2p->p2ps_prov) { in p2p_process_prov_disc_req()
1047 p2p->p2ps_prov->status = reject; in p2p_process_prov_disc_req()
1048 p2p->p2ps_prov->conncap = conncap; in p2p_process_prov_disc_req()
1051 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject, in p2p_process_prov_disc_req()
1057 0, NULL, NULL, 0, freq, in p2p_process_prov_disc_req()
1060 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, in p2p_process_prov_disc_req()
1070 sizeof(resp_fcap), freq, in p2p_process_prov_disc_req()
1072 } else if (msg.status && p2p->p2ps_prov) { in p2p_process_prov_disc_req()
1073 p2p->p2ps_prov->status = P2P_SC_SUCCESS; in p2p_process_prov_disc_req()
1074 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa, in p2p_process_prov_disc_req()
1082 sizeof(resp_fcap), freq, NULL, 0); in p2p_process_prov_disc_req()
1085 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, in p2p_process_prov_disc_req()
1093 sizeof(resp_fcap), freq, in p2p_process_prov_disc_req()
1097 msg.group_id_len - ETH_ALEN : 0); in p2p_process_prov_disc_req()
1100 p2p->p2ps_prov->method = msg.wps_config_methods; in p2p_process_prov_disc_req()
1102 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, in p2p_process_prov_disc_req()
1110 sizeof(resp_fcap), freq, NULL, 0); in p2p_process_prov_disc_req()
1116 p2p->p2ps_prov->method = msg.wps_config_methods; in p2p_process_prov_disc_req()
1121 p2p->cfg->p2ps_prov_complete( in p2p_process_prov_disc_req()
1122 p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa, in p2p_process_prov_disc_req()
1128 freq, NULL, 0); in p2p_process_prov_disc_req()
1135 * prov_disc_req callback is used to generate P2P-PROV-DISC-ENTER-PIN, in p2p_process_prov_disc_req()
1136 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events. in p2p_process_prov_disc_req()
1148 * 5. P2PS follow-on with SUCCESS_DEFERRED, in p2p_process_prov_disc_req()
1152 if (p2p->cfg->prov_disc_req && in p2p_process_prov_disc_req()
1168 p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_req()
1182 switch (config_methods) { in p2p_process_prov_disc_req()
1184 dev->wps_prov_info = WPS_CONFIG_KEYPAD; in p2p_process_prov_disc_req()
1187 dev->wps_prov_info = WPS_CONFIG_DISPLAY; in p2p_process_prov_disc_req()
1190 dev->wps_prov_info = WPS_CONFIG_PUSHBUTTON; in p2p_process_prov_disc_req()
1193 dev->wps_prov_info = WPS_CONFIG_P2PS; in p2p_process_prov_disc_req()
1196 dev->wps_prov_info = 0; in p2p_process_prov_disc_req()
1201 os_memcpy(dev->interface_addr, msg.intended_addr, in p2p_process_prov_disc_req()
1218 if ((_val) && !msg->_attr) { \ in p2p_validate_p2ps_pd_resp()
1220 return -1; \ in p2p_validate_p2ps_pd_resp()
1233 session_id = WPA_GET_LE32(msg->session_id); in p2p_validate_p2ps_pd_resp()
1234 adv_id = WPA_GET_LE32(msg->adv_id); in p2p_validate_p2ps_pd_resp()
1236 if (p2p->p2ps_prov->session_id != session_id) { in p2p_validate_p2ps_pd_resp()
1239 return -1; in p2p_validate_p2ps_pd_resp()
1242 if (!ether_addr_equal(p2p->p2ps_prov->session_mac, msg->session_mac)) { in p2p_validate_p2ps_pd_resp()
1245 return -1; in p2p_validate_p2ps_pd_resp()
1248 if (p2p->p2ps_prov->adv_id != adv_id) { in p2p_validate_p2ps_pd_resp()
1251 return -1; in p2p_validate_p2ps_pd_resp()
1254 if (!ether_addr_equal(p2p->p2ps_prov->adv_mac, msg->adv_mac)) { in p2p_validate_p2ps_pd_resp()
1257 return -1; in p2p_validate_p2ps_pd_resp()
1260 if (msg->listen_channel) { in p2p_validate_p2ps_pd_resp()
1262 "Ignore malformed PD Response - unexpected Listen Channel"); in p2p_validate_p2ps_pd_resp()
1263 return -1; in p2p_validate_p2ps_pd_resp()
1266 if (*msg->status == P2P_SC_SUCCESS && in p2p_validate_p2ps_pd_resp()
1267 !(!!msg->conn_cap ^ !!msg->persistent_dev)) { in p2p_validate_p2ps_pd_resp()
1269 "Ignore malformed PD Response - either conn_cap or persistent group should be present"); in p2p_validate_p2ps_pd_resp()
1270 return -1; in p2p_validate_p2ps_pd_resp()
1273 if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) { in p2p_validate_p2ps_pd_resp()
1275 "Ignore malformed PD Response - persistent group is present, but the status isn't success"); in p2p_validate_p2ps_pd_resp()
1276 return -1; in p2p_validate_p2ps_pd_resp()
1279 if (msg->conn_cap) { in p2p_validate_p2ps_pd_resp()
1280 conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER; in p2p_validate_p2ps_pd_resp()
1281 conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT; in p2p_validate_p2ps_pd_resp()
1284 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli, in p2p_validate_p2ps_pd_resp()
1286 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli, in p2p_validate_p2ps_pd_resp()
1323 if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) { in p2p_process_prov_disc_resp()
1345 /* Switch bits to local relative */ in p2p_process_prov_disc_resp()
1346 switch (conncap) { in p2p_process_prov_disc_resp()
1361 if (dev == NULL || !dev->req_config_methods) { in p2p_process_prov_disc_resp()
1367 wpabuf_free(dev->info.wfd_subelems); in p2p_process_prov_disc_resp()
1368 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); in p2p_process_prov_disc_resp()
1373 if (dev->dialog_token != msg.dialog_token) { in p2p_process_prov_disc_resp()
1375 msg.dialog_token, dev->dialog_token); in p2p_process_prov_disc_resp()
1380 if (p2p->pending_action_state == P2P_PENDING_PD) { in p2p_process_prov_disc_resp()
1381 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); in p2p_process_prov_disc_resp()
1382 p2p->pending_action_state = P2P_NO_PENDING_ACTION; in p2p_process_prov_disc_resp()
1385 p2ps_seeker = p2p->p2ps_prov && p2p->p2ps_prov->pd_seeker; in p2p_process_prov_disc_resp()
1391 req_config_methods = dev->req_config_methods; in p2p_process_prov_disc_resp()
1397 if (p2p->user_initiated_pd && in p2p_process_prov_disc_resp()
1398 ether_addr_equal(p2p->pending_pd_devaddr, sa)) in p2p_process_prov_disc_resp()
1404 if (p2p->cfg->prov_disc_fail) in p2p_process_prov_disc_resp()
1405 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_resp()
1414 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | in p2p_process_prov_disc_resp()
1420 dev->flags |= P2P_DEV_PD_PEER_DISPLAY; in p2p_process_prov_disc_resp()
1426 dev->flags |= P2P_DEV_PD_PEER_KEYPAD; in p2p_process_prov_disc_resp()
1431 dev->flags |= P2P_DEV_PD_PEER_P2PS; in p2p_process_prov_disc_resp()
1436 p2p->p2ps_prov) { in p2p_process_prov_disc_resp()
1437 dev->oper_freq = 0; in p2p_process_prov_disc_resp()
1448 p2p_peer_channels_check(p2p, &p2p->channels, dev, in p2p_process_prov_disc_resp()
1451 p2p_dbg(p2p, "P2PS PD Response - no common channels"); in p2p_process_prov_disc_resp()
1454 if (p2p_channels_includes(&p2p->channels, in p2p_process_prov_disc_resp()
1457 p2p_channels_includes(&dev->channels, in p2p_process_prov_disc_resp()
1460 dev->oper_freq = in p2p_process_prov_disc_resp()
1466 "P2PS PD Response - invalid operating channel"); in p2p_process_prov_disc_resp()
1470 if (p2p->cfg->p2ps_prov_complete) { in p2p_process_prov_disc_resp()
1471 int freq = 0; in p2p_process_prov_disc_resp() local
1477 * Re-select the operating channel as it is in p2p_process_prov_disc_resp()
1485 freq = p2p_channel_to_freq(p2p->op_reg_class, in p2p_process_prov_disc_resp()
1486 p2p->op_channel); in p2p_process_prov_disc_resp()
1487 if (freq < 0) in p2p_process_prov_disc_resp()
1488 freq = 0; in p2p_process_prov_disc_resp()
1491 p2p->cfg->p2ps_prov_complete( in p2p_process_prov_disc_resp()
1492 p2p->cfg->cb_ctx, status, sa, adv_mac, in p2p_process_prov_disc_resp()
1493 p2p->p2ps_prov->session_mac, in p2p_process_prov_disc_resp()
1494 group_mac, adv_id, p2p->p2ps_prov->session_id, in p2p_process_prov_disc_resp()
1497 msg.feature_cap, msg.feature_cap_len, freq, in p2p_process_prov_disc_resp()
1499 msg.group_id ? msg.group_id_len - ETH_ALEN : 0); in p2p_process_prov_disc_resp()
1504 status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) { in p2p_process_prov_disc_resp()
1505 if (p2p->cfg->p2ps_prov_complete) in p2p_process_prov_disc_resp()
1506 p2p->cfg->p2ps_prov_complete( in p2p_process_prov_disc_resp()
1507 p2p->cfg->cb_ctx, status, sa, adv_mac, in p2p_process_prov_disc_resp()
1508 p2p->p2ps_prov->session_mac, in p2p_process_prov_disc_resp()
1509 group_mac, adv_id, p2p->p2ps_prov->session_id, in p2p_process_prov_disc_resp()
1515 if (p2p->cfg->remove_stale_groups) { in p2p_process_prov_disc_resp()
1516 p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx, in p2p_process_prov_disc_resp()
1517 dev->info.p2p_device_addr, in p2p_process_prov_disc_resp()
1533 if (p2p->cfg->prov_disc_fail) in p2p_process_prov_disc_resp()
1534 p2p->cfg->prov_disc_fail( in p2p_process_prov_disc_resp()
1535 p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_resp()
1541 if (p2p->cfg->prov_disc_fail) in p2p_process_prov_disc_resp()
1542 p2p->cfg->prov_disc_fail( in p2p_process_prov_disc_resp()
1543 p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_resp()
1548 if (p2p->cfg->prov_disc_fail) in p2p_process_prov_disc_resp()
1549 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_resp()
1558 dev->wps_prov_info = msg.wps_config_methods; in p2p_process_prov_disc_resp()
1560 os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN); in p2p_process_prov_disc_resp()
1565 dev->req_config_methods = 0; in p2p_process_prov_disc_resp()
1566 p2p->cfg->send_action_done(p2p->cfg->cb_ctx); in p2p_process_prov_disc_resp()
1567 if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) { in p2p_process_prov_disc_resp()
1568 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with " in p2p_process_prov_disc_resp()
1569 MACSTR, MAC2STR(dev->info.p2p_device_addr)); in p2p_process_prov_disc_resp()
1570 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; in p2p_process_prov_disc_resp()
1576 * prov_disc_resp callback is used to generate P2P-PROV-DISC-ENTER-PIN, in p2p_process_prov_disc_resp()
1577 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events. in p2p_process_prov_disc_resp()
1589 if (p2p->cfg->prov_disc_resp && in p2p_process_prov_disc_resp()
1596 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, in p2p_process_prov_disc_resp()
1599 if (p2p->state == P2P_PD_DURING_FIND) { in p2p_process_prov_disc_resp()
1610 int freq; in p2p_send_prov_disc_req() local
1613 freq = force_freq; in p2p_send_prov_disc_req()
1615 freq = dev->listen_freq > 0 ? dev->listen_freq : in p2p_send_prov_disc_req()
1616 dev->oper_freq; in p2p_send_prov_disc_req()
1617 if (freq <= 0) { in p2p_send_prov_disc_req()
1620 MAC2STR(dev->info.p2p_device_addr)); in p2p_send_prov_disc_req()
1621 return -1; in p2p_send_prov_disc_req()
1624 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { in p2p_send_prov_disc_req()
1625 if (!(dev->info.dev_capab & in p2p_send_prov_disc_req()
1629 MAC2STR(dev->info.p2p_device_addr)); in p2p_send_prov_disc_req()
1630 return -1; in p2p_send_prov_disc_req()
1635 if (p2p->p2ps_prov) { in p2p_send_prov_disc_req()
1636 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) { in p2p_send_prov_disc_req()
1637 if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY) in p2p_send_prov_disc_req()
1638 dev->req_config_methods = WPS_CONFIG_KEYPAD; in p2p_send_prov_disc_req()
1639 else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD) in p2p_send_prov_disc_req()
1640 dev->req_config_methods = WPS_CONFIG_DISPLAY; in p2p_send_prov_disc_req()
1642 dev->req_config_methods = WPS_CONFIG_P2PS; in p2p_send_prov_disc_req()
1645 if (p2p->p2ps_prov->method) in p2p_send_prov_disc_req()
1646 dev->req_config_methods = in p2p_send_prov_disc_req()
1647 p2p->p2ps_prov->method; in p2p_send_prov_disc_req()
1648 else if (dev->info.config_methods & WPS_CONFIG_P2PS) in p2p_send_prov_disc_req()
1649 dev->req_config_methods = WPS_CONFIG_P2PS; in p2p_send_prov_disc_req()
1650 else if (dev->info.config_methods & WPS_CONFIG_DISPLAY) in p2p_send_prov_disc_req()
1651 dev->req_config_methods = WPS_CONFIG_DISPLAY; in p2p_send_prov_disc_req()
1653 dev->req_config_methods = WPS_CONFIG_KEYPAD; in p2p_send_prov_disc_req()
1656 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x", in p2p_send_prov_disc_req()
1657 p2p->p2ps_prov->method, p2p->p2ps_prov->status, in p2p_send_prov_disc_req()
1658 dev->req_config_methods); in p2p_send_prov_disc_req()
1660 if (p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq, in p2p_send_prov_disc_req()
1661 p2p->p2ps_prov->pref_freq, 1) < 0) in p2p_send_prov_disc_req()
1662 return -1; in p2p_send_prov_disc_req()
1667 return -1; in p2p_send_prov_disc_req()
1669 if (p2p->state != P2P_IDLE) in p2p_send_prov_disc_req()
1670 p2p_stop_listen_for_freq(p2p, freq); in p2p_send_prov_disc_req()
1671 p2p->pending_action_state = P2P_PENDING_PD; in p2p_send_prov_disc_req()
1672 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, in p2p_send_prov_disc_req()
1673 p2p->cfg->dev_addr, dev->info.p2p_device_addr, in p2p_send_prov_disc_req()
1677 return -1; in p2p_send_prov_disc_req()
1680 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); in p2p_send_prov_disc_req()
1697 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { in p2p_prov_disc_req()
1701 return -1; in p2p_prov_disc_req()
1709 return -1; in p2p_prov_disc_req()
1712 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED && in p2p_prov_disc_req()
1713 p2p->p2ps_prov) { in p2p_prov_disc_req()
1715 p2ps_prov->method = p2p->p2ps_prov->method; in p2p_prov_disc_req()
1719 dev->wps_prov_info = 0; in p2p_prov_disc_req()
1721 p2p->p2ps_prov = p2ps_prov; in p2p_prov_disc_req()
1723 dev->req_config_methods = config_methods; in p2p_prov_disc_req()
1725 dev->flags |= P2P_DEV_PD_FOR_JOIN; in p2p_prov_disc_req()
1727 dev->flags &= ~P2P_DEV_PD_FOR_JOIN; in p2p_prov_disc_req()
1729 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && in p2p_prov_disc_req()
1730 p2p->state != P2P_LISTEN_ONLY) { in p2p_prov_disc_req()
1737 p2p->user_initiated_pd = user_initiated_pd; in p2p_prov_disc_req()
1738 p2p->pd_force_freq = force_freq; in p2p_prov_disc_req()
1740 if (p2p->user_initiated_pd) in p2p_prov_disc_req()
1741 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; in p2p_prov_disc_req()
1747 dev->dialog_token++; in p2p_prov_disc_req()
1748 if (dev->dialog_token == 0) in p2p_prov_disc_req()
1749 dev->dialog_token = 1; in p2p_prov_disc_req()
1759 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { in p2p_reset_pending_pd()
1760 if (!ether_addr_equal(p2p->pending_pd_devaddr, in p2p_reset_pending_pd()
1761 dev->info.p2p_device_addr)) in p2p_reset_pending_pd()
1763 if (!dev->req_config_methods) in p2p_reset_pending_pd()
1765 if (dev->flags & P2P_DEV_PD_FOR_JOIN) in p2p_reset_pending_pd()
1768 dev->req_config_methods = 0; in p2p_reset_pending_pd()
1771 p2p->user_initiated_pd = 0; in p2p_reset_pending_pd()
1772 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); in p2p_reset_pending_pd()
1773 p2p->pd_retries = 0; in p2p_reset_pending_pd()
1774 p2p->pd_force_freq = 0; in p2p_reset_pending_pd()
1780 os_free(p2p->p2ps_prov); in p2ps_prov_free()
1781 p2p->p2ps_prov = NULL; in p2ps_prov_free()