]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
dpp-nfc: Improved version of HandoverServer::serve()
authorJouni Malinen <jouni@codeaurora.org>
Thu, 30 Jul 2020 21:38:42 +0000 (00:38 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 30 Jul 2020 22:00:11 +0000 (01:00 +0300)
Fix processing of the case where no handover select is sent out and add
automatic (delayed) termination of the link on completing the handover
successfully.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
wpa_supplicant/examples/dpp-nfc.py

index d4a050a5e2bfc351232d7bfcf1435a4e9ae7be5a..3bec4573a7da7137b27de3212164b222df336a4d 100755 (executable)
@@ -8,6 +8,7 @@
 # See README for more details.
 
 import binascii
+import errno
 import os
 import struct
 import sys
@@ -493,6 +494,48 @@ class HandoverServer(nfc.handover.HandoverServer):
         self.llc = llc
         self.handover = handover
 
+    def serve(self, socket):
+        peer_sap = socket.getpeername()
+        summary("Serving handover client on remote sap {0}".format(peer_sap))
+        send_miu = socket.getsockopt(nfc.llcp.SO_SNDMIU)
+        try:
+            while socket.poll("recv"):
+                req = bytearray()
+                while socket.poll("recv"):
+                    r = socket.recv()
+                    if r is None:
+                        return None
+                    summary("Received %d octets" % len(r))
+                    req += r
+                    if len(req) == 0:
+                        continue
+                    try:
+                        list(ndef.message_decoder(req, 'strict', {}))
+                    except ndef.DecodeError:
+                        continue
+                    summary("Full message received")
+                    resp = self._process_request_data(req)
+                    if resp is None or len(resp) == 0:
+                        summary("No handover select to send out - wait for a possible alternative handover request")
+                        req = bytearray()
+                        continue
+
+                    for offset in range(0, len(resp), send_miu):
+                        if not socket.send(resp[offset:offset + send_miu]):
+                            summary("Failed to send handover select - connection closed")
+                            return
+                    summary("Sent out full handover select")
+                    if handover.terminate_on_hs_send_completion:
+                        handover.delayed_exit()
+
+        except nfc.llcp.Error as e:
+            global terminate_now
+            summary("HandoverServer exception: %s" % e,
+                    color=None if e.errno == errno.EPIPE or terminate_now else C_RED)
+        finally:
+            socket.close()
+            summary("Handover serve thread exiting")
+
     def process_handover_request_message(self, records):
         handover = self.handover
         self.ho_server_processing = True
@@ -634,6 +677,7 @@ class HandoverServer(nfc.handover.HandoverServer):
         summary("Sending handover select: " + str(sel))
         if found:
             summary("Handover completed successfully")
+            handover.terminate_on_hs_send_completion = True
             self.success = True
             handover.hs_sent = True
         elif handover.no_alt_proposal:
@@ -848,6 +892,7 @@ class ConnectionHandover():
         self.client = None
         self.client_thread = None
         self.reset()
+        self.exit_thread = None
 
     def reset(self):
         self.wait_connection = False
@@ -859,6 +904,7 @@ class ConnectionHandover():
         self.alt_proposal_used = False
         self.i_m_selector = False
         self.start_client_alt = False
+        self.terminate_on_hs_send_completion = False
 
     def start_handover_server(self, llc):
         summary("Start handover server")
@@ -870,6 +916,19 @@ class ConnectionHandover():
             self.client.close()
             self.client = None
 
+    def run_delayed_exit(self):
+        summary("Trying to exit (delayed)..")
+        time.sleep(0.25)
+        summary("Trying to exit (after wait)..")
+        global terminate_now
+        terminate_now = True
+
+    def delayed_exit(self):
+        global only_one
+        if only_one:
+            self.exit_thread = threading.Thread(target=self.run_delayed_exit)
+            self.exit_thread.start()
+
 def llcp_startup(llc):
     global handover
     handover.start_handover_server(llc)