xref: /aosp_15_r20/external/wpa_supplicant_8/hostapd/wps-ap-nfc.py (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker#!/usr/bin/python
2*03f9172cSAndroid Build Coastguard Worker#
3*03f9172cSAndroid Build Coastguard Worker# Example nfcpy to hostapd wrapper for WPS NFC operations
4*03f9172cSAndroid Build Coastguard Worker# Copyright (c) 2012-2013, Jouni Malinen <[email protected]>
5*03f9172cSAndroid Build Coastguard Worker#
6*03f9172cSAndroid Build Coastguard Worker# This software may be distributed under the terms of the BSD license.
7*03f9172cSAndroid Build Coastguard Worker# See README for more details.
8*03f9172cSAndroid Build Coastguard Worker
9*03f9172cSAndroid Build Coastguard Workerimport os
10*03f9172cSAndroid Build Coastguard Workerimport sys
11*03f9172cSAndroid Build Coastguard Workerimport time
12*03f9172cSAndroid Build Coastguard Workerimport argparse
13*03f9172cSAndroid Build Coastguard Worker
14*03f9172cSAndroid Build Coastguard Workerimport nfc
15*03f9172cSAndroid Build Coastguard Workerimport nfc.ndef
16*03f9172cSAndroid Build Coastguard Workerimport nfc.llcp
17*03f9172cSAndroid Build Coastguard Workerimport nfc.handover
18*03f9172cSAndroid Build Coastguard Worker
19*03f9172cSAndroid Build Coastguard Workerimport logging
20*03f9172cSAndroid Build Coastguard Worker
21*03f9172cSAndroid Build Coastguard Workerimport wpaspy
22*03f9172cSAndroid Build Coastguard Worker
23*03f9172cSAndroid Build Coastguard Workerwpas_ctrl = '/var/run/hostapd'
24*03f9172cSAndroid Build Coastguard Workercontinue_loop = True
25*03f9172cSAndroid Build Coastguard Workersummary_file = None
26*03f9172cSAndroid Build Coastguard Workersuccess_file = None
27*03f9172cSAndroid Build Coastguard Worker
28*03f9172cSAndroid Build Coastguard Workerdef summary(txt):
29*03f9172cSAndroid Build Coastguard Worker    print(txt)
30*03f9172cSAndroid Build Coastguard Worker    if summary_file:
31*03f9172cSAndroid Build Coastguard Worker        with open(summary_file, 'a') as f:
32*03f9172cSAndroid Build Coastguard Worker            f.write(txt + "\n")
33*03f9172cSAndroid Build Coastguard Worker
34*03f9172cSAndroid Build Coastguard Workerdef success_report(txt):
35*03f9172cSAndroid Build Coastguard Worker    summary(txt)
36*03f9172cSAndroid Build Coastguard Worker    if success_file:
37*03f9172cSAndroid Build Coastguard Worker        with open(success_file, 'a') as f:
38*03f9172cSAndroid Build Coastguard Worker            f.write(txt + "\n")
39*03f9172cSAndroid Build Coastguard Worker
40*03f9172cSAndroid Build Coastguard Workerdef wpas_connect():
41*03f9172cSAndroid Build Coastguard Worker    ifaces = []
42*03f9172cSAndroid Build Coastguard Worker    if os.path.isdir(wpas_ctrl):
43*03f9172cSAndroid Build Coastguard Worker        try:
44*03f9172cSAndroid Build Coastguard Worker            ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
45*03f9172cSAndroid Build Coastguard Worker        except OSError as error:
46*03f9172cSAndroid Build Coastguard Worker            print("Could not find hostapd: ", error)
47*03f9172cSAndroid Build Coastguard Worker            return None
48*03f9172cSAndroid Build Coastguard Worker
49*03f9172cSAndroid Build Coastguard Worker    if len(ifaces) < 1:
50*03f9172cSAndroid Build Coastguard Worker        print("No hostapd control interface found")
51*03f9172cSAndroid Build Coastguard Worker        return None
52*03f9172cSAndroid Build Coastguard Worker
53*03f9172cSAndroid Build Coastguard Worker    for ctrl in ifaces:
54*03f9172cSAndroid Build Coastguard Worker        try:
55*03f9172cSAndroid Build Coastguard Worker            wpas = wpaspy.Ctrl(ctrl)
56*03f9172cSAndroid Build Coastguard Worker            return wpas
57*03f9172cSAndroid Build Coastguard Worker        except Exception as e:
58*03f9172cSAndroid Build Coastguard Worker            pass
59*03f9172cSAndroid Build Coastguard Worker    return None
60*03f9172cSAndroid Build Coastguard Worker
61*03f9172cSAndroid Build Coastguard Worker
62*03f9172cSAndroid Build Coastguard Workerdef wpas_tag_read(message):
63*03f9172cSAndroid Build Coastguard Worker    wpas = wpas_connect()
64*03f9172cSAndroid Build Coastguard Worker    if (wpas == None):
65*03f9172cSAndroid Build Coastguard Worker        return False
66*03f9172cSAndroid Build Coastguard Worker    if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")):
67*03f9172cSAndroid Build Coastguard Worker        return False
68*03f9172cSAndroid Build Coastguard Worker    return True
69*03f9172cSAndroid Build Coastguard Worker
70*03f9172cSAndroid Build Coastguard Worker
71*03f9172cSAndroid Build Coastguard Workerdef wpas_get_config_token():
72*03f9172cSAndroid Build Coastguard Worker    wpas = wpas_connect()
73*03f9172cSAndroid Build Coastguard Worker    if (wpas == None):
74*03f9172cSAndroid Build Coastguard Worker        return None
75*03f9172cSAndroid Build Coastguard Worker    ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF")
76*03f9172cSAndroid Build Coastguard Worker    if "FAIL" in ret:
77*03f9172cSAndroid Build Coastguard Worker        return None
78*03f9172cSAndroid Build Coastguard Worker    return ret.rstrip().decode("hex")
79*03f9172cSAndroid Build Coastguard Worker
80*03f9172cSAndroid Build Coastguard Worker
81*03f9172cSAndroid Build Coastguard Workerdef wpas_get_password_token():
82*03f9172cSAndroid Build Coastguard Worker    wpas = wpas_connect()
83*03f9172cSAndroid Build Coastguard Worker    if (wpas == None):
84*03f9172cSAndroid Build Coastguard Worker        return None
85*03f9172cSAndroid Build Coastguard Worker    ret = wpas.request("WPS_NFC_TOKEN NDEF")
86*03f9172cSAndroid Build Coastguard Worker    if "FAIL" in ret:
87*03f9172cSAndroid Build Coastguard Worker        return None
88*03f9172cSAndroid Build Coastguard Worker    return ret.rstrip().decode("hex")
89*03f9172cSAndroid Build Coastguard Worker
90*03f9172cSAndroid Build Coastguard Worker
91*03f9172cSAndroid Build Coastguard Workerdef wpas_get_handover_sel():
92*03f9172cSAndroid Build Coastguard Worker    wpas = wpas_connect()
93*03f9172cSAndroid Build Coastguard Worker    if (wpas == None):
94*03f9172cSAndroid Build Coastguard Worker        return None
95*03f9172cSAndroid Build Coastguard Worker    ret = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR")
96*03f9172cSAndroid Build Coastguard Worker    if "FAIL" in ret:
97*03f9172cSAndroid Build Coastguard Worker        return None
98*03f9172cSAndroid Build Coastguard Worker    return ret.rstrip().decode("hex")
99*03f9172cSAndroid Build Coastguard Worker
100*03f9172cSAndroid Build Coastguard Worker
101*03f9172cSAndroid Build Coastguard Workerdef wpas_report_handover(req, sel):
102*03f9172cSAndroid Build Coastguard Worker    wpas = wpas_connect()
103*03f9172cSAndroid Build Coastguard Worker    if (wpas == None):
104*03f9172cSAndroid Build Coastguard Worker        return None
105*03f9172cSAndroid Build Coastguard Worker    return wpas.request("NFC_REPORT_HANDOVER RESP WPS " +
106*03f9172cSAndroid Build Coastguard Worker                        str(req).encode("hex") + " " +
107*03f9172cSAndroid Build Coastguard Worker                        str(sel).encode("hex"))
108*03f9172cSAndroid Build Coastguard Worker
109*03f9172cSAndroid Build Coastguard Worker
110*03f9172cSAndroid Build Coastguard Workerclass HandoverServer(nfc.handover.HandoverServer):
111*03f9172cSAndroid Build Coastguard Worker    def __init__(self, llc):
112*03f9172cSAndroid Build Coastguard Worker        super(HandoverServer, self).__init__(llc)
113*03f9172cSAndroid Build Coastguard Worker        self.ho_server_processing = False
114*03f9172cSAndroid Build Coastguard Worker        self.success = False
115*03f9172cSAndroid Build Coastguard Worker
116*03f9172cSAndroid Build Coastguard Worker    # override to avoid parser error in request/response.pretty() in nfcpy
117*03f9172cSAndroid Build Coastguard Worker    # due to new WSC handover format
118*03f9172cSAndroid Build Coastguard Worker    def _process_request(self, request):
119*03f9172cSAndroid Build Coastguard Worker        summary("received handover request {}".format(request.type))
120*03f9172cSAndroid Build Coastguard Worker        response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
121*03f9172cSAndroid Build Coastguard Worker        if not request.type == 'urn:nfc:wkt:Hr':
122*03f9172cSAndroid Build Coastguard Worker            summary("not a handover request")
123*03f9172cSAndroid Build Coastguard Worker        else:
124*03f9172cSAndroid Build Coastguard Worker            try:
125*03f9172cSAndroid Build Coastguard Worker                request = nfc.ndef.HandoverRequestMessage(request)
126*03f9172cSAndroid Build Coastguard Worker            except nfc.ndef.DecodeError as e:
127*03f9172cSAndroid Build Coastguard Worker                summary("error decoding 'Hr' message: {}".format(e))
128*03f9172cSAndroid Build Coastguard Worker            else:
129*03f9172cSAndroid Build Coastguard Worker                response = self.process_request(request)
130*03f9172cSAndroid Build Coastguard Worker        summary("send handover response {}".format(response.type))
131*03f9172cSAndroid Build Coastguard Worker        return response
132*03f9172cSAndroid Build Coastguard Worker
133*03f9172cSAndroid Build Coastguard Worker    def process_request(self, request):
134*03f9172cSAndroid Build Coastguard Worker        summary("HandoverServer - request received")
135*03f9172cSAndroid Build Coastguard Worker        try:
136*03f9172cSAndroid Build Coastguard Worker            print("Parsed handover request: " + request.pretty())
137*03f9172cSAndroid Build Coastguard Worker        except Exception as e:
138*03f9172cSAndroid Build Coastguard Worker            print(e)
139*03f9172cSAndroid Build Coastguard Worker        print(str(request).encode("hex"))
140*03f9172cSAndroid Build Coastguard Worker
141*03f9172cSAndroid Build Coastguard Worker        sel = nfc.ndef.HandoverSelectMessage(version="1.2")
142*03f9172cSAndroid Build Coastguard Worker
143*03f9172cSAndroid Build Coastguard Worker        for carrier in request.carriers:
144*03f9172cSAndroid Build Coastguard Worker            print("Remote carrier type: " + carrier.type)
145*03f9172cSAndroid Build Coastguard Worker            if carrier.type == "application/vnd.wfa.wsc":
146*03f9172cSAndroid Build Coastguard Worker                summary("WPS carrier type match - add WPS carrier record")
147*03f9172cSAndroid Build Coastguard Worker                data = wpas_get_handover_sel()
148*03f9172cSAndroid Build Coastguard Worker                if data is None:
149*03f9172cSAndroid Build Coastguard Worker                    summary("Could not get handover select carrier record from hostapd")
150*03f9172cSAndroid Build Coastguard Worker                    continue
151*03f9172cSAndroid Build Coastguard Worker                print("Handover select carrier record from hostapd:")
152*03f9172cSAndroid Build Coastguard Worker                print(data.encode("hex"))
153*03f9172cSAndroid Build Coastguard Worker                if "OK" in wpas_report_handover(carrier.record, data):
154*03f9172cSAndroid Build Coastguard Worker                    success_report("Handover reported successfully")
155*03f9172cSAndroid Build Coastguard Worker                else:
156*03f9172cSAndroid Build Coastguard Worker                    summary("Handover report rejected")
157*03f9172cSAndroid Build Coastguard Worker
158*03f9172cSAndroid Build Coastguard Worker                message = nfc.ndef.Message(data);
159*03f9172cSAndroid Build Coastguard Worker                sel.add_carrier(message[0], "active", message[1:])
160*03f9172cSAndroid Build Coastguard Worker
161*03f9172cSAndroid Build Coastguard Worker        print("Handover select:")
162*03f9172cSAndroid Build Coastguard Worker        try:
163*03f9172cSAndroid Build Coastguard Worker            print(sel.pretty())
164*03f9172cSAndroid Build Coastguard Worker        except Exception as e:
165*03f9172cSAndroid Build Coastguard Worker            print(e)
166*03f9172cSAndroid Build Coastguard Worker        print(str(sel).encode("hex"))
167*03f9172cSAndroid Build Coastguard Worker
168*03f9172cSAndroid Build Coastguard Worker        summary("Sending handover select")
169*03f9172cSAndroid Build Coastguard Worker        self.success = True
170*03f9172cSAndroid Build Coastguard Worker        return sel
171*03f9172cSAndroid Build Coastguard Worker
172*03f9172cSAndroid Build Coastguard Worker
173*03f9172cSAndroid Build Coastguard Workerdef wps_tag_read(tag):
174*03f9172cSAndroid Build Coastguard Worker    success = False
175*03f9172cSAndroid Build Coastguard Worker    if len(tag.ndef.message):
176*03f9172cSAndroid Build Coastguard Worker        for record in tag.ndef.message:
177*03f9172cSAndroid Build Coastguard Worker            print("record type " + record.type)
178*03f9172cSAndroid Build Coastguard Worker            if record.type == "application/vnd.wfa.wsc":
179*03f9172cSAndroid Build Coastguard Worker                summary("WPS tag - send to hostapd")
180*03f9172cSAndroid Build Coastguard Worker                success = wpas_tag_read(tag.ndef.message)
181*03f9172cSAndroid Build Coastguard Worker                break
182*03f9172cSAndroid Build Coastguard Worker    else:
183*03f9172cSAndroid Build Coastguard Worker        summary("Empty tag")
184*03f9172cSAndroid Build Coastguard Worker
185*03f9172cSAndroid Build Coastguard Worker    if success:
186*03f9172cSAndroid Build Coastguard Worker        success_report("Tag read succeeded")
187*03f9172cSAndroid Build Coastguard Worker
188*03f9172cSAndroid Build Coastguard Worker    return success
189*03f9172cSAndroid Build Coastguard Worker
190*03f9172cSAndroid Build Coastguard Worker
191*03f9172cSAndroid Build Coastguard Workerdef rdwr_connected_write(tag):
192*03f9172cSAndroid Build Coastguard Worker    summary("Tag found - writing - " + str(tag))
193*03f9172cSAndroid Build Coastguard Worker    global write_data
194*03f9172cSAndroid Build Coastguard Worker    tag.ndef.message = str(write_data)
195*03f9172cSAndroid Build Coastguard Worker    success_report("Tag write succeeded")
196*03f9172cSAndroid Build Coastguard Worker    print("Done - remove tag")
197*03f9172cSAndroid Build Coastguard Worker    global only_one
198*03f9172cSAndroid Build Coastguard Worker    if only_one:
199*03f9172cSAndroid Build Coastguard Worker        global continue_loop
200*03f9172cSAndroid Build Coastguard Worker        continue_loop = False
201*03f9172cSAndroid Build Coastguard Worker    global write_wait_remove
202*03f9172cSAndroid Build Coastguard Worker    while write_wait_remove and tag.is_present:
203*03f9172cSAndroid Build Coastguard Worker        time.sleep(0.1)
204*03f9172cSAndroid Build Coastguard Worker
205*03f9172cSAndroid Build Coastguard Workerdef wps_write_config_tag(clf, wait_remove=True):
206*03f9172cSAndroid Build Coastguard Worker    summary("Write WPS config token")
207*03f9172cSAndroid Build Coastguard Worker    global write_data, write_wait_remove
208*03f9172cSAndroid Build Coastguard Worker    write_wait_remove = wait_remove
209*03f9172cSAndroid Build Coastguard Worker    write_data = wpas_get_config_token()
210*03f9172cSAndroid Build Coastguard Worker    if write_data == None:
211*03f9172cSAndroid Build Coastguard Worker        summary("Could not get WPS config token from hostapd")
212*03f9172cSAndroid Build Coastguard Worker        return
213*03f9172cSAndroid Build Coastguard Worker
214*03f9172cSAndroid Build Coastguard Worker    print("Touch an NFC tag")
215*03f9172cSAndroid Build Coastguard Worker    clf.connect(rdwr={'on-connect': rdwr_connected_write})
216*03f9172cSAndroid Build Coastguard Worker
217*03f9172cSAndroid Build Coastguard Worker
218*03f9172cSAndroid Build Coastguard Workerdef wps_write_password_tag(clf, wait_remove=True):
219*03f9172cSAndroid Build Coastguard Worker    summary("Write WPS password token")
220*03f9172cSAndroid Build Coastguard Worker    global write_data, write_wait_remove
221*03f9172cSAndroid Build Coastguard Worker    write_wait_remove = wait_remove
222*03f9172cSAndroid Build Coastguard Worker    write_data = wpas_get_password_token()
223*03f9172cSAndroid Build Coastguard Worker    if write_data == None:
224*03f9172cSAndroid Build Coastguard Worker        summary("Could not get WPS password token from hostapd")
225*03f9172cSAndroid Build Coastguard Worker        return
226*03f9172cSAndroid Build Coastguard Worker
227*03f9172cSAndroid Build Coastguard Worker    print("Touch an NFC tag")
228*03f9172cSAndroid Build Coastguard Worker    clf.connect(rdwr={'on-connect': rdwr_connected_write})
229*03f9172cSAndroid Build Coastguard Worker
230*03f9172cSAndroid Build Coastguard Worker
231*03f9172cSAndroid Build Coastguard Workerdef rdwr_connected(tag):
232*03f9172cSAndroid Build Coastguard Worker    global only_one, no_wait
233*03f9172cSAndroid Build Coastguard Worker    summary("Tag connected: " + str(tag))
234*03f9172cSAndroid Build Coastguard Worker
235*03f9172cSAndroid Build Coastguard Worker    if tag.ndef:
236*03f9172cSAndroid Build Coastguard Worker        print("NDEF tag: " + tag.type)
237*03f9172cSAndroid Build Coastguard Worker        try:
238*03f9172cSAndroid Build Coastguard Worker            print(tag.ndef.message.pretty())
239*03f9172cSAndroid Build Coastguard Worker        except Exception as e:
240*03f9172cSAndroid Build Coastguard Worker            print(e)
241*03f9172cSAndroid Build Coastguard Worker        success = wps_tag_read(tag)
242*03f9172cSAndroid Build Coastguard Worker        if only_one and success:
243*03f9172cSAndroid Build Coastguard Worker            global continue_loop
244*03f9172cSAndroid Build Coastguard Worker            continue_loop = False
245*03f9172cSAndroid Build Coastguard Worker    else:
246*03f9172cSAndroid Build Coastguard Worker        summary("Not an NDEF tag - remove tag")
247*03f9172cSAndroid Build Coastguard Worker        return True
248*03f9172cSAndroid Build Coastguard Worker
249*03f9172cSAndroid Build Coastguard Worker    return not no_wait
250*03f9172cSAndroid Build Coastguard Worker
251*03f9172cSAndroid Build Coastguard Worker
252*03f9172cSAndroid Build Coastguard Workerdef llcp_startup(clf, llc):
253*03f9172cSAndroid Build Coastguard Worker    print("Start LLCP server")
254*03f9172cSAndroid Build Coastguard Worker    global srv
255*03f9172cSAndroid Build Coastguard Worker    srv = HandoverServer(llc)
256*03f9172cSAndroid Build Coastguard Worker    return llc
257*03f9172cSAndroid Build Coastguard Worker
258*03f9172cSAndroid Build Coastguard Workerdef llcp_connected(llc):
259*03f9172cSAndroid Build Coastguard Worker    print("P2P LLCP connected")
260*03f9172cSAndroid Build Coastguard Worker    global wait_connection
261*03f9172cSAndroid Build Coastguard Worker    wait_connection = False
262*03f9172cSAndroid Build Coastguard Worker    global srv
263*03f9172cSAndroid Build Coastguard Worker    srv.start()
264*03f9172cSAndroid Build Coastguard Worker    return True
265*03f9172cSAndroid Build Coastguard Worker
266*03f9172cSAndroid Build Coastguard Worker
267*03f9172cSAndroid Build Coastguard Workerdef main():
268*03f9172cSAndroid Build Coastguard Worker    clf = nfc.ContactlessFrontend()
269*03f9172cSAndroid Build Coastguard Worker
270*03f9172cSAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(description='nfcpy to hostapd integration for WPS NFC operations')
271*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
272*03f9172cSAndroid Build Coastguard Worker                        action='store_const', dest='loglevel',
273*03f9172cSAndroid Build Coastguard Worker                        help='verbose debug output')
274*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('-q', const=logging.WARNING, action='store_const',
275*03f9172cSAndroid Build Coastguard Worker                        dest='loglevel', help='be quiet')
276*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('--only-one', '-1', action='store_true',
277*03f9172cSAndroid Build Coastguard Worker                        help='run only one operation and exit')
278*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('--no-wait', action='store_true',
279*03f9172cSAndroid Build Coastguard Worker                        help='do not wait for tag to be removed before exiting')
280*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('--summary',
281*03f9172cSAndroid Build Coastguard Worker                        help='summary file for writing status updates')
282*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('--success',
283*03f9172cSAndroid Build Coastguard Worker                        help='success file for writing success update')
284*03f9172cSAndroid Build Coastguard Worker    parser.add_argument('command', choices=['write-config',
285*03f9172cSAndroid Build Coastguard Worker                                            'write-password'],
286*03f9172cSAndroid Build Coastguard Worker                        nargs='?')
287*03f9172cSAndroid Build Coastguard Worker    args = parser.parse_args()
288*03f9172cSAndroid Build Coastguard Worker
289*03f9172cSAndroid Build Coastguard Worker    global only_one
290*03f9172cSAndroid Build Coastguard Worker    only_one = args.only_one
291*03f9172cSAndroid Build Coastguard Worker
292*03f9172cSAndroid Build Coastguard Worker    global no_wait
293*03f9172cSAndroid Build Coastguard Worker    no_wait = args.no_wait
294*03f9172cSAndroid Build Coastguard Worker
295*03f9172cSAndroid Build Coastguard Worker    if args.summary:
296*03f9172cSAndroid Build Coastguard Worker        global summary_file
297*03f9172cSAndroid Build Coastguard Worker        summary_file = args.summary
298*03f9172cSAndroid Build Coastguard Worker
299*03f9172cSAndroid Build Coastguard Worker    if args.success:
300*03f9172cSAndroid Build Coastguard Worker        global success_file
301*03f9172cSAndroid Build Coastguard Worker        success_file = args.success
302*03f9172cSAndroid Build Coastguard Worker
303*03f9172cSAndroid Build Coastguard Worker    logging.basicConfig(level=args.loglevel)
304*03f9172cSAndroid Build Coastguard Worker
305*03f9172cSAndroid Build Coastguard Worker    try:
306*03f9172cSAndroid Build Coastguard Worker        if not clf.open("usb"):
307*03f9172cSAndroid Build Coastguard Worker            print("Could not open connection with an NFC device")
308*03f9172cSAndroid Build Coastguard Worker            raise SystemExit
309*03f9172cSAndroid Build Coastguard Worker
310*03f9172cSAndroid Build Coastguard Worker        if args.command == "write-config":
311*03f9172cSAndroid Build Coastguard Worker            wps_write_config_tag(clf, wait_remove=not args.no_wait)
312*03f9172cSAndroid Build Coastguard Worker            raise SystemExit
313*03f9172cSAndroid Build Coastguard Worker
314*03f9172cSAndroid Build Coastguard Worker        if args.command == "write-password":
315*03f9172cSAndroid Build Coastguard Worker            wps_write_password_tag(clf, wait_remove=not args.no_wait)
316*03f9172cSAndroid Build Coastguard Worker            raise SystemExit
317*03f9172cSAndroid Build Coastguard Worker
318*03f9172cSAndroid Build Coastguard Worker        global continue_loop
319*03f9172cSAndroid Build Coastguard Worker        while continue_loop:
320*03f9172cSAndroid Build Coastguard Worker            print("Waiting for a tag or peer to be touched")
321*03f9172cSAndroid Build Coastguard Worker            wait_connection = True
322*03f9172cSAndroid Build Coastguard Worker            try:
323*03f9172cSAndroid Build Coastguard Worker                if not clf.connect(rdwr={'on-connect': rdwr_connected},
324*03f9172cSAndroid Build Coastguard Worker                                   llcp={'on-startup': llcp_startup,
325*03f9172cSAndroid Build Coastguard Worker                                         'on-connect': llcp_connected}):
326*03f9172cSAndroid Build Coastguard Worker                    break
327*03f9172cSAndroid Build Coastguard Worker            except Exception as e:
328*03f9172cSAndroid Build Coastguard Worker                print("clf.connect failed")
329*03f9172cSAndroid Build Coastguard Worker
330*03f9172cSAndroid Build Coastguard Worker            global srv
331*03f9172cSAndroid Build Coastguard Worker            if only_one and srv and srv.success:
332*03f9172cSAndroid Build Coastguard Worker                raise SystemExit
333*03f9172cSAndroid Build Coastguard Worker
334*03f9172cSAndroid Build Coastguard Worker    except KeyboardInterrupt:
335*03f9172cSAndroid Build Coastguard Worker        raise SystemExit
336*03f9172cSAndroid Build Coastguard Worker    finally:
337*03f9172cSAndroid Build Coastguard Worker        clf.close()
338*03f9172cSAndroid Build Coastguard Worker
339*03f9172cSAndroid Build Coastguard Worker    raise SystemExit
340*03f9172cSAndroid Build Coastguard Worker
341*03f9172cSAndroid Build Coastguard Workerif __name__ == '__main__':
342*03f9172cSAndroid Build Coastguard Worker    main()
343