1d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#!/usr/bin/python 2d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt# 3d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations 4f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi> 5d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt# 6d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt# This software may be distributed under the terms of the BSD license. 7d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt# See README for more details. 8d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 9d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport os 10d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport sys 11d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport time 12f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtimport random 13cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport threading 14cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport argparse 15d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 16d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport nfc 17d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport nfc.ndef 18d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport nfc.llcp 19d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtimport nfc.handover 20d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 21f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtimport logging 22f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 23700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtimport wpaspy 24d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 25d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtwpas_ctrl = '/var/run/wpa_supplicant' 26cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtsrv = None 27cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtcontinue_loop = True 28cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtterminate_now = False 2996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtsummary_file = None 3096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtsuccess_file = None 3196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 3296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtdef summary(txt): 3396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt print txt 3496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if summary_file: 3596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt with open(summary_file, 'a') as f: 3696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt f.write(txt + "\n") 3796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 3896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtdef success_report(txt): 3996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary(txt) 4096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if success_file: 4196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt with open(success_file, 'a') as f: 4296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt f.write(txt + "\n") 43d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 44d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtdef wpas_connect(): 45d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ifaces = [] 46d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if os.path.isdir(wpas_ctrl): 47d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try: 48d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 49d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt except OSError, error: 50d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "Could not find wpa_supplicant: ", error 51d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return None 52d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 53d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if len(ifaces) < 1: 54d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "No wpa_supplicant control interface found" 55d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return None 56d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 57d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for ctrl in ifaces: 58d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try: 59700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas = wpaspy.Ctrl(ctrl) 60d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpas 61700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt except Exception, e: 62d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pass 63d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return None 64d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 65d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 66d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtdef wpas_tag_read(message): 67d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas = wpas_connect() 68d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas == None): 694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return False 70cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")): 714b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return False 724b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return True 73d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 741e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidtdef wpas_get_config_token(id=None): 75f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpas = wpas_connect() 76f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (wpas == None): 77f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return None 781e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if id: 794b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id) 804b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt else: 814b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF") 824b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if "FAIL" in ret: 834b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return None 844b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return ret.rstrip().decode("hex") 85f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 86f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidtdef wpas_get_er_config_token(uuid): 8833e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt wpas = wpas_connect() 8933e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt if (wpas == None): 9033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt return None 91cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ret = wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid) 92cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if "FAIL" in ret: 93cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return None 94cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return ret.rstrip().decode("hex") 9533e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 9633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 97f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtdef wpas_get_password_token(): 98f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpas = wpas_connect() 99f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (wpas == None): 100f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return None 10196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt ret = wpas.request("WPS_NFC_TOKEN NDEF") 10296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if "FAIL" in ret: 10396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return None 10496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return ret.rstrip().decode("hex") 105f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 106d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtdef wpas_get_handover_req(): 107d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas = wpas_connect() 108d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas == None): 109d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return None 11096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR") 11196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if "FAIL" in ret: 11296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return None 11396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return ret.rstrip().decode("hex") 114d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 115d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 11633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidtdef wpas_get_handover_sel(uuid): 117d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas = wpas_connect() 118d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas == None): 119f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return None 12033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt if uuid is None: 121cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() 122cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else: 123cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip() 124cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if "FAIL" in res: 125cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return None 126cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return res.decode("hex") 12733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 12833e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 12933e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidtdef wpas_report_handover(req, sel, type): 13033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt wpas = wpas_connect() 13133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt if (wpas == None): 13233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt return None 13333e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " + 134f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt str(req).encode("hex") + " " + 135f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt str(sel).encode("hex")) 136d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 137d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 13833e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidtclass HandoverServer(nfc.handover.HandoverServer): 139cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt def __init__(self, llc): 140cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt super(HandoverServer, self).__init__(llc) 141cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt self.sent_carrier = None 142cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt self.ho_server_processing = False 143cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt self.success = False 14433e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 14596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt # override to avoid parser error in request/response.pretty() in nfcpy 14696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt # due to new WSC handover format 14796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt def _process_request(self, request): 14896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("received handover request {}".format(request.type)) 14996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt response = nfc.ndef.Message("\xd1\x02\x01Hs\x12") 15096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if not request.type == 'urn:nfc:wkt:Hr': 15196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("not a handover request") 15296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt else: 15396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt try: 15496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt request = nfc.ndef.HandoverRequestMessage(request) 15596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt except nfc.ndef.DecodeError as e: 15696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("error decoding 'Hr' message: {}".format(e)) 15796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt else: 15896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt response = self.process_request(request) 15996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("send handover response {}".format(response.type)) 16096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return response 16196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 16233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt def process_request(self, request): 163cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt self.ho_server_processing = True 16496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("HandoverServer - request received") 165cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 166cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Parsed handover request: " + request.pretty() 167cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 168cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 16933e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 17033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt sel = nfc.ndef.HandoverSelectMessage(version="1.2") 17133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 17233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt for carrier in request.carriers: 17333e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Remote carrier type: " + carrier.type 17433e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt if carrier.type == "application/vnd.wfa.wsc": 17596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("WPS carrier type match - add WPS carrier record") 17633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt data = wpas_get_handover_sel(self.uuid) 17733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt if data is None: 17896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Could not get handover select carrier record from wpa_supplicant") 17933e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt continue 18033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Handover select carrier record from wpa_supplicant:" 18133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print data.encode("hex") 18233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt self.sent_carrier = data 18396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"): 18496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt success_report("Handover reported successfully (responder)") 18596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt else: 18696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Handover report rejected (responder)") 18733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 18833e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt message = nfc.ndef.Message(data); 18933e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt sel.add_carrier(message[0], "active", message[1:]) 19033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 19133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Handover select:" 192cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 193cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print sel.pretty() 194cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 195cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 19633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print str(sel).encode("hex") 19733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 19896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Sending handover select") 199cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt self.success = True 20033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt return sel 20133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 20233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 203cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wps_handover_init(llc): 20496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Trying to initiate WPS handover") 205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 206d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data = wpas_get_handover_req() 207d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (data == None): 20896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Could not get handover request carrier record from wpa_supplicant") 209d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 210f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") 211f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 212f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt message = nfc.ndef.HandoverRequestMessage(version="1.2") 213f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt message.nonce = random.randint(0, 0xffff) 214cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt datamsg = nfc.ndef.Message(data) 215cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt message.add_carrier(datamsg[0], "active", datamsg[1:]) 216f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 217f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Handover request:" 218cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 219cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print message.pretty() 220cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 221cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 222cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print str(message).encode("hex") 223d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 224cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt client = nfc.handover.HandoverClient(llc) 225d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try: 22696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Trying to initiate NFC connection handover") 227d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt client.connect() 22896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Connected for handover") 229d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt except nfc.llcp.ConnectRefused: 23096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Handover connection refused") 23196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt client.close() 23296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 23396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt except Exception, e: 23496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Other exception: " + str(e)) 235d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt client.close() 236d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 237d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 23896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Sending handover request") 239d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 240d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if not client.send(message): 24196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Failed to send handover request") 24296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt client.close() 24396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 244d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 24596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Receiving handover response") 246d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt message = client._recv() 247f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if message is None: 24896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("No response received") 249f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt client.close() 250f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 251f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if message.type != "urn:nfc:wkt:Hs": 25296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Response was not Hs - received: " + message.type) 253f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt client.close() 254f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 255f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 256f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Received message" 257cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 258cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print message.pretty() 259cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 260cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 261cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print str(message).encode("hex") 262f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt message = nfc.ndef.HandoverSelectMessage(message) 26396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Handover select received") 264cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 265cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print message.pretty() 266cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 267cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 268f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 269f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt for carrier in message.carriers: 270f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Remote carrier type: " + carrier.type 271f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if carrier.type == "application/vnd.wfa.wsc": 272f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "WPS carrier type match - send to wpa_supplicant" 27396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if "OK" in wpas_report_handover(data, carrier.record, "INIT"): 27496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt success_report("Handover reported successfully (initiator)") 27596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt else: 27696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Handover report rejected (initiator)") 277cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt # nfcpy does not support the new format.. 278cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt #wifi = nfc.ndef.WifiConfigRecord(carrier.record) 279cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt #print wifi.pretty() 280d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 281d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "Remove peer" 282d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt client.close() 283d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "Done with handover" 284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global only_one 285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if only_one: 286cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global continue_loop 287cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue_loop = False 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 289cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global no_wait 290cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if no_wait: 291cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Trying to exit.." 292cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global terminate_now 293cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt terminate_now = True 294d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2954b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtdef wps_tag_read(tag, wait_remove=True): 2964b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt success = False 297d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if len(tag.ndef.message): 298cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt for record in tag.ndef.message: 299d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "record type " + record.type 300d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if record.type == "application/vnd.wfa.wsc": 30196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("WPS tag - send to wpa_supplicant") 3024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt success = wpas_tag_read(tag.ndef.message) 303d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt break 304d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else: 30596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Empty tag") 30696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 30796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if success: 30896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt success_report("Tag read succeeded") 309d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3104b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if wait_remove: 3114b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt print "Remove tag" 3124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt while tag.is_present: 3134b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt time.sleep(0.1) 3144b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 3154b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return success 316d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 317d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 318cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef rdwr_connected_write(tag): 31996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Tag found - writing - " + str(tag)) 320cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global write_data 321cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt tag.ndef.message = str(write_data) 32296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt success_report("Tag write succeeded") 323cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Done - remove tag" 324cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global only_one 325cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if only_one: 326cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global continue_loop 327cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue_loop = False 328cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global write_wait_remove 329cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt while write_wait_remove and tag.is_present: 330cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt time.sleep(0.1) 331cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 3324b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtdef wps_write_config_tag(clf, id=None, wait_remove=True): 333f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Write WPS config token" 334cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global write_data, write_wait_remove 335cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_wait_remove = wait_remove 336cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_data = wpas_get_config_token(id) 337cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if write_data == None: 338f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Could not get WPS config token from wpa_supplicant" 3394b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt sys.exit(1) 340f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 341f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Touch an NFC tag" 342cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clf.connect(rdwr={'on-connect': rdwr_connected_write}) 343f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 344f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 345cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wps_write_er_config_tag(clf, uuid, wait_remove=True): 34633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Write WPS ER config token" 347cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global write_data, write_wait_remove 348cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_wait_remove = wait_remove 349cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_data = wpas_get_er_config_token(uuid) 350cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if write_data == None: 35133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Could not get WPS config token from wpa_supplicant" 35233e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt return 35333e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 35433e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt print "Touch an NFC tag" 355cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clf.connect(rdwr={'on-connect': rdwr_connected_write}) 35633e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 35733e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 3584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtdef wps_write_password_tag(clf, wait_remove=True): 359f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Write WPS password token" 360cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global write_data, write_wait_remove 361cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_wait_remove = wait_remove 362cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt write_data = wpas_get_password_token() 363cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if write_data == None: 364f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Could not get WPS password token from wpa_supplicant" 365f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 366f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 367f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt print "Touch an NFC tag" 368cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clf.connect(rdwr={'on-connect': rdwr_connected_write}) 369f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 370f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 371cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef rdwr_connected(tag): 372cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global only_one, no_wait 37396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Tag connected: " + str(tag)) 374f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 375cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if tag.ndef: 376cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "NDEF tag: " + tag.type 377cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 378cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print tag.ndef.message.pretty() 379cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 380cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print e 381cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt success = wps_tag_read(tag, not only_one) 382cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if only_one and success: 383cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global continue_loop 384cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue_loop = False 385cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else: 38696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary("Not an NDEF tag - remove tag") 38796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return True 388f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 389cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return not no_wait 390f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 391d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 392cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_worker(llc): 393cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global arg_uuid 394cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if arg_uuid is None: 395cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_handover_init(llc) 396cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Exiting llcp_worker thread" 397cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 39833e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 399cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global srv 400cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global wait_connection 401cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt while not wait_connection and srv.sent_carrier is None: 402cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if srv.ho_server_processing: 403cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt time.sleep(0.025) 404cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 405cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_startup(clf, llc): 406cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global arg_uuid 407cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if arg_uuid: 408cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Start LLCP server" 409cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global srv 410cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt srv = HandoverServer(llc) 411cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if arg_uuid is "ap": 412cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Trying to handle WPS handover" 413cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt srv.uuid = None 4144b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt else: 415cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Trying to handle WPS handover with AP " + arg_uuid 416cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt srv.uuid = arg_uuid 417cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return llc 418cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 419cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_connected(llc): 420cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "P2P LLCP connected" 421cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global wait_connection 422cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wait_connection = False 423cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global arg_uuid 424cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if arg_uuid: 425cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global srv 426cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt srv.start() 427cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else: 428cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt threading.Thread(target=llcp_worker, args=(llc,)).start() 429cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "llcp_connected returning" 430cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return True 4314b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 432f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 433cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef terminate_loop(): 434cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global terminate_now 435cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return terminate_now 436cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 437cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef main(): 438cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clf = nfc.ContactlessFrontend() 439cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 440cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for WPS NFC operations') 441cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO, 442cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt action='store_const', dest='loglevel', 443cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt help='verbose debug output') 444cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('-q', const=logging.WARNING, action='store_const', 445cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dest='loglevel', help='be quiet') 446cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('--only-one', '-1', action='store_true', 447cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt help='run only one operation and exit') 448cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('--no-wait', action='store_true', 449cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt help='do not wait for tag to be removed before exiting') 450cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('--uuid', 451cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt help='UUID of an AP (used for WPS ER operations)') 452cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('--id', 453cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt help='network id (used for WPS ER operations)') 45496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt parser.add_argument('--summary', 45596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt help='summary file for writing status updates') 45696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt parser.add_argument('--success', 45796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt help='success file for writing success update') 458cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt parser.add_argument('command', choices=['write-config', 459cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 'write-er-config', 460cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 'write-password'], 461cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt nargs='?') 462cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt args = parser.parse_args() 463cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 464cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global arg_uuid 465cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt arg_uuid = args.uuid 466cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 467cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global only_one 468cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt only_one = args.only_one 469cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 470cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global no_wait 471cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt no_wait = args.no_wait 472cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 47396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if args.summary: 47496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt global summary_file 47596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt summary_file = args.summary 47696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 47796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if args.success: 47896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt global success_file 47996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt success_file = args.success 48096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 481cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt logging.basicConfig(level=args.loglevel) 4824b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 483cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 484cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if not clf.open("usb"): 485cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "Could not open connection with an NFC device" 4861e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt raise SystemExit 4871e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt 488cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if args.command == "write-config": 489cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_write_config_tag(clf, id=args.id, wait_remove=not args.no_wait) 49033e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt raise SystemExit 49133e38bfa7159cef089d6ee0d904778e184c72c47Dmitry Shmidt 492cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if args.command == "write-er-config": 493cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_write_er_config_tag(clf, args.uuid, wait_remove=not args.no_wait) 494f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt raise SystemExit 495f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 496cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if args.command == "write-password": 497cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_write_password_tag(clf, wait_remove=not args.no_wait) 4984b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt raise SystemExit 4994b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 500cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global continue_loop 501cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt while continue_loop: 502d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt print "Waiting for a tag or peer to be touched" 503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wait_connection = True 504cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt try: 505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if not clf.connect(rdwr={'on-connect': rdwr_connected}, 506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt llcp={'on-startup': llcp_startup, 507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 'on-connect': llcp_connected}, 508cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt terminate=terminate_loop): 5094b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt break 510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt except Exception, e: 511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt print "clf.connect failed" 512f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt global srv 514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if only_one and srv and srv.success: 515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt raise SystemExit 516d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 517d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt except KeyboardInterrupt: 518d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt raise SystemExit 519d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt finally: 520d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt clf.close() 521d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 522d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt raise SystemExit 523d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 524d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtif __name__ == '__main__': 525d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt main() 526