def test_07(self, llc): """Default server limits""" payload = bytearray(x % 256 for x in range(1024 - 32)) records = [ndef.Record("application/octet-stream", "1", payload)] ndef_message = b''.join(ndef.message_encoder(records)) snep = nfc.snep.SnepClient(llc) try: info("connect to {0}".format("urn:nfc:sn:snep")) snep.connect("urn:nfc:sn:snep") except nfc.llcp.ConnectRefused: raise cli.TestFail("could not connect to default server") try: info("put {0} octets ndef message".format(len(ndef_message))) snep.put_octets(ndef_message) identifier = ndef.Record("application/octet-stream", "1") info("request ndef message {}".format(identifier)) identifier = b''.join(ndef.message_encoder([identifier])) try: ndef_message = snep.get_octets(identifier) except nfc.snep.SnepError as e: if e.errno != nfc.snep.NotImplemented: raise cli.TestFail("received unexpected response code") info("received 'not implemented' response as expected") else: raise cli.TestFail("received unexpected message from server") finally: info("disconnect from server") snep.close()
def test_read_ndef(mocker, tag): # noqa: F811 with pytest.raises(NotImplementedError) as excinfo: tag.ndef assert str(excinfo.value) == \ "_read_ndef_data is not implemented for this tag type" read_ndef_data = mocker.patch("nfc.tag.Tag.NDEF._read_ndef_data") read_ndef_data.return_value = None assert tag.ndef is None read_ndef_data.return_value = HEX('') assert isinstance(tag.ndef, nfc.tag.Tag.NDEF) assert tag.ndef.octets == HEX('') assert tag.ndef.records == [] assert tag.ndef.message == nfc.ndef.Message(nfc.ndef.Record()) read_ndef_data.return_value = HEX('D00000') assert tag.ndef.has_changed is True assert isinstance(tag.ndef, nfc.tag.Tag.NDEF) assert tag.ndef.octets == HEX('D00000') assert tag.ndef.records == [ndef.Record()] assert tag.ndef.message == nfc.ndef.Message(nfc.ndef.Record()) read_ndef_data.return_value = HEX('D50000') assert tag.ndef.has_changed is True assert isinstance(tag.ndef, nfc.tag.Tag.NDEF) assert tag.ndef.octets == HEX('D50000') assert tag.ndef.records == [ndef.Record('unknown')] assert tag.ndef.message == nfc.ndef.Message(nfc.ndef.Record('unknown')) read_ndef_data.return_value = None assert tag.ndef.has_changed is True assert tag.ndef is None
def test_05(self, llc): """Undeliverable resource""" payload = bytearray(range(122 - 29)) records = [ndef.Record("application/octet-stream", "1", payload)] ndef_message_sent = b''.join(ndef.message_encoder(records)) max_ndef_msg_recv_size = len(ndef_message_sent) - 1 snep = nfc.snep.SnepClient(llc, max_ndef_msg_recv_size) try: info("connect to {0}".format(validation_server)) snep.connect(validation_server) except nfc.llcp.ConnectRefused: raise cli.TestFail("could not connect to validation server") try: info("put {0} octets ndef message".format(len(ndef_message_sent))) snep.put_octets(ndef_message_sent) info( "request ndef message with max acceptable lenght of {} octets". format(max_ndef_msg_recv_size)) identifier = ndef.Record("application/octet-stream", "1") identifier = b''.join(ndef.message_encoder([identifier])) try: snep.get_octets(identifier) except nfc.snep.SnepError as e: if e.errno != nfc.snep.ExcessData: raise cli.TestFail("received unexpected response code") info("received 'excess data' response as expected") else: raise cli.TestFail("received unexpected message from server") finally: info("disconnect from {0}".format(validation_server)) snep.close()
def test_04(self, llc): """Multiple ndef messages""" ndef_message_sent = list() ndef_message_rcvd = list() payload = bytearray(range(50)) records = [ndef.Record("application/octet-stream", "1", payload)] ndef_message_sent.append(b''.join(ndef.message_encoder(records))) records = [ndef.Record("application/octet-stream", "2", payload)] ndef_message_sent.append(b''.join(ndef.message_encoder(records))) snep = nfc.snep.SnepClient(llc, max_ndef_msg_recv_size=10000) try: info("connect to {0}".format(validation_server)) snep.connect(validation_server) except nfc.llcp.ConnectRefused: raise cli.TestFail("could not connect to validation server") try: info("put 1st ndef message") snep.put_octets(ndef_message_sent[0]) info("put 2nd ndef message") snep.put_octets(ndef_message_sent[1]) info("get 1st ndef message") identifier = ndef.Record("application/octet-stream", "1") identifier = b''.join(ndef.message_encoder([identifier])) ndef_message = snep.get_octets(identifier) ndef_message_rcvd.append(ndef_message) info("get 2nd ndef message") identifier = ndef.Record("application/octet-stream", "2") identifier = b''.join(ndef.message_encoder([identifier])) ndef_message = snep.get_octets(identifier) ndef_message_rcvd.append(ndef_message) for i in range(len(ndef_message_sent)): if not ndef_message_rcvd == ndef_message_sent: info("rcvd ndef message {0} differs".format(i)) raise cli.TestFail("rcvd message {0} differs".format(i)) else: info("rcvd message {0} is correct".format(i)) except Exception as e: raise cli.TestFail("exception " + str(e)) finally: info("disconnect from {0}".format(validation_server)) snep.close()
def test_06(self, llc): """Unavailable resource""" snep = nfc.snep.SnepClient(llc) try: info("connect to {0}".format(validation_server)) snep.connect(validation_server) except nfc.llcp.ConnectRefused: raise cli.TestFail("could not connect to validation server") try: identifier = ndef.Record("application/octet-stream", "na") info("request ndef message {}".format(identifier)) identifier = b''.join(ndef.message_encoder([identifier])) try: snep.get_octets(identifier) except nfc.snep.SnepError as e: if e.errno != nfc.snep.NotFound: raise cli.TestFail("received unexpected response code") info("received 'not found' response as expected") else: raise cli.TestFail("received unexpected message from server") finally: info("disconnect from {0}".format(validation_server)) snep.close()
def test_write_terminator_after_skip(self, tag): assert tag.ndef is not None tag.clf.exchange.reset_mock() tag.clf.exchange.side_effect = [ fromhex("54 330203f002030300"), # WRITE-E8(2) fromhex("54 d5004d0000000000"), # WRITE-E8(3) fromhex("54 0000000000000000"), # WRITE-E8(4) fromhex("54 0000000000000000"), # WRITE-E8(5) fromhex("54 0000000000000000"), # WRITE-E8(6) fromhex("54 0000000000000000"), # WRITE-E8(7) fromhex("54 0000000000000000"), # WRITE-E8(8) fromhex("54 0000000000000000"), # WRITE-E8(9) fromhex("54 0000000000000000"), # WRITE-E8(10) fromhex("54 0000000000000000"), # WRITE-E8(11) fromhex("54 0000000000000000"), # WRITE-E8(12) fromhex("54 fe7475767778797a"), # WRITE-E8(16) fromhex("54 330203f002030350"), # WRITE-E8(2) ] tag.ndef.records = [ndef.Record('unknown', data=bytearray(5 + 9 * 8))] assert tag.clf.exchange.mock_calls == [ mock.call(fromhex('54 02 330203f002030300 01020304'), 0.1), mock.call(fromhex('54 03 d5004d0000000000 01020304'), 0.1), mock.call(fromhex('54 04 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 05 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 06 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 07 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 08 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 09 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 0a 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 0b 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 0c 0000000000000000 01020304'), 0.1), mock.call(fromhex('54 10 fe7475767778797a 01020304'), 0.1), mock.call(fromhex('54 02 330203f002030350 01020304'), 0.1), ]
def test_write_ndef(mocker, tag): # noqa: F811 read_ndef_data = mocker.patch("nfc.tag.Tag.NDEF._read_ndef_data") read_ndef_data.return_value = HEX('') assert isinstance(tag.ndef, nfc.tag.Tag.NDEF) with pytest.raises(AttributeError) as excinfo: tag.ndef.octets = HEX('D00000') assert str(excinfo.value) == "tag ndef area is not writeable" tag.ndef._writeable = True with pytest.raises(ValueError) as excinfo: tag.ndef.octets = HEX('D00000') assert str(excinfo.value) == "data length exceeds tag capacity" tag.ndef._capacity = 3 with pytest.raises(NotImplementedError) as excinfo: tag.ndef.octets = HEX('D00000') assert str(excinfo.value) == \ "_write_ndef_data is not implemented for this tag type" mocker.patch("nfc.tag.Tag.NDEF._write_ndef_data") tag.ndef.octets = HEX('D00000') assert tag.ndef.octets == HEX('D00000') tag.ndef.records = [ndef.Record('unknown')] assert tag.ndef.octets == HEX('D50000') tag.ndef.message = nfc.ndef.Message(nfc.ndef.Record()) assert tag.ndef.octets == HEX('D00000')
def create_ndef(message,encoding): record = ndef.Record('urn:nfc:ext:ln','invoice', bytes(message,encoding)) print("Record: {}".format(record)) encoder = ndef.message_encoder() encoder.send(None) encoder.send(record) # A none message must be sent for the last message = encoder.send(None) return message
def beam(llc): snep_client = nfc.snep.SnepClient(llc) records = ndef.Record('/message.txt', 'id', 'imei') #send_octets = ndef.message_encoder(records) #rcvd_octets = snep_client.get_records(send_octets) #records = list(ndef.message_decorder(rcvd_octets)) snep_client.get_octets(records) snep_client.put_records([ndef.UriRecord('http://naver.com')])
def run_send_file_action(args, llc): if args.type == 'unknown': mimetype = mimetypes.guess_type(args.file.name, strict=False)[0] if mimetype is not None: args.type = mimetype if args.name is None: args.name = args.file.name if args.file.name != "<stdin>" else "" record = ndef.Record(args.type, args.name, args.file.read()) log.info("send {}".format(record)) send_message(args, llc, [record])
def cmd(ctx, message, **kwargs): """The *payload* command either changes the current last record's data (NDEF Record PAYLOAD) or, if the current message does not have any records, creates a record with the given record data. The changed record is verified to successfully encode and decode unless disabled with -x. The data string may contain hexadecimal bytes using '\\xNN' notation where each N is a nibble from [0-F]. \b Examples: ndeftool payload 'Hello World' typename 'text/plain' print ndeftool payload '\\x02enHello World' typename 'urn:nfc:wkt:T' print -l """ dmsg(__name__ + ' ' + str(kwargs)) dmsg(repr(kwargs['data'])) if not message: message = [ndef.Record('unknown')] record_type = message[-1].type record_name = message[-1].name record_data = eval(repr(kwargs['data'].encode()).replace('\\\\', '\\')) record = ndef.Record(record_type, record_name, record_data) if not kwargs['no_check']: octets = b''.join(ndef.message_encoder([record])) errors = ctx.meta['decode-errors'] try: record = next(ndef.message_decoder(octets, errors)) except ndef.DecodeError as error: raise click.ClickException(str(error)) message[-1] = record return message
def cmd(ctx, message, **kwargs): """The *typename* command either changes the current last record's type (NDEF Record TNF and TYPE) or, if the current message does not have any records, creates a record with the given record type. The changed record is verified to successfully encode and decode unless disabled with -x. \b Examples: ndeftool typename 'text/plain' print ndeftool typename 'text/plain' payload 'Hello World' print """ dmsg(__name__ + ' ' + str(kwargs)) if not message: message = [ndef.Record()] record_type = kwargs['type'].encode('latin', 'replace') record_name = message[-1].name record_data = message[-1].data try: record = ndef.Record(record_type, record_name, record_data) except ValueError as error: raise click.ClickException(str(error)) if not kwargs['no_check']: octets = b''.join(ndef.message_encoder([record])) errors = ctx.meta['decode-errors'] try: record = next(ndef.message_decoder(octets, errors)) except ndef.DecodeError as error: raise click.ClickException(str(error)) message[-1] = record return message
def test_06(self, llc): """Unknown carrier type""" client = handover_connect(llc, self.options) try: unknown_carrier = "urn:nfc:ext:nfcpy.org:unknown-carrier-type" records = [ ndef.HandoverRequestRecord("1.2", os.urandom(2)), ndef.Record(unknown_carrier, "unknown-carrier") ] records[0].add_alternative_carrier("active", records[1].name) handover_send(client, records) records = handover_recv(client, timeout=3.0) info("received {}".format(records[0].type)) if records[0].version_info.major != 1: raise TestFail("handover major version is not 1") if len(records[0].alternative_carriers) != 0: raise TestFail("an empty carrier selection is expected") finally: client.close()
def test_07(self, llc): """Two handover requests""" client = handover_connect(llc, self.options) try: unknown_carrier = "urn:nfc:ext:nfcpy.org:unknown-carrier-type" records = [ ndef.HandoverRequestRecord("1.2", os.urandom(2)), ndef.Record(unknown_carrier, "unknown-carrier") ] records[0].add_alternative_carrier("active", records[1].name) info("request carrier {}".format(records[1].type)) handover_send(client, records) records = handover_recv(client, timeout=3.0) info("received {}".format(records[0].type)) if records[0].version_info.major != 1: raise TestFail("handover major version is not 1") if len(records[0].alternative_carriers) != 0: raise TestFail("an empty carrier selection is expected first") bt_record = ndef.BluetoothEasyPairingRecord("01:02:03:04:05:06") bt_record.name = "carrier-1" bt_record.device_name = "Handover Test Client" bt_record.device_class = 0x10010C bt_record.add_service_class(0x1105) bt_record.add_service_class(0x1106) hr_record = ndef.HandoverRequestRecord("1.2", os.urandom(2)) hr_record.add_alternative_carrier("active", bt_record.name) info("propose carrier {}".format(bt_record.type)) handover_send(client, [hr_record, bt_record]) records = handover_recv(client, timeout=3.0) info("received {}".format(records[0].type)) finally: client.close()
def cmd(message, **kwargs): """The *identifier* command either changes the current last record's name (NDEF Record ID) or, if the current message does not have any records, creates a record with unknown record type and the given record name. \b Examples: ndeftool identifier 'record identifier' print ndeftool text 'first' id 'r1' text 'second' id 'r2' print """ dmsg(__name__ + ' ' + str(kwargs)) if not message: message = [ndef.Record('unknown')] try: message[-1].name = kwargs['name'].encode('latin', 'replace') except ValueError as error: raise click.ClickException(str(error)) return message
def test_write_new_ndef_data(self, tag, mmap, ndef_octets): assert tag.ndef is not None assert tag.ndef.octets == ndef_octets tag.clf.exchange.side_effect = [ fromhex("0d 00"), fromhex("0e d0"), fromhex("0f 00"), fromhex("0d 03"), fromhex("10 00"), fromhex("11 fe"), fromhex("0d 03"), ] tag.ndef.records = [ndef.Record()] assert tag.clf.exchange.mock_calls == [ mock.call(fromhex('00 00 00 01020304'), 0.1), mock.call(fromhex('53 0d 00 01020304'), 0.1), mock.call(fromhex('53 0e d0 01020304'), 0.1), mock.call(fromhex('53 0f 00 01020304'), 0.1), mock.call(fromhex('53 10 00 01020304'), 0.1), mock.call(fromhex('53 11 fe 01020304'), 0.1), mock.call(fromhex('53 0d 03 01020304'), 0.1), ] assert tag.ndef.octets == fromhex("D00000")
def write_nfc_hs(clf, wait_remove=True): print("Write NFC Handover Select record on a tag") data = wpas_get_nfc_uri() if data is None: summary("Could not get NFC URI from wpa_supplicant") return global dpp_sel_wait_remove dpp_sel_wait_remove = wait_remove print("URI: %s" % data) uri = ndef.UriRecord(data) print(uri) carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) hs = ndef.HandoverSelectRecord('1.4') hs.add_alternative_carrier('active', carrier.name) print(hs) print(carrier) print("Touch an NFC tag") global dpp_tag_data dpp_tag_data = [hs, carrier] print(dpp_tag_data) clf.connect(rdwr={'on-connect': rdwr_connected_write_tag})
def test_unknown_records_encode(self): record = self.RECORD(0x11) record.unknown_records.append(ndef.Record('text/plain')) assert record.data == bytearray.fromhex('11d20a00746578742f706c61696e')
def dpp_handover_client(llc): uri = wpas_get_nfc_uri(start_listen=False) uri = ndef.UriRecord(uri) print("NFC URI record for DPP: " + str(uri)) carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) hr = ndef.HandoverRequestRecord(version="1.4", crn=os.urandom(2)) hr.add_alternative_carrier('active', carrier.name) message = [hr, carrier] print("NFC Handover Request message for DPP: " + str(message)) client = nfc.handover.HandoverClient(llc) try: summary("Trying to initiate NFC connection handover") client.connect() summary("Connected for handover") except nfc.llcp.ConnectRefused: summary("Handover connection refused") client.close() return except Exception as e: summary("Other exception: " + str(e)) client.close() return summary("Sending handover request") if not client.send_records(message): summary("Failed to send handover request") client.close() return summary("Receiving handover response") message = client.recv_records(timeout=3.0) if message is None: summary("No response received") client.close() return print("Received message: " + str(message)) if len(message) < 1 or \ not isinstance(message[0], ndef.HandoverSelectRecord): summary("Response was not Hs - received: " + message.type) client.close() return print("Received message") print("alternative carriers: " + str(message[0].alternative_carriers)) dpp_found = False for carrier in message: if isinstance(carrier, ndef.HandoverSelectRecord): continue print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": if len(carrier.data) == 0 or carrier.data[0] != 0: print("URI Identifier Code 'None' not seen") continue print("DPP carrier type match - send to wpa_supplicant") dpp_found = True uri = carrier.data[1:].decode("utf-8") print("DPP URI: " + uri) res = wpas_report_handover_sel(uri) if res is None or "FAIL" in res: summary("DPP handover report rejected") break success_report("DPP handover reported successfully (initiator)") print("peer_id=" + res) peer_id = int(res) # TODO: Single Configurator instance wpas = wpas_connect() if wpas is None: break res = wpas.request("DPP_CONFIGURATOR_ADD") if "FAIL" in res: print("Failed to initiate Configurator") break conf_id = int(res) global own_id print("Initiate DPP authentication") cmd = "DPP_AUTH_INIT peer=%d own=%d conf=sta-dpp configurator=%d" % ( peer_id, own_id, conf_id) res = wpas.request(cmd) if "FAIL" in res: print("Failed to initiate DPP authentication") break if not dpp_found: print( "DPP carrier not seen in response - allow peer to initiate a new handover with different parameters" ) client.close() print("Returning from dpp_handover_client") return print("Remove peer") client.close() print("Done with handover") global only_one if only_one: print("only_one -> stop loop") global continue_loop continue_loop = False global no_wait if no_wait: print("Trying to exit..") global terminate_now terminate_now = True print("Returning from dpp_handover_client")
def process_handover_request_message(self, records): self.ho_server_processing = True clear_raw_mode() print("\nHandoverServer - request received: " + str(records)) carrier = None hs = ndef.HandoverSelectRecord('1.4') sel = [hs] found = False for carrier in records: if isinstance(carrier, ndef.HandoverRequestRecord): continue print("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": print("DPP carrier type match - add DPP carrier record") if len(carrier.data) == 0 or carrier.data[0] != 0: print("URI Identifier Code 'None' not seen") continue uri = carrier.data[1:].decode("utf-8") print("Received DPP URI: " + uri) data = wpas_get_nfc_uri(start_listen=False) print("Own URI (pre-processing): %s" % data) res = wpas_report_handover_req(uri) if res is None or "FAIL" in res: print("DPP handover request processing failed") continue found = True self.received_carrier = carrier wpas = wpas_connect() if wpas is None: continue global own_id data = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % own_id).rstrip() if "FAIL" in data: continue print("Own URI (post-processing): %s" % data) uri = ndef.UriRecord(data) print("Own bootstrapping NFC URI record: " + str(uri)) info = wpas.request("DPP_BOOTSTRAP_INFO %d" % own_id) freq = None for line in info.splitlines(): if line.startswith("use_freq="): freq = int(line.split('=')[1]) if freq is None: print("No channel negotiated over NFC - use channel 1") freq = 2412 res = wpas.request("DPP_LISTEN %d" % freq) if "OK" not in res: print("Failed to start DPP listen") break carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) print("Own DPP carrier record: " + str(carrier)) hs.add_alternative_carrier('active', carrier.name) sel = [hs, carrier] break summary("Sending handover select: " + str(sel)) if found: self.success = True else: self.try_own = True return sel
def pack_file(f): record_data = f.read() record_type = magic.from_buffer(record_data, mime=1) record_name = getattr(f, 'name', '<stdin>')[0:255] return ndef.Record(record_type, record_name, record_data)
def process_handover_request_message(self, records): handover = self.handover self.ho_server_processing = True global in_raw_mode was_in_raw_mode = in_raw_mode clear_raw_mode() if was_in_raw_mode: print("\n") summary("HandoverServer - request received: " + str(records)) for carrier in records: if not isinstance(carrier, ndef.HandoverRequestRecord): continue if carrier.collision_resolution_number: handover.peer_crn = carrier.collision_resolution_number summary("peer_crn: %d" % handover.peer_crn) if handover.my_crn is None and handover.my_crn_ready: summary("Still trying to send own handover request - wait a moment to see if that succeeds before checking crn values") for i in range(10): if handover.my_crn is not None: break time.sleep(0.01) if handover.my_crn is not None: summary("my_crn: %d" % handover.my_crn) if handover.my_crn is not None and handover.peer_crn is not None: if handover.my_crn == handover.peer_crn: summary("Same crn used - automatic collision resolution failed") # TODO: Should generate a new Handover Request message return '' if ((handover.my_crn & 1) == (handover.peer_crn & 1) and \ handover.my_crn > handover.peer_crn) or \ ((handover.my_crn & 1) != (handover.peer_crn & 1) and \ handover.my_crn < handover.peer_crn): summary("I'm the Handover Selector Device") handover.i_m_selector = True else: summary("Peer is the Handover Selector device") summary("Ignore the received request.") return '' hs = ndef.HandoverSelectRecord('1.4') sel = [hs] found = False for carrier in records: if isinstance(carrier, ndef.HandoverRequestRecord): continue summary("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": summary("DPP carrier type match - add DPP carrier record") if len(carrier.data) == 0 or carrier.data[0] != 0: summary("URI Identifier Code 'None' not seen", color=C_RED) continue uri = carrier.data[1:].decode("utf-8") summary("Received DPP URI: " + uri) global test_uri, test_alt_uri if test_uri: summary("TEST MODE: Using specified URI") data = test_sel_uri if test_sel_uri else test_uri elif handover.alt_proposal and handover.altchanlist: summary("Use alternative channel list while processing alternative proposal from peer") data = wpas_get_nfc_uri(start_listen=False, chan_override=handover.altchanlist, pick_channel=True) else: data = wpas_get_nfc_uri(start_listen=False, pick_channel=True) summary("Own URI (pre-processing): %s" % data) if test_uri: summary("TEST MODE: Fake processing") res = "OK" data += " [%s]" % uri else: res = wpas_report_handover_req(uri) if res is None or "FAIL" in res: summary("DPP handover request processing failed", color=C_RED) if handover.altchanlist: data = wpas_get_nfc_uri(start_listen=False, chan_override=handover.altchanlist) summary("Own URI (try another channel list): %s" % data) continue if test_alt_uri: summary("TEST MODE: Reject initial proposal") continue found = True if not test_uri: wpas = wpas_connect() if wpas is None: continue global own_id data = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % own_id).rstrip() if "FAIL" in data: continue summary("Own URI (post-processing): %s" % data) handover.my_uri = data handover.peer_uri = uri uri = ndef.UriRecord(data) summary("Own bootstrapping NFC URI record: " + str(uri)) if not test_uri: info = wpas.request("DPP_BOOTSTRAP_INFO %d" % own_id) freq = None for line in info.splitlines(): if line.startswith("use_freq="): freq = int(line.split('=')[1]) if freq is None or freq == 0: summary("No channel negotiated over NFC - use channel 6") freq = 2437 else: summary("Negotiated channel: %d MHz" % freq) if not dpp_start_listen(wpas, freq): break carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) summary("Own DPP carrier record: " + str(carrier)) hs.add_alternative_carrier('active', carrier.name) sel = [hs, carrier] break summary("Sending handover select: " + str(sel)) if found: summary("Handover completed successfully") handover.terminate_on_hs_send_completion = True self.success = True handover.hs_sent = True handover.i_m_selector = True elif handover.no_alt_proposal: summary("Do not try alternative proposal anymore - handover failed", color=C_RED) handover.hs_sent = True else: summary("Try to initiate with alternative parameters") handover.try_own = True handover.hs_sent = False handover.no_alt_proposal = True if handover.client_thread: handover.start_client_alt = True else: handover.client_thread = threading.Thread(target=llcp_worker, args=(self.llc, True)) handover.client_thread.start() return sel
def dpp_handover_client(llc): uri = wpas_get_nfc_uri(start_listen=False) if uri is None: summary("Cannot start handover client - no bootstrap URI available") return uri = ndef.UriRecord(uri) summary("NFC URI record for DPP: " + str(uri)) carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) crn = os.urandom(2) hr = ndef.HandoverRequestRecord(version="1.4", crn=crn) hr.add_alternative_carrier('active', carrier.name) message = [hr, carrier] summary("NFC Handover Request message for DPP: " + str(message)) global peer_crn if peer_crn is not None: summary( "NFC handover request from peer was already received - do not send own" ) return client = nfc.handover.HandoverClient(llc) try: summary("Trying to initiate NFC connection handover") client.connect() summary("Connected for handover") except nfc.llcp.ConnectRefused: summary("Handover connection refused") client.close() return except Exception as e: summary("Other exception: " + str(e)) client.close() return if peer_crn is not None: summary( "NFC handover request from peer was already received - do not send own" ) client.close() return summary("Sending handover request") global my_crn, my_crn_ready, hs_sent my_crn_ready = True if not client.send_records(message): my_crn_ready = False summary("Failed to send handover request") client.close() return my_crn, = struct.unpack('>H', crn) summary("Receiving handover response") try: message = client.recv_records(timeout=3.0) except Exception as e: # This is fine if we are the handover selector if hs_sent: summary( "Client receive failed as expected since I'm the handover server: %s" % str(e)) else: summary("Client receive failed: %s" % str(e)) message = None if message is None: if hs_sent: summary( "No response received as expected since I'm the handover server" ) else: summary("No response received") client.close() return summary("Received message: " + str(message)) if len(message) < 1 or \ not isinstance(message[0], ndef.HandoverSelectRecord): summary("Response was not Hs - received: " + message.type) client.close() return summary("Received handover select message") summary("alternative carriers: " + str(message[0].alternative_carriers)) dpp_found = False for carrier in message: if isinstance(carrier, ndef.HandoverSelectRecord): continue summary("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": if len(carrier.data) == 0 or carrier.data[0] != 0: summary("URI Identifier Code 'None' not seen") continue summary("DPP carrier type match - send to wpa_supplicant") dpp_found = True uri = carrier.data[1:].decode("utf-8") summary("DPP URI: " + uri) res = wpas_report_handover_sel(uri) if res is None or "FAIL" in res: summary("DPP handover report rejected") break success_report("DPP handover reported successfully (initiator)") summary("peer_id=" + res) peer_id = int(res) wpas = wpas_connect() if wpas is None: break global enrollee_only global config_params if enrollee_only: extra = " role=enrollee" elif config_params: extra = " role=configurator " + config_params else: # TODO: Single Configurator instance res = wpas.request("DPP_CONFIGURATOR_ADD") if "FAIL" in res: summary("Failed to initiate Configurator") break conf_id = int(res) extra = " conf=sta-dpp configurator=%d" % conf_id global own_id summary("Initiate DPP authentication") cmd = "DPP_AUTH_INIT peer=%d own=%d" % (peer_id, own_id) cmd += extra res = wpas.request(cmd) if "FAIL" in res: summary("Failed to initiate DPP authentication") break if not dpp_found: summary( "DPP carrier not seen in response - allow peer to initiate a new handover with different parameters" ) client.close() summary("Returning from dpp_handover_client") return summary("Remove peer") client.close() summary("Done with handover") global only_one if only_one: print("only_one -> stop loop") global continue_loop continue_loop = False global no_wait if no_wait: print("Trying to exit..") global terminate_now terminate_now = True summary("Returning from dpp_handover_client")
def process_handover_request_message(self, records): self.ho_server_processing = True global in_raw_mode was_in_raw_mode = in_raw_mode clear_raw_mode() if was_in_raw_mode: print("\n") summary("HandoverServer - request received: " + str(records)) global my_crn, peer_crn, my_crn_ready for carrier in records: if not isinstance(carrier, ndef.HandoverRequestRecord): continue if carrier.collision_resolution_number: peer_crn = carrier.collision_resolution_number summary("peer_crn: %d" % peer_crn) if my_crn is None and my_crn_ready: summary( "Still trying to send own handover request - wait a moment to see if that succeeds before checking crn values" ) for i in range(10): if my_crn is not None: break time.sleep(0.01) if my_crn is not None: summary("my_crn: %d" % my_crn) if my_crn is not None and peer_crn is not None: if my_crn == peer_crn: summary( "Same crn used - automatic collision resolution failed") # TODO: Should generate a new Handover Request message return '' if ((my_crn & 1) == (peer_crn & 1) and my_crn > peer_crn) or \ ((my_crn & 1) != (peer_crn & 1) and my_crn < peer_crn): summary("I'm the Handover Selector Device") pass else: summary("Peer is the Handover Selector device") summary("Ignore the received request.") return '' hs = ndef.HandoverSelectRecord('1.4') sel = [hs] found = False for carrier in records: if isinstance(carrier, ndef.HandoverRequestRecord): continue summary("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": summary("DPP carrier type match - add DPP carrier record") if len(carrier.data) == 0 or carrier.data[0] != 0: summary("URI Identifier Code 'None' not seen") continue uri = carrier.data[1:].decode("utf-8") summary("Received DPP URI: " + uri) data = wpas_get_nfc_uri(start_listen=False, pick_channel=True) summary("Own URI (pre-processing): %s" % data) res = wpas_report_handover_req(uri) if res is None or "FAIL" in res: summary("DPP handover request processing failed") continue found = True wpas = wpas_connect() if wpas is None: continue global own_id data = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % own_id).rstrip() if "FAIL" in data: continue summary("Own URI (post-processing): %s" % data) uri = ndef.UriRecord(data) summary("Own bootstrapping NFC URI record: " + str(uri)) info = wpas.request("DPP_BOOTSTRAP_INFO %d" % own_id) freq = None for line in info.splitlines(): if line.startswith("use_freq="): freq = int(line.split('=')[1]) if freq is None or freq == 0: summary("No channel negotiated over NFC - use channel 6") freq = 2437 else: summary("Negotiated channel: %d MHz" % freq) if get_status_field(wpas, "bssid[0]"): summary("Own AP freq: %s MHz" % str(get_status_field(wpas, "freq"))) if get_status_field(wpas, "beacon_set", extra="DRIVER") is None: summary("Enable beaconing to have radio ready for RX") wpas.request("DISABLE") wpas.request("SET start_disabled 0") wpas.request("ENABLE") cmd = "DPP_LISTEN %d" % freq global enrollee_only global configurator_only if enrollee_only: cmd += " role=enrollee" elif configurator_only: cmd += " role=configurator" summary(cmd) res = wpas.request(cmd) if "OK" not in res: summary("Failed to start DPP listen") break carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) summary("Own DPP carrier record: " + str(carrier)) hs.add_alternative_carrier('active', carrier.name) sel = [hs, carrier] break summary("Sending handover select: " + str(sel)) if found: self.success = True else: self.try_own = True global hs_sent hs_sent = True return sel
def post(self): parser = reqparse.RequestParser() parser.add_argument('first_name') parser.add_argument('last_name') parser.add_argument('phone_number') parser.add_argument('phone_personal') parser.add_argument('email_address') parser.add_argument('email_personal') parser.add_argument('organization') parser.add_argument('position') parser.add_argument('policy') args = parser.parse_args() print(str(args)) vcard = vobject.vCard() if args['first_name'] and args['last_name']: vcard.add('n') vcard.add('fn') vcard.n.value = vobject.vcard.Name(family=args['last_name'], given=args['first_name']) vcard.fn.value = ' '.join([args['first_name'], args['last_name']]) elif args['first_name']: vcard.add('n') vcard.add('fn') vcard.n.value = vobject.vcard.Name(given=args['first_name']) vcard.fn.value = args['first_name'] elif args['last_name']: vcard.add('n') vcard.add('fn') vcard.n.value = vobject.vcard.Name(family=args['last_name']) vcard.fn.value = args['last_name'] if args['phone_number']: vcard.add('tel') #vcard.tel.value = ''.join(['+7', args['phone_number']]) vcard.tel.value = args['phone_number'] if args['phone_personal']: vcard.tel.type_param = 'CELL' else: vcard.tel.type_param = 'WORK' if args['email_address']: vcard.add('email') vcard.email.value = args['email_address'] if args['email_personal']: vcard.email.type_param = 'HOME' else: vcard.email.type_param = 'WORK' if args['organization']: vcard.add('org') vcard.org.value[0] = args['organization'] if args['position']: vcard.add('title') vcard.title.value = args['position'] vcard_newlines = '\n'.join(vcard.serialize().splitlines()) if args['policy']: with open('/usr/src/app/vcards/' + str(uuid.uuid4()) + '.vcf', 'w') as f: f.write(vcard_newlines) vcard_bytes = bytes(vcard_newlines, 'utf-8') ndf_record = ndef.Record(type='text/vcard', name='', data=vcard_bytes) ndef_data = b''.join(ndef.message_encoder([ndf_record])) device = NTAGWriter() try: device.write_ndef_message(ndef_data) except NTAGWriterError as e: return e, 500 return 'Written', 201
def run_dpp_handover_client(handover, alt=False): chan_override = None if alt: chan_override = handover.altchanlist handover.alt_proposal_used = True global test_uri, test_alt_uri if test_uri: summary("TEST MODE: Using specified URI (alt=%s)" % str(alt)) uri = test_alt_uri if alt else test_uri else: uri = wpas_get_nfc_uri(start_listen=False, chan_override=chan_override) if uri is None: summary("Cannot start handover client - no bootstrap URI available", color=C_RED) return handover.my_uri = uri uri = ndef.UriRecord(uri) summary("NFC URI record for DPP: " + str(uri)) carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data) global test_crn if test_crn: prev, = struct.unpack('>H', test_crn) summary("TEST MODE: Use specified crn %d" % prev) crn = test_crn test_crn = struct.pack('>H', prev + 0x10) else: crn = os.urandom(2) hr = ndef.HandoverRequestRecord(version="1.4", crn=crn) hr.add_alternative_carrier('active', carrier.name) message = [hr, carrier] summary("NFC Handover Request message for DPP: " + str(message)) if handover.peer_crn is not None and not alt: summary("NFC handover request from peer was already received - do not send own") return if handover.client: summary("Use already started handover client") client = handover.client else: summary("Start handover client") client = HandoverClient(handover, handover.llc) try: summary("Trying to initiate NFC connection handover") client.connect() summary("Connected for handover") except nfc.llcp.ConnectRefused: summary("Handover connection refused") client.close() return except Exception as e: summary("Other exception: " + str(e)) client.close() return handover.client = client if handover.peer_crn is not None and not alt: summary("NFC handover request from peer was already received - do not send own") return summary("Sending handover request") handover.my_crn_ready = True if not client.send_records(message): handover.my_crn_ready = False summary("Failed to send handover request", color=C_RED) run_client_alt(handover, alt) return handover.my_crn, = struct.unpack('>H', crn) summary("Receiving handover response") try: start = time.time() message = client.recv_records(timeout=3.0) end = time.time() summary("Received {} record(s) in {} seconds".format(len(message) if message is not None else -1, end - start)) except Exception as e: # This is fine if we are the handover selector if handover.hs_sent: summary("Client receive failed as expected since I'm the handover server: %s" % str(e)) elif handover.alt_proposal_used and not alt: summary("Client received failed for initial proposal as expected since alternative proposal was also used: %s" % str(e)) else: summary("Client receive failed: %s" % str(e), color=C_RED) message = None if message is None: if handover.hs_sent: summary("No response received as expected since I'm the handover server") elif handover.alt_proposal_used and not alt: summary("No response received for initial proposal as expected since alternative proposal was also used") elif handover.try_own and not alt: summary("No response received for initial proposal as expected since alternative proposal will also be sent") else: summary("No response received", color=C_RED) run_client_alt(handover, alt) return summary("Received message: " + str(message)) if len(message) < 1 or \ not isinstance(message[0], ndef.HandoverSelectRecord): summary("Response was not Hs - received: " + message.type) return summary("Received handover select message") summary("alternative carriers: " + str(message[0].alternative_carriers)) if handover.i_m_selector: summary("Ignore the received select since I'm the handover selector") run_client_alt(handover, alt) return if handover.alt_proposal_used and not alt: summary("Ignore received handover select for the initial proposal since alternative proposal was sent") client.close() return dpp_found = False for carrier in message: if isinstance(carrier, ndef.HandoverSelectRecord): continue summary("Remote carrier type: " + carrier.type) if carrier.type == "application/vnd.wfa.dpp": if len(carrier.data) == 0 or carrier.data[0] != 0: summary("URI Identifier Code 'None' not seen", color=C_RED) continue summary("DPP carrier type match - send to wpa_supplicant") dpp_found = True uri = carrier.data[1:].decode("utf-8") summary("DPP URI: " + uri) handover.peer_uri = uri if test_uri: summary("TEST MODE: Fake processing") break res = wpas_report_handover_sel(uri) if res is None or "FAIL" in res: summary("DPP handover report rejected", color=C_RED) break success_report("DPP handover reported successfully (initiator)") summary("peer_id=" + res) peer_id = int(res) wpas = wpas_connect() if wpas is None: break global enrollee_only global config_params if enrollee_only: extra = " role=enrollee" elif config_params: extra = " role=configurator " + config_params else: # TODO: Single Configurator instance res = wpas.request("DPP_CONFIGURATOR_ADD") if "FAIL" in res: summary("Failed to initiate Configurator", color=C_RED) break conf_id = int(res) extra = " conf=sta-dpp configurator=%d" % conf_id global own_id summary("Initiate DPP authentication") cmd = "DPP_AUTH_INIT peer=%d own=%d" % (peer_id, own_id) cmd += extra res = wpas.request(cmd) if "FAIL" in res: summary("Failed to initiate DPP authentication", color=C_RED) break if not dpp_found and handover.no_alt_proposal: summary("DPP carrier not seen in response - do not allow alternative proposal anymore") elif not dpp_found: summary("DPP carrier not seen in response - allow peer to initiate a new handover with different parameters") handover.alt_proposal = True handover.my_crn_ready = False handover.my_crn = None handover.peer_crn = None handover.hs_sent = False summary("Returning from dpp_handover_client") return summary("Remove peer") handover.close() summary("Done with handover") global only_one if only_one: print("only_one -> stop loop") global continue_loop continue_loop = False global no_wait if no_wait or only_one: summary("Trying to exit..") global terminate_now terminate_now = True summary("Returning from dpp_handover_client")
def test_unknown_records_decode(self): octets = bytearray.fromhex('11d20a00746578742f706c61696e') record = self.RECORD(0x11) record.unknown_records.append(ndef.Record('text/plain')) assert self.RECORD._decode_payload(octets, 'strict') == record
assert record.alternative_carriers[0].auxiliary_data_reference[1] == 'a2' assert record.alternative_carriers[1].carrier_power_state == 'inactive' assert record.alternative_carriers[1].carrier_data_reference == 'bt31' assert record.alternative_carriers[1].auxiliary_data_reference[0] == 'a3' assert len(record.unknown_records) == 1 assert record.unknown_records[0].type == 'text/plain' assert record.unknown_records[0].name == 'txt' assert record.unknown_records[0].data == b'Hello' handover_request_messages = [ ('d102014872 11', [ndef.HandoverRequestRecord('1.1')]), ('91020a487211 d10204616301013100 5a030201612f62310001', [ndef.HandoverRequestRecord('1.1', None, (1, '1')), ndef.Record('a/b', '1', b'\x00\x01')]), ('d10208487212 d1020263721234', [ndef.HandoverRequestRecord('1.2', 0x1234)]), ('910211487212 91020263721234 510204616301013100 5a030201612f62310001', [ndef.HandoverRequestRecord('1.2', 0x1234, (1, '1')), ndef.Record('a/b', '1', b'\x00\x01')]), ('910211487212 91020263721234 510204616301013100 590205014863310203612f62', [ndef.HandoverRequestRecord('1.2', 0x1234, (1, '1')), ndef.HandoverCarrierRecord('a/b', None, '1')]), ] class TestHandoverRequestMessage: @pytest.mark.parametrize("encoded, message", handover_request_messages) def test_decode(self, encoded, message): octets = bytes(bytearray.fromhex(encoded))
def __init__(self, llc): self.ndef_message = [ndef.Record()] service_name = "urn:nfc:xsn:nfcpy.org:x-snep" nfc.snep.SnepServer.__init__(self, llc, service_name, 2048)