From d6bfaaac69d452432df52be67201fbf2dddd1adc Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 12 Feb 2014 12:48:26 +0200 Subject: [PATCH] NFC: Add summary and success file options for nfcpy scripts These can be used to get updates on NFC operation status and success for external programs. Signed-hostap: Jouni Malinen --- hostapd/wps-ap-nfc.py | 79 ++++++++++++++++++------ wpa_supplicant/examples/p2p-nfc.py | 92 ++++++++++++++++++++-------- wpa_supplicant/examples/wps-nfc.py | 98 ++++++++++++++++++++++-------- 3 files changed, 201 insertions(+), 68 deletions(-) diff --git a/hostapd/wps-ap-nfc.py b/hostapd/wps-ap-nfc.py index 58e538a45..aa75d5bca 100755 --- a/hostapd/wps-ap-nfc.py +++ b/hostapd/wps-ap-nfc.py @@ -22,6 +22,20 @@ import wpaspy wpas_ctrl = '/var/run/hostapd' continue_loop = True +summary_file = None +success_file = None + +def summary(txt): + print txt + if summary_file: + with open(summary_file, 'a') as f: + f.write(txt + "\n") + +def success_report(txt): + summary(txt) + if success_file: + with open(success_file, 'a') as f: + f.write(txt + "\n") def wpas_connect(): ifaces = [] @@ -48,7 +62,7 @@ def wpas_connect(): def wpas_tag_read(message): wpas = wpas_connect() if (wpas == None): - return + return False if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")): return False return True @@ -58,21 +72,30 @@ def wpas_get_config_token(): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex") + ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF") + if "FAIL" in ret: + return None + return ret.rstrip().decode("hex") def wpas_get_password_token(): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex") + ret = wpas.request("WPS_NFC_TOKEN NDEF") + if "FAIL" in ret: + return None + return ret.rstrip().decode("hex") def wpas_get_handover_sel(): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex") + ret = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR") + if "FAIL" in ret: + return None + return ret.rstrip().decode("hex") def wpas_report_handover(req, sel): @@ -91,7 +114,7 @@ class HandoverServer(nfc.handover.HandoverServer): self.success = False def process_request(self, request): - print "HandoverServer - request received" + summary("HandoverServer - request received") try: print "Parsed handover request: " + request.pretty() except Exception, e: @@ -103,14 +126,17 @@ class HandoverServer(nfc.handover.HandoverServer): 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" + summary("WPS carrier type match - add WPS carrier record") data = wpas_get_handover_sel() if data is None: - print "Could not get handover select carrier record from hostapd" + summary("Could not get handover select carrier record from hostapd") continue print "Handover select carrier record from hostapd:" print data.encode("hex") - wpas_report_handover(carrier.record, data) + if "OK" in wpas_report_handover(carrier.record, data): + success_report("Handover reported successfully") + else: + summary("Handover report rejected") message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) @@ -122,7 +148,7 @@ class HandoverServer(nfc.handover.HandoverServer): print e print str(sel).encode("hex") - print "Sending handover select" + summary("Sending handover select") self.success = True return sel @@ -133,19 +159,23 @@ def wps_tag_read(tag): for record in tag.ndef.message: print "record type " + record.type if record.type == "application/vnd.wfa.wsc": - print "WPS tag - send to hostapd" + summary("WPS tag - send to hostapd") success = wpas_tag_read(tag.ndef.message) break else: - print "Empty tag" + summary("Empty tag") + + if success: + success_report("Tag read succeeded") return success def rdwr_connected_write(tag): - print "Tag found - writing" + summary("Tag found - writing - " + str(tag)) global write_data tag.ndef.message = str(write_data) + success_report("Tag write succeeded") print "Done - remove tag" global only_one if only_one: @@ -156,12 +186,12 @@ def rdwr_connected_write(tag): time.sleep(0.1) def wps_write_config_tag(clf, wait_remove=True): - print "Write WPS config token" + summary("Write WPS config token") global write_data, write_wait_remove write_wait_remove = wait_remove write_data = wpas_get_config_token() if write_data == None: - print "Could not get WPS config token from hostapd" + summary("Could not get WPS config token from hostapd") return print "Touch an NFC tag" @@ -169,12 +199,12 @@ def wps_write_config_tag(clf, wait_remove=True): def wps_write_password_tag(clf, wait_remove=True): - print "Write WPS password token" + summary("Write WPS password token") global write_data, write_wait_remove write_wait_remove = wait_remove write_data = wpas_get_password_token() if write_data == None: - print "Could not get WPS password token from hostapd" + summary("Could not get WPS password token from hostapd") return print "Touch an NFC tag" @@ -183,7 +213,7 @@ def wps_write_password_tag(clf, wait_remove=True): def rdwr_connected(tag): global only_one, no_wait - print "Tag connected: " + str(tag) + summary("Tag connected: " + str(tag)) if tag.ndef: print "NDEF tag: " + tag.type @@ -196,7 +226,8 @@ def rdwr_connected(tag): global continue_loop continue_loop = False else: - print "Not an NDEF tag - remove tag" + summary("Not an NDEF tag - remove tag") + return True return not no_wait @@ -229,6 +260,10 @@ def main(): help='run only one operation and exit') parser.add_argument('--no-wait', action='store_true', help='do not wait for tag to be removed before exiting') + parser.add_argument('--summary', + help='summary file for writing status updates') + parser.add_argument('--success', + help='success file for writing success update') parser.add_argument('command', choices=['write-config', 'write-password'], nargs='?') @@ -240,6 +275,14 @@ def main(): global no_wait no_wait = args.no_wait + if args.summary: + global summary_file + summary_file = args.summary + + if args.success: + global success_file + success_file = args.success + logging.basicConfig(level=args.loglevel) try: diff --git a/wpa_supplicant/examples/p2p-nfc.py b/wpa_supplicant/examples/p2p-nfc.py index 585029ba1..94edca1dc 100755 --- a/wpa_supplicant/examples/p2p-nfc.py +++ b/wpa_supplicant/examples/p2p-nfc.py @@ -33,6 +33,20 @@ no_input = False srv = None continue_loop = True terminate_now = False +summary_file = None +success_file = None + +def summary(txt): + print txt + if summary_file: + with open(summary_file, 'a') as f: + f.write(txt + "\n") + +def success_report(txt): + summary(txt) + if success_file: + with open(success_file, 'a') as f: + f.write(txt + "\n") def wpas_connect(): ifaces = [] @@ -63,7 +77,7 @@ def wpas_connect(): def wpas_tag_read(message): wpas = wpas_connect() if (wpas == None): - return + return False cmd = "WPS_NFC_TAG_READ " + str(message).encode("hex") global force_freq if force_freq: @@ -144,7 +158,7 @@ def p2p_handover_client(llc): if include_p2p_req: data = wpas_get_handover_req() if (data == None): - print "Could not get handover request carrier record from wpa_supplicant" + summary("Could not get handover request carrier record from wpa_supplicant") return print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") datamsg = nfc.ndef.Message(data) @@ -173,31 +187,33 @@ def p2p_handover_client(llc): client = nfc.handover.HandoverClient(llc) try: - print "Trying handover"; + summary("Trying to initiate NFC connection handover") client.connect() - print "Connected for handover" + summary("Connected for handover") except nfc.llcp.ConnectRefused: - print "Handover connection refused" + summary("Handover connection refused") client.close() return except Exception, e: - print "Other exception: " + str(e) + summary("Other exception: " + str(e)) client.close() return - print "Sending handover request" + summary("Sending handover request") if not client.send(message): - print "Failed to send handover request" + summary("Failed to send handover request") + client.close() + return - print "Receiving handover response" + summary("Receiving handover response") message = client._recv() if message is None: - print "No response received" + summary("No response received") client.close() return if message.type != "urn:nfc:wkt:Hs": - print "Response was not Hs - received: " + message.type + summary("Response was not Hs - received: " + message.type) client.close() return @@ -208,7 +224,7 @@ def p2p_handover_client(llc): print e print str(message).encode("hex") message = nfc.ndef.HandoverSelectMessage(message) - print "Handover select received" + summary("Handover select received") try: print message.pretty() except Exception, e: @@ -218,7 +234,10 @@ def p2p_handover_client(llc): print "Remote carrier type: " + carrier.type if carrier.type == "application/vnd.wfa.p2p": print "P2P carrier type match - send to wpa_supplicant" - wpas_report_handover(data, carrier.record, "INIT") + if "OK" in wpas_report_handover(data, carrier.record, "INIT"): + success_report("P2P handover reported successfully (initiator)") + else: + summary("P2P handover report rejected") break print "Remove peer" @@ -275,8 +294,11 @@ class HandoverServer(nfc.handover.HandoverServer): print "Handover select carrier record from wpa_supplicant:" print data.encode("hex") self.sent_carrier = data - wpas_report_handover(self.received_carrier, self.sent_carrier, - "RESP") + if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"): + success_report("P2P handover reported successfully (responder)") + else: + summary("P2P handover report rejected") + break message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) @@ -302,8 +324,11 @@ class HandoverServer(nfc.handover.HandoverServer): print "Handover select carrier record from wpa_supplicant:" print data.encode("hex") self.sent_carrier = data - wpas_report_handover_wsc(self.received_carrier, - self.sent_carrier, "RESP") + if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"): + success_report("WSC handover reported successfully") + else: + summary("WSC handover report rejected") + break message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) @@ -317,7 +342,7 @@ class HandoverServer(nfc.handover.HandoverServer): print e print str(sel).encode("hex") - print "Sending handover select" + summary("Sending handover select") self.success = True return sel @@ -356,23 +381,27 @@ def p2p_tag_read(tag): for record in tag.ndef.message: print "record type " + record.type if record.type == "application/vnd.wfa.wsc": - print "WPS tag - send to wpa_supplicant" + summary("WPS tag - send to wpa_supplicant") success = wpas_tag_read(tag.ndef.message) break if record.type == "application/vnd.wfa.p2p": - print "P2P tag - send to wpa_supplicant" + summary("P2P tag - send to wpa_supplicant") success = wpas_tag_read(tag.ndef.message) break else: - print "Empty tag" + summary("Empty tag") + + if success: + success_report("Tag read succeeded") return success def rdwr_connected_p2p_write(tag): - print "Tag found - writing" + summary("Tag found - writing - " + str(tag)) global p2p_sel_data tag.ndef.message = str(p2p_sel_data) + success_report("Tag write succeeded") print "Done - remove tag" global only_one if only_one: @@ -385,7 +414,7 @@ def wps_write_p2p_handover_sel(clf, wait_remove=True): print "Write P2P handover select" data = wpas_get_handover_sel(tag=True) if (data == None): - print "Could not get P2P handover select from wpa_supplicant" + summary("Could not get P2P handover select from wpa_supplicant") return global p2p_sel_wait_remove @@ -407,7 +436,7 @@ def wps_write_p2p_handover_sel(clf, wait_remove=True): def rdwr_connected(tag): global only_one, no_wait - print "Tag connected: " + str(tag) + summary("Tag connected: " + str(tag)) if tag.ndef: print "NDEF tag: " + tag.type @@ -420,7 +449,8 @@ def rdwr_connected(tag): global continue_loop continue_loop = False else: - print "Not an NDEF tag - remove tag" + summary("Not an NDEF tag - remove tag") + return True return not no_wait @@ -515,6 +545,10 @@ def main(): help='connection handover only (do not allow tag read)') parser.add_argument('--freq', '-f', help='forced frequency of operating channel in MHz') + parser.add_argument('--summary', + help='summary file for writing status updates') + parser.add_argument('--success', + help='success file for writing success update') parser.add_argument('command', choices=['write-p2p-sel'], nargs='?') args = parser.parse_args() @@ -542,6 +576,14 @@ def main(): global include_wps_req include_wps_req = False + if args.summary: + global summary_file + summary_file = args.summary + + if args.success: + global success_file + success_file = args.success + if args.no_input: global no_input no_input = True diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py index 35d12706e..e57eded8f 100755 --- a/wpa_supplicant/examples/wps-nfc.py +++ b/wpa_supplicant/examples/wps-nfc.py @@ -26,6 +26,20 @@ wpas_ctrl = '/var/run/wpa_supplicant' srv = None continue_loop = True terminate_now = False +summary_file = None +success_file = None + +def summary(txt): + print txt + if summary_file: + with open(summary_file, 'a') as f: + f.write(txt + "\n") + +def success_report(txt): + summary(txt) + if success_file: + with open(success_file, 'a') as f: + f.write(txt + "\n") def wpas_connect(): ifaces = [] @@ -84,14 +98,19 @@ def wpas_get_password_token(): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex") - + ret = wpas.request("WPS_NFC_TOKEN NDEF") + if "FAIL" in ret: + return None + return ret.rstrip().decode("hex") def wpas_get_handover_req(): wpas = wpas_connect() if (wpas == None): return None - return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex") + ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR") + if "FAIL" in ret: + return None + return ret.rstrip().decode("hex") def wpas_get_handover_sel(uuid): @@ -125,7 +144,7 @@ class HandoverServer(nfc.handover.HandoverServer): def process_request(self, request): self.ho_server_processing = True - print "HandoverServer - request received" + summary("HandoverServer - request received") try: print "Parsed handover request: " + request.pretty() except Exception, e: @@ -136,15 +155,18 @@ class HandoverServer(nfc.handover.HandoverServer): 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" + summary("WPS carrier type match - add WPS carrier record") data = wpas_get_handover_sel(self.uuid) if data is None: - print "Could not get handover select carrier record from wpa_supplicant" + summary("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 - wpas_report_handover(carrier.record, self.sent_carrier, "RESP") + if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"): + success_report("Handover reported successfully (responder)") + else: + summary("Handover report rejected (responder)") message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) @@ -156,17 +178,17 @@ class HandoverServer(nfc.handover.HandoverServer): print e print str(sel).encode("hex") - print "Sending handover select" + summary("Sending handover select") self.success = True return sel def wps_handover_init(llc): - print "Trying to initiate WPS handover" + summary("Trying to initiate WPS handover") data = wpas_get_handover_req() if (data == None): - print "Could not get handover request carrier record from wpa_supplicant" + summary("Could not get handover request carrier record from wpa_supplicant") return print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") @@ -184,27 +206,33 @@ def wps_handover_init(llc): client = nfc.handover.HandoverClient(llc) try: - print "Trying handover"; + summary("Trying to initiate NFC connection handover") client.connect() - print "Connected for handover" + summary("Connected for handover") except nfc.llcp.ConnectRefused: - print "Handover connection refused" + summary("Handover connection refused") + client.close() + return + except Exception, e: + summary("Other exception: " + str(e)) client.close() return - print "Sending handover request" + summary("Sending handover request") if not client.send(message): - print "Failed to send handover request" + summary("Failed to send handover request") + client.close() + return - print "Receiving handover response" + summary("Receiving handover response") message = client._recv() if message is None: - print "No response received" + summary("No response received") client.close() return if message.type != "urn:nfc:wkt:Hs": - print "Response was not Hs - received: " + message.type + summary("Response was not Hs - received: " + message.type) client.close() return @@ -215,7 +243,7 @@ def wps_handover_init(llc): print e print str(message).encode("hex") message = nfc.ndef.HandoverSelectMessage(message) - print "Handover select received" + summary("Handover select received") try: print message.pretty() except Exception, e: @@ -225,7 +253,10 @@ def wps_handover_init(llc): 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, "INIT") + if "OK" in wpas_report_handover(data, carrier.record, "INIT"): + success_report("Handover reported successfully (initiator)") + else: + summary("Handover report rejected (initiator)") # nfcpy does not support the new format.. #wifi = nfc.ndef.WifiConfigRecord(carrier.record) #print wifi.pretty() @@ -250,11 +281,14 @@ def wps_tag_read(tag, wait_remove=True): for record in tag.ndef.message: print "record type " + record.type if record.type == "application/vnd.wfa.wsc": - print "WPS tag - send to wpa_supplicant" + summary("WPS tag - send to wpa_supplicant") success = wpas_tag_read(tag.ndef.message) break else: - print "Empty tag" + summary("Empty tag") + + if success: + success_report("Tag read succeeded") if wait_remove: print "Remove tag" @@ -265,9 +299,10 @@ def wps_tag_read(tag, wait_remove=True): def rdwr_connected_write(tag): - print "Tag found - writing" + summary("Tag found - writing - " + str(tag)) global write_data tag.ndef.message = str(write_data) + success_report("Tag write succeeded") print "Done - remove tag" global only_one if only_one: @@ -318,7 +353,7 @@ def wps_write_password_tag(clf, wait_remove=True): def rdwr_connected(tag): global only_one, no_wait - print "Tag connected: " + str(tag) + summary("Tag connected: " + str(tag)) if tag.ndef: print "NDEF tag: " + tag.type @@ -331,7 +366,8 @@ def rdwr_connected(tag): global continue_loop continue_loop = False else: - print "Not an NDEF tag - remove tag" + summary("Not an NDEF tag - remove tag") + return True return not no_wait @@ -398,6 +434,10 @@ def main(): help='UUID of an AP (used for WPS ER operations)') parser.add_argument('--id', help='network id (used for WPS ER operations)') + parser.add_argument('--summary', + help='summary file for writing status updates') + parser.add_argument('--success', + help='success file for writing success update') parser.add_argument('command', choices=['write-config', 'write-er-config', 'write-password'], @@ -413,6 +453,14 @@ def main(): global no_wait no_wait = args.no_wait + if args.summary: + global summary_file + summary_file = args.summary + + if args.success: + global success_file + success_file = args.success + logging.basicConfig(level=args.loglevel) try: