dpp-nfc: Collision detection for handover request
Address possible handover request collisions for cases where both devices try to initiate handover simultaneously. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
9ad3fe9343
commit
1e0bc897ab
1 changed files with 46 additions and 4 deletions
|
@ -8,6 +8,7 @@
|
||||||
# See README for more details.
|
# See README for more details.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
@ -33,6 +34,8 @@ continue_loop = True
|
||||||
terminate_now = False
|
terminate_now = False
|
||||||
summary_file = None
|
summary_file = None
|
||||||
success_file = None
|
success_file = None
|
||||||
|
my_crn = None
|
||||||
|
peer_crn = None
|
||||||
|
|
||||||
def summary(txt):
|
def summary(txt):
|
||||||
print(txt)
|
print(txt)
|
||||||
|
@ -209,11 +212,16 @@ def dpp_handover_client(llc):
|
||||||
uri = ndef.UriRecord(uri)
|
uri = ndef.UriRecord(uri)
|
||||||
print("NFC URI record for DPP: " + str(uri))
|
print("NFC URI record for DPP: " + str(uri))
|
||||||
carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data)
|
carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data)
|
||||||
hr = ndef.HandoverRequestRecord(version="1.4", crn=os.urandom(2))
|
crn = os.urandom(2)
|
||||||
|
hr = ndef.HandoverRequestRecord(version="1.4", crn=crn)
|
||||||
hr.add_alternative_carrier('active', carrier.name)
|
hr.add_alternative_carrier('active', carrier.name)
|
||||||
message = [hr, carrier]
|
message = [hr, carrier]
|
||||||
print("NFC Handover Request message for DPP: " + str(message))
|
print("NFC Handover Request message for DPP: " + str(message))
|
||||||
|
|
||||||
|
global peer_crn
|
||||||
|
if peer_crn is not None:
|
||||||
|
print("NFC handover request from peer was already received - do not send own")
|
||||||
|
return
|
||||||
client = nfc.handover.HandoverClient(llc)
|
client = nfc.handover.HandoverClient(llc)
|
||||||
try:
|
try:
|
||||||
summary("Trying to initiate NFC connection handover")
|
summary("Trying to initiate NFC connection handover")
|
||||||
|
@ -228,6 +236,11 @@ def dpp_handover_client(llc):
|
||||||
client.close()
|
client.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if peer_crn is not None:
|
||||||
|
print("NFC handover request from peer was already received - do not send own")
|
||||||
|
client.close()
|
||||||
|
return
|
||||||
|
|
||||||
summary("Sending handover request")
|
summary("Sending handover request")
|
||||||
|
|
||||||
if not client.send_records(message):
|
if not client.send_records(message):
|
||||||
|
@ -235,6 +248,9 @@ def dpp_handover_client(llc):
|
||||||
client.close()
|
client.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
global my_crn
|
||||||
|
my_crn, = struct.unpack('>H', crn)
|
||||||
|
|
||||||
summary("Receiving handover response")
|
summary("Receiving handover response")
|
||||||
message = client.recv_records(timeout=3.0)
|
message = client.recv_records(timeout=3.0)
|
||||||
if message is None:
|
if message is None:
|
||||||
|
@ -335,7 +351,32 @@ class HandoverServer(nfc.handover.HandoverServer):
|
||||||
clear_raw_mode()
|
clear_raw_mode()
|
||||||
print("\nHandoverServer - request received: " + str(records))
|
print("\nHandoverServer - request received: " + str(records))
|
||||||
|
|
||||||
carrier = None
|
global my_crn, peer_crn
|
||||||
|
|
||||||
|
for carrier in records:
|
||||||
|
if not isinstance(carrier, ndef.HandoverRequestRecord):
|
||||||
|
continue
|
||||||
|
if carrier.collision_resolution_number:
|
||||||
|
peer_crn = carrier.collision_resolution_number
|
||||||
|
print("peer_crn:", peer_crn)
|
||||||
|
|
||||||
|
if my_crn is not None:
|
||||||
|
print("my_crn:", my_crn)
|
||||||
|
|
||||||
|
if my_crn is not None and peer_crn is not None:
|
||||||
|
if my_crn == peer_crn:
|
||||||
|
print("Same crn used - automatic collision resolution failed")
|
||||||
|
# TODO: Should generate a new Handover Request message
|
||||||
|
return ''
|
||||||
|
if ((my_crn & 1) == (peer_crn & 1) and my_crn > peer_crn) or \
|
||||||
|
((my_crn & 1) != (peer_crn & 1) and my_crn < peer_crn):
|
||||||
|
print("I'm the Handover Selector Device")
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print("Peer is the Handover Selector device")
|
||||||
|
print("Ignore the received request.")
|
||||||
|
return ''
|
||||||
|
|
||||||
hs = ndef.HandoverSelectRecord('1.4')
|
hs = ndef.HandoverSelectRecord('1.4')
|
||||||
sel = [hs]
|
sel = [hs]
|
||||||
|
|
||||||
|
@ -362,7 +403,6 @@ class HandoverServer(nfc.handover.HandoverServer):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
found = True
|
found = True
|
||||||
self.received_carrier = carrier
|
|
||||||
|
|
||||||
wpas = wpas_connect()
|
wpas = wpas_connect()
|
||||||
if wpas is None:
|
if wpas is None:
|
||||||
|
@ -585,8 +625,10 @@ def llcp_startup(llc):
|
||||||
|
|
||||||
def llcp_connected(llc):
|
def llcp_connected(llc):
|
||||||
print("P2P LLCP connected")
|
print("P2P LLCP connected")
|
||||||
global wait_connection
|
global wait_connection, my_crn, peer_crn
|
||||||
wait_connection = False
|
wait_connection = False
|
||||||
|
my_crn = None
|
||||||
|
peer_crn = None
|
||||||
global srv
|
global srv
|
||||||
srv.start()
|
srv.start()
|
||||||
if init_on_touch or not no_input:
|
if init_on_touch or not no_input:
|
||||||
|
|
Loading…
Reference in a new issue