aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-02-15 15:07:28 (GMT)
committerJouni Malinen <j@w1.fi>2014-01-27 19:10:56 (GMT)
commit93588780558074279f1603b2155d93bc76d71407 (patch)
treea131a09bf1b5485fdf7a16f5b0f0f3ec952c21e0 /wpa_supplicant
parentc00ab85f7e45f8ab4b0039320146f339d3227a3c (diff)
downloadhostap-93588780558074279f1603b2155d93bc76d71407.zip
hostap-93588780558074279f1603b2155d93bc76d71407.tar.gz
hostap-93588780558074279f1603b2155d93bc76d71407.tar.bz2
P2P NFC: Build connection handover messages
"NFC_GET_HANDOVER_{REQ,SEL} NDEF P2P-CR" can now be used to build P2P alternative carrier record for NFC connection handover request/select messages. Static connection handover case can be enabled by configuring the DH parameters (either with wps_nfc_* configuration parameters or with WPS_NFC_TOKEN command at run time. The NFC Tag contents can be generated with "NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG" after having configured Listen channel (p2p_listen_reg_class/p2p_listen_channel). Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c63
-rw-r--r--wpa_supplicant/p2p_supplicant.c103
-rw-r--r--wpa_supplicant/p2p_supplicant.h4
3 files changed, 170 insertions, 0 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7ba17db..cde9c46 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -928,6 +928,30 @@ static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s,
}
+static int wpas_ctrl_nfc_get_handover_req_p2p(struct wpa_supplicant *wpa_s,
+ char *reply, size_t max_len,
+ int ndef)
+{
+ struct wpabuf *buf;
+ int res;
+
+ buf = wpas_p2p_nfc_handover_req(wpa_s, ndef);
+ if (buf == NULL) {
+ wpa_printf(MSG_DEBUG, "P2P: Could not generate NFC handover request");
+ return -1;
+ }
+
+ res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
+ wpabuf_len(buf));
+ reply[res++] = '\n';
+ reply[res] = '\0';
+
+ wpabuf_free(buf);
+
+ return res;
+}
+
+
static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
char *cmd, char *reply,
size_t max_len)
@@ -954,6 +978,11 @@ static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
wpa_s, reply, max_len, ndef);
}
+ if (os_strcmp(pos, "P2P-CR") == 0) {
+ return wpas_ctrl_nfc_get_handover_req_p2p(
+ wpa_s, reply, max_len, ndef);
+ }
+
return -1;
}
@@ -980,6 +1009,28 @@ static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
}
+static int wpas_ctrl_nfc_get_handover_sel_p2p(struct wpa_supplicant *wpa_s,
+ char *reply, size_t max_len,
+ int ndef, int tag)
+{
+ struct wpabuf *buf;
+ int res;
+
+ buf = wpas_p2p_nfc_handover_sel(wpa_s, ndef, tag);
+ if (buf == NULL)
+ return -1;
+
+ res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
+ wpabuf_len(buf));
+ reply[res++] = '\n';
+ reply[res] = '\0';
+
+ wpabuf_free(buf);
+
+ return res;
+}
+
+
static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
char *cmd, char *reply,
size_t max_len)
@@ -1003,11 +1054,23 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
if (pos2)
*pos2++ = '\0';
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
+ if (!ndef)
+ return -1;
return wpas_ctrl_nfc_get_handover_sel_wps(
wpa_s, reply, max_len, ndef,
os_strcmp(pos, "WPS-CR") == 0, pos2);
}
+ if (os_strcmp(pos, "P2P-CR") == 0) {
+ return wpas_ctrl_nfc_get_handover_sel_p2p(
+ wpa_s, reply, max_len, ndef, 0);
+ }
+
+ if (os_strcmp(pos, "P2P-CR-TAG") == 0) {
+ return wpas_ctrl_nfc_get_handover_sel_p2p(
+ wpa_s, reply, max_len, ndef, 1);
+ }
+
return -1;
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 8ec70dc..e61d5ce 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -6923,3 +6923,106 @@ int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
wpa_s->p2p_last_4way_hs_fail = ssid;
return 0;
}
+
+
+#ifdef CONFIG_WPS_NFC
+
+static struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc,
+ struct wpabuf *p2p)
+{
+ struct wpabuf *ret;
+
+ if (wsc == NULL) {
+ wpabuf_free(p2p);
+ return NULL;
+ }
+
+ if (p2p == NULL) {
+ wpabuf_free(wsc);
+ wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover");
+ return NULL;
+ }
+
+ ret = wpabuf_alloc(2 + wpabuf_len(wsc) + 2 + wpabuf_len(p2p));
+ if (ret == NULL) {
+ wpabuf_free(wsc);
+ wpabuf_free(p2p);
+ return NULL;
+ }
+
+ wpabuf_put_be16(ret, wpabuf_len(wsc));
+ wpabuf_put_buf(ret, wsc);
+ wpabuf_put_be16(ret, wpabuf_len(p2p));
+ wpabuf_put_buf(ret, p2p);
+
+ wpabuf_free(wsc);
+ wpabuf_free(p2p);
+ wpa_hexdump_buf(MSG_DEBUG,
+ "P2P: Generated NFC connection handover message", ret);
+
+ if (ndef && ret) {
+ struct wpabuf *tmp;
+ tmp = ndef_build_p2p(ret);
+ wpabuf_free(ret);
+ if (tmp == NULL) {
+ wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request");
+ return NULL;
+ }
+ ret = tmp;
+ }
+
+ return ret;
+}
+
+
+struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
+ int ndef)
+{
+ struct wpabuf *wsc, *p2p;
+
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
+ wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request");
+ return NULL;
+ }
+
+ if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
+ wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
+ &wpa_s->conf->wps_nfc_dh_privkey) < 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request");
+ return NULL;
+ }
+
+ wsc = wps_build_nfc_handover_req_p2p(wpa_s->parent->wps,
+ wpa_s->conf->wps_nfc_dh_pubkey);
+ p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p);
+
+ return wpas_p2p_nfc_handover(ndef, wsc, p2p);
+}
+
+
+struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
+ int ndef, int tag)
+{
+ struct wpabuf *wsc, *p2p;
+
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+ return NULL;
+
+ if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
+ wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
+ &wpa_s->conf->wps_nfc_dh_privkey) < 0)
+ return NULL;
+
+ wsc = wps_build_nfc_handover_sel_p2p(wpa_s->parent->wps,
+ tag ?
+ wpa_s->conf->wps_nfc_dev_pw_id :
+ DEV_PW_NFC_CONNECTION_HANDOVER,
+ wpa_s->conf->wps_nfc_dh_pubkey,
+ tag ? wpa_s->conf->wps_nfc_dev_pw :
+ NULL);
+ p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p);
+
+ return wpas_p2p_nfc_handover(ndef, wsc, p2p);
+}
+
+#endif /* CONFIG_WPS_NFC */
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 7abfb12..17e7bae 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -148,6 +148,10 @@ void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
const u8 *psk, size_t psk_len);
void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
int iface_addr);
+struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
+ int ndef);
+struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
+ int ndef, int tag);
#ifdef CONFIG_P2P
int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);