diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 67bd859ca..b744eb1e4 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -4523,4 +4523,23 @@ int p2p_process_nfc_connection_handover(struct p2p_data *p2p, return 0; } + +void p2p_set_authorized_oob_dev_pw_id(struct p2p_data *p2p, u16 dev_pw_id, + int go_intent, + const u8 *own_interface_addr) +{ + + p2p->authorized_oob_dev_pw_id = dev_pw_id; + if (dev_pw_id == 0) { + p2p_dbg(p2p, "NFC OOB Password unauthorized for static handover"); + return; + } + + p2p_dbg(p2p, "NFC OOB Password (id=%u) authorized for static handover", + dev_pw_id); + + p2p->go_intent = go_intent; + os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); +} + #endif /* CONFIG_WPS_NFC */ diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 2a64ca5cf..fcf8cfc55 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1921,4 +1921,8 @@ struct p2p_nfc_params { int p2p_process_nfc_connection_handover(struct p2p_data *p2p, struct p2p_nfc_params *params); +void p2p_set_authorized_oob_dev_pw_id(struct p2p_data *p2p, u16 dev_pw_id, + int go_intent, + const u8 *own_interface_addr); + #endif /* P2P_H */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 3bfcc909a..a30f67b07 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4675,6 +4675,11 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) return 0; } +#ifdef CONFIG_WPS_NFC + if (os_strcmp(cmd, "nfc_tag") == 0) + return wpas_p2p_nfc_tag_enabled(wpa_s, !!atoi(param)); +#endif /* CONFIG_WPS_NFC */ + wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", cmd); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index fe50b001a..26d53c266 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -7303,4 +7303,68 @@ int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init, return ret; } + +int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled) +{ + const u8 *if_addr; + int go_intent = wpa_s->conf->p2p_go_intent; + + if (wpa_s->global->p2p == NULL) + return -1; + + if (!enabled) { + p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0, + 0, NULL); + if (wpa_s->p2p_nfc_tag_enabled) + wpas_p2p_remove_pending_group_interface(wpa_s); + wpa_s->p2p_nfc_tag_enabled = 0; + return 0; + } + + if (wpa_s->global->p2p_disabled) + return -1; + + if (wpa_s->conf->wps_nfc_dh_pubkey == NULL || + wpa_s->conf->wps_nfc_dh_privkey == NULL || + wpa_s->conf->wps_nfc_dev_pw == NULL || + wpa_s->conf->wps_nfc_dev_pw_id < 0x10) { + wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured " + "to allow static handover cases"); + return -1; + } + + wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id; + wpabuf_free(wpa_s->p2p_oob_dev_pw); + wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw); + if (wpa_s->p2p_oob_dev_pw == NULL) + return -1; + wpa_s->p2p_peer_oob_pk_hash_known = 0; + + wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); + + if (wpa_s->create_p2p_iface) { + enum wpa_driver_if_type iftype; + /* Prepare to add a new interface for the group */ + iftype = WPA_IF_P2P_GROUP; + if (go_intent == 15) + iftype = WPA_IF_P2P_GO; + if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) { + wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " + "interface for the group"); + return -1; + } + + if_addr = wpa_s->pending_interface_addr; + } else + if_addr = wpa_s->own_addr; + + wpa_s->p2p_nfc_tag_enabled = enabled; + + p2p_set_authorized_oob_dev_pw_id( + wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent, + if_addr); + + return 0; +} + #endif /* CONFIG_WPS_NFC */ diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 46c91cd20..4adea48a2 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -157,6 +157,7 @@ int wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s, int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init, const struct wpabuf *req, const struct wpabuf *sel); +int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled); #ifdef CONFIG_P2P int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index df07f466f..46f895666 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -714,6 +714,7 @@ struct wpa_supplicant { unsigned int p2p_go_group_formation_completed:1; unsigned int waiting_presence_resp; int p2p_first_connection_timeout; + unsigned int p2p_nfc_tag_enabled:1; unsigned int p2p_peer_oob_pk_hash_known:1; int p2p_persistent_go_freq; int p2p_persistent_id;