README.md | ●●●●● patch | view | raw | blame | history | |
bcm20795.py | ●●●●● patch | view | raw | blame | history | |
cv2.py | ●●●●● patch | view | raw | blame | history | |
cv3.py | ●●●●● patch | view | raw | blame | history | |
cvcomm.py | ●●●●● patch | view | raw | blame | history | |
nfc.py | ●●●●● patch | view | raw | blame | history | |
traffic_cv2.txt | patch | view | raw | blame | history | |
traffic_cv3.txt | ●●●●● patch | view | raw | blame | history |
README.md
@@ -1,4 +1,4 @@ # Enable NFC on Dell ControlVault2 # Enable NFC on Dell ControlVault2 and ControlVault3 ## Introduction @@ -14,7 +14,7 @@ 1. Clone the repository. 1. Install python3 and python3-usb. 1. Run: `./bcm20795.py on` (use `sudo` if necessary). 1. Run: `./nfc.py on` (use `sudo` if necessary). 1. Run `pcsc_scan` or whatever you prefer. 1. Enjoy! @@ -24,8 +24,9 @@ Currently only the following devices were tested and are known to work: * `0a5c:5832` * `0a5c:5834` * `0a5c:5832` (ControlVault 2), * `0a5c:5833` (ControlVault 3), * `0a5c:5834` (ControlVault 2). Firmware update (done during driver installation on Windows) may be required. @@ -36,19 +37,20 @@ * Dell Latitude 7280 * Dell Latitude 7290 * Dell Latitude 7390 * Dell Latitude 7400 * Dell Latitude E5270 * Dell Latitude E7470 * Dell Latitude E7490 ## How it works? Python script sends the same sequence of commands the Windows driver does. The traffic was sniffed using USBPcap and Wireshark (kudos to [~jkramarz](https://github.com/jkramarz) for that). Python script sends the same sequence of commands the Windows driver does. The traffic was sniffed using USBPcap and Wireshark (kudos to [~jkramarz](https://github.com/jkramarz) and [~lgarbarini](https://github.com/lgarbarini) and for that). The data is sent as-is and responses are read, but no error-checking is done. The semi-annotated traffic dump is available as [traffic.txt](traffic.txt) - feel free to decode it further! The semi-annotated traffic dumps are available as [traffic_cv2.txt](traffic_cv2.txt) and [traffic_cv3.txt](traffic_cv3.txt) - feel free to decode it further! The communication protocol is based on NCI (NFC Controller Interface). Unfortunately the specs are not freely available and some proprietary extensions are used. libnfc-nci and kernel sources were used to decode some structs. The communication protocol is based on NCI (NFC Controller Interface). Unfortunately the specs are not freely available and some proprietary extensions are used. libnfc-nci and kernel sources were used to decode vendor-independent structs. ## References bcm20795.py
File was deleted cv2.py
New file @@ -0,0 +1,46 @@ import cvcomm class ControlVault2: NAME = 'Broadcom ControlVault 2' turn_on_seq1 = [ "10 2f 04 00", "10 2f 1d 03 05 90 65", "10 2f 2d 00", "10 2f 11 01 f7", "01 27 fc 0c 08 00 01 00 01 00 00 00 00 00 00 00", ] turn_on_seq2 = [ "10 20 00 01 01", "10 20 01 02 01 00", "10 20 02 67 01 b9 64 01 00 ff ff 50 00 8b 13 00 10 00 06 00 00 00 00 00 ff 00 00 00 ff 00 00 04 00 00 00 00 03 00 00 00 03 00 0c 00 00 0d 00 00 00 00 00 00 00 00 00 00 33 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 02 53 3b 0f 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00", "10 20 02 90 0a ca 05 00 00 00 00 2c 80 01 01 b0 05 01 03 03 03 08 b5 03 01 03 ff c9 0d 24 00 00 00 01 00 bb 00 e4 00 0a 01 02 d6 0d 01 02 00 00 00 00 00 01 00 01 5a 00 8a b2 02 e8 03 c8 1e 06 1f 00 0a 00 30 00 04 24 00 1c 00 75 00 77 00 76 00 1c 00 03 00 0a 00 56 01 00 00 40 04 d7 01 07 dd 32 00 00 00 29 16 08 08 06 04 00 00 00 1f 27 0a 6d 20 00 52 20 00 00 00 01 85 00 00 32 1f 00 00 02 0a 16 00 02 55 55 55 55 55 55 55 55 55 55 55 55 55 1e", "10 20 02 06 01 b7 03 02 00 01", "10 2f 06 01 01", "10 20 02 0e 02 51 08 20 79 ff ff ff ff ff ff 58 01 07", "10 21 00 07 02 04 03 02 05 03 03", "10 20 02 17 01 29 14 46 66 6d 01 01 11 02 02 07 ff 03 02 00 13 04 01 64 07 01 03", "10 20 02 1a 02 61 14 46 66 6d 01 01 11 02 02 07 ff 03 02 00 13 04 01 64 07 01 03 60 01 07", "10 20 02 10 05 30 01 04 31 01 00 32 01 40 38 01 00 50 01 02", "10 20 02 05 01 00 02 fa 00", "10 20 02 0b 01 c2 08 01 08 00 04 80 c3 c9 01", "10 21 03 0d 06 00 01 01 01 02 01 80 01 82 01 06 01", ] def __init__(self, device): self.device = device self.communicator = cvcomm.ControlVaultCommunicator(device) def turn_on(self): self.communicator.ctrl_transfer(0x41, 0, 1, 3) self.communicator.talk(self.turn_on_seq1) self.communicator.ctrl_transfer(0x41, 1, 0, 3) self.communicator.talk(self.turn_on_seq2) self.communicator.ctrl_transfer(0x41, 1, 1, 3) def turn_off(self): self.communicator.ctrl_transfer(0x41, 1, 0, 3) self.communicator.ctrl_transfer(0x41, 0, 0, 3) def reset(self): self.device.reset() cv3.py
New file @@ -0,0 +1,43 @@ import cvcomm class ControlVault3: NAME = 'Broadcom ControlVault 3' turn_on_seq1 = [ "20 00 01 00", ] turn_on_seq2 = [ "20 00 01 00", "20 01 00", "20 03 02 01 52", "20 02 1f 0a 21 01 00 28 01 00 30 01 04 31 01 03 54 01 06 5b 01 00 60 01 07 80 01 01 81 01 01 82 01 0e", "21 00 10 05 04 03 02 05 03 03 01 01 01 02 01 01 03 01 01", "21 01 07 00 01 01 03 00 01 05", "20 02 09 01 b9 06 01 00 00 0b 00 00", "20 02 c7 11 18 01 02 2a 01 32 80 01 00 c2 02 03 02 c4 02 00 13 ca 05 00 0f 0d 03 08 cb 01 00 d6 0b 01 01 00 01 12 00 01 00 01 00 01 d8 01 01 de 04 01 00 00 00 e0 07 00 60 93 1c 63 3e 0a e1 02 79 07 e2 2a 48 07 0c 10 00 31 39 39 39 39 39 39 39 39 39 39 41 39 90 90 90 90 3f 90 90 90 88 8a 8c 94 94 28 04 07 00 00 00 00 00 00 00 00 e3 08 17 04 16 0d 10 0c 2b 0b e4 01 37 e5 1e e0 1e 02 12 00 0a 00 10 04 54 54 54 54 2b 52 50 53 4e 20 2d 18 0c 02 07 00 94 70 94 70 20 e6 2d 01 68 00 77 00 8b 00 a7 00 d6 00 22 01 c0 01 9e 58 4c 40 33 26 20 1e 68 00 77 00 8b 00 a7 00 d6 00 22 01 c0 01 5e 58 4c 40 33 2b 26 1e", "2f 1b 06 08 00 00 01 00 00", "20 02 2d 04 29 11 46 66 6d 01 01 11 02 02 03 80 03 02 00 01 04 01 64 2a 01 30 61 11 46 66 6d 01 01 11 02 02 03 80 03 02 00 01 04 01 64 62 01 30", "20 02 0e 04 18 01 01 32 01 40 50 01 02 00 02 2c 01", "21 03 0d 06 00 01 01 01 02 01 06 01 80 01 82 01", ] def __init__(self, device): self.device = device self.communicator = cvcomm.ControlVaultCommunicator(device) def turn_on(self): self.communicator.ctrl_transfer(0x41, 1, 0, 3) self.communicator.talk(self.turn_on_seq1) self.communicator.ctrl_transfer(0x41, 1, 1, 3) self.communicator.ctrl_transfer(0x41, 0, 0, 3) self.communicator.ctrl_transfer(0x41, 0, 1, 3) self.communicator.ctrl_transfer(0x41, 1, 0, 3) self.communicator.talk(self.turn_on_seq2) self.communicator.ctrl_transfer(0x41, 1, 1, 3) def turn_off(self): self.communicator.ctrl_transfer(0x41, 1, 0, 3) self.communicator.ctrl_transfer(0x41, 0, 0, 3) def reset(self): self.device.reset() cvcomm.py
New file @@ -0,0 +1,93 @@ import logging import math import struct import usb.util def to_hex(val): return ' '.join([bytes([i]).hex() for i in val]) class ControlVaultCommunicator: def __init__(self, device, spi_master=0x01, spi_slave=0x00, spi_crc=0x00): self.logger = logging.getLogger(__name__) self.device = device self.bulk_in, self.bulk_out = self._find_endpoints() self.spi_master = spi_master self.spi_slave = spi_slave self.spi_crc = spi_crc self.spi_slave_prefix = struct.pack('>BB', self.spi_slave, self.spi_crc) def ctrl_transfer(self, *args, **kwargs): self.logger.debug('Control: {} {}'.format(args, kwargs)) return self.device.ctrl_transfer(*args, **kwargs) def write(self, *args, **kwargs): return self.bulk_out.write(*args, **kwargs) def read(self, *args, **kwargs): return self.bulk_in.read(*args, **kwargs) def send_packet(self, payload): length = len(payload) packet = struct.pack('>BBH', self.spi_master, self.spi_crc, length) + payload self.logger.debug('Put: {}'.format(to_hex(packet))) self.write(packet) def recv_packet(self): packet = self.read(64, timeout=5000).tobytes() tag = packet[0:2] if tag != self.spi_slave_prefix: raise Exception('Unknown tag: {}'.format(tag.hex())) length = packet[2:4] length = struct.unpack('>H', length)[0] for i in range(0, math.ceil(length/64) - 1): packet += self.read(64).tobytes() self.logger.debug('Got: {}'.format(to_hex(packet))) return packet[4:] def talk(self, exchange): for packet in exchange: self.send_packet(bytes.fromhex(packet)) data = self.recv_packet() if data[1] == 0x61: packet = self.recv_packet() def _find_endpoints(self): self.logger.debug('Enumerating interfaces...') configuration = self.device.get_active_configuration() bcm_interface = None for interface in configuration: if interface.bInterfaceClass == 0xff and interface.iInterface == 0x08: if bcm_interface is not None: raise Exception('More than one vendor-specific interface found!') bcm_interface = interface if bcm_interface is None: raise Exception('Cannot find vendor-specific interface') self.logger.debug('Interface found: {}'.format(bcm_interface._str())) self.logger.debug('Enumerating endpoints...') bulk_in = None bulk_out = None for endpoint in bcm_interface: if endpoint.bmAttributes & usb.util._ENDPOINT_TRANSFER_TYPE_MASK == usb.util.ENDPOINT_TYPE_BULK: if endpoint.bEndpointAddress & usb.util._ENDPOINT_DIR_MASK == usb.util.ENDPOINT_IN: if bulk_in is not None: raise Exception('More than one BULK IN endpoint found!') bulk_in = endpoint self.logger.debug('BULK IN found: {}'.format(bulk_in._str())) if endpoint.bEndpointAddress & usb.util._ENDPOINT_DIR_MASK == usb.util.ENDPOINT_OUT: if bulk_out is not None: raise Exception('More than one BULK OUT endpoint found!') bulk_out = endpoint self.logger.debug('BULK OUT found: {}'.format(bulk_out._str())) if bulk_in is None: raise Exception('BULK IN endpoint not found!') if bulk_out is None: raise Exception('BULK OUT endpoint not found!') self.logger.debug('Endpoint discovery successful.') return bulk_in, bulk_out nfc.py
New file @@ -0,0 +1,76 @@ #!/usr/bin/env python3 import logging import sys import usb.core class UsbDeviceMatcher: def __init__(self, properties, handler): self.properties = properties self.handler = handler def matches(self, candidate): for prop, value in self.properties.items(): if prop not in candidate.__dict__ or candidate.__dict__[prop] != value: return False return True class UsbDeviceFinder: SUPPORTED_DEVICES = [ UsbDeviceMatcher({'idVendor': 0x0A5C, 'idProduct': 0x5832}, lambda device: __import__('cv2').ControlVault2(device)), UsbDeviceMatcher({'idVendor': 0x0A5C, 'idProduct': 0x5833}, lambda device: __import__('cv3').ControlVault3(device)), UsbDeviceMatcher({'idVendor': 0x0A5C, 'idProduct': 0x5834}, lambda device: __import__('cv2').ControlVault2(device)), ] @classmethod def _dev_matcher(cls, device): for matcher in cls.SUPPORTED_DEVICES: if matcher.matches(device): return True return False @classmethod def _cls_matcher(cls, device): for matcher in cls.SUPPORTED_DEVICES: if matcher.matches(device): return matcher.handler(device) raise Exception('Cannot find handler for device {:04X}:{:04X}'.format(dev.idVendor, dev.idProduct)) @classmethod def find(cls): logger = logging.getLogger(__name__) logger.info('Looking for supported device...') device = usb.core.find(custom_match=cls._dev_matcher) if device is None: raise Exception('Cannot find BCM device - check list of supported devices') logger.info('Found {:04X}:{:04X}'.format(device.idVendor, device.idProduct)) handler = cls._cls_matcher(device) logger.info('Handler {} ({})'.format(handler.__class__.__name__, handler.NAME)) return handler if __name__ == "__main__": if len(sys.argv) < 2: print('Usage: {} [on|off|reset]'.format(sys.argv[0])) sys.exit(2) logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) handler = UsbDeviceFinder.find() if sys.argv[1] == 'on': logger.info('Turning NFC on...') handler.turn_on() logger.info('NFC should be turned on now!') elif sys.argv[1] == 'off': logger.info('Turning NFC off...') handler.turn_off() logger.info('NFC should be turned off now!') elif sys.argv[1] == 'reset': logger.info('Resetting device...') handler.reset() logger.info('NFC device has been reset!') else: raise Exception('Unknown option: {}'.format(sys.argv[1])) traffic_cv2.txt
traffic_cv3.txt
New file @@ -0,0 +1,529 @@ idVendor 0x0A5C idProduct 0x5843 Interface 4 - Application-Specific EP 1 IN EP 1 OUT EP 5 IN Interface 5 - Smart Card EP 2 IN EP 2 OUT EP 6 IN Interface 6 - Smart Card EP 3 IN EP 3 OUT EP 7 IN Interface 7 - Vendor Specific EP 4 IN EP 4 OUT EP 8 IN Legend: > - New outgoing message (beginning) >> - Message continuation (division for readability) < - New incoming message (beginning) << - Message continuation (division for readability) # CTRL - Control endpoint communication (bmRequestType, bRequest, wValue, wIndex) Communication via Endpoint 4 ########## TURNING ON ########## # CTRL 0x41 0x01 0x0000 0x0003 > 01 00 00 04 01 = SPI_MASTER 00 = NO_CRC 00 04 = size >> 20 00 01 00 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 00 = NCI_MSG_CORE_RESET 01 = NCI_CORE_PARAM_SIZE_RESET 00 = NCI_RESET_TYPE_KEEP_CFG < 00 00 00 06 00 = SPI_SLAVE 00 = NO_CRC 00 06 = size << 40 00 03 00 10 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 00 = NCI_MSG_CORE_RESET 03 = NCI_CORE_PARAM_SIZE_RESET_RSP 00 = NCI_STATUS_OK 10 = NCI_VERSION (1.0) 00 = NCI_RESET_STATUS_KEPT_CFG # CTRL 0x41 0x01 0x0001 0x0003 # CTRL 0x41 0x00 0x0000 0x0003 # CTRL 0x41 0x00 0x0001 0x0003 # CTRL 0x41 0x01 0x0000 0x0003 > 01 00 00 04 01 = SPI_MASTER 00 = NO_CRC 00 04 = size >> 20 00 01 00 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 00 = NCI_MSG_CORE_RESET 01 = NCI_CORE_PARAM_SIZE_RESET 00 = NCI_RESET_TYPE_KEEP_CFG < 00 00 00 06 00 = SPI_SLAVE 00 = NO_CRC 00 06 = size << 40 00 03 00 11 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 00 = NCI_MSG_CORE_RESET 03 = NCI_CORE_PARAM_SIZE_RESET_RSP 00 = NCI_STATUS_OK 11 = NCI_VERSION (1.1) 00 = NCI_RESET_STATUS_KEPT_CFG > 01 00 00 03 01 = SPI_MASTER 00 = NO_CRC 00 03 = size >> 20 01 00 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 01 = NCI_MSG_CORE_INIT 00 = size < 00 00 00 1a 00 = SPI_SLAVE 00 = NO_CRC 00 1a = size << 40 01 17 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 01 = NCI_MSG_CORE_INIT 17 = size 00 = NCI_STATUS_OK << 03 0e 02 01 03 0e 02 01 NFCC_FEATURES 02 = multiple NFCEEs 01 = RF_DISCOVER_CMD supported 08 = AID-based routing supported 04 = Protocol-based routing supported 02 = Technology-based routing supported 02 = Switched-off state supported 01 = Proprietary parameters << 06 00 01 02 03 81 83 06 = num_of_ifaces (6) 00 = NCI_INTERFACE_EE_DIRECT_RF 01 = NCI_INTERFACE_FRAME 02 = NCI_INTERFACE_ISO_DEP 03 = NCI_INTERFACE_NFC_DEP 81 = Proprietary Interface (81) 83 = Proprietary Interface (83) << 08 00 04 ff 0f 00 2e 04 10 2b 41 08 = num_of_conns_max (8) 00 04 = num_of_routes_max ff = size_control_payload_max 0f 00 = size_large_params_max 2e = manufacturer_id 04 10 2b 41 = manufacturer_specific > 01 00 00 05 01 = SPI_MASTER 00 = NO_CRC 00 05 = size >> 20 03 02 01 52 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 03 = NCI_MSG_CORE_GET_CONFIG 02 = num_of_params (2) 01 = CON_DEVICES_LIMIT 52 = LF_T3T_MAX < 00 00 00 08 00 = SPI_SLAVE 00 = NO_CRC 00 08 = size << 40 03 05 00 01 52 01 10 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 03 = NCI_MSG_CORE_GET_CONFIG ??? > 01 00 00 22 01 = SPI_MASTER 00 = NO_CRC 00 22 = size >> 20 02 1f 0a 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 1f = size 0a = num_of_params (10) >> 21 01 00 21 = PI_BIT_RATE 01 = size_of_param 00 = 106 Kbit/s >> 28 01 00 28 = PN_NFC_DEP_SPEED 01 = size_of_param 00 = Highest Available Bitrate >> 30 01 04 30 = LA_BIT_FRAME_SDD 01 = size_of_param 04 = Bit Frame SDD value to be sent in Byte 1 of SENS_RES >> 31 01 03 31 = LA_PLATFORM_CONFIG 01 = size_of_param 03 = Platform Configuration value to be sent in Byte 2 of SENS_RES >> 54 01 06 54 = LF_CON_BITR_F 01 = size_of_param 02 = listen for 212 kbps 04 = listen for 424 kbps >> 5b 01 00 5b = LI_BIT_RATE 01 = size_of_param 00 = 106 Kbit/s >> 60 01 07 60 = LN_WT 01 = size_of_param 07 = waiting time (7) >> 80 01 01 80 = RF_FIELD_INFO 01 = size_of_param 01 = RF_FIELD_INFO_NTF allowed >> 81 01 01 81 = RF_NFCEE_ACTION 01 = size_of_param 01 = send RF NFCEE Actions >> 82 01 0e 82 = NFCDEP_OP 01 = size_of_param 02 = ATTENTION only for error recovery 04 = don't send msgs without Transport Data Bytes 08 = chaining uses max number of Transport Data Bytes < 00 00 00 05 00 = SPI_SLAVE 00 = NO_CRC 00 05 = size << 40 02 02 00 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 02 = size 00 = NCI_STATUS_OK 00 = num_of_invalid_params (0) > 01 00 00 13 01 = SPI_MASTER 00 = NO_CRC 00 13 = size >> 21 00 10 05 21 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 00 = NCI_MSG_RF_DISCOVER_MAP 10 = size (16) 05 = num_mapping_configs >> 04 03 02 04 = NCI_PROTOCOL_ISO_DEP 03 = NCI_INTERFACE_MODE_POLL_N_LISTEN 02 = NCI_INTERFACE_ISO_DEP >> 05 03 03 05 = NCI_PROTOCOL_NFC_DEP 03 = NCI_INTERFACE_MODE_POLL_N_LISTEN 03 = NCI_INTERFACE_NFC_DEP >> 01 01 01 01 = PROTOCOL_T1T 01 = NCI_INTERFACE_MODE_POLL 01 = NCI_INTERFACE_FRAME >> 02 01 01 02 = PROTOCOL_T2T 01 = NCI_INTERFACE_MODE_POLL 01 = NCI_INTERFACE_FRAME >> 03 01 01 03 = PROTOCOL_T3T 01 = NCI_INTERFACE_MODE_POLL 01 = NCI_INTERFACE_FRAME < 00 00 00 04 00 = SPI_SLAVE 00 = NO_CRC 00 04 = size << 61 07 01 00 61 = NCI_MTS_NTF | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 07 = NCI_MSG_RF_FIELD 01 = size 00 = No RF field < 00 00 00 04 00 = SPI_SLAVE 00 = NO_CRC 00 04 = size << 41 00 01 00 41 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 00 = NCI_MSG_RF_DISCOVER_MAP 01 = NCI_DISCOVER_PARAM_SIZE_RSP 00 = NCI_STATUS_OK > 01 00 00 0a 01 = SPI_MASTER 00 = NO_CRC 00 0a = size >> 21 01 07 00 01 01 03 00 01 05 21 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 01 = NCI_MSG_RF_SET_ROUTING 07 = size 00 = last message 01 = routing_entries (1) 01 = protocol-based routing 03 = length (3) 00 = DH NFCEE ID 01 = power state (1 - switched on) 05 = PROTOCOL_NFC_DEP < 00 00 00 04 00 = SPI_SLAVE 00 = NO_CRC 00 04 = size << 41 01 01 00 41 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 01 = NCI_MSG_RF_SET_ROUTING 01 = size 00 = NCI_STATUS_OK > 01 00 00 0c 01 = SPI_MASTER 00 = NO_CRC 00 0c = size >> 20 02 09 01 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 09 = size 01 = num_of_params >> b9 06 01 00 00 0b 00 00 b9 = Proprietary parameter (b9) 06 = size_of_param < 00 00 00 05 00 = SPI_SLAVE 00 = NO_CRC 00 05 = size << 40 02 02 00 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 02 = size 00 = NCI_STATUS_OK 00 = num_of_invalid_params (0) > 01 00 00 ca 01 = SPI_MASTER 00 = NO_CRC 00 ca = size >> 20 02 c7 11 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG c7 = size 11 = num_of_params (17) >> 18 01 02 18 = PF_BIT_RATE 01 = size_of_param 02 = 424 Kbit/s >> 2a 01 32 2a = PN_ATR_REQ_CONFIG 01 = size_of_param 30 = 0011b for LLCP 02 = ? >> 80 01 00 80 = RF_FIELD_INFO 01 = size_of_param 00 = RF_FIELD_INFO_NTF not allowed >> c2 02 03 02 c2 = Proprietary parameter (c2) 02 = size_of_param >> c4 02 00 13 c4 = Proprietary parameter (c4) 02 = size_of_param >> ca 05 00 0f 0d 03 08 ca = Proprietary parameter (ca) 05 = size_of_param >> cb 01 00 cb = Proprietary parameter (cb) 01 = size_of_param >> d6 0b 01 01 00 01 12 00 01 00 01 00 01 d6 = Proprietary parameter (d6) 0b = size_of_param >> d8 01 01 d8 = Proprietary parameter (d8) 01 = size_of_param >> de 04 01 00 00 00 de = Proprietary parameter (de) 04 = size_of_param >> e0 07 00 60 93 1c 63 3e 0a e0 = Proprietary parameter (e0) 07 = size_of_param >> e1 02 79 07 e1 = Proprietary parameter (e1) 02 = size_of_param >> e2 2a 48 07 0c 10 00 31 39 39 39 39 39 39 39 39 39 39 41 39 90 90 90 90 3f 90 90 90 88 8a 8c 94 94 28 04 07 00 00 00 00 00 00 00 00 e2 = Proprietary parameter (e2) 2a = size_of_param >> e3 08 17 04 16 0d 10 0c 2b 0b e3 = Proprietary parameter (e3) 08 = size_of_param >> e4 01 37 e4 = Proprietary parameter (e4) 01 = size_of_param >> e5 1e e0 1e 02 12 00 0a 00 10 04 54 54 54 54 2b 52 50 53 4e 20 2d 18 0c 02 07 00 94 70 94 70 20 e5 = Proprietary parameter (e5) 1e = size_of_param >> e6 2d 01 68 00 77 00 8b 00 a7 00 d6 00 22 01 c0 01 9e 58 4c 40 33 26 20 1e 68 00 77 00 8b 00 a7 00 d6 00 22 01 c0 01 5e 58 4c 40 33 2b 26 1e e6 = Proprietary parameter (e6) 2d = size_of_param < 00 00 00 05 00 = SPI_SLAVE 00 = NO_CRC 00 05 = size << 40 02 02 00 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 02 = size 00 = NCI_STATUS_OK 00 = num_of_invalid_params (0) > 01 00 00 09 01 = SPI_MASTER 00 = NO_CRC 00 09 = size >> 2f 1b 06 08 00 00 01 00 00 2f = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_PROP 1b = Proprietary message (1b) 06 = size < 00 00 00 04 00 = SPI_SLAVE 00 = NO_CRC 00 04 = size << 4f 1b 01 00 4f = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_PROP 1b = Proprietary message (1b) 01 = size > 01 00 00 30 01 = SPI_MASTER 00 = NO_CRC 00 30 = size >> 20 02 2d 04 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 2d = size 04 = num_of_params (4) >> 29 11 46 66 6d 01 01 11 02 02 03 80 03 02 00 01 04 01 64 29 = PN_ATR_REQ_GEN_BYTES 11 = size_of_param General Bytes for ATR_REQ >> 2a 01 30 2a = PN_ATR_REQ_CONFIG 01 = size_of_param 30 = 0011b for LLCP >> 61 11 46 66 6d 01 01 11 02 02 03 80 03 02 00 01 04 01 64 61 = LN_ATR_RES_GEN_BYTES 11 = size_of_param General Bytes in ATR_RES >> 62 01 30 62 = LN_ATR_RES_CONFIG 01 = size_of_param 30 = 0011b for LLCP < 00 00 00 05 00 = SPI_SLAVE 00 = NO_CRC 00 05 = size << 40 02 02 00 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 02 = size 00 = NCI_STATUS_OK 00 = num_of_invalid_params (0) > 01 00 00 11 01 = SPI_MASTER 00 = NO_CRC 00 11 = size >> 20 02 0e 04 20 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 0e = size 04 = num_of_params (4) >> 18 01 01 18 = PF_BIT_RATE 01 = size_of_param 01 = 212 Kbit/s >> 32 01 40 32 = LA_SEL_INFO 01 = size_of_param 40 = NFC-DEP >> 50 01 02 50 = LF_PROTOCOL_TYPE 01 = size_of_param 02 = NFC-DEP >> 00 02 2c 01 00 = TOTAL_DURATION 02 = size_of_param 2c 01 = 11 256 ms < 00 00 00 05 00 = SPI_SLAVE 00 = NO_CRC 00 05 = size << 40 02 02 00 00 40 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_CORE 02 = NCI_MSG_CORE_SET_CONFIG 02 = size 00 = NCI_STATUS_OK 00 = num_of_invalid_params (0) > 01 00 00 10 01 = SPI_MASTER 00 = NO_CRC 00 10 = size >> 21 03 0d 06 21 = NCI_MTS_CMD | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 03 = NCI_MSG_RF_DISCOVER 0d = size 06 = num_of_configs (6) >> 00 01 00 = NFC_A_PASSIVE_POLL_MODE 01 = every discovery period >> 01 01 01 = NFC_B_PASSIVE_POLL_MODE 01 = every discovery period >> 02 01 02 = NFC_F_PASSIVE_POLL_MODE 01 = every discovery period >> 06 01 06 = NFC_15693_PASSIVE_POLL_MODE 01 = every discovery period >> 80 01 80 = NFC_A_PASSIVE_LISTEN_MODE 01 = every discovery period >> 82 01 82 = NFC_F_PASSIVE_LISTEN_MODE 01 = every discovery period < 00 00 00 04 00 = SPI_SLAVE 00 = NO_CRC 00 04 = size << 41 03 01 00 41 = NCI_MTS_RSP | NCI_PBF_NO_OR_LAST | NCI_GID_RF_MANAGE 03 = NCI_MSG_RF_DISCOVER 01 = size 00 = STATUS_OK # CTRL 0x41 0x01 0x0001 0x0003