WPS NFC: Add connection handover support for ER
wpa_supplicant can now generate the WPS carrier record for connection handover response when acting as an ER. The AP whose configuration is provided in this way is identified with an UUID as an argument to wps-nfc.py. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
c39fdb8529
commit
f3f2ba2e6e
4 changed files with 129 additions and 12 deletions
|
@ -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,
|
static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
|
||||||
char *reply, size_t max_len,
|
char *reply, size_t max_len,
|
||||||
int ndef, int cr)
|
int ndef, int cr, char *uuid)
|
||||||
{
|
{
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
int res;
|
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)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -934,7 +934,7 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
|
||||||
char *cmd, char *reply,
|
char *cmd, char *reply,
|
||||||
size_t max_len)
|
size_t max_len)
|
||||||
{
|
{
|
||||||
char *pos;
|
char *pos, *pos2;
|
||||||
int ndef;
|
int ndef;
|
||||||
|
|
||||||
pos = os_strchr(cmd, ' ');
|
pos = os_strchr(cmd, ' ');
|
||||||
|
@ -949,10 +949,13 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
pos2 = os_strchr(pos, ' ');
|
||||||
|
if (pos2)
|
||||||
|
*pos2++ = '\0';
|
||||||
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
|
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
|
||||||
return wpas_ctrl_nfc_get_handover_sel_wps(
|
return wpas_ctrl_nfc_get_handover_sel_wps(
|
||||||
wpa_s, reply, max_len, ndef,
|
wpa_s, reply, max_len, ndef,
|
||||||
os_strcmp(pos, "WPS-CR") == 0);
|
os_strcmp(pos, "WPS-CR") == 0, pos2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -82,15 +82,86 @@ def wpas_get_handover_req():
|
||||||
return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
|
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()
|
wpas = wpas_connect()
|
||||||
if (wpas == None):
|
if (wpas == None):
|
||||||
return 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(req).encode("hex") + " " +
|
||||||
str(sel).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):
|
def wps_handover_init(peer):
|
||||||
print "Trying to initiate WPS handover"
|
print "Trying to initiate WPS handover"
|
||||||
|
|
||||||
|
@ -154,7 +225,7 @@ def wps_handover_init(peer):
|
||||||
print "Remote carrier type: " + carrier.type
|
print "Remote carrier type: " + carrier.type
|
||||||
if carrier.type == "application/vnd.wfa.wsc":
|
if carrier.type == "application/vnd.wfa.wsc":
|
||||||
print "WPS carrier type match - send to wpa_supplicant"
|
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)
|
wifi = nfc.ndef.WifiConfigRecord(carrier.record)
|
||||||
print wifi.pretty()
|
print wifi.pretty()
|
||||||
|
|
||||||
|
@ -281,6 +352,10 @@ def main():
|
||||||
clf = nfc.ContactlessFrontend()
|
clf = nfc.ContactlessFrontend()
|
||||||
|
|
||||||
try:
|
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":
|
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
|
||||||
wps_write_config_tag(clf)
|
wps_write_config_tag(clf)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
@ -298,7 +373,10 @@ def main():
|
||||||
|
|
||||||
tag = find_peer(clf)
|
tag = find_peer(clf)
|
||||||
if isinstance(tag, nfc.DEP):
|
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
|
continue
|
||||||
|
|
||||||
if tag.ndef:
|
if tag.ndef:
|
||||||
|
|
|
@ -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,
|
#ifdef CONFIG_WPS_NFC
|
||||||
int ndef, int cr)
|
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)
|
if (!cr)
|
||||||
return NULL;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||||
const struct wpabuf *data);
|
const struct wpabuf *data);
|
||||||
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr);
|
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,
|
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,
|
int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s,
|
||||||
const struct wpabuf *data);
|
const struct wpabuf *data);
|
||||||
int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
|
int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
|
||||||
|
|
Loading…
Reference in a new issue