1cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#!/usr/bin/python
2cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#
3cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt# Example nfcpy to wpa_supplicant wrapper for P2P NFC operations
4cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
5cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#
6cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt# This software may be distributed under the terms of the BSD license.
7cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt# See README for more details.
8cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
9cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport os
10cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport sys
11cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport time
12cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport random
13cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport threading
14cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport argparse
15cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
16cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport nfc
17cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport nfc.ndef
18cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport nfc.llcp
19cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport nfc.handover
20cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
21cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport logging
22cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
23cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtimport wpaspy
24cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
25cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtwpas_ctrl = '/var/run/wpa_supplicant'
26cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtifname = None
27cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtinit_on_touch = False
28cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtin_raw_mode = False
29cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtprev_tcgetattr = 0
30cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtinclude_wps_req = True
31cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtinclude_p2p_req = True
32cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtno_input = False
33cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtsrv = None
34cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtcontinue_loop = True
35cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtterminate_now = False
3696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtsummary_file = None
3796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtsuccess_file = None
3896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
3996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtdef summary(txt):
4096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    print txt
4196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if summary_file:
4296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        with open(summary_file, 'a') as f:
4396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            f.write(txt + "\n")
4496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
4596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtdef success_report(txt):
4696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary(txt)
4796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if success_file:
4896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        with open(success_file, 'a') as f:
4996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            f.write(txt + "\n")
50cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
51cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_connect():
52cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    ifaces = []
53cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if os.path.isdir(wpas_ctrl):
54cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
55cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
56cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except OSError, error:
57cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Could not find wpa_supplicant: ", error
58cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            return None
59cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
60cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if len(ifaces) < 1:
61cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "No wpa_supplicant control interface found"
62cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
63cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
64cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    for ctrl in ifaces:
65cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if ifname:
66cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if ifname not in ctrl:
67cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                continue
68cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
69cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Trying to use control interface " + ctrl
70cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            wpas = wpaspy.Ctrl(ctrl)
71cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            return wpas
72cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except Exception, e:
73cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            pass
74cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return None
75cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
76cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
77cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_tag_read(message):
78cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
79cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
8096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return False
81cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    cmd = "WPS_NFC_TAG_READ " + str(message).encode("hex")
82cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global force_freq
83cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if force_freq:
84cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        cmd = cmd + " freq=" + force_freq
85cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if "FAIL" in wpas.request(cmd):
86cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return False
87cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return True
88cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
89cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
90cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_get_handover_req():
91cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
92cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
93cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
9496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    res = wpas.request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip()
95cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if "FAIL" in res:
96cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
9796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    return res.decode("hex")
98cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
99cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_get_handover_req_wps():
100cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
101cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
102cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
10396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    res = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip()
10496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if "FAIL" in res:
10596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return None
10696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    return res.decode("hex")
107cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
108cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
109cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_get_handover_sel(tag=False):
110cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
111cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
112cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
113cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if tag:
11496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG").rstrip()
11596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    else:
11696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip()
11796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if "FAIL" in res:
11896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return None
11996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    return res.decode("hex")
120cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
121cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
122cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_get_handover_sel_wps():
123cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
124cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
125cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
126cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR");
127cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if "FAIL" in res:
128cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
129cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return res.rstrip().decode("hex")
130cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
131cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
132cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_report_handover(req, sel, type):
133cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
134cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
135cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
136cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    cmd = "NFC_REPORT_HANDOVER " + type + " P2P " + str(req).encode("hex") + " " + str(sel).encode("hex")
137cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global force_freq
138cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if force_freq:
139cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        cmd = cmd + " freq=" + force_freq
140cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return wpas.request(cmd)
141cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
142cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
143cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wpas_report_handover_wsc(req, sel, type):
144cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wpas = wpas_connect()
145cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (wpas == None):
146cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return None
147cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    cmd = "NFC_REPORT_HANDOVER " + type + " WPS " + str(req).encode("hex") + " " + str(sel).encode("hex")
148cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if force_freq:
149cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        cmd = cmd + " freq=" + force_freq
150cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return wpas.request(cmd)
151cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
152cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
153cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef p2p_handover_client(llc):
154cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    message = nfc.ndef.HandoverRequestMessage(version="1.2")
155cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    message.nonce = random.randint(0, 0xffff)
156cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
157cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global include_p2p_req
158cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if include_p2p_req:
159cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        data = wpas_get_handover_req()
160cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if (data == None):
16196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            summary("Could not get handover request carrier record from wpa_supplicant")
162cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            return
163cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Handover request carrier record from wpa_supplicant: " + data.encode("hex")
164cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        datamsg = nfc.ndef.Message(data)
165cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        message.add_carrier(datamsg[0], "active", datamsg[1:])
166cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
167cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global include_wps_req
168cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if include_wps_req:
169cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Handover request (pre-WPS):"
170cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
171cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print message.pretty()
172cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except Exception, e:
173cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print e
174cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
175cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        data = wpas_get_handover_req_wps()
176cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if data:
177cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Add WPS request in addition to P2P"
178cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            datamsg = nfc.ndef.Message(data)
179cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            message.add_carrier(datamsg[0], "active", datamsg[1:])
180cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
181cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Handover request:"
182cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
183cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print message.pretty()
184cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except Exception, e:
185cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print e
186cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print str(message).encode("hex")
187cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
188cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    client = nfc.handover.HandoverClient(llc)
189cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
19096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Trying to initiate NFC connection handover")
191cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        client.connect()
19296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Connected for handover")
193cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except nfc.llcp.ConnectRefused:
19496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Handover connection refused")
195cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        client.close()
196cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
197cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except Exception, e:
19896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Other exception: " + str(e))
199cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        client.close()
200cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
201cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
20296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary("Sending handover request")
203cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
204cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if not client.send(message):
20596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Failed to send handover request")
20696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        client.close()
20796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return
208cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
20996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary("Receiving handover response")
210cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    message = client._recv()
211cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if message is None:
21296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("No response received")
213cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        client.close()
214cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
215cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if message.type != "urn:nfc:wkt:Hs":
21696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Response was not Hs - received: " + message.type)
217cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        client.close()
218cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
219cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
220cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Received message"
221cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
222cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print message.pretty()
223cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except Exception, e:
224cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print e
225cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print str(message).encode("hex")
226cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    message = nfc.ndef.HandoverSelectMessage(message)
22796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary("Handover select received")
228cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
229cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print message.pretty()
230cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except Exception, e:
231cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print e
232cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
233cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    for carrier in message.carriers:
234cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Remote carrier type: " + carrier.type
235cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if carrier.type == "application/vnd.wfa.p2p":
236cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "P2P carrier type match - send to wpa_supplicant"
23796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
23896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                success_report("P2P handover reported successfully (initiator)")
23996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            else:
24096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                summary("P2P handover report rejected")
241cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            break
242cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
243cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Remove peer"
244cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    client.close()
245cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Done with handover"
246cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global only_one
247cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if only_one:
248cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "only_one -> stop loop"
249cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global continue_loop
250cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        continue_loop = False
251cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
252cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global no_wait
253cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if no_wait:
254cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Trying to exit.."
255cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global terminate_now
256cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        terminate_now = True
257cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
258cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
259cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtclass HandoverServer(nfc.handover.HandoverServer):
260cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    def __init__(self, llc):
261cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        super(HandoverServer, self).__init__(llc)
262cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        self.sent_carrier = None
263cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        self.ho_server_processing = False
264cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        self.success = False
265cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
26696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    # override to avoid parser error in request/response.pretty() in nfcpy
26796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    # due to new WSC handover format
26896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    def _process_request(self, request):
26996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("received handover request {}".format(request.type))
27096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
27196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        if not request.type == 'urn:nfc:wkt:Hr':
27296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            summary("not a handover request")
27396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        else:
27496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            try:
27596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                request = nfc.ndef.HandoverRequestMessage(request)
27696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            except nfc.ndef.DecodeError as e:
27796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                summary("error decoding 'Hr' message: {}".format(e))
27896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt            else:
27996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                response = self.process_request(request)
28096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("send handover response {}".format(response.type))
28196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return response
28296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    def process_request(self, request):
284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        self.ho_server_processing = True
285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        clear_raw_mode()
286cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "HandoverServer - request received"
287cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
288cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Parsed handover request: " + request.pretty()
289cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except Exception, e:
290cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print e
291cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
292cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        sel = nfc.ndef.HandoverSelectMessage(version="1.2")
293cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
294cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        found = False
295cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
296cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        for carrier in request.carriers:
297cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Remote carrier type: " + carrier.type
298cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if carrier.type == "application/vnd.wfa.p2p":
299cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "P2P carrier type match - add P2P carrier record"
300cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                found = True
301cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                self.received_carrier = carrier.record
302cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "Carrier record:"
303cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                try:
304cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print carrier.record.pretty()
305cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                except Exception, e:
306cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print e
307cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                data = wpas_get_handover_sel()
308cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                if data is None:
309cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print "Could not get handover select carrier record from wpa_supplicant"
310cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    continue
311cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "Handover select carrier record from wpa_supplicant:"
312cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print data.encode("hex")
313cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                self.sent_carrier = data
31496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"):
31596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    success_report("P2P handover reported successfully (responder)")
31696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                else:
31796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    summary("P2P handover report rejected")
31896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    break
319cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
320cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                message = nfc.ndef.Message(data);
321cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                sel.add_carrier(message[0], "active", message[1:])
322cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                break
323cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
324cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        for carrier in request.carriers:
325cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if found:
326cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                break
327cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Remote carrier type: " + carrier.type
328cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if carrier.type == "application/vnd.wfa.wsc":
329cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "WSC carrier type match - add WSC carrier record"
330cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                found = True
331cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                self.received_carrier = carrier.record
332cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "Carrier record:"
333cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                try:
334cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print carrier.record.pretty()
335cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                except Exception, e:
336cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print e
337cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                data = wpas_get_handover_sel_wps()
338cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                if data is None:
339cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    print "Could not get handover select carrier record from wpa_supplicant"
340cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    continue
341cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "Handover select carrier record from wpa_supplicant:"
342cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print data.encode("hex")
343cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                self.sent_carrier = data
34496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"):
34596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    success_report("WSC handover reported successfully")
34696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                else:
34796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    summary("WSC handover report rejected")
34896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    break
349cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
350cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                message = nfc.ndef.Message(data);
351cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                sel.add_carrier(message[0], "active", message[1:])
352cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                found = True
353cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                break
354cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
355cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Handover select:"
356cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
357cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print sel.pretty()
358cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except Exception, e:
359cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print e
360cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print str(sel).encode("hex")
361cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
36296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Sending handover select")
363cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        self.success = True
364cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return sel
365cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
366cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
367cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef clear_raw_mode():
368cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    import sys, tty, termios
369cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global prev_tcgetattr, in_raw_mode
370cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if not in_raw_mode:
371cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
372cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    fd = sys.stdin.fileno()
373cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
374cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    in_raw_mode = False
375cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
376cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
377cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef getch():
378cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    import sys, tty, termios, select
379cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global prev_tcgetattr, in_raw_mode
380cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    fd = sys.stdin.fileno()
381cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    prev_tcgetattr = termios.tcgetattr(fd)
382cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    ch = None
383cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
384cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        tty.setraw(fd)
385cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        in_raw_mode = True
386cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        [i, o, e] = select.select([fd], [], [], 0.05)
387cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if i:
388cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            ch = sys.stdin.read(1)
389cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    finally:
390cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
391cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        in_raw_mode = False
392cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return ch
393cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
394cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
395cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef p2p_tag_read(tag):
396cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    success = False
397cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if len(tag.ndef.message):
398cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        for record in tag.ndef.message:
399cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "record type " + record.type
400cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if record.type == "application/vnd.wfa.wsc":
40196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                summary("WPS tag - send to wpa_supplicant")
402cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                success = wpas_tag_read(tag.ndef.message)
403cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                break
404cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if record.type == "application/vnd.wfa.p2p":
40596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                summary("P2P tag - send to wpa_supplicant")
406cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                success = wpas_tag_read(tag.ndef.message)
407cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                break
408cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    else:
40996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Empty tag")
41096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
41196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if success:
41296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        success_report("Tag read succeeded")
413cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
414cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return success
415cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
416cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
417cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef rdwr_connected_p2p_write(tag):
41896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary("Tag found - writing - " + str(tag))
419cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global p2p_sel_data
420cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    tag.ndef.message = str(p2p_sel_data)
42196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    success_report("Tag write succeeded")
422cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Done - remove tag"
423cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global only_one
424cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if only_one:
425cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global continue_loop
426cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        continue_loop = False
427cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global p2p_sel_wait_remove
428cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return p2p_sel_wait_remove
429cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
430cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef wps_write_p2p_handover_sel(clf, wait_remove=True):
431cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Write P2P handover select"
432cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    data = wpas_get_handover_sel(tag=True)
433cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if (data == None):
43496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Could not get P2P handover select from wpa_supplicant")
435cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        return
436cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
437cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global p2p_sel_wait_remove
438cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    p2p_sel_wait_remove = wait_remove
439cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global p2p_sel_data
440cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    p2p_sel_data = nfc.ndef.HandoverSelectMessage(version="1.2")
441cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    message = nfc.ndef.Message(data);
442cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    p2p_sel_data.add_carrier(message[0], "active", message[1:])
443cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Handover select:"
444cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
445cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print p2p_sel_data.pretty()
446cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except Exception, e:
447cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print e
448cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print str(p2p_sel_data).encode("hex")
449cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
450cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Touch an NFC tag"
451cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    clf.connect(rdwr={'on-connect': rdwr_connected_p2p_write})
452cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
453cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
454cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef rdwr_connected(tag):
455cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global only_one, no_wait
45696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    summary("Tag connected: " + str(tag))
457cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
458cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if tag.ndef:
459cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "NDEF tag: " + tag.type
460cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        try:
461cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print tag.ndef.message.pretty()
462cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        except Exception, e:
463cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print e
464cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        success = p2p_tag_read(tag)
465cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if only_one and success:
466cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            global continue_loop
467cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            continue_loop = False
468cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    else:
46996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary("Not an NDEF tag - remove tag")
47096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        return True
471cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
472cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return not no_wait
473cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
474cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
475cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_worker(llc):
476cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global init_on_touch
477cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if init_on_touch:
478cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Starting handover client"
479cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            p2p_handover_client(llc)
480cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            return
481cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
482cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global no_input
483cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if no_input:
484cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Wait for handover to complete"
485cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    else:
486cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Wait for handover to complete - press 'i' to initiate ('w' for WPS only, 'p' for P2P only)"
487cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global srv
488cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global wait_connection
489cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    while not wait_connection and srv.sent_carrier is None:
490cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if srv.ho_server_processing:
491cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            time.sleep(0.025)
492cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        elif no_input:
493cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            time.sleep(0.5)
494cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        else:
495cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            global include_wps_req, include_p2p_req
496cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            res = getch()
497cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if res == 'i':
498cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_wps_req = True
499cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_p2p_req = True
500cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            elif res == 'p':
501cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_wps_req = False
502cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_p2p_req = True
503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            elif res == 'w':
504cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_wps_req = True
505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                include_p2p_req = False
506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            else:
507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                continue
508cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            clear_raw_mode()
509cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Starting handover client"
510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            p2p_handover_client(llc)
511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            return
512cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    clear_raw_mode()
514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Exiting llcp_worker thread"
515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_startup(clf, llc):
517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "Start LLCP server"
518cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global srv
519cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    srv = HandoverServer(llc)
520cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return llc
521cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
522cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef llcp_connected(llc):
523cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    print "P2P LLCP connected"
524cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global wait_connection
525cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    wait_connection = False
526cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global init_on_touch
527cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if not init_on_touch:
528cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global srv
529cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        srv.start()
530cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if init_on_touch or not no_input:
531cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        threading.Thread(target=llcp_worker, args=(llc,)).start()
532cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return True
533cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
534cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef terminate_loop():
535cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global terminate_now
536cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    return terminate_now
537cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
538cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtdef main():
539cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    clf = nfc.ContactlessFrontend()
540cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
541cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for P2P and WPS NFC operations')
542cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
543cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        action='store_const', dest='loglevel',
544cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='verbose debug output')
545cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('-q', const=logging.WARNING, action='store_const',
546cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        dest='loglevel', help='be quiet')
547cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--only-one', '-1', action='store_true',
548cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='run only one operation and exit')
549cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--init-on-touch', '-I', action='store_true',
550cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='initiate handover on touch')
551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--no-wait', action='store_true',
552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='do not wait for tag to be removed before exiting')
553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--ifname', '-i',
554cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='network interface name')
555cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--no-wps-req', '-N', action='store_true',
556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='do not include WPS carrier record in request')
557cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--no-input', '-a', action='store_true',
558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='do not use stdout input to initiate handover')
559cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--tag-read-only', '-t', action='store_true',
560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='tag read only (do not allow connection handover)')
56196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    parser.add_argument('--handover-only', action='store_true',
56296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                        help='connection handover only (do not allow tag read)')
563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('--freq', '-f',
564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        help='forced frequency of operating channel in MHz')
56596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    parser.add_argument('--summary',
56696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                        help='summary file for writing status updates')
56796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    parser.add_argument('--success',
56896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                        help='success file for writing success update')
569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    parser.add_argument('command', choices=['write-p2p-sel'],
570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        nargs='?')
571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    args = parser.parse_args()
572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
573cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global only_one
574cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    only_one = args.only_one
575cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
576cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global no_wait
577cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    no_wait = args.no_wait
578cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
579cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global force_freq
580cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    force_freq = args.freq
581cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
582cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    logging.basicConfig(level=args.loglevel)
583cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
584cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global init_on_touch
585cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    init_on_touch = args.init_on_touch
586cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
587cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if args.ifname:
588cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global ifname
589cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        ifname = args.ifname
590cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        print "Selected ifname " + ifname
591cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
592cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if args.no_wps_req:
593cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global include_wps_req
594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        include_wps_req = False
595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
59696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if args.summary:
59796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        global summary_file
59896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        summary_file = args.summary
59996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
60096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt    if args.success:
60196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        global success_file
60296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt        success_file = args.success
60396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    if args.no_input:
605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global no_input
606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        no_input = True
607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    clf = nfc.ContactlessFrontend()
609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    global wait_connection
610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    try:
612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if not clf.open("usb"):
613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Could not open connection with an NFC device"
614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            raise SystemExit
615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        if args.command == "write-p2p-sel":
617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            wps_write_p2p_handover_sel(clf, wait_remove=not args.no_wait)
618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            raise SystemExit
619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
620cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        global continue_loop
621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        while continue_loop:
622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            print "Waiting for a tag or peer to be touched"
623cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            wait_connection = True
624cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            try:
625cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                if args.tag_read_only:
626cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    if not clf.connect(rdwr={'on-connect': rdwr_connected}):
627cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        break
62896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                elif args.handover_only:
62996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                    if not clf.connect(llcp={'on-startup': llcp_startup,
63096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                                             'on-connect': llcp_connected},
63196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                                       terminate=terminate_loop):
63296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt                        break
633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                else:
634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                    if not clf.connect(rdwr={'on-connect': rdwr_connected},
635cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                                       llcp={'on-startup': llcp_startup,
636cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                                             'on-connect': llcp_connected},
637cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                                       terminate=terminate_loop):
638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                        break
639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            except Exception, e:
640cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                print "clf.connect failed"
641cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            global srv
643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt            if only_one and srv and srv.success:
644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt                raise SystemExit
645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
646cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    except KeyboardInterrupt:
647cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        raise SystemExit
648cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    finally:
649cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt        clf.close()
650cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
651cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    raise SystemExit
652cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtif __name__ == '__main__':
654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt    main()
655