P2P NFC: Add NFC tag enabling for static handover
authorJouni Malinen <jouni@qca.qualcomm.com>
Sat, 27 Apr 2013 14:50:50 +0000 (17:50 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 27 Jan 2014 19:10:56 +0000 (21:10 +0200)
The device with the NFC Tag can be configured to enable NFC to be used
with "P2P_SET nfc_tag 1" and "P2P_LISTEN" commands to allow static
handover to be used.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/p2p/p2p.c
src/p2p/p2p.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant_i.h

index 67bd859..b744eb1 100644 (file)
@@ -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 */
index 2a64ca5..fcf8cfc 100644 (file)
@@ -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 */
index 3bfcc90..a30f67b 100644 (file)
@@ -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);
 
index fe50b00..26d53c2 100644 (file)
@@ -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 */
index 46c91cd..4adea48 100644 (file)
@@ -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);
index df07f46..46f8956 100644 (file)
@@ -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;