dpp-nfc: Support channel list negotiation

If the peer's channel list in negotiated handover does not have any
common channels and the local end is configured with an alternative
channel list, try to initiate another negotiation handover with the
alternative channels.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-06-23 13:24:38 +03:00 committed by Jouni Malinen
parent eddf22e1f2
commit 5908fedc10

View file

@ -179,12 +179,15 @@ def dpp_bootstrap_gen(wpas, type="qrcode", chan=None, mac=None, info=None,
raise Exception("Failed to generate bootstrapping info") raise Exception("Failed to generate bootstrapping info")
return int(res) return int(res)
def wpas_get_nfc_uri(start_listen=True, pick_channel=False): def wpas_get_nfc_uri(start_listen=True, pick_channel=False, chan_override=None):
wpas = wpas_connect() wpas = wpas_connect()
if wpas is None: if wpas is None:
return None return None
global own_id, chanlist global own_id, chanlist
chan = chanlist if chan_override:
chan = chan_override
else:
chan = chanlist
if chan is None and get_status_field(wpas, "bssid[0]"): if chan is None and get_status_field(wpas, "bssid[0]"):
freq = get_status_field(wpas, "freq") freq = get_status_field(wpas, "freq")
if freq: if freq:
@ -219,8 +222,12 @@ def wpas_report_handover_sel(uri):
cmd = "DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (own_id, uri) cmd = "DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (own_id, uri)
return wpas.request(cmd) return wpas.request(cmd)
def dpp_handover_client(llc): def dpp_handover_client(llc, alt=False):
uri = wpas_get_nfc_uri(start_listen=False) chan_override = None
if alt:
global altchanlist
chan_override = altchanlist
uri = wpas_get_nfc_uri(start_listen=False, chan_override=chan_override)
if uri is None: if uri is None:
summary("Cannot start handover client - no bootstrap URI available") summary("Cannot start handover client - no bootstrap URI available")
return return
@ -346,6 +353,10 @@ def dpp_handover_client(llc):
if not dpp_found: if not dpp_found:
summary("DPP carrier not seen in response - allow peer to initiate a new handover with different parameters") summary("DPP carrier not seen in response - allow peer to initiate a new handover with different parameters")
my_crn_ready = False
my_crn = None
peer_crn = None
hs_sent = False
client.close() client.close()
summary("Returning from dpp_handover_client") summary("Returning from dpp_handover_client")
return return
@ -374,6 +385,7 @@ class HandoverServer(nfc.handover.HandoverServer):
self.ho_server_processing = False self.ho_server_processing = False
self.success = False self.success = False
self.try_own = False self.try_own = False
self.llc = llc
def process_handover_request_message(self, records): def process_handover_request_message(self, records):
self.ho_server_processing = True self.ho_server_processing = True
@ -439,6 +451,11 @@ class HandoverServer(nfc.handover.HandoverServer):
res = wpas_report_handover_req(uri) res = wpas_report_handover_req(uri)
if res is None or "FAIL" in res: if res is None or "FAIL" in res:
summary("DPP handover request processing failed") summary("DPP handover request processing failed")
global altchanlist
if altchanlist:
data = wpas_get_nfc_uri(start_listen=False,
chan_override=altchanlist)
summary("Own URI (try another channel list): %s" % data)
continue continue
found = True found = True
@ -492,9 +509,14 @@ class HandoverServer(nfc.handover.HandoverServer):
summary("Sending handover select: " + str(sel)) summary("Sending handover select: " + str(sel))
if found: if found:
summary("Handover completed successfully")
self.success = True self.success = True
else: else:
summary("Try to initiate with alternative parameters")
self.try_own = True self.try_own = True
if not init_on_touch and no_input:
# Need to start client thread now
threading.Thread(target=llcp_worker, args=(self.llc,)).start()
global hs_sent global hs_sent
hs_sent = True hs_sent = True
return sel return sel
@ -648,7 +670,12 @@ def llcp_worker(llc):
if srv.try_own: if srv.try_own:
srv.try_own = False srv.try_own = False
summary("Try to initiate another handover with own parameters") summary("Try to initiate another handover with own parameters")
dpp_handover_client(llc) global peer_crn, my_crn, my_crn_ready, hs_sent
my_crn_ready = False
my_crn = None
peer_crn = None
hs_sent = False
dpp_handover_client(llc, alt=True)
summary("Exiting llcp_worker thread (retry with own parameters)") summary("Exiting llcp_worker thread (retry with own parameters)")
return return
if srv.ho_server_processing: if srv.ho_server_processing:
@ -737,6 +764,7 @@ def main():
help='success file for writing success update') help='success file for writing success update')
parser.add_argument('--device', default='usb', help='NFC device to open') parser.add_argument('--device', default='usb', help='NFC device to open')
parser.add_argument('--chan', default=None, help='channel list') parser.add_argument('--chan', default=None, help='channel list')
parser.add_argument('--altchan', default=None, help='alternative channel list')
parser.add_argument('command', choices=['write-nfc-uri', parser.add_argument('command', choices=['write-nfc-uri',
'write-nfc-hs'], 'write-nfc-hs'],
nargs='?') nargs='?')
@ -749,8 +777,9 @@ def main():
global no_wait global no_wait
no_wait = args.no_wait no_wait = args.no_wait
global chanlist global chanlist, altchanlist
chanlist = args.chan chanlist = args.chan
altchanlist = args.altchan
logging.basicConfig(level=args.loglevel) logging.basicConfig(level=args.loglevel)