diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index f36fef759..87467b801 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -910,12 +910,12 @@ static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s, static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s, char *reply, size_t max_len, - int ndef, int cr) + int ndef, int cr, char *uuid) { struct wpabuf *buf; int res; - buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr); + buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid); if (buf == NULL) return -1; @@ -934,7 +934,7 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) { - char *pos; + char *pos, *pos2; int ndef; pos = os_strchr(cmd, ' '); @@ -949,10 +949,13 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s, else return -1; + pos2 = os_strchr(pos, ' '); + if (pos2) + *pos2++ = '\0'; if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) { return wpas_ctrl_nfc_get_handover_sel_wps( wpa_s, reply, max_len, ndef, - os_strcmp(pos, "WPS-CR") == 0); + os_strcmp(pos, "WPS-CR") == 0, pos2); } return -1; diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py index 725886fc0..2d54cd24c 100755 --- a/wpa_supplicant/examples/wps-nfc.py +++ b/wpa_supplicant/examples/wps-nfc.py @@ -82,15 +82,86 @@ def wpas_get_handover_req(): return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex") -def wpas_report_handover(req, sel): +def wpas_get_handover_sel(uuid): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("NFC_REPORT_HANDOVER INIT WPS " + + return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip().decode("hex") + + +def wpas_report_handover(req, sel, type): + wpas = wpas_connect() + if (wpas == None): + return None + return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " + str(req).encode("hex") + " " + str(sel).encode("hex")) +class HandoverServer(nfc.handover.HandoverServer): + def __init__(self): + super(HandoverServer, self).__init__() + + def process_request(self, request): + print "HandoverServer - request received" + print "Parsed handover request: " + request.pretty() + + sel = nfc.ndef.HandoverSelectMessage(version="1.2") + + for carrier in request.carriers: + print "Remote carrier type: " + carrier.type + if carrier.type == "application/vnd.wfa.wsc": + print "WPS carrier type match - add WPS carrier record" + self.received_carrier = carrier.record + data = wpas_get_handover_sel(self.uuid) + if data is None: + print "Could not get handover select carrier record from wpa_supplicant" + continue + print "Handover select carrier record from wpa_supplicant:" + print data.encode("hex") + self.sent_carrier = data + + message = nfc.ndef.Message(data); + sel.add_carrier(message[0], "active", message[1:]) + + print "Handover select:" + print sel.pretty() + print str(sel).encode("hex") + + print "Sending handover select" + return sel + + +def wps_handover_resp(peer, uuid): + print "Trying to handle WPS handover with AP " + uuid + + srv = HandoverServer() + srv.sent_carrier = None + srv.uuid = uuid + + nfc.llcp.activate(peer); + + try: + print "Trying handover"; + srv.start() + print "Wait for disconnect" + while nfc.llcp.connected(): + time.sleep(0.1) + print "Disconnected after handover" + except nfc.llcp.ConnectRefused: + print "Handover connection refused" + nfc.llcp.shutdown() + return + + if srv.sent_carrier: + wpas_report_handover(srv.received_carrier, srv.sent_carrier, "RESP") + + print "Remove peer" + nfc.llcp.shutdown() + print "Done with handover" + time.sleep(1) + + def wps_handover_init(peer): print "Trying to initiate WPS handover" @@ -154,7 +225,7 @@ def wps_handover_init(peer): print "Remote carrier type: " + carrier.type if carrier.type == "application/vnd.wfa.wsc": print "WPS carrier type match - send to wpa_supplicant" - wpas_report_handover(data, carrier.record) + wpas_report_handover(data, carrier.record, "INIT") wifi = nfc.ndef.WifiConfigRecord(carrier.record) print wifi.pretty() @@ -281,6 +352,10 @@ def main(): clf = nfc.ContactlessFrontend() try: + arg_uuid = None + if len(sys.argv) > 1: + arg_uuid = sys.argv[1] + if len(sys.argv) > 1 and sys.argv[1] == "write-config": wps_write_config_tag(clf) raise SystemExit @@ -298,7 +373,10 @@ def main(): tag = find_peer(clf) if isinstance(tag, nfc.DEP): - wps_handover_init(tag) + if arg_uuid is None: + wps_handover_init(tag) + else: + wps_handover_resp(tag, arg_uuid) continue if tag.ndef: diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index c89479f7d..509a7c0c8 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -2003,12 +2003,48 @@ struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr) } -struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s, - int ndef, int cr) +#ifdef CONFIG_WPS_NFC +struct wpabuf * wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s, + int ndef, const char *uuid) { + struct wpabuf *ret; + u8 u[UUID_LEN]; + + if (!wpa_s->wps_er) + return NULL; + + if (uuid == NULL || uuid_str2bin(uuid, u)) + return NULL; + + /* + * Handover Select carrier record for WPS uses the same format as + * configuration token. + */ + ret = wps_er_nfc_config_token(wpa_s->wps_er, u); + if (ndef && ret) { + struct wpabuf *tmp; + tmp = ndef_build_wifi(ret); + wpabuf_free(ret); + if (tmp == NULL) + return NULL; + ret = tmp; + } + + return ret; +} +#endif /* CONFIG_WPS_NFC */ + + +struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s, + int ndef, int cr, const char *uuid) +{ + struct wpabuf *ret; if (!cr) return NULL; - return wpas_ap_wps_nfc_handover_sel(wpa_s, ndef); + ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef); + if (ret) + return ret; + return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid); } diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h index 5bc5ffa5d..8bb9546e1 100644 --- a/wpa_supplicant/wps_supplicant.h +++ b/wpa_supplicant/wps_supplicant.h @@ -70,7 +70,7 @@ int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s, const struct wpabuf *data); struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr); struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s, - int ndef, int cr); + int ndef, int cr, const char *uuid); int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s, const struct wpabuf *data); int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,