diff --git a/.gitignore b/.gitignore index cad5e63..5956980 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ src/sync.ffs_db .DS_Store +.vscode/ \ No newline at end of file diff --git a/API.md b/API.md index 6cb0b5c..7d86586 100644 --- a/API.md +++ b/API.md @@ -2,7 +2,7 @@ The `Electroniccats_PN7150` class enables Arduino library for I2C access to the PN7150 RFID/Near Field Communication chip. -### Class: `Electroniccats_PN7150` +## Class: `Electroniccats_PN7150` Include and instantiate the Electroniccats_PN7150 class. Creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 @@ -26,7 +26,7 @@ Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); #define PN7150_VEN (7) #define PN7150_ADDR (0x28) -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // Creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 void setup(){ Serial.begin(115200); @@ -41,86 +41,1559 @@ void setup(){ int setupNFC(){ Serial.println("Initializing..."); - int setupOK = nfc.connectNCI(); //Wake up the board + int setupOK = nfc.connectNCI(); // Wake up the board if (!setupOK){ - setupOK = nfc.ConfigMode(mode); //Set up the configuration mode - if (!setupOK) setupOK = nfc.StartDiscovery(mode); //NCI Discovery mode + setupOK = nfc.configMode(); // Set up the configuration mode + if (!setupOK) setupOK = nfc.startDiscovery(); // NCI Discovery mode } return setupOK; } ``` -### Method: `GetFwVersion` -Get Firmware Version. +## Electroniccats_PN7150 Methods -```c -uint8_t GetFwVersion(); +### Method: `getFirmwareVersion` + +Get the firmware version of the NXP-NCI controller. + +```cpp +int getFirmwareVersion(); +``` + +#### Example + +```cpp +int version = nfc.getFirmwareVersion(); +``` + +### Method: `connectNCI` + +Initialize the connection with the NXP-NCI controller and updates the firmware version that can be obtained with the `getFirmwareVersion` method. + +```cppp +uint8_t connectNCI(); +``` + +Returns `0` if the connection is established correctly, otherwise returns `1`. + +#### Example + +```cpp +uint8_t statusNFC = nfc.connectNCI(); + +if (!statusNFC) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `configMode` + +Configure the device mode. Reader/Writer as default. + +```cpp +uint8_t configMode(); +``` + +Returns `0` if the mode is configured correctly, otherwise returns `1`. + +#### Example + +```cpp +uint8_t status = nfc.configMode(); + +if (!status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `setReaderWriterMode` + +Configure the device mode to Reader/Writer. + +```cpp +bool setReaderWriterMode(); +``` + +Returns `true` if the mode is configured correctly, otherwise returns `false`. + +#### Example + +```cpp +bool status = nfc.setReaderWriterMode(); + +if (status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `setEmulationMode` + +Configure the device mode to Card Emulation. + +```cpp +bool setEmulationMode(); +``` + +Returns `true` if the mode is configured correctly, otherwise returns `false`. + +#### Example + +```cpp +bool status = nfc.setEmulationMode(); + +if (status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `setP2PMode` + +Configure the device mode to Peer to Peer. + +```cpp +bool setP2PMode(); +``` + +Returns `true` if the mode is configured correctly, otherwise returns `false`. + +#### Example + +```cpp +bool status = nfc.setP2PMode(); + +if (status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `getMode` + +Get the current device mode. + +```cpp +int getMode(); +``` + +#### Example + +```cpp +switch (nfc.getMode()) { + case nfc.mode.READER_WRITER: + Serial.println("Reader/Writer mode"); + break; + case nfc.mode.EMULATION: + Serial.println("Card Emulation mode"); + break; + case nfc.mode.P2P: + Serial.println("Peer to Peer mode"); + break; + default: + Serial.println("Unknown mode"); + break; +} +``` + +### Method: `configureSettings` + +Configure some aspects of the NFC controller, such as the hardware configuration, RF (radio frequency) configuration, and other settings. + +```cpp +bool configureSettings(); +``` + +A custom NFC UID can be configured by passing the UID and its length as parameters. + +```cpp +bool configureSettings(uint8_t *nfcuid, uint8_t uidlen); +``` + +Returns `0` if the parameters are configured correctly, otherwise returns `1`. + +#### Example 1 + +```cpp +bool status = nfc.configureSettings(); + +if (!status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +#### Example 2 + +```cpp +uint8_t nfcuid[] = {0x08, 0x00, 0x00, 0x00, 0x00, 0x00}; +uint8_t uidlen = 6; + +bool status = nfc.configureSettings(nfcuid, uidlen); + +if (!status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Method: `startDiscovery` + +Start the discovery mode for the device. + +```cpp +uint8_t startDiscovery(); +``` + +Returns `0` if the mode is configured correctly, otherwise returns `1`. + +#### Example + +```cpp +uint8_t status = nfc.startDiscovery(); + +if (!status) { + Serial.println("Set up is ok"); +} else { + Serial.println("Error while setting up mode, check connections!"); +} +``` + +### Methods: `stopDiscovery` + +Stop the discovery process of the device. + +```cpp +bool stopDiscovery(); +``` + +Returns `0`. Never returns `1`. + +#### Example + +```cpp +nfc.stopDiscovery(); +``` + +### Method: `isTagDetected` + +Returns `true` if a tag is detected, otherwise returns `false`. The timeout is set to 500ms by default and can be changed by passing a parameter. + +```cpp +bool isTagDetected(uint16_t tout = 500); +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.println("Tag detected!"); + // Do something +} +``` + +### Method: `cardModeSend` + +Send a data packet in card mode. + +```cpp +bool cardModeSend(unsigned char *pData, unsigned char DataSize); +``` + +### Method: `cardModeReceive` + +Receive a data packet from a card. + +```cpp +bool cardModeReceive(unsigned char *pData, unsigned char *pDataSize); +``` + +### Method: `handleCardEmulation` + +Resets the card emulation state and processes the card mode for card emulation. + +```cpp +void handleCardEmulation(); +``` + +### Method: `waitForTagRemoval` + +Waits for the tag to be removed. + +```cpp +void waitForTagRemoval(); +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); + Serial.println("Card removed!"); +} +``` + +### Method: `readerTagCmd` + +Sends a command to the reader. + +```cpp +bool readerTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize); +``` + +### Method: `readerReActivate` + +Reactivates a target after it has been deactivated. + +```cpp +bool readerReActivate(); +``` + +### Method: `activateNextTagDiscovery` + +Activates the next tag discovered. + +```cpp +bool activateNextTagDiscovery(); +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + // It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + Serial.println("Multiple cards are detected!"); + nfc.activateNextTagDiscovery(); + } +} +``` + +### Method: `readNdefMessage` + +Reads the NDEF message from the tag. + +```cpp +void readNdefMessage(); +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + nfc.readNdefMessage(); +} +``` + +### Method: `writeNdefMessage` + +Writes the NDEF message to the tag. + +```cpp +void writeNdefMessage(); +``` + +### Method: `nciFactoryTestPrbs` + +Performs a factory test for the NCI controller. + +```cpp +bool nciFactoryTestPrbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate); +``` + +### Method: `nciFactoryTestRfOn` + +Performs a factory test for the NCI controller. + +```cpp +bool nciFactoryTestRfOn(); +``` + +### Method: `reset` + +Stops the discovery process, configures the device mode if it is necessary and starts the discovery process again. + +```cpp +bool reset(); +``` + +#### Example + +```cpp +nfc.reset(); +``` + +### Method: `setReadMsgCallback` + +Registers a callback function to be called when an NDEF message is received. + +```cpp +void setReadMsgCallback(CustomCallback_t function); +``` + +#### Example + +```cpp +void messageReceived() { + Serial.println("Message received!"); +} + +void setup() { + nfc.setReadMsgCallback(messageReceived); +} +``` + +### Method: `isReaderDetected` + +Returns `true` if a reader is detected, otherwise returns `false`. + +```cpp +bool isReaderDetected(); +``` + +#### Example + +```cpp +if (nfc.isReaderDetected()) { + Serial.println("Reader detected!"); + // Do something +} +``` + +### Method: `closeCommunication` + +Send a command to the reader to close the communication. + +```cpp +void closeCommunication(); +``` + +#### Example + +```cpp +if (nfc.isReaderDetected()) { + Serial.println("Reader detected!"); + nfc.handleCardEmulation(); + nfc.closeCommunication(); +} +``` + +### Method: `sendMessage` + +Send an NDEF message to the reader. + +```cpp +void sendMessage(); +``` + +#### Example + +```cpp +if (nfc.isReaderDetected()) { + Serial.println("Reader detected!"); + Serial.println("Sending NDEF message..."); + nfc.sendMessage(); +} +``` + +## Class Interface + +### Constant `UNDETERMINED` + +Constant for the undetermined interface. + +```cpp +UNDETERMINED = 0x0 +``` + +#### Example + +```cpp +nfc.interface.UNDETERMINED; +``` + +### Constant `FRAME` + +Constant for the frame interface. + +```cpp +FRAME = 0x1 +``` + +#### Example + +```cpp +nfc.interface.FRAME; +``` + +### Constant `ISODEP` + +Constant for the ISO-DEP interface. + +```cpp +ISODEP = 0x2 +``` + +#### Example + +```cpp +nfc.interface.ISODEP; +``` + +### Constant `NFCDEP` + +Constant for the NFC-DEP interface. + +```cpp +NFCDEP = 0x3 +``` + +#### Example + +```cpp +nfc.interface.NFCDEP; +``` + +### Constant `TAGCMD` + +Constant for the tag interface. + +```cpp +TAGCMD = 0x80 +``` + +#### Example + +```cpp +nfc.interface.TAGCMD; +``` + +## Class Mode + +### Constant `READER_WRITER` + +Constant for the Reader/Writer mode. + +```cpp +READER_WRITER = 1 +``` + +#### Example + +```cpp +nfc.mode.READER_WRITER; +``` + +### Constant `EMULATION` + +Constant for the Card Emulation mode. + +```cpp +EMULATION = 2 +``` + +#### Example + +```cpp +nfc.mode.EMULATION; +``` + +### Constant `P2P` + +Constant for the Peer to Peer mode. + +```cpp +P2P = 3 +``` + +#### Example + +```cpp +nfc.mode.P2P; +``` + +## Class ModeTech + +### Constant `POLL` + +Constant for the Poll mode. + +```cpp +POLL = 0x00 +``` + +#### Example + +```cpp +nfc.modeTech.POLL; +``` + +### Constant `LISTEN` + +Constant for the Listen mode. + +```cpp +LISTEN = 0x80 +``` + +#### Example + +```cpp +nfc.modeTech.LISTEN; +``` + +### Constant `MASK` + +Constant for the Mask mode. + +```cpp +MASK = 0xF0 +``` + +#### Example + +```cpp +nfc.modeTech.MASK; +``` + +## Class Protocol + +### Constant `UNDETERMINED` + +Constant for the undetermined protocol. + +```cpp +UNDETERMINED = 0x0 +``` + +#### Example + +```cpp +nfc.protocol.UNDETERMINED; +``` + +### Constant `T1T` + +Constant for the T1T protocol. + +```cpp +T1T = 0x1 +``` + +#### Example + +```cpp +nfc.protocol.T1T; +``` + +### Constant `T2T` + +Constant for the T2T protocol. + +```cpp +T2T = 0x2 +``` + +#### Example + +```cpp +nfc.protocol.T2T; +``` + +### Constant `T3T` + +Constant for the T3T protocol. + +```cpp +T3T = 0x3 +``` + +#### Example + +```cpp +nfc.protocol.T3T; +``` + +### Constant `ISODEP` + +Constant for the ISO-DEP protocol. + +```cpp +ISODEP = 0x4 +``` + +#### Example + +```cpp +nfc.protocol.ISODEP; +``` + +### Constant `NFCDEP` + +Constant for the NFC-DEP protocol. + +```cpp +NFCDEP = 0x5 +``` + +#### Example + +```cpp +nfc.protocol.NFCDEP; +``` + +### Constant `ISO15693` + +Constant for the ISO15693 protocol. + +```cpp +ISO15693 = 0x6 +``` + +#### Example + +```cpp +nfc.protocol.ISO15693; +``` + +### Constant `MIFARE` + +Constant for the MIFARE protocol. + +```cpp +MIFARE = 0x80 +``` + +#### Example + +```cpp +nfc.protocol.MIFARE; +``` + +## Class Tech + +### Constant `PASSIVE_NFCA` + +Constant for the Passive NFC-A technology. + +```cpp +PASSIVE_NFCA = 0 +``` + +#### Example + +```cpp +nfc.tech.PASSIVE_NFCA; +``` + +### Constant `PASSIVE_NFCB` + +Constant for the Passive NFC-B technology. + +```cpp +PASSIVE_NFCB = 1 +``` + +#### Example + +```cpp +nfc.tech.PASSIVE_NFCB; +``` + +### Constant `PASSIVE_NFCF` + +Constant for the Passive NFC-F technology. + +```cpp +PASSIVE_NFCF = 2 +``` + +#### Example + +```cpp +nfc.tech.PASSIVE_NFCF; +``` + +### Constant `ACTIVE_NFCA` + +Constant for the Active NFC-A technology. + +```cpp +ACTIVE_NFCA = 3 +``` + +#### Example + +```cpp +nfc.tech.ACTIVE_NFCA; +``` + +### Constant `ACTIVE_NFCF` + +Constant for the Active NFC-F technology. + +```cpp +ACTIVE_NFCF = 5 +``` + +#### Example + +```cpp +nfc.tech.ACTIVE_NFCF; +``` + +### Constant `PASSIVE_15693` + +Constant for the Passive 15693 technology. + +```cpp +PASSIVE_15693 = 6 +``` + +#### Example + +```cpp +nfc.tech.PASSIVE_15693; +``` + +### Constant `PASSIVE_NFCV` + +Constant for the Passive NFC-V technology (ISO 15693). + +```cpp +PASSIVE_NFCV = 6 +``` + +#### Example + +```cpp +nfc.tech.PASSIVE_NFCV; +``` + +## Class RemoteDevice + +A `RemoteDevice` object represents a remote NFC device such as a tag or a reader. + +### Getters for device properties + +### Method: `getInterface` + +Get the interface of the device. + +```cpp +unsigned char getInterface() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("Interface: "); + switch (nfc.remoteDevice.getInterface()) { + case nfc.interface.ISODEP: + Serial.println("ISO-DEP"); + break; + case nfc.interface.NFCDEP: + Serial.println("NFC-DEP"); + break; + case nfc.interface.TAGCMD: + Serial.println("TAG"); + break; + case nfc.interface.FRAME: + Serial.println("FRAME"); + break; + case nfc.interface.UNDETERMINED: + Serial.println("UNDETERMINED"); + break; + default: + Serial.println("UNKNOWN"); + break; + } +} +``` + +### Method: `getProtocol` + +Get the protocol of the device. + +```cpp +unsigned char getProtocol() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("Protocol: "); + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.T1T: + Serial.println("T1T"); + break; + case nfc.protocol.T2T: + Serial.println("T2T"); + break; + case nfc.protocol.T3T: + Serial.println("T3T"); + break; + case nfc.protocol.ISODEP: + Serial.println("ISO-DEP"); + break; + case nfc.protocol.NFCDEP: + Serial.println("NFC-DEP"); + break; + case nfc.protocol.ISO15693: + Serial.println("ISO15693"); + break; + case nfc.protocol.MIFARE: + Serial.println("MIFARE"); + break; + case nfc.protocol.UNDETERMINED: + Serial.println("UNDETERMINED"); + break; + default: + Serial.println("UNKNOWN"); + break; + } +} +``` + +### Method: `getModeTech` + +Get the mode tech of the device. + +```cpp +unsigned char getModeTech() const; ``` -### Method: `ConfigMode` +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("Technology: "); + switch (nfc.remoteDevice.getModeTech()) { + case nfc.tech.PASSIVE_NFCA: + Serial.println("PASSIVE NFC A"); + break; + case nfc.tech.PASSIVE_NFCB: + Serial.println("PASSIVE NFC B"); + break; + case nfc.tech.PASSIVE_NFCF: + Serial.println("PASSIVE NFC F"); + break; + case nfc.tech.PASSIVE_15693: + Serial.println("PASSIVE 15693"); + break; + } +} +``` -Configure Mode for device +### Method: `hasMoreTags` -- `1`: RW Mode. -- `2`: Emulation mode. +Returns `true` if there are more tags to be discovered, otherwise returns `false`. -```c -uint8_t Electroniccats_PN7150::ConfigMode(uint8_t modeSE) +```cpp +bool hasMoreTags() const; ``` -### Method: `StartDiscovery` +#### Example -Returns . +```cpp +if (nfc.isTagDetected()) { + if (nfc.remoteDevice.hasMoreTags()) { + Serial.println("Multiple cards are detected!"); + nfc.activateNextTagDiscovery(); + } +} +``` -```c -uint8_t StartDiscovery(mode); +### Getters for device information properties + +### Method: `getSensResLen` + +Get the SENS RES length of the device. + +```cpp +unsigned char getSensResLen() const; ``` -### Method: `CardModeReceive` +### Method: `getSensRes` -Returns . +Get the SENS RES (ATQA) of the device. Only available for tags that use passive communication and the NFC-A, NFC-B or NFC-F technologies, otherwise returns `NULL`. -```c -bool CardModeReceive (unsigned char *pData unsigned char *pDataSize); +```cpp +const unsigned char* getSensRes() const; ``` -### Method: `CardModeSend` +#### Example -Return. +```cpp +if (nfc.isTagDetected()) { + Serial.print("ATQA: "); + for (int i = 0; i < nfc.remoteDevice.getSensResLen(); i++) { + Serial.print(nfc.remoteDevice.getSensRes()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} +``` -```c -bool CardModeSend (unsigned char *pData, unsigned char DataSize); +### Method: `getSelResLen` + +Get the SEL RES length of the device. + +```cpp +unsigned char getSelResLen() const; ``` -### Method: `ReaderActivateNext` +### Method: `getSelRes` -Return. +Get the SEL RES (SAK) of the device. Only available for tags that use passive communication and the NFC-A technology, otherwise returns `NULL`. -```c -bool ReaderActivateNext(RfIntf_t *pRfIntf); +```cpp +const unsigned char* getSelRes() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("SAK: "); + for (int i = 0; i < nfc.remoteDevice.getSelResLen(); i++) { + Serial.print(nfc.remoteDevice.getSelRes()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} ``` -### Method: `WaitForDiscoveryNotification` +### Method: `getNFCIDLen` -Return. +Get the NFCID length of the device. -```c -bool WaitForDiscoveryNotification(RfIntf_t *pRfIntf); +```cpp +unsigned char getNFCIDLen() const; ``` +### Method: `getNFCID` + +Get the NFCID of the device. Only available for tags that use passive communication and the NFC-A technology, otherwise returns `NULL`. -### Method: `ProcessReaderMode` +```cpp +const unsigned char* getNFCID() const; +``` -Return. +#### Example -```c -void ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); +```cpp +if (nfc.isTagDetected()) { + Serial.print("NFCID: "); + for (int i = 0; i < nfc.remoteDevice.getNFCIDLen(); i++) { + Serial.print(nfc.remoteDevice.getNFCID()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} ``` -### Methods: `StopDiscovery` +### Method: `getRatsLen` -Return. +Get the RATS length of the device. -```c -bool StopDiscovery(void); +```cpp +unsigned char getRatsLen() const; +``` + +### Method: `getRats` + +Get the RATS of the device. Only available for tags that use passive communication and the NFC-A technology, otherwise returns `NULL`. + +```cpp +const unsigned char* getRats() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("RATS: "); + for (int i = 0; i < nfc.remoteDevice.getRatsLen(); i++) { + Serial.print(nfc.remoteDevice.getRats()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} +``` + +### Method: `getAttribResLen` + +Get the ATTRIB RES length of the device. + +```cpp +unsigned char getAttribResLen() const; +``` + +### Method: `getAttribRes` + +Get the ATTRIB RES of the device. Only available for tags that use passive communication and the NFC-B technology, otherwise returns `NULL`. + +```cpp +const unsigned char* getAttribRes() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("ATTRIB RES: "); + for (int i = 0; i < nfc.remoteDevice.getAttribResLen(); i++) { + Serial.print(nfc.remoteDevice.getAttribRes()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} +``` + +### Method: `getBitRate` + +Get the bit rate of the device. Only available for tags that use passive communication and the NFC-F technology, otherwise returns `NULL`. + +```cpp +unsigned char getBitRate() const; +``` + +#### Example + +```cpp +Serial.print("Bitrate = "); +Serial.println((nfc.remoteDevice.getBitRate() == 1) ? "212" : "424"); +``` + +### Method: `getAFI` + +Get the AFI of the device. Only available for tags that use passive communication and the NFC-V technology, otherwise returns `NULL`. + +```cpp +unsigned char getAFI() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("AFI = "); + Serial.println(nfc.remoteDevice.getAFI()); +} +``` + +### Method: `getDSFID` + +Get the DSF ID of the device. Only available for tags that use passive communication and the NFC-V technology, otherwise returns `NULL`. + +```cpp +unsigned char getDSFID() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("DSF ID = "); + Serial.println(nfc.remoteDevice.getDSFID(), HEX); +} +``` + +### Method: `getID` + +Get the ID of the device. Only available for tags that use passive communication and the NFC-V technology, otherwise returns `NULL`. + +```cpp +const unsigned char* getID() const; +``` + +#### Example + +```cpp +if (nfc.isTagDetected()) { + Serial.print("ID: "); + for (int i = 0; i < sizeof(nfc.remoteDevice.getID()); i++) { + Serial.print(nfc.remoteDevice.getID()[i], HEX); + Serial.print(" "); + } + Serial.println(); +} +``` + +## Class NdefMessage + +A `NdefMessage` object represents an NDEF message. An NDEF message is a container for one or more NDEF records. + +### Method: `begin` + +Registers a callback function to be called when an NDEF message is received wich updates the message content. + +```cpp +void begin(); +``` + +#### Example + +```cpp +NdefMessage message; + +void setup() { + message.begin(); +} +``` + +### Method: `getContentSize` + +Get the content size of the message. + +```cpp +static unsigned short getContentSize(); +``` + +### Method: `getContent` + +Get the content of the message. + +```cpp +static unsigned char *getContent(); +``` + +### Method: `setContent` + +Set the content of the message. + +```cpp +static void setContent(unsigned char *content, unsigned short contentSize); +``` + +### Method: `getRecord` + +Get the record of the message. + +```cpp +NdefRecord_t getRecord(); +``` + +The record is a structure that contains the following properties: + +```cpp +typedef struct { + NdefRecordType_e recordType; + unsigned char *recordPayload; + unsigned int recordPayloadSize; +} NdefRecord_t; +``` + +#### Example + +```cpp +message.getRecord(); +``` + +### Method: `isEmpty` + +Returns `true` if the message is empty, otherwise returns `false`. + +```cpp +bool isEmpty(); +``` + +#### Example + +```cpp +if (message.isEmpty()) { + Serial.println("The message is empty!"); +} +``` + +### Method: `isNotEmpty` + +Returns `true` if the message is not empty, otherwise returns `false`. + +```cpp +bool isNotEmpty(); +``` + +#### Example + +```cpp +if (message.isNotEmpty()) { + Serial.println("The message is not empty!"); +} +``` + +### Method: `hasRecord` + +Returns `true` if the message has a record, otherwise returns `false`. + +```cpp +bool hasRecord(); +``` + +#### Example + +```cpp +if (message.hasRecord()) { + Serial.println("The message has a record!"); +} +``` + +## Class NdefRecord + +A `NdefRecord` object represents an NDEF record. An NDEF record is a data structure that contains data that is stored or transported in an NDEF message. + +#### Example + +```cpp +NdefRecord record; +``` + +### Method: `create` + +Creates a new NDEF record. + +```cpp +void create(NdefRecord_t record); +``` + +#### Example + +```cpp +record.create(message.getRecord()); +``` + +### Method: `isEmpty` + +Returns `true` if the record is empty, otherwise returns `false`. + +```cpp +bool isEmpty(); +``` + +#### Example + +```cpp +if (record.isEmpty()) { + Serial.println("The record is empty!"); +} +``` + +### Method: `isNotEmpty` + +Returns `true` if the record is not empty, otherwise returns `false`. + +```cpp +bool isNotEmpty(); +``` + +#### Example + +```cpp +if (record.isNotEmpty()) { + Serial.println("The record is not empty!"); +} +``` + +### Method: `getType` + +Get the type of the record. + +```cpp +NdefRecordType_e getType(); +``` + +The type is a structure that contains the following properties: + +```cpp +typedef enum { + WELL_KNOWN_SIMPLE_TEXT, + WELL_KNOWN_SIMPLE_URI, + WELL_KNOWN_SMART_POSTER, + WELL_KNOWN_HANDOVER_SELECT, + WELL_KNOWN_HANDOVER_REQUEST, + WELL_KNOWN_ALTERNATIVE_CARRIER, + WELL_KNOWN_COLLISION_RESOLUTION, + MEDIA_VCARD, + MEDIA_HANDOVER_WIFI, + MEDIA_HANDOVER_BT, + MEDIA_HANDOVER_BLE, + MEDIA_HANDOVER_BLE_SECURE, + ABSOLUTE_URI, + UNSUPPORTED_NDEF_RECORD = 0xFF +} NdefRecordType_e; +``` + +### Method: `getPayloadSize` + +Get the payload size of the record. + +```cpp +unsigned short getPayloadSize(); +``` + +### Method: `getPayload` + +Get the payload of the record. + +```cpp +unsigned char *getPayload(); +``` + +#### Example + +```cpp +Serial.print("Payload: "); +for (int i = 0; i < record.getPayloadSize(); i++) { + Serial.print(record.getPayload()[i], HEX); + Serial.print(" "); +} +Serial.println(); +``` + +### Method: `getText` + +Get the text of the record if the type is `WELL_KNOWN_SIMPLE_TEXT`, otherwise returns `"null"`. + +```cpp +String getText(); +``` + +#### Example + +```cpp +Serial.print("Text: "); +Serial.println(record.getText()); +``` + +### Method: `getBluetoothName` + +Get the Bluetooth name of the record if the type is `MEDIA_HANDOVER_BT`, otherwise returns `"null"`. + +```cpp +String getBluetoothName(); +``` + +#### Example + +```cpp +Serial.print("Bluetooth name: "); +Serial.println(record.getBluetoothName()); +``` + +### Method: `getBluetoothAddress` + +Get the Bluetooth address of the record if the type is `MEDIA_HANDOVER_BT`, otherwise returns `"null"`. + +```cpp +String getBluetoothAddress(); +``` + +#### Example + +```cpp +Serial.print("Bluetooth address: "); +Serial.println(record.getBluetoothAddress()); +``` + +### Method: `getWifiSSID` + +Get the WiFi SSID of the record if the type is `MEDIA_HANDOVER_WIFI`, otherwise returns `"null"`. + +```cpp +String getWifiSSID(); +``` + +#### Example + +```cpp +Serial.print("WiFi SSID: "); +Serial.println(record.getWifiSSID()); +``` + +### Method: `getWifiPassword` + +Get the WiFi password of the record if the type is `MEDIA_HANDOVER_WIFI`, otherwise returns `"null"`. + +```cpp +String getWiFiPassword(); +``` + +#### Example + +```cpp +Serial.print("WiFi password: "); +Serial.println(record.getWiFiPassword()); +``` + +### Method: `getWiFiAuthenticationType` + +Get the WiFi authentication type of the record if the type is `MEDIA_HANDOVER_WIFI`, otherwise returns `"null"`. + +```cpp +String getWiFiAuthenticationType(); +``` + +#### Example + +```cpp +Serial.print("WiFi authentication type: "); +Serial.println(record.getWiFiAuthenticationType()); +``` + +### Method: `getWiFiEncryptionType` + +Get the WiFi encryption type of the record if the type is `MEDIA_HANDOVER_WIFI`, otherwise returns `"null"`. + +```cpp +String getWiFiEncryptionType(); +``` + +#### Example + +```cpp +Serial.print("WiFi encryption type: "); +Serial.println(record.getWiFiEncryptionType()); +``` + +### Method: `getVCardContent` + +Get the vCard content of the record if the type is `MEDIA_VCARD`, otherwise returns `"null"`. + +```cpp +String getVCardContent(); +``` + +#### Example + +```cpp +Serial.print("vCard content: "); +Serial.println(record.getVCardContent()); +``` + +### Method: `getUri` + +Get the URI of the record if the type is `WELL_KNOWN_SIMPLE_URI`, otherwise returns `"null"`. + +```cpp +String getUri(); +``` + +#### Example + +```cpp +Serial.print("URI: "); +Serial.println(record.getUri()); ``` \ No newline at end of file diff --git a/README.md b/README.md index de93f19..dd36353 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ Optimized for fast design-in, NXP's PN7150 NFC solutions fully comply with the N PN7150 is the high-performance version of PN7120, the plug'n-play NFC solution for easy integration into any OS environment, reducing Bill of Material (BOM) size and cost. PN71xx controllers are ideal for home automation applications such as gateways and work seamlessly with NFC-connected tags. +## API Documentation + +Check the [API Documentation](/API.md) for more information about the methods available in the library. + ### Compatibility * Arduino MKR Family diff --git a/examples/DetectTags/DetectTags.ino b/examples/DetectTags/DetectTags.ino index e262d72..5315597 100644 --- a/examples/DetectTags/DetectTags.ino +++ b/examples/DetectTags/DetectTags.ino @@ -1,185 +1,180 @@ /** - * Example detect tags and show their unique ID - * Authors: + * Example detect tags and show their unique ID + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com * + * Updated by Francisco Torres - Electronic Cats - electroniccats.com + * * March 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation +// Function prototypes +String getHexRepresentation(const byte* data, const uint32_t numBytes); +void displayCardInfo(); -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); +void setup() { + Serial.begin(9600); + while (!Serial) + ; + Serial.println("Detect NFC tags with PN7150"); + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board + Serial.println("Error while setting up the mode, check connections!"); + while (1) + ; + } + + if (nfc.configureSettings()) { + Serial.println("The Configure Settings is failed!"); + while (1) + ; + } + + // Read/Write mode as default + if (nfc.configMode()) { // Set up the configuration mode + Serial.println("The Configure Mode is failed!!"); + while (1) + ; + } + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an Card ..."); } -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format - uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++) - { - Serial.print(F("0x")); - // Append leading 0 for small values +void loop() { + if (nfc.isTagDetected()) { + displayCardInfo(); + + // It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); + Serial.println("Multiple cards are detected!"); + } + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); + Serial.println("Card removed!"); + } + + Serial.println("Restarting..."); + nfc.reset(); + Serial.println("Waiting for a Card..."); + delay(500); +} + +String getHexRepresentation(const byte* data, const uint32_t numBytes) { + String hexString; + + if (numBytes == 0) { + hexString = "null"; + } + + for (uint32_t szPos = 0; szPos < numBytes; szPos++) { + hexString += "0x"; if (data[szPos] <= 0xF) - Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); - if ((numBytes > 1) && (szPos != numBytes - 1)) - { - Serial.print(F(" ")); + hexString += "0"; + hexString += String(data[szPos] & 0xFF, HEX); + if ((numBytes > 1) && (szPos != numBytes - 1)) { + hexString += " "; } } - Serial.println(); + return hexString; } -void displayCardInfo(RfIntf_t RfIntf){ //Funtion in charge to show the card/s in te field + +void displayCardInfo() { // Funtion in charge to show the card/s in te field char tmp[16]; - while (1){ - switch(RfIntf.Protocol){ //Indetify card protocol - case PROT_T1T: - case PROT_T2T: - case PROT_T3T: - case PROT_ISODEP: + + while (true) { + switch (nfc.remoteDevice.getProtocol()) { // Indetify card protocol + case nfc.protocol.T1T: + case nfc.protocol.T2T: + case nfc.protocol.T3T: + case nfc.protocol.ISODEP: Serial.print(" - POLL MODE: Remote activated tag type: "); - Serial.println(RfIntf.Protocol); + Serial.println(nfc.remoteDevice.getProtocol()); break; - case PROT_ISO15693: + case nfc.protocol.ISO15693: Serial.println(" - POLL MODE: Remote ISO15693 card activated"); break; - case PROT_MIFARE: + case nfc.protocol.MIFARE: Serial.println(" - POLL MODE: Remote MIFARE card activated"); break; - default: + default: Serial.println(" - POLL MODE: Undetermined target"); return; } - switch(RfIntf.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_NFCA): - Serial.print("\tSENS_RES = "); - sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[0]); - Serial.print(tmp); Serial.print(" "); - sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[1]); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tNFCID = "); - PrintBuf(RfIntf.Info.NFC_APP.NfcId, RfIntf.Info.NFC_APP.NfcIdLen); - - if(RfIntf.Info.NFC_APP.SelResLen != 0) { - Serial.print("\tSEL_RES = "); - sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SelRes[0]); - Serial.print(tmp); Serial.println(" "); - - } - break; - - case (MODE_POLL | TECH_PASSIVE_NFCB): - if(RfIntf.Info.NFC_BPP.SensResLen != 0) { - Serial.print("\tSENS_RES = "); - PrintBuf(RfIntf.Info.NFC_BPP.SensRes,RfIntf.Info.NFC_BPP.SensResLen); - } - break; - - case (MODE_POLL | TECH_PASSIVE_NFCF): - Serial.print("\tBitrate = "); - Serial.println((RfIntf.Info.NFC_FPP.BitRate == 1) ? "212" : "424"); - - if(RfIntf.Info.NFC_FPP.SensResLen != 0) { - Serial.print("\tSENS_RES = "); - PrintBuf(RfIntf.Info.NFC_FPP.SensRes,RfIntf.Info.NFC_FPP.SensResLen); - } - break; - - case (MODE_POLL | TECH_PASSIVE_15693): - Serial.print("\tID = "); - PrintBuf(RfIntf.Info.NFC_VPP.ID,sizeof(RfIntf.Info.NFC_VPP.ID)); - - Serial.print("\ntAFI = "); - Serial.println(RfIntf.Info.NFC_VPP.AFI); - - Serial.print("\tDSFID = "); - Serial.println(RfIntf.Info.NFC_VPP.DSFID,HEX); - break; - - default: - break; - } - if(RfIntf.MoreTags) { // It will try to identify more NFC cards if they are the same technology - if(nfc.ReaderActivateNext(&RfIntf) == NFC_ERROR) break; - } - else break; - } -} + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (nfc.tech.PASSIVE_NFCA): + Serial.println("\tTechnology: NFC-A"); + Serial.print("\tSENS RES = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getSensRes(), nfc.remoteDevice.getSensResLen())); -void setup(){ - Serial.begin(9600); - while(!Serial); - Serial.println("Detect NFC tags with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board - Serial.println("Error while setting up the mode, check connections!"); - while (1); - } - - if (nfc.ConfigureSettings()) { - Serial.println("The Configure Settings is failed!"); - while (1); - } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode - Serial.println("The Configure Mode is failed!!"); - while (1); - } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an Card ..."); -} + Serial.print("\tNFC ID = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getNFCID(), nfc.remoteDevice.getNFCIDLen())); + + Serial.print("\tSEL RES = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getSelRes(), nfc.remoteDevice.getSelResLen())); + + break; + + case (nfc.tech.PASSIVE_NFCB): + Serial.println("\tTechnology: NFC-B"); + Serial.print("\tSENS RES = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getSensRes(), nfc.remoteDevice.getSensResLen())); + + Serial.println("\tAttrib RES = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getAttribRes(), nfc.remoteDevice.getAttribResLen())); + + break; + + case (nfc.tech.PASSIVE_NFCF): + Serial.println("\tTechnology: NFC-F"); + Serial.print("\tSENS RES = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getSensRes(), nfc.remoteDevice.getSensResLen())); + + Serial.print("\tBitrate = "); + Serial.println((nfc.remoteDevice.getBitRate() == 1) ? "212" : "424"); + + break; + + case (nfc.tech.PASSIVE_NFCV): + Serial.println("\tTechnology: NFC-V"); + Serial.print("\tID = "); + Serial.println(getHexRepresentation(nfc.remoteDevice.getID(), sizeof(nfc.remoteDevice.getID()))); + + Serial.print("\tAFI = "); + Serial.println(nfc.remoteDevice.getAFI()); + + Serial.print("\tDSF ID = "); + Serial.println(nfc.remoteDevice.getDSFID(), HEX); + break; -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - displayCardInfo(RfInterface); - switch(RfInterface.Protocol) { - case PROT_T1T: - case PROT_T2T: - case PROT_T3T: - case PROT_ISODEP: - nfc.ProcessReaderMode(RfInterface, READ_NDEF); - break; - - case PROT_ISO15693: - break; - - case PROT_MIFARE: - nfc.ProcessReaderMode(RfInterface, READ_NDEF); - break; - default: - break; + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + // It can detect multiple cards at the same time if they are the same technology + if (nfc.remoteDevice.hasMoreTags()) { + Serial.println("Multiple cards are detected!"); + if (!nfc.activateNextTagDiscovery()) { + break; // Can't activate next tag + } + } else { + break; } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); - Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); } - ResetMode(); - delay(500); } diff --git a/examples/DetectTags/Makefile b/examples/DetectTags/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/DetectTags/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/DetectingReaders/DetectingReaders.ino b/examples/DetectingReaders/DetectingReaders.ino index 4a4113d..b3a55fb 100644 --- a/examples/DetectingReaders/DetectingReaders.ino +++ b/examples/DetectingReaders/DetectingReaders.ino @@ -12,59 +12,39 @@ * Distributed as-is; no warranty is given. */ -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) +#include -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) -unsigned char STATUSOK[] = {0x90, 0x00}, Cmd[256], CmdSize; +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // Creates a global NFC device interface object, attached to pins 11 (IRQ) and 13 (VEN) and using the default I2C address 0x28 -uint8_t mode = 2; // modes: 1 = Reader/ Writer, 2 = Emulation - -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Detect NFC readers with PN7150"); - Serial.println("Initializing..."); + Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board - Serial.println("Error while setting up the mode, check connections!"); - while (1); - } - - if (nfc.ConfigureSettings()) { - Serial.println("The Configure Settings is failed!"); - while (1); - } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode - Serial.println("The Configure Mode is failed!!"); - while (1); + if (nfc.begin()) { + Serial.println("Error initializing PN7150"); + while (true) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an Reader Card ..."); + + // Needed to detect readers + nfc.setEmulationMode(); + Serial.print("Waiting for a reader..."); } -void loop(){ - if(nfc.CardModeReceive(Cmd, &CmdSize) == 0) { //Data in buffer? - if ((CmdSize >= 2) && (Cmd[0] == 0x00)) { //Expect at least two bytes - switch (Cmd[1]) { - case 0xA4: //Something tries to select a file, meaning that it is a reader - Serial.println("Reader detected!"); - break; - - case 0xB0: //SFI - break; - - case 0xD0: //... - break; - - default: - break; - } - nfc.CardModeSend(STATUSOK, sizeof(STATUSOK)); - } +void loop() { + Serial.print("."); + + if (nfc.isReaderDetected()) { + Serial.println("\nReader detected!"); + nfc.handleCardEmulation(); + nfc.closeCommunication(); + Serial.print("\nWaiting for a reader"); } } diff --git a/examples/DetectingReaders/Makefile b/examples/DetectingReaders/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/DetectingReaders/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/ISO14443-3A_read_block/ISO14443-3A_read_block.ino b/examples/ISO14443-3A_read_block/ISO14443-3A_read_block.ino index 3135fe8..3444f98 100644 --- a/examples/ISO14443-3A_read_block/ISO14443-3A_read_block.ino +++ b/examples/ISO14443-3A_read_block/ISO14443-3A_read_block.ino @@ -1,138 +1,136 @@ /** - * Example to read a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information - * Authors: + * Example to read a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * November 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) -#define BLK_NB_ISO14443_3A (5) //Block to be read it +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) +#define BLK_NB_ISO14443_3A (5) // Block to be read it -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation - -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); -} - -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++){ + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); + Serial.print(data[szPos] & 0xff, HEX); if ((numBytes > 1) && (szPos != numBytes - 1)) Serial.print(F(" ")); } Serial.println(); } -void PCD_ISO14443_3A_scenario (void){ - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - /* Read block */ - unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; - - status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ - Serial.print("Error reading block: "); - Serial.print(ReadBlock[1],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("------------------------Block "); - Serial.print(BLK_NB_ISO14443_3A, HEX); - Serial.println("-------------------------"); - PrintBuf(Resp, 4); +void PCD_ISO14443_3A_scenario(void) { + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + /* Read block */ + unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; + + status = nfc.readerTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0x00)) { + Serial.print("Error reading block: "); + Serial.print(ReadBlock[1], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("------------------------Block "); + Serial.print(BLK_NB_ISO14443_3A, HEX); + Serial.println("-------------------------"); + PrintBuf(Resp, 4); } -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Read ISO14443-3A(T2T) data block 5 with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an ISO14443-3A Card ..."); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an ISO14443-3A Card..."); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { case PROT_T2T: Serial.println(" - Found ISO14443-3A(T2T) card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_NFCA): - char tmp[16]; - Serial.print("\tSENS_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); - Serial.print(tmp); Serial.print(" "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tNFCID = "); - PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); - - if(RfInterface.Info.NFC_APP.SelResLen != 0) { - Serial.print("\tSEL_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); - Serial.print(tmp); Serial.println(" "); - } + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (MODE_POLL | TECH_PASSIVE_NFCA): + char tmp[16]; + Serial.print("\tSENS_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[0]); + Serial.print(tmp); + Serial.print(" "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[1]); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tNFCID = "); + PrintBuf(nfc.remoteDevice.getNFCID(), nfc.remoteDevice.getNFCIDLen()); + + if (nfc.remoteDevice.getSelResLen() != 0) { + Serial.print("\tSEL_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSelRes()[0]); + Serial.print(tmp); + Serial.println(" "); + } break; - } - PCD_ISO14443_3A_scenario(); - break; - + } + PCD_ISO14443_3A_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); - break; + Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); } - ResetMode(); + + Serial.println("Restarting..."); + nfc.reset(); + Serial.println("Waiting for an ISO14443-3A Card..."); delay(500); } diff --git a/examples/ISO14443-3A_read_block/Makefile b/examples/ISO14443-3A_read_block/Makefile new file mode 100644 index 0000000..67609a6 --- /dev/null +++ b/examples/ISO14443-3A_read_block/Makefile @@ -0,0 +1,20 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +# BOARD_TAG = rp2040:rp2040:generic +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) --warnings all + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/ISO14443-3A_write_block/ISO14443-3A_write_block.ino b/examples/ISO14443-3A_write_block/ISO14443-3A_write_block.ino index 259c89d..8af33b8 100644 --- a/examples/ISO14443-3A_write_block/ISO14443-3A_write_block.ino +++ b/examples/ISO14443-3A_write_block/ISO14443-3A_write_block.ino @@ -1,154 +1,152 @@ /** - * Example to write a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information - * Authors: + * Example to write a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * November 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) -#define BLK_NB_ISO14443_3A (5) //Block to be read it -#define DATA_WRITE_ISO14443_3A 0x11, 0x22, 0x33, 0x44 //Data to write +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +#define BLK_NB_ISO14443_3A (5) // Block to be read it +#define DATA_WRITE_ISO14443_3A 0x11, 0x22, 0x33, 0x44 // Data to write -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); -} - -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++){ + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); + Serial.print(data[szPos] & 0xff, HEX); if ((numBytes > 1) && (szPos != numBytes - 1)) Serial.print(F(" ")); } Serial.println(); } -void PCD_ISO14443_3A_scenario (void){ - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - /* Read block */ - unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; - /* Write block */ - unsigned char WriteBlock[] = {0xA2, BLK_NB_ISO14443_3A, DATA_WRITE_ISO14443_3A}; - - // Write - status = nfc.ReaderTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) - { - Serial.print("Error writing block: "); - Serial.print(ReadBlock[1],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("Wrote: "); - Serial.println(WriteBlock[1]); - - //Read block - status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ - Serial.print("Error reading block: "); - Serial.print(ReadBlock[1],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("------------------------Block "); - Serial.print(BLK_NB_ISO14443_3A, HEX); - Serial.println("-------------------------"); - PrintBuf(Resp, 4); +void PCD_ISO14443_3A_scenario(void) { + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + /* Read block */ + unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; + /* Write block */ + unsigned char WriteBlock[] = {0xA2, BLK_NB_ISO14443_3A, DATA_WRITE_ISO14443_3A}; + + // Write + status = nfc.readerTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error writing block: "); + Serial.print(ReadBlock[1], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("Wrote: "); + Serial.println(WriteBlock[1]); + + // Read block + status = nfc.readerTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0x00)) { + Serial.print("Error reading block: "); + Serial.print(ReadBlock[1], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("------------------------Block "); + Serial.print(BLK_NB_ISO14443_3A, HEX); + Serial.println("-------------------------"); + PrintBuf(Resp, 4); } -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Write ISO14443-3A(T2T) data block 5 with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an ISO14443-3A Card ..."); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an ISO14443-3A Card..."); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { case PROT_T2T: Serial.println(" - Found ISO14443-3A(T2T) card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_NFCA): - char tmp[16]; - Serial.print("\tSENS_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); - Serial.print(tmp); Serial.print(" "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tNFCID = "); - PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); - - if(RfInterface.Info.NFC_APP.SelResLen != 0) { - Serial.print("\tSEL_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); - Serial.print(tmp); Serial.println(" "); - } + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (MODE_POLL | TECH_PASSIVE_NFCA): + char tmp[16]; + Serial.print("\tSENS_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[0]); + Serial.print(tmp); + Serial.print(" "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[1]); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tNFCID = "); + PrintBuf(nfc.remoteDevice.getNFCID(), nfc.remoteDevice.getNFCIDLen()); + + if (nfc.remoteDevice.getSelResLen() != 0) { + Serial.print("\tSEL_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSelRes()[0]); + Serial.print(tmp); + Serial.println(" "); + } break; - } - PCD_ISO14443_3A_scenario(); - break; - + } + PCD_ISO14443_3A_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); - break; + Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); } - ResetMode(); + + Serial.println("Restarting..."); + nfc.reset(); + Serial.println("Waiting for an ISO14443-3A Card..."); delay(500); } diff --git a/examples/ISO14443-3A_write_block/Makefile b/examples/ISO14443-3A_write_block/Makefile new file mode 100644 index 0000000..67609a6 --- /dev/null +++ b/examples/ISO14443-3A_write_block/Makefile @@ -0,0 +1,20 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +# BOARD_TAG = rp2040:rp2040:generic +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) --warnings all + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/ISO15693_read_block/ISO15693_read_block.ino b/examples/ISO15693_read_block/ISO15693_read_block.ino index 4b1e680..62376f3 100644 --- a/examples/ISO15693_read_block/ISO15693_read_block.ino +++ b/examples/ISO15693_read_block/ISO15693_read_block.ino @@ -1,135 +1,130 @@ /** - * Example to read a ISO15693 block 8 and show its information - * Authors: + * Example to read a ISO15693 block 8 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * November 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) -#define BLK_NB_ISO15693 (8) //Block to be read it +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) +#define BLK_NB_ISO15693 (8) // Block to be read it -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation - -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); -} - -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++){ + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); + Serial.print(data[szPos] & 0xff, HEX); if ((numBytes > 1) && (szPos != numBytes - 1)) Serial.print(F(" ")); } Serial.println(); } -void PCD_ISO15693_scenario (void){ - #define BLK_NB_ISO15693 8 - - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; - - status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ - Serial.print("Error reading block: "); - Serial.print(ReadBlock[2],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("------------------------Block "); - Serial.print(BLK_NB_ISO15693, HEX); - Serial.println("-------------------------"); - PrintBuf(Resp+1, RespSize-2); +void PCD_ISO15693_scenario(void) { +#define BLK_NB_ISO15693 8 + + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; + + status = nfc.readerTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0x00)) { + Serial.print("Error reading block: "); + Serial.print(ReadBlock[2], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("------------------------Block "); + Serial.print(BLK_NB_ISO15693, HEX); + Serial.println("-------------------------"); + PrintBuf(Resp + 1, RespSize - 2); } -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Read ISO15693 data block 8 with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings is failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode is failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an ISO15693 Card ..."); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an ISO15693 Card..."); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { - case PROT_ISO15693: +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.ISO15693: Serial.println(" - Found ISO15693 card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_15693): - char tmp[16]; - Serial.print("\tID = "); - PrintBuf(RfInterface.Info.NFC_VPP.ID, sizeof(RfInterface.Info.NFC_VPP.ID)); - - Serial.print("\tAFI = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.AFI); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tDSFID = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.DSFID); - Serial.print(tmp); Serial.println(" "); + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (nfc.tech.PASSIVE_15693): + char tmp[16]; + Serial.print("\tID = "); + PrintBuf(nfc.remoteDevice.getID(), sizeof(nfc.remoteDevice.getID())); + + Serial.print("\tAFI = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getAFI()); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tDSFID = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getDSFID()); + Serial.print(tmp); + Serial.println(" "); break; - } - PCD_ISO15693_scenario(); - break; - + } + PCD_ISO15693_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not ISO15693!"); - break; + Serial.println(" - Found a card, but it is not ISO15693!"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); - Serial.println("CARD REMOVED!"); - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); + Serial.println("CARD REMOVED!");; } - ResetMode(); + nfc.reset(); + Serial.println("Waiting for an ISO15693 Card..."); delay(500); } diff --git a/examples/ISO15693_read_block/Makefile b/examples/ISO15693_read_block/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/ISO15693_read_block/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/ISO15693_write_block/ISO15693_write_block.ino b/examples/ISO15693_write_block/ISO15693_write_block.ino index a6765fc..b314b0c 100644 --- a/examples/ISO15693_write_block/ISO15693_write_block.ino +++ b/examples/ISO15693_write_block/ISO15693_write_block.ino @@ -1,148 +1,144 @@ /** - * Example to write a ISO15693 block 8 and show its information - * Authors: + * Example to write a ISO15693 block 8 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * November 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) -#define BLK_NB_ISO15693 (8) //Block to write -#define DATA_WRITE_ISO15693 0x11, 0x22, 0x33, 0x44 //Data to write +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +#define BLK_NB_ISO15693 (8) // Block to write +#define DATA_WRITE_ISO15693 0x11, 0x22, 0x33, 0x44 // Data to write -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Write ISO15693 data block 8 with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings is failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode is failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an ISO15693 Card ..."); -} - -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an ISO15693 Card..."); } -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++){ + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); + Serial.print(data[szPos] & 0xff, HEX); if ((numBytes > 1) && (szPos != numBytes - 1)) Serial.print(F(" ")); } Serial.println(); } -void PCD_ISO15693_scenario (void){ - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; - unsigned char WriteBlock[] = {0x02, 0x21, BLK_NB_ISO15693, DATA_WRITE_ISO15693}; - - // Write - status = nfc.ReaderTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) - { - Serial.print("Error writing block: "); - Serial.print(ReadBlock[2],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("Wrote: "); - Serial.println(WriteBlock[2]); - - // Read - status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ - Serial.print("Error reading block: "); - Serial.print(ReadBlock[2],HEX); - Serial.print(" with error: "); - Serial.print(Resp[RespSize-1],HEX); - return; - } - Serial.print("------------------------Block "); - Serial.print(BLK_NB_ISO15693, HEX); - Serial.println("-------------------------"); - PrintBuf(Resp+1, RespSize-2); +void PCD_ISO15693_scenario(void) { + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; + unsigned char WriteBlock[] = {0x02, 0x21, BLK_NB_ISO15693, DATA_WRITE_ISO15693}; + + // Write + status = nfc.readerTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error writing block: "); + Serial.print(ReadBlock[2], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("Wrote: "); + Serial.println(WriteBlock[2]); + + // Read + status = nfc.readerTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0x00)) { + Serial.print("Error reading block: "); + Serial.print(ReadBlock[2], HEX); + Serial.print(" with error: "); + Serial.print(Resp[RespSize - 1], HEX); + return; + } + Serial.print("------------------------Block "); + Serial.print(BLK_NB_ISO15693, HEX); + Serial.println("-------------------------"); + PrintBuf(Resp + 1, RespSize - 2); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { - case PROT_ISO15693: +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.ISO15693: Serial.println(" - Found ISO15693 card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_15693): - char tmp[16]; - Serial.print("\tID = "); - PrintBuf(RfInterface.Info.NFC_VPP.ID, sizeof(RfInterface.Info.NFC_VPP.ID)); - - Serial.print("\tAFI = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.AFI); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tDSFID = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.DSFID); - Serial.print(tmp); Serial.println(" "); + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (nfc.tech.PASSIVE_15693): + char tmp[16]; + Serial.print("\tID = "); + PrintBuf(nfc.remoteDevice.getID(), sizeof(nfc.remoteDevice.getID())); + + Serial.print("\tAFI = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getAFI()); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tDSFID = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getDSFID()); + Serial.print(tmp); + Serial.println(" "); break; - } - PCD_ISO15693_scenario(); - break; - + } + PCD_ISO15693_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not ISO15693!"); - break; + Serial.println(" - Found a card, but it is not ISO15693!"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); + ; } - ResetMode(); + nfc.reset(); + Serial.println("Waiting for an ISO15693 Card..."); delay(500); } diff --git a/examples/ISO15693_write_block/Makefile b/examples/ISO15693_write_block/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/ISO15693_write_block/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/MifareClassic_read_block/Makefile b/examples/MifareClassic_read_block/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/MifareClassic_read_block/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/MifareClassic_read_block/MifareClassic_read_block.ino b/examples/MifareClassic_read_block/MifareClassic_read_block.ino index 23f7bc6..6c9e0d8 100644 --- a/examples/MifareClassic_read_block/MifareClassic_read_block.ino +++ b/examples/MifareClassic_read_block/MifareClassic_read_block.ino @@ -1,147 +1,144 @@ /** - * Example to read a Mifare Classic block 4 and show its information - * Authors: + * Example to read a Mifare Classic block 4 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * March 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) - -#define BLK_NB_MFC 4 // Block tat wants to be read -#define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key - -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags - -uint8_t mode = 1; - // modes: 1 = Reader/ Writer, 2 = Emulation -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); -} -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) + +#define BLK_NB_MFC 4 // Block tat wants to be read +#define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key + +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 11 (IRQ) and 13 (VEN) and using the default I2C address 0x28 + +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++) - { + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); - if ((numBytes > 1) && (szPos != numBytes - 1)) - { + Serial.print(data[szPos] & 0xff, HEX); + if ((numBytes > 1) && (szPos != numBytes - 1)) { Serial.print(F(" ")); } } Serial.println(); } -void PCD_MIFARE_scenario (void){ - Serial.println("Start reading process..."); - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - /* Authenticate sector 1 with generic keys */ - unsigned char Auth[] = {0x40, BLK_NB_MFC/4, 0x10, KEY_MFC}; - /* Read block 4 */ - unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; - - /* Authenticate */ - status = nfc.ReaderTagCmd(Auth, sizeof(Auth), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) - Serial.println("Auth error!"); - - /* Read block */ - status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) - Serial.print("Error reading sector!"); - - Serial.print("------------------------Sector "); - Serial.print(BLK_NB_MFC/4, DEC); - Serial.println("-------------------------"); - - PrintBuf(Resp+1, RespSize-2); +void PCD_MIFARE_scenario(void) { + Serial.println("Start reading process..."); + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + /* Authenticate sector 1 with generic keys */ + unsigned char Auth[] = {0x40, BLK_NB_MFC / 4, 0x10, KEY_MFC}; + /* Read block 4 */ + unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; + + /* Authenticate */ + status = nfc.readerTagCmd(Auth, sizeof(Auth), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) + Serial.println("Auth error!"); + + /* Read block */ + status = nfc.readerTagCmd(Read, sizeof(Read), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) + Serial.print("Error reading sector!"); + + Serial.print("------------------------Sector "); + Serial.print(BLK_NB_MFC / 4, DEC); + Serial.println("-------------------------"); + + PrintBuf(Resp + 1, RespSize - 2); } -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); + while (!Serial) + ; Serial.println("Read mifare classic data block 4 with PN7150"); - - Serial.println("Initializing..."); - if (nfc.connectNCI()) { //Wake up the board + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings is failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode is failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an Mifare Classic Card ..."); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an Mifare Classic Card..."); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { - case PROT_MIFARE: +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.MIFARE: Serial.println(" - Found MIFARE card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_NFCA): - char tmp[16]; - Serial.print("\tSENS_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); - Serial.print(tmp); Serial.print(" "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tNFCID = "); - PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); - - if(RfInterface.Info.NFC_APP.SelResLen != 0) { - Serial.print("\tSEL_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); - Serial.print(tmp); Serial.println(" "); - } + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (nfc.tech.PASSIVE_NFCA): + char tmp[16]; + Serial.print("\tSENS_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[0]); + Serial.print(tmp); + Serial.print(" "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[1]); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tNFCID = "); + PrintBuf(nfc.remoteDevice.getNFCID(), nfc.remoteDevice.getNFCIDLen()); + + if (nfc.remoteDevice.getSelResLen() != 0) { + Serial.print("\tSEL_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSelRes()[0]); + Serial.print(tmp); + Serial.println(" "); + } break; - } - PCD_MIFARE_scenario(); - break; - + } + PCD_MIFARE_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not Mifare"); - break; + Serial.println(" - Found a card, but it is not Mifare"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); } - ResetMode(); + + Serial.println("Restarting..."); + nfc.reset(); + Serial.println("Waiting for an Mifare Classic Card..."); delay(500); } diff --git a/examples/MifareClassic_write_block/Makefile b/examples/MifareClassic_write_block/Makefile new file mode 100644 index 0000000..b401ac6 --- /dev/null +++ b/examples/MifareClassic_write_block/Makefile @@ -0,0 +1,21 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +# BOARD_TAG = arduino:mbed_rp2040:pico +# BOARD_TAG = rp2040:rp2040:generic +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/MifareClassic_write_block/MifareClassic_write_block.ino b/examples/MifareClassic_write_block/MifareClassic_write_block.ino index 69f5376..7e0cb0a 100644 --- a/examples/MifareClassic_write_block/MifareClassic_write_block.ino +++ b/examples/MifareClassic_write_block/MifareClassic_write_block.ino @@ -1,184 +1,181 @@ /** - * Example to write a Mifare Classic block 4 and show its information - * Authors: + * Example to write a Mifare Classic block 4 and show its information + * Authors: * Salvador Mendoza - @Netxing - salmg.net * For Electronic Cats - electroniccats.com - * + * * March 2020 - * - * This code is beerware; if you see me (or any other collaborator - * member) at the local, and you've found our code helpful, + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. */ - -#include "Electroniccats_PN7150.h" -#define PN7150_IRQ (15) -#define PN7150_VEN (14) -#define PN7150_ADDR (0x28) -#define BLK_NB_MFC 4 // Block that wants to be read -#define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) -// Data to be written in the Mifare Classic block -#define DATA_WRITE_MFC 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff - -Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -RfIntf_t RfInterface; //Intarface to save data for multiple tags +#define BLK_NB_MFC 4 // Block that wants to be read +#define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key -uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation +// Data to be written in the Mifare Classic block +#define DATA_WRITE_MFC 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff -void ResetMode(){ //Reset the configuration mode after each reading - Serial.println("Re-initializing..."); - nfc.ConfigMode(mode); - nfc.StartDiscovery(mode); -} +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // creates a global NFC device interface object, attached to pins 7 (IRQ) and 8 (VEN) and using the default I2C address 0x28 -void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format +void PrintBuf(const byte* data, const uint32_t numBytes) { // Print hex data buffer in format uint32_t szPos; - for (szPos=0; szPos < numBytes; szPos++) - { + for (szPos = 0; szPos < numBytes; szPos++) { Serial.print(F("0x")); // Append leading 0 for small values if (data[szPos] <= 0xF) Serial.print(F("0")); - Serial.print(data[szPos]&0xff, HEX); - if ((numBytes > 1) && (szPos != numBytes - 1)) - { + Serial.print(data[szPos] & 0xff, HEX); + if ((numBytes > 1) && (szPos != numBytes - 1)) { Serial.print(F(" ")); } } Serial.println(); } -uint8_t PCD_MIFARE_scenario (void){ - Serial.println("Start reading process..."); - bool status; - unsigned char Resp[256]; - unsigned char RespSize; - /* Authenticate sector 1 with generic keys */ - unsigned char Auth[] = {0x40, BLK_NB_MFC/4, 0x10, KEY_MFC}; - /* Read block 4 */ - unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; - /* Write block 4 */ - unsigned char WritePart1[] = {0x10, 0xA0, BLK_NB_MFC}; - unsigned char WritePart2[] = {0x10, DATA_WRITE_MFC}; - - /* Authenticate */ - status = nfc.ReaderTagCmd(Auth, sizeof(Auth), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ - Serial.println("Auth error!"); - return 1; - } - - /* Read block */ - status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ - Serial.print("Error reading block!"); - return 2; - } - Serial.print("------------------------Sector "); - Serial.print(BLK_NB_MFC/4, DEC); - Serial.println("-------------------------"); - Serial.print("-------------------------Block "); - Serial.print(BLK_NB_MFC, DEC); - Serial.println("-------------------------"); - PrintBuf(Resp+1, RespSize-2); - - /* Write block */ - status = nfc.ReaderTagCmd(WritePart1, sizeof(WritePart1), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ - Serial.print("Error writing block!"); - return 3; - } - status = nfc.ReaderTagCmd(WritePart2, sizeof(WritePart2), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ - Serial.print("Error writing block!"); - return 4; - } - /* Read block again to see te changes*/ - status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); - if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) - { - Serial.print("Error reading block!"); - return 5; - } - Serial.print("------------------------Sector "); - Serial.print(BLK_NB_MFC/4, DEC); - Serial.println("-------------------------"); - Serial.print("----------------- New Data in Block "); - Serial.print(BLK_NB_MFC, DEC); - Serial.println("-----------------"); - PrintBuf(Resp+1, RespSize-2); - return 0; +uint8_t PCD_MIFARE_scenario(void) { + Serial.println("Start reading process..."); + bool status; + unsigned char Resp[256]; + unsigned char RespSize; + /* Authenticate sector 1 with generic keys */ + unsigned char Auth[] = {0x40, BLK_NB_MFC / 4, 0x10, KEY_MFC}; + /* Read block 4 */ + unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; + /* Write block 4 */ + unsigned char WritePart1[] = {0x10, 0xA0, BLK_NB_MFC}; + unsigned char WritePart2[] = {0x10, DATA_WRITE_MFC}; + + /* Authenticate */ + status = nfc.readerTagCmd(Auth, sizeof(Auth), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.println("Auth error!"); + return 1; + } + + /* Read block */ + status = nfc.readerTagCmd(Read, sizeof(Read), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error reading block!"); + return 2; + } + Serial.print("------------------------Sector "); + Serial.print(BLK_NB_MFC / 4, DEC); + Serial.println("-------------------------"); + Serial.print("-------------------------Block "); + Serial.print(BLK_NB_MFC, DEC); + Serial.println("-------------------------"); + PrintBuf(Resp + 1, RespSize - 2); + + /* Write block */ + status = nfc.readerTagCmd(WritePart1, sizeof(WritePart1), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error writing block!"); + return 3; + } + status = nfc.readerTagCmd(WritePart2, sizeof(WritePart2), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error writing block!"); + return 4; + } + /* Read block again to see te changes*/ + status = nfc.readerTagCmd(Read, sizeof(Read), Resp, &RespSize); + if ((status == NFC_ERROR) || (Resp[RespSize - 1] != 0)) { + Serial.print("Error reading block!"); + return 5; + } + Serial.print("------------------------Sector "); + Serial.print(BLK_NB_MFC / 4, DEC); + Serial.println("-------------------------"); + Serial.print("----------------- New Data in Block "); + Serial.print(BLK_NB_MFC, DEC); + Serial.println("-----------------"); + PrintBuf(Resp + 1, RespSize - 2); + return 0; } -void setup(){ +void setup() { Serial.begin(9600); - while(!Serial); - Serial.println("Write mifare classic data block 4 with PN7150"); - - if (nfc.connectNCI()) { //Wake up the board + while (!Serial) + ; + Serial.println("Read mifare classic data block 4 with PN7150"); + + Serial.println("Initializing..."); + if (nfc.connectNCI()) { // Wake up the board Serial.println("Error while setting up the mode, check connections!"); - while (1); + while (1) + ; } - - if (nfc.ConfigureSettings()) { + + if (nfc.configureSettings()) { Serial.println("The Configure Settings is failed!"); - while (1); + while (1) + ; } - - if(nfc.ConfigMode(mode)){ //Set up the configuration mode + + if (nfc.configMode()) { // Set up the configuration mode Serial.println("The Configure Mode is failed!!"); - while (1); + while (1) + ; } - nfc.StartDiscovery(mode); //NCI Discovery mode - Serial.println("Waiting for an Mifare Classic Card ..."); + nfc.startDiscovery(); // NCI Discovery mode + Serial.println("Waiting for an Mifare Classic Card..."); } -void loop(){ - if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards - switch(RfInterface.Protocol) { - case PROT_MIFARE: +void loop() { + if (nfc.isTagDetected()) { + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.MIFARE: Serial.println(" - Found MIFARE card"); - switch(RfInterface.ModeTech) { //Indetify card technology - case (MODE_POLL | TECH_PASSIVE_NFCA): - char tmp[16]; - Serial.print("\tSENS_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); - Serial.print(tmp); Serial.print(" "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); - Serial.print(tmp); Serial.println(" "); - - Serial.print("\tNFCID = "); - PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); - - if(RfInterface.Info.NFC_APP.SelResLen != 0) { - Serial.print("\tSEL_RES = "); - sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); - Serial.print(tmp); Serial.println(" "); - } + switch (nfc.remoteDevice.getModeTech()) { // Indetify card technology + case (nfc.tech.PASSIVE_NFCA): + char tmp[16]; + Serial.print("\tSENS_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[0]); + Serial.print(tmp); + Serial.print(" "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSensRes()[1]); + Serial.print(tmp); + Serial.println(" "); + + Serial.print("\tNFCID = "); + PrintBuf(nfc.remoteDevice.getNFCID(), nfc.remoteDevice.getNFCIDLen()); + + if (nfc.remoteDevice.getSelResLen() != 0) { + Serial.print("\tSEL_RES = "); + sprintf(tmp, "0x%.2X", nfc.remoteDevice.getSelRes()[0]); + Serial.print(tmp); + Serial.println(" "); + } break; - } - PCD_MIFARE_scenario(); - break; - + } + PCD_MIFARE_scenario(); + break; + default: - Serial.println(" - Found a card, but it is not Mifare"); - break; + Serial.println(" - Found a card, but it is not Mifare"); + break; } - - //* It can detect multiple cards at the same time if they use the same protocol - if(RfInterface.MoreTags) { - nfc.ReaderActivateNext(&RfInterface); + + //* It can detect multiple cards at the same time if they use the same protocol + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); } - //* Wait for card removal - nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); + + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); Serial.println("CARD REMOVED!"); - - nfc.StopDiscovery(); - nfc.StartDiscovery(mode); } - ResetMode(); + + Serial.println("Restarting..."); + nfc.reset(); + Serial.println("Waiting for an Mifare Classic Card..."); delay(500); } diff --git a/examples/NDEFRead/Makefile b/examples/NDEFRead/Makefile new file mode 100644 index 0000000..67609a6 --- /dev/null +++ b/examples/NDEFRead/Makefile @@ -0,0 +1,20 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +# BOARD_TAG = rp2040:rp2040:generic +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) --warnings all + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/NDEFRead/NDEFRead.ino b/examples/NDEFRead/NDEFRead.ino new file mode 100644 index 0000000..05cdeb1 --- /dev/null +++ b/examples/NDEFRead/NDEFRead.ino @@ -0,0 +1,271 @@ +/** + * Example to read NDEF messages + * Authors: + * Salvador Mendoza - @Netxing - salmg.net + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include "Electroniccats_PN7150.h" +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) + +// Function prototypes +void messageReceived(); +String getHexRepresentation(const byte *data, const uint32_t dataSize); +void displayDeviceInfo(); +void displayRecordInfo(NdefRecord record); + +// Create a global NFC device interface object, attached to pins 11 (IRQ) and 13 (VEN) and using the default I2C address 0x28 +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); +NdefMessage message; + +void setup() { + Serial.begin(9600); + while (!Serial) + ; + Serial.println("Detect NFC tags with PN7150"); + + // Register a callback function to be called when an NDEF message is received + nfc.setReadMsgCallback(messageReceived); + + Serial.println("Initializing..."); + + if (nfc.begin()) { + Serial.println("Error initializing PN7150"); + while (true) + ; + } + + message.begin(); + nfc.setReaderWriterMode(); + Serial.print("Waiting for a Card..."); +} + +void loop() { + if (nfc.isTagDetected()) { + displayDeviceInfo(); + switch (nfc.remoteDevice.getProtocol()) { + // Read NDEF message from NFC Forum Type 1, 2, 3, 4, 5 tags + case nfc.protocol.T1T: + case nfc.protocol.T2T: + case nfc.protocol.T3T: + case nfc.protocol.ISODEP: + case nfc.protocol.MIFARE: + nfc.readNdefMessage(); + break; + case nfc.protocol.ISO15693: + default: + break; + } + + // It can detect multiple cards at the same time if they are the same technology + if (nfc.remoteDevice.hasMoreTags()) { + nfc.activateNextTagDiscovery(); + Serial.println("Multiple cards are detected!"); + } + Serial.println("Remove the Card"); + nfc.waitForTagRemoval(); + Serial.println("Card removed!"); + Serial.println("Restarting..."); + nfc.reset(); + Serial.print("Waiting for a Card"); + } + + Serial.print("."); + delay(500); +} + +/// @brief Callback function called when an NDEF message is received +void messageReceived() { + NdefRecord record; + Serial.println("Processing Callback..."); + + // message is automatically updated when a new NDEF message is received + // only if we call message.begin() in setup() + if (message.isEmpty()) { + Serial.println("--- Provisioned buffer size too small or NDEF message empty"); + return; + } + + // Show NDEF message details + do { + record.create(message.getRecord()); // Get a new record every time we call getRecord() + displayRecordInfo(record); + } while (record.isNotEmpty()); +} + +String getHexRepresentation(const byte *data, const uint32_t dataSize) { + String hexString; + + if (dataSize == 0) { + hexString = "null"; + } + + for (uint32_t index = 0; index < dataSize; index++) { + if (data[index] <= 0xF) + hexString += "0"; + String hexValue = String(data[index] & 0xFF, HEX); + hexValue.toUpperCase(); + hexString += hexValue; + if ((dataSize > 1) && (index != dataSize - 1)) { + hexString += ":"; + } + } + return hexString; +} + +void displayDeviceInfo() { + Serial.println(); + Serial.print("Interface: "); + switch (nfc.remoteDevice.getInterface()) { + case nfc.interface.ISODEP: + Serial.println("ISO-DEP"); + break; + case nfc.interface.NFCDEP: + Serial.println("NFC-DEP"); + break; + case nfc.interface.TAGCMD: + Serial.println("TAG"); + break; + case nfc.interface.FRAME: + Serial.println("FRAME"); + break; + case nfc.interface.UNDETERMINED: + Serial.println("UNDETERMINED"); + break; + default: + Serial.println("UNKNOWN"); + break; + } + + Serial.print("Protocol: "); + switch (nfc.remoteDevice.getProtocol()) { + case nfc.protocol.UNDETERMINED: + Serial.println("UNDETERMINED"); + break; + case nfc.protocol.T1T: + Serial.println("T1T"); + break; + case nfc.protocol.T2T: + Serial.println("T2T"); + break; + case nfc.protocol.T3T: + Serial.println("T3T"); + break; + case nfc.protocol.ISODEP: + Serial.println("ISO-DEP"); + break; + case nfc.protocol.NFCDEP: + Serial.println("NFC-DEP"); + break; + case nfc.protocol.ISO15693: + Serial.println("ISO15693"); + break; + case nfc.protocol.MIFARE: + Serial.println("MIFARE"); + break; + default: + Serial.println("UNKNOWN"); + break; + } + + Serial.print("Technology: "); + switch (nfc.remoteDevice.getModeTech()) { + case nfc.modeTech.POLL | nfc.tech.PASSIVE_NFCA: + Serial.println("PASSIVE NFC A"); + break; + case nfc.modeTech.POLL | nfc.tech.PASSIVE_NFCB: + Serial.println("PASSIVE NFC B"); + break; + case nfc.modeTech.POLL | nfc.tech.PASSIVE_NFCF: + Serial.println("PASSIVE NFC F"); + break; + case nfc.modeTech.POLL | nfc.tech.PASSIVE_15693: + Serial.println("PASSIVE 15693"); + break; + } +} + +void displayRecordInfo(NdefRecord record) { + if (record.isEmpty()) { + Serial.println("No more records, exiting..."); + return; + } + + uint8_t *payload = record.getPayload(); + Serial.println("--- NDEF record received:"); + + switch (record.getType()) { + case MEDIA_VCARD: + Serial.println("vCard:"); + Serial.println(record.getVCardContent()); + break; + + case WELL_KNOWN_SIMPLE_TEXT: + Serial.println("\tWell known simple text"); + Serial.println("\t- Text record: " + record.getText()); + break; + + case WELL_KNOWN_SIMPLE_URI: + Serial.println("\tWell known simple URI"); + Serial.print("\t- URI record: "); + Serial.println(record.getUri()); + break; + + case MEDIA_HANDOVER_WIFI: + Serial.println("\tReceived WIFI credentials:"); + Serial.println("\t- SSID: " + record.getWiFiSSID()); + Serial.println("\t- Network key: " + record.getWiFiPassword()); + Serial.println("\t- Authentication type: " + record.getWiFiAuthenticationType()); + Serial.println("\t- Encryption type: " + record.getWiFiEncryptionType()); + break; + + case WELL_KNOWN_HANDOVER_SELECT: + Serial.print("\tHandover select version: "); + Serial.print(*payload >> 4); + Serial.print("."); + Serial.println(*payload & 0xF); + break; + + case WELL_KNOWN_HANDOVER_REQUEST: + Serial.print("\tHandover request version: "); + Serial.print(*payload >> 4); + Serial.print("."); + Serial.println(*payload & 0xF); + break; + + case MEDIA_HANDOVER_BT: + Serial.println("\tBluetooth handover"); + Serial.println("\t- Bluetooth name: " + record.getBluetoothName()); + Serial.println("\t- Bluetooth address: " + record.getBluetoothAddress()); + break; + + case MEDIA_HANDOVER_BLE: + Serial.print("\tBLE Handover"); + Serial.println("\t- Payload size: " + String(record.getPayloadSize()) + " bytes"); + Serial.print("\t- Payload = "); + Serial.println(getHexRepresentation(record.getPayload(), record.getPayloadSize())); + break; + + case MEDIA_HANDOVER_BLE_SECURE: + Serial.print("\tBLE secure Handover"); + Serial.println("\t- Payload size: " + String(record.getPayloadSize()) + " bytes"); + Serial.print("\t- Payload = "); + Serial.println(getHexRepresentation(record.getPayload(), record.getPayloadSize())); + break; + + default: + Serial.println("\tUnsupported NDEF record, cannot parse"); + break; + } + + Serial.println(""); +} diff --git a/examples/NDEFSend/Makefile b/examples/NDEFSend/Makefile new file mode 100644 index 0000000..4ab2c77 --- /dev/null +++ b/examples/NDEFSend/Makefile @@ -0,0 +1,19 @@ +BOARD_TAG = electroniccats:mbed_rp2040:bombercat +MONITOR_PORT = /dev/cu.usbmodem1101 + +compile: + arduino-cli compile --fqbn $(BOARD_TAG) + +upload: + arduino-cli upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + arduino-cli monitor -p $(MONITOR_PORT) + +clean: + arduino-cli cache clean + +wait: + sleep 2 + +all: compile upload wait monitor \ No newline at end of file diff --git a/examples/NDEFSend/NDEFSend.ino b/examples/NDEFSend/NDEFSend.ino new file mode 100644 index 0000000..15b18e0 --- /dev/null +++ b/examples/NDEFSend/NDEFSend.ino @@ -0,0 +1,72 @@ +/** + * Example to send NDEF messages + * Authors: + * Salvador Mendoza - @Netxing - salmg.net + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include + +#define PN7150_IRQ (11) +#define PN7150_VEN (13) +#define PN7150_ADDR (0x28) + +// Function prototypes +void sendMessageCallback(unsigned char *pNdefRecord, unsigned short NdefRecordSize); + +Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); // Creates a global NFC device interface object, attached to pins 11 (IRQ) and 13 (VEN) and using the default I2C address 0x28 + +const char ndefMessage[] = {0xD1, // MB/ME/CF/1/IL/TNF + 0x01, // Type length (1 byte) + 0x08, // Payload length + 'T', // Type -> 'T' for text, 'U' for URI + 0x02, // Status + 'e', 'n', // Language + 'H', 'e', 'l', 'l', 'o'}; // Message Payload + +void setup() { + Serial.begin(9600); + while (!Serial) + ; + Serial.println("Send NDEF Message with PN7150"); + + if (T4T_NDEF_EMU_SetMessage((unsigned char *)ndefMessage, sizeof(ndefMessage), (void *)*sendMessageCallback)) { + Serial.println("Set message success!"); + } else { + Serial.println("Set message failed!"); + } + + Serial.println("Initializing..."); + + if (nfc.begin()) { + Serial.println("Error initializing PN7150"); + while (true) + ; + } + + // Needed to detect readers + nfc.setEmulationMode(); + Serial.print("Waiting for an NDEF device"); +} + +void loop() { + Serial.print("."); + + if (nfc.isReaderDetected()) { + Serial.println("\nReader detected!"); + Serial.println("Sending NDEF message..."); + nfc.sendMessage(); + Serial.print("\nWaiting for an NDEF device"); + } +} + +void sendMessageCallback(unsigned char *pNdefRecord, unsigned short NdefRecordSize) { + Serial.println("NDEF Record sent!"); +} diff --git a/examples/P2P_Discovery/P2P_Discovery.ino b/examples/P2P_Discovery/P2P_Discovery.ino index df9fded..1473e14 100644 --- a/examples/P2P_Discovery/P2P_Discovery.ino +++ b/examples/P2P_Discovery/P2P_Discovery.ino @@ -40,7 +40,7 @@ void setup(){ while (1); } - if (nfc.ConfigureSettings()) { + if (nfc.configureSettings()) { Serial.println("The Configure Settings failed!"); while (1); } @@ -62,7 +62,7 @@ void loop(){ Serial.println(" - P2P INITIATOR MODE: Remote Target activated"); /* Process with SNEP for NDEF exchange */ - nfc.ProcessP2pMode(RfInterface); + nfc.processP2pMode(RfInterface); Serial.println("Peer lost!"); } ResetMode(); diff --git a/keywords.txt b/keywords.txt index 69ce991..15fce2c 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,35 +1,248 @@ -####################################### +############################################################################## # Syntax Coloring Map For ElectronicCats PN7150 +############################################################################## +# Class and data types (KEYWORD1) +############################################################################## + +Electroniccats_PN7150 KEYWORD1 +nfc KEYWORD1 +NdefMessage KEYWORD1 +message KEYWORD1 +NdefRecord KEYWORD1 +record KEYWORD1 +remoteDevice KEYWORD1 +protocol KEYWORD1 +tech KEYWORD1 +modeTech KEYWORD1 +interface KEYWORD1 + +############################################################################## +# Methods and Functions (KEYWORD2) +############################################################################## +# # Electroniccats_PN7150.h ####################################### -# # Class (KEYWORD1) + +GetFwVersion KEYWORD2 +begin KEYWORD2 +hasMessage KEYWORD2 +writeData KEYWORD2 +readData KEYWORD2 +getFirmwareVersion KEYWORD2 +GetFwVersion KEYWORD2 +configMode KEYWORD2 +ConfigMode KEYWORD2 +configureSettings KEYWORD2 +ConfigureSettings KEYWORD2 +startDiscovery KEYWORD2 +StartDiscovery KEYWORD2 +stopDiscovery KEYWORD2 +StopDiscovery KEYWORD2 +waitForDiscoveryNotification KEYWORD2 +WaitForDiscoveryNotification KEYWORD2 +isTagDetected KEYWORD2 +connectNCI KEYWORD2 +wakeupNCI KEYWORD2 +cardModeSend KEYWORD2 +CardModeSend KEYWORD2 +cardModeReceive KEYWORD2 +CardModeReceive KEYWORD2 +processCardMode KEYWORD2 +ProcessCardMode KEYWORD2 +processReaderMode KEYWORD2 +ProcessReaderMode KEYWORD2 +processP2pMode KEYWORD2 +ProcessP2pMode KEYWORD2 +presenceCheck KEYWORD2 +PresenceCheck KEYWORD2 +waitForTagRemoval KEYWORD2 +readerTagCmd KEYWORD2 +ReaderTagCmd KEYWORD2 +readerReActivate KEYWORD2 +ReaderReActivate KEYWORD2 +readerActivateNext KEYWORD2 +ReaderActivateNext KEYWORD2 +activateNextTagDiscovery KEYWORD2 +readNdef KEYWORD2 +readNdefMessage KEYWORD2 +ReadNdef KEYWORD2 +writeNdef KEYWORD2 +writeNdefMessage KEYWORD2 +WriteNdef KEYWORD2 +nciFactoryTestPrbs KEYWORD2 +NxpNci_FactoryTest_Prbs KEYWORD2 +nciFactoryTestRfOn KEYWORD2 +NxpNci_FactoryTest_RfOn KEYWORD2 +reset KEYWORD2 +setReaderWriterMode KEYWORD2 +setEmulationMode KEYWORD2 +setP2PMode KEYWORD2 +setSendMsgCallback KEYWORD2 +isReaderDetected KEYWORD2 +closeCommunication KEYWORD2 +sendMessage KEYWORD2 +ndefCallback KEYWORD2 + +####################################### +## Mode.h ####################################### -Electroniccats_PN7150 KEYWORD1 +getMode KEYWORD2 ####################################### -# Methods and Functions (KEYWORD2) +## NdefMessage.h ####################################### -GetFwVersion KEYWORD2 -begin KEYWORD2 -writeData KEYWORD2 -readData KEYWORD2 -hasMessage KEYWORD2 -ConfigMode KEYWORD2 -StartDiscovery KEYWORD2 -connectNCI KEYWORD2 -wakeupNCI KEYWORD2 -CardModeSend KEYWORD2 -CardModeReceive KEYWORD2 -WaitForDiscoveryNotification KEYWORD2 -FillInterfaceInfo KEYWORD2 -ReaderTagCmd KEYWORD2 -StopDiscovery KEYWORD2 -ProcessReaderMode KEYWORD2 -PresenceCheck KEYWORD2 -ReaderReActivate KEYWORD2 -PrintBuf KEYWORD2 -ReaderActivateNext KEYWORD2 +getContent KEYWORD2 +getContentSize KEYWORD2 +setContent KEYWORD2 +getRecord KEYWORD2 +isEmpty KEYWORD2 +isNotEmpty KEYWORD2 +hasRecord KEYWORD2 + +####################################### +## NdefRecord.h +####################################### +create KEYWORD2 +getType KEYWORD2 +getPayload KEYWORD2 +getPayloadSize KEYWORD2 +getText KEYWORD2 +getBluetoothName KEYWORD2 +getBluetoothAddress KEYWORD2 +getWiFiSSID KEYWORD2 +getWiFiAuthenticationType KEYWORD2 +getWiFiEncryptionType KEYWORD2 +getWiFiNetworkKey KEYWORD2 +getVCardContent KEYWORD2 +getUri KEYWORD2 + +####################################### +## NdefRecord.h +####################################### + +getInterface KEYWORD2 +getProtocol KEYWORD2 +getModeTech KEYWORD2 +hasMoreTags KEYWORD2 +getSensRes KEYWORD2 +getSensResLen KEYWORD2 +getNFCID KEYWORD2 +getNFCIDLen KEYWORD2 +getSelRes KEYWORD2 +getSelResLen KEYWORD2 +getRats KEYWORD2 +getRatsLen KEYWORD2 +getAttribRes KEYWORD2 +getAttribResLen KEYWORD2 +getBitRate KEYWORD2 +getAFI KEYWORD2 +getDSFID KEYWORD2 +getID KEYWORD2 +setInterface KEYWORD2 +setProtocol KEYWORD2 +setProtocol KEYWORD2 +setModeTech KEYWORD2 +setMoreTagsAvailable KEYWORD2 +setInfo KEYWORD2 + +############################################################################## +# Constants (LITERAL1) +############################################################################## +## Interface.h +####################################### + +INTF_UNDETERMINED LITERAL1 +INTF_FRAME LITERAL1 +INTF_ISODEP LITERAL1 +INTF_NFCDEP LITERAL1 +INTF_TAGCMD LITERAL1 + +UNDETERMINED LITERAL1 +FRAME LITERAL1 +ISODEP LITERAL1 +NFCDEP LITERAL1 +TAGCMD LITERAL1 + +####################################### +## Mode.h ####################################### +READER_WRITER LITERAL1 +EMULATION LITERAL1 +P2P LITERAL1 + +####################################### +## ModeTech.h +####################################### + +MODE_POLL LITERAL1 +MODE_LISTEN LITERAL1 +MODE_MASK LITERAL1 + +POLL LITERAL1 +LISTEN LITERAL1 +MASK LITERAL1 + +####################################### +## Protocol.h +####################################### + +PROT_UNDETERMINED LITERAL1 +PROT_T1T LITERAL1 +PROT_T2T LITERAL1 +PROT_T3T LITERAL1 +PROT_ISODEP LITERAL1 +PROT_MIFARE LITERAL1 +PROT_ISO15693 LITERAL1 + +UNDETERMINED LITERAL1 +T1T LITERAL1 +T2T LITERAL1 +T3T LITERAL1 +ISODEP LITERAL1 +MIFARE LITERAL1 +ISO15693 LITERAL1 + +####################################### +## Tech.h +####################################### + +TECH_ACTIVE_NFCA LITERAL1 +TECH_PASSIVE_NFCB LITERAL1 +TECH_PASSIVE_NFCF LITERAL1 +TECH_ACTIVE_NFCA LITERAL1 +TECH_ACTIVE_NFCF LITERAL1 +TECH_PASSIVE_15693 LITERAL1 + +PASSIVE_NFCA LITERAL1 +PASSIVE_NFCB LITERAL1 +PASSIVE_NFCF LITERAL1 +ACTIVE_NFCA LITERAL1 +ACTIVE_NFCF LITERAL1 +PASSIVE_15693 LITERAL1 +PASSIVE_NFCV LITERAL1 + +####################################### +## ndef_helper.h +####################################### + +WELL_KNOWN_SIMPLE_TEXT LITERAL1 +WELL_KNOWN_SIMPLE_URI LITERAL1 +WELL_KNOWN_SMART_POSTER LITERAL1 +WELL_KNOWN_HANDOVER_SELECT LITERAL1 +WELL_KNOWN_HANDOVER_REQUEST LITERAL1 +WELL_KNOWN_ALTERNATIVE_CARRIER LITERAL1 +WELL_KNOWN_COLLISION_RESOLUTION LITERAL1 +MEDIA_VCARD LITERAL1 +MEDIA_HANDOVER_WIFI LITERAL1 +MEDIA_HANDOVER_BT LITERAL1 +MEDIA_HANDOVER_BLE LITERAL1 +MEDIA_HANDOVER_BLE_SECURE LITERAL1 +ABSOLUTE_URI LITERAL1 +UNSUPPORTED_NDEF_RECORD LITERAL1 + +recordType LITERAL1 +recordPayload LITERAL1 +recordPayloadSize LITERAL1 \ No newline at end of file diff --git a/library.properties b/library.properties index 26a6423..adec0e7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Electronic Cats PN7150 -version=1.8.0 +version=2.0.0 author=Electronic Cats and Salvador Mendoza maintainer=Electronic Cats sentence=Arduino library for SPI and I2C access to the PN7150 RFID/Near Field Communication chip. diff --git a/src/Electroniccats_PN7150.cpp b/src/Electroniccats_PN7150.cpp index 49dca96..f3979d9 100644 --- a/src/Electroniccats_PN7150.cpp +++ b/src/Electroniccats_PN7150.cpp @@ -2,1890 +2,1768 @@ * NXP PN7150 Driver * Porting authors: * Salvador Mendoza - @Netxing - salmg.net - * Andres Sabas - Electronic Cats - Electroniccats.com + * Andres Sabas - Electronic Cats - electroniccats.com + * Francisco Torres - Electronic Cats - electroniccats.com * - * November 2020 + * August 2023 * * This code is beerware; if you see me (or any other collaborator * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. * - * Some methods and ideas were extract from https://github.com/Strooom/PN7150 - * - * + * Some methods and ideas were extracted from https://github.com/Strooom/PN7150 */ + #include "Electroniccats_PN7150.h" -#include "P2P_NDEF.h" -#include "ndef_helper.h" -#include "RW_NDEF.h" -#include "T4T_NDEF_emu.h" uint8_t gNextTag_Protocol = PROT_UNDETERMINED; uint8_t NCIStartDiscovery_length = 0; uint8_t NCIStartDiscovery[30]; -unsigned char DiscoveryTechnologiesCE[] = { //Emulation +unsigned char DiscoveryTechnologiesCE[] = { // Emulation MODE_LISTEN | MODE_POLL}; -unsigned char DiscoveryTechnologiesRW[] = { //Read & Write +unsigned char DiscoveryTechnologiesRW[] = { // Read & Write MODE_POLL | TECH_PASSIVE_NFCA, MODE_POLL | TECH_PASSIVE_NFCF, MODE_POLL | TECH_PASSIVE_NFCB, MODE_POLL | TECH_PASSIVE_15693}; -unsigned char DiscoveryTechnologiesP2P[] = { //P2P +unsigned char DiscoveryTechnologiesP2P[] = { // P2P MODE_POLL | TECH_PASSIVE_NFCA, MODE_POLL | TECH_PASSIVE_NFCF, /* Only one POLL ACTIVE mode can be enabled, if both are defined only NFCF applies */ MODE_POLL | TECH_ACTIVE_NFCA, - //MODE_POLL | TECH_ACTIVE_NFCF, + // MODE_POLL | TECH_ACTIVE_NFCF, - //MODE_LISTEN | TECH_PASSIVE_NFCA, + // MODE_LISTEN | TECH_PASSIVE_NFCA, MODE_LISTEN | TECH_PASSIVE_NFCF, MODE_LISTEN | TECH_ACTIVE_NFCA, MODE_LISTEN | TECH_ACTIVE_NFCF}; Electroniccats_PN7150::Electroniccats_PN7150(uint8_t IRQpin, uint8_t VENpin, - uint8_t I2Caddress, TwoWire *wire) : _IRQpin(IRQpin), _VENpin(VENpin), _I2Caddress(I2Caddress), _wire(wire) -{ - pinMode(_IRQpin, INPUT); - if (_VENpin != 255) - pinMode(_VENpin, OUTPUT); + uint8_t I2Caddress, TwoWire *wire) : _IRQpin(IRQpin), _VENpin(VENpin), _I2Caddress(I2Caddress), _wire(wire) { + pinMode(_IRQpin, INPUT); + if (_VENpin != 255) + pinMode(_VENpin, OUTPUT); + + this->_hasBeenInitialized = false; } -uint8_t Electroniccats_PN7150::begin() -{ - _wire->begin(); - if (_VENpin != 255) { - digitalWrite(_VENpin, HIGH); - delay(1); - digitalWrite(_VENpin, LOW); - delay(1); - digitalWrite(_VENpin, HIGH); - delay(3); - } - return SUCCESS; +uint8_t Electroniccats_PN7150::begin() { + _wire->begin(); + if (_VENpin != 255) { + digitalWrite(_VENpin, HIGH); + delay(1); + digitalWrite(_VENpin, LOW); + delay(1); + digitalWrite(_VENpin, HIGH); + delay(3); + } + + if (connectNCI()) { + return ERROR; + } + + if (configureSettings()) { + return ERROR; + } + + if (configMode()) { + return ERROR; + } + + if (startDiscovery()) { + return ERROR; + } + + this->_hasBeenInitialized = true; + + return SUCCESS; } -bool Electroniccats_PN7150::hasMessage() const -{ - return (HIGH == digitalRead(_IRQpin)); // PN7150 indicates it has data by driving IRQ signal HIGH +bool Electroniccats_PN7150::isTimeOut() const { + return ((millis() - timeOutStartTime) >= timeOut); } -uint8_t Electroniccats_PN7150::writeData(uint8_t txBuffer[], uint32_t txBufferLevel) const -{ - uint32_t nmbrBytesWritten = 0; - _wire->beginTransmission((uint8_t)_I2Caddress); //configura transmision - nmbrBytesWritten = _wire->write(txBuffer, (size_t)(txBufferLevel)); //carga en buffer - #ifdef DEBUG2 - Serial.println("[DEBUG] written bytes = 0x"+String(nmbrBytesWritten,HEX)); - #endif - if (nmbrBytesWritten == txBufferLevel) - { - byte resultCode; - resultCode = _wire->endTransmission(); //envio de datos segun yo - #ifdef DEBUG2 - Serial.println("[DEBUG] write data code = 0x"+String(resultCode,HEX)); - #endif - return resultCode; - } - else - { - return 4; // Could not properly copy data to I2C buffer, so treat as other error, see i2c_t3 - } +void Electroniccats_PN7150::setTimeOut(unsigned long theTimeOut) { + timeOutStartTime = millis(); + timeOut = theTimeOut; } -uint32_t Electroniccats_PN7150::readData(uint8_t rxBuffer[]) const -{ - uint32_t bytesReceived; // keeps track of how many bytes we actually received - if (hasMessage()) - { // only try to read something if the PN7150 indicates it has something - bytesReceived = _wire->requestFrom(_I2Caddress, (uint8_t)3); // first reading the header, as this contains how long the payload will be - //Imprimir datos de bytes received, tratar de extraer con funcion read - //Leer e inyectar directo al buffer los siguientes 3 - #ifdef DEBUG2 - Serial.println("[DEBUG] bytesReceived = 0x"+String(bytesReceived,HEX)); - #endif - rxBuffer[0] = _wire->read(); - rxBuffer[1] = _wire->read(); - rxBuffer[2] = _wire->read(); - #ifdef DEBUG2 - for(int i=0;i<3;i++){ - Serial.println("[DEBUG] Byte["+String(i)+"] = 0x"+String(rxBuffer[i],HEX)); - } - #endif - uint8_t payloadLength = rxBuffer[2]; - if (payloadLength > 0) - { - bytesReceived += _wire->requestFrom(_I2Caddress, (uint8_t)payloadLength); // then reading the payload, if any - #ifdef DEBUG2 - Serial.println("[DEBUG] payload bytes = 0x"+String(bytesReceived-3,HEX)); - #endif - uint32_t index = 3; - while (index < bytesReceived) - { - rxBuffer[index] = _wire->read(); - #ifdef DEBUG2 - Serial.println("[DEBUG] payload["+String(index)+"] = 0x"+String(rxBuffer[index],HEX)); - #endif - index++; - } - index = 0; - } - } - else - { - bytesReceived = 0; +uint8_t Electroniccats_PN7150::wakeupNCI() { // the device has to wake up using a core reset + uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x01}; + uint16_t NbBytes = 0; + + // Reset RF settings restauration flag + (void)writeData(NCICoreReset, 4); + getMessage(15); + NbBytes = rxMessageLength; + if ((NbBytes == 0) || (rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00)) { + return ERROR; + } + getMessage(); + NbBytes = rxMessageLength; + if (NbBytes != 0) { + // NCI_PRINT_BUF("NCI << ", Answer, NbBytes); + // Is CORE_GENERIC_ERROR_NTF ? + if ((rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x07)) { + /* Is PN7150B0HN/C11004 Anti-tearing recovery procedure triggered ? */ + // if ((rxBuffer[3] == 0xE6)) gRfSettingsRestored_flag = true; + } else { + return ERROR; } - return bytesReceived; + } + return SUCCESS; } -bool Electroniccats_PN7150::isTimeOut() const -{ - return ((millis() - timeOutStartTime) >= timeOut); +bool Electroniccats_PN7150::getMessage(uint16_t timeout) { // check for message using timeout, 5 milisec as default + setTimeOut(timeout); + rxMessageLength = 0; + while (!isTimeOut()) { + rxMessageLength = readData(rxBuffer); + if (rxMessageLength) + break; + else if (timeout == 1337) + setTimeOut(timeout); + } + return rxMessageLength; } -void Electroniccats_PN7150::setTimeOut(unsigned long theTimeOut) -{ - timeOutStartTime = millis(); - timeOut = theTimeOut; +bool Electroniccats_PN7150::hasMessage() const { + return (HIGH == digitalRead(_IRQpin)); // PN7150 indicates it has data by driving IRQ signal HIGH } -bool Electroniccats_PN7150::getMessage(uint16_t timeout) -{ // check for message using timeout, 5 milisec as default - setTimeOut(timeout); - rxMessageLength = 0; - while (!isTimeOut()) - { - rxMessageLength = readData(rxBuffer); - if (rxMessageLength) - break; - else if (timeout == 1337) - setTimeOut(timeout); - } - return rxMessageLength; +uint8_t Electroniccats_PN7150::writeData(uint8_t txBuffer[], uint32_t txBufferLevel) const { + uint32_t nmbrBytesWritten = 0; + _wire->beginTransmission((uint8_t)_I2Caddress); // configura transmision + nmbrBytesWritten = _wire->write(txBuffer, (size_t)(txBufferLevel)); // carga en buffer +#ifdef DEBUG2 + Serial.println("[DEBUG] written bytes = 0x" + String(nmbrBytesWritten, HEX)); +#endif + if (nmbrBytesWritten == txBufferLevel) { + byte resultCode; + resultCode = _wire->endTransmission(); // envio de datos segun yo +#ifdef DEBUG2 + Serial.println("[DEBUG] write data code = 0x" + String(resultCode, HEX)); +#endif + return resultCode; + } else { + return 4; // Could not properly copy data to I2C buffer, so treat as other error, see i2c_t3 + } } -uint8_t Electroniccats_PN7150::wakeupNCI() -{ // the device has to wake up using a core reset - uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x01}; - uint16_t NbBytes = 0; - - // Reset RF settings restauration flag - (void)writeData(NCICoreReset, 4); - getMessage(15); - NbBytes = rxMessageLength; - if ((NbBytes == 0) || (rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00)) - { - return ERROR; +uint32_t Electroniccats_PN7150::readData(uint8_t rxBuffer[]) const { + uint32_t bytesReceived; // keeps track of how many bytes we actually received + if (hasMessage()) { // only try to read something if the PN7150 indicates it has something + bytesReceived = _wire->requestFrom(_I2Caddress, (uint8_t)3); // first reading the header, as this contains how long the payload will be +// Imprimir datos de bytes received, tratar de extraer con funcion read +// Leer e inyectar directo al buffer los siguientes 3 +#ifdef DEBUG2 + Serial.println("[DEBUG] bytesReceived = 0x" + String(bytesReceived, HEX)); +#endif + rxBuffer[0] = _wire->read(); + rxBuffer[1] = _wire->read(); + rxBuffer[2] = _wire->read(); +#ifdef DEBUG2 + for (int i = 0; i < 3; i++) { + Serial.println("[DEBUG] Byte[" + String(i) + "] = 0x" + String(rxBuffer[i], HEX)); } - getMessage(); - NbBytes = rxMessageLength; - if (NbBytes != 0) - { - //NCI_PRINT_BUF("NCI << ", Answer, NbBytes); - // Is CORE_GENERIC_ERROR_NTF ? - if ((rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x07)) - { - /* Is PN7150B0HN/C11004 Anti-tearing recovery procedure triggered ? */ - //if ((rxBuffer[3] == 0xE6)) gRfSettingsRestored_flag = true; - } - else - { - return ERROR; - } +#endif + uint8_t payloadLength = rxBuffer[2]; + if (payloadLength > 0) { + bytesReceived += _wire->requestFrom(_I2Caddress, (uint8_t)payloadLength); // then reading the payload, if any +#ifdef DEBUG2 + Serial.println("[DEBUG] payload bytes = 0x" + String(bytesReceived - 3, HEX)); +#endif + uint32_t index = 3; + while (index < bytesReceived) { + rxBuffer[index] = _wire->read(); +#ifdef DEBUG2 + Serial.println("[DEBUG] payload[" + String(index) + "] = 0x" + String(rxBuffer[index], HEX)); +#endif + index++; + } + index = 0; } - return SUCCESS; + } else { + bytesReceived = 0; + } + return bytesReceived; } -uint8_t Electroniccats_PN7150::connectNCI() -{ - uint8_t i = 2; - uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; - - // Open connection to NXPNCI - begin(); - // Loop until NXPNCI answers - while (wakeupNCI() != SUCCESS) - { - if (i-- == 0) - return ERROR; - delay(500); - } +int Electroniccats_PN7150::getFirmwareVersion() { + return ((gNfcController_fw_version[0] & 0xFF) << 16) | ((gNfcController_fw_version[1] & 0xFF) << 8) | (gNfcController_fw_version[2] & 0xFF); +} - (void)writeData(NCICoreInit, sizeof(NCICoreInit)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) - return ERROR; +// Deprecated, use getFirmwareVersion() instead +int Electroniccats_PN7150::GetFwVersion() { + return getFirmwareVersion(); +} - // Retrieve NXP-NCI NFC Controller generation - if (rxBuffer[17 + rxBuffer[8]] == 0x08) - gNfcController_generation = 1; - else if (rxBuffer[17 + rxBuffer[8]] == 0x10) - gNfcController_generation = 2; - - // Retrieve NXP-NCI NFC Controller FW version - gNfcController_fw_version[0] = rxBuffer[17 + rxBuffer[8]]; //0xROM_CODE_V - gNfcController_fw_version[1] = rxBuffer[18 + rxBuffer[8]]; //0xFW_MAJOR_NO - gNfcController_fw_version[2] = rxBuffer[19 + rxBuffer[8]]; //0xFW_MINOR_NO - #ifdef DEBUG - Serial.println("0xROM_CODE_V: " + String(gNfcController_fw_version[0], HEX)); - Serial.println("FW_MAJOR_NO: " + String(gNfcController_fw_version[1], HEX)); - Serial.println("0xFW_MINOR_NO: " + String(gNfcController_fw_version[2], HEX)); - Serial.println("gNfcController_generation: " + String(gNfcController_generation, HEX)); - #endif +uint8_t Electroniccats_PN7150::connectNCI() { + uint8_t i = 2; + uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; + // Check if begin function has been called + if (this->_hasBeenInitialized) { return SUCCESS; -} + } + + // Open connection to NXPNCI + _wire->begin(); + if (_VENpin != 255) { + digitalWrite(_VENpin, HIGH); + delay(1); + digitalWrite(_VENpin, LOW); + delay(1); + digitalWrite(_VENpin, HIGH); + delay(3); + } + + // Loop until NXPNCI answers + while (wakeupNCI() != SUCCESS) { + if (i-- == 0) + return ERROR; + delay(500); + } + + (void)writeData(NCICoreInit, sizeof(NCICoreInit)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) + return ERROR; + + // Retrieve NXP-NCI NFC Controller generation + if (rxBuffer[17 + rxBuffer[8]] == 0x08) + gNfcController_generation = 1; + else if (rxBuffer[17 + rxBuffer[8]] == 0x10) + gNfcController_generation = 2; + + // Retrieve NXP-NCI NFC Controller FW version + gNfcController_fw_version[0] = rxBuffer[17 + rxBuffer[8]]; // 0xROM_CODE_V + gNfcController_fw_version[1] = rxBuffer[18 + rxBuffer[8]]; // 0xFW_MAJOR_NO + gNfcController_fw_version[2] = rxBuffer[19 + rxBuffer[8]]; // 0xFW_MINOR_NO +#ifdef DEBUG + Serial.println("0xROM_CODE_V: " + String(gNfcController_fw_version[0], HEX)); + Serial.println("FW_MAJOR_NO: " + String(gNfcController_fw_version[1], HEX)); + Serial.println("0xFW_MINOR_NO: " + String(gNfcController_fw_version[2], HEX)); + Serial.println("gNfcController_generation: " + String(gNfcController_generation, HEX)); +#endif -int Electroniccats_PN7150::GetFwVersion() -{ - return ((gNfcController_fw_version[0] & 0xFF) << 16) | ((gNfcController_fw_version[1] & 0xFF) << 8) | (gNfcController_fw_version[2] & 0xFF); + return SUCCESS; } -uint8_t Electroniccats_PN7150::ConfigMode(uint8_t modeSE) -{ - unsigned mode = (modeSE == 1 ? MODE_RW : modeSE == 2 ? MODE_CARDEMU - : MODE_P2P); +/// @brief Update the internal mode, stop discovery, and build the command to configure the PN7150 chip based on the input mode +/// @param modeSE +/// @return SUCCESS or ERROR +uint8_t Electroniccats_PN7150::ConfigMode(uint8_t modeSE) { + unsigned mode = (modeSE == 1 ? MODE_RW : modeSE == 2 ? MODE_CARDEMU + : MODE_P2P); - uint8_t Command[MAX_NCI_FRAME_SIZE]; + // Update internal mode + if (!Electroniccats_PN7150::setMode(modeSE)) { + return ERROR; // Invalid mode, out of range + } - uint8_t Item = 0; - uint8_t NCIDiscoverMap[] = {0x21, 0x00}; + Electroniccats_PN7150::stopDiscovery(); - //Emulation mode - const uint8_t DM_CARDEMU[] = {0x4, 0x2, 0x2}; - const uint8_t R_CARDEMU[] = {0x1, 0x3, 0x0, 0x1, 0x4}; + uint8_t Command[MAX_NCI_FRAME_SIZE]; - //RW Mode - const uint8_t DM_RW[] = {0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x3, 0x1, 0x1, 0x4, 0x1, 0x2, 0x80, 0x01, 0x80}; - uint8_t NCIPropAct[] = {0x2F, 0x02, 0x00}; + uint8_t Item = 0; + uint8_t NCIDiscoverMap[] = {0x21, 0x00}; - //P2P Support - const uint8_t DM_P2P[] = {0x5, 0x3, 0x3}; - const uint8_t R_P2P[] = {0x1, 0x3, 0x0, 0x1, 0x5}; - uint8_t NCISetConfig_NFC[] = {0x20, 0x02, 0x1F, 0x02, 0x29, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA, 0x61, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA}; + // Emulation mode + const uint8_t DM_CARDEMU[] = {0x4, 0x2, 0x2}; + const uint8_t R_CARDEMU[] = {0x1, 0x3, 0x0, 0x1, 0x4}; - uint8_t NCIRouting[] = {0x21, 0x01, 0x07, 0x00, 0x01}; - uint8_t NCISetConfig_NFCA_SELRSP[] = {0x20, 0x02, 0x04, 0x01, 0x32, 0x01, 0x00}; + // RW Mode + const uint8_t DM_RW[] = {0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x3, 0x1, 0x1, 0x4, 0x1, 0x2, 0x80, 0x01, 0x80}; + uint8_t NCIPropAct[] = {0x2F, 0x02, 0x00}; - if (mode == 0) - return SUCCESS; + // P2P Support + const uint8_t DM_P2P[] = {0x5, 0x3, 0x3}; + const uint8_t R_P2P[] = {0x1, 0x3, 0x0, 0x1, 0x5}; + uint8_t NCISetConfig_NFC[] = {0x20, 0x02, 0x1F, 0x02, 0x29, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA, 0x61, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA}; - /* Enable Proprietary interface for T4T card presence check procedure */ - if (modeSE == 1) - { - if (mode == MODE_RW) - { - (void)writeData(NCIPropAct, sizeof(NCIPropAct)); - getMessage(); + uint8_t NCIRouting[] = {0x21, 0x01, 0x07, 0x00, 0x01}; + uint8_t NCISetConfig_NFCA_SELRSP[] = {0x20, 0x02, 0x04, 0x01, 0x32, 0x01, 0x00}; - if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) - return ERROR; - } - } + if (mode == 0) + return SUCCESS; - //* Building Discovery Map command - Item = 0; + /* Enable Proprietary interface for T4T card presence check procedure */ + if (modeSE == 1) { + if (mode == MODE_RW) { + (void)writeData(NCIPropAct, sizeof(NCIPropAct)); + getMessage(); - if ((mode & MODE_CARDEMU and modeSE == 2) || (mode & MODE_P2P and modeSE == 3)) - { - memcpy(&Command[4 + (3 * Item)], (modeSE == 2 ? DM_CARDEMU : DM_P2P), sizeof((modeSE == 2 ? DM_CARDEMU : DM_P2P))); - Item++; + if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) + return ERROR; } - if (mode & MODE_RW and modeSE == 1) - { - memcpy(&Command[4 + (3 * Item)], DM_RW, sizeof(DM_RW)); - Item += sizeof(DM_RW) / 3; + } + + //* Building Discovery Map command + Item = 0; + + if ((mode & MODE_CARDEMU and modeSE == 2) || (mode & MODE_P2P and modeSE == 3)) { + memcpy(&Command[4 + (3 * Item)], (modeSE == 2 ? DM_CARDEMU : DM_P2P), sizeof((modeSE == 2 ? DM_CARDEMU : DM_P2P))); + Item++; + } + if (mode & MODE_RW and modeSE == 1) { + memcpy(&Command[4 + (3 * Item)], DM_RW, sizeof(DM_RW)); + Item += sizeof(DM_RW) / 3; + } + if (Item != 0) { + memcpy(Command, NCIDiscoverMap, sizeof(NCIDiscoverMap)); + Command[2] = 1 + (Item * 3); + Command[3] = Item; + (void)writeData(Command, 3 + Command[2]); + getMessage(10); + if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) { + return ERROR; } - if (Item != 0) - { - memcpy(Command, NCIDiscoverMap, sizeof(NCIDiscoverMap)); - Command[2] = 1 + (Item * 3); - Command[3] = Item; - (void)writeData(Command, 3 + Command[2]); - getMessage(10); - if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) - { - return ERROR; - } + } + + // Configuring routing + Item = 0; + + if (modeSE == 2 || modeSE == 3) { // Emulation or P2P + memcpy(&Command[5 + (5 * Item)], (modeSE == 2 ? R_CARDEMU : R_P2P), sizeof((modeSE == 2 ? R_CARDEMU : R_P2P))); + Item++; + + if (Item != 0) { + memcpy(Command, NCIRouting, sizeof(NCIRouting)); + Command[2] = 2 + (Item * 5); + Command[4] = Item; + (void)writeData(Command, 3 + Command[2]); + getMessage(); + if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) + return ERROR; } + NCISetConfig_NFCA_SELRSP[6] += (modeSE == 2 ? 0x20 : 0x40); - // Configuring routing - Item = 0; + if (NCISetConfig_NFCA_SELRSP[6] != 0x00) { + (void)writeData(NCISetConfig_NFCA_SELRSP, sizeof(NCISetConfig_NFCA_SELRSP)); + getMessage(); - if (modeSE == 2 || modeSE == 3) - { //Emulation or P2P - memcpy(&Command[5 + (5 * Item)], (modeSE == 2 ? R_CARDEMU : R_P2P), sizeof((modeSE == 2 ? R_CARDEMU : R_P2P))); - Item++; + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) + return ERROR; + else + return SUCCESS; + } - if (Item != 0) - { - memcpy(Command, NCIRouting, sizeof(NCIRouting)); - Command[2] = 2 + (Item * 5); - Command[4] = Item; - (void)writeData(Command, 3 + Command[2]); - getMessage(); - if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) - return ERROR; - } - NCISetConfig_NFCA_SELRSP[6] += (modeSE == 2 ? 0x20 : 0x40); + if (mode & MODE_P2P and modeSE == 3) { + (void)writeData(NCISetConfig_NFC, sizeof(NCISetConfig_NFC)); + getMessage(); - if (NCISetConfig_NFCA_SELRSP[6] != 0x00) - { - (void)writeData(NCISetConfig_NFCA_SELRSP, sizeof(NCISetConfig_NFCA_SELRSP)); - getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) + return ERROR; + } + } + return SUCCESS; +} - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) - return ERROR; - else - return SUCCESS; - } +uint8_t Electroniccats_PN7150::configMode() { + int mode = Electroniccats_PN7150::getMode(); + return Electroniccats_PN7150::ConfigMode(mode); +} - if (mode & MODE_P2P and modeSE == 3) - { - (void)writeData(NCISetConfig_NFC, sizeof(NCISetConfig_NFC)); - getMessage(); +bool Electroniccats_PN7150::configureSettings(void) { +#if NXP_CORE_CONF + /* NCI standard dedicated settings + * Refer to NFC Forum NCI standard for more details + */ + uint8_t NxpNci_CORE_CONF[] = { + 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ + 0x00, 0x02, 0x00, 0x01 /* TOTAL_DURATION */ + }; +#endif - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00)) - return ERROR; - } - } - return SUCCESS; -} +#if NXP_CORE_CONF_EXTN + /* NXP-NCI extension dedicated setting + * Refer to NFC controller User Manual for more details + */ + uint8_t NxpNci_CORE_CONF_EXTN[] = { + 0x20, 0x02, 0x0D, 0x03, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x40, 0x01, 0x00, /* TAG_DETECTOR_CFG */ + 0xA0, 0x41, 0x01, 0x04, /* TAG_DETECTOR_THRESHOLD_CFG */ + 0xA0, 0x43, 0x01, 0x00 /* TAG_DETECTOR_FALLBACK_CNT_CFG */ + }; +#endif -uint8_t Electroniccats_PN7150::StartDiscovery(uint8_t modeSE) -{ - unsigned char TechTabSize = (modeSE == 1 ? sizeof(DiscoveryTechnologiesRW) : modeSE == 2 ? sizeof(DiscoveryTechnologiesCE) - : sizeof(DiscoveryTechnologiesP2P)); - - NCIStartDiscovery_length = 0; - NCIStartDiscovery[0] = 0x21; - NCIStartDiscovery[1] = 0x03; - NCIStartDiscovery[2] = (TechTabSize * 2) + 1; - NCIStartDiscovery[3] = TechTabSize; - for (uint8_t i = 0; i < TechTabSize; i++) - { - NCIStartDiscovery[(i * 2) + 4] = (modeSE == 1 ? DiscoveryTechnologiesRW[i] : modeSE == 2 ? DiscoveryTechnologiesCE[i] - : DiscoveryTechnologiesP2P[i]); - - NCIStartDiscovery[(i * 2) + 5] = 0x01; - } +#if NXP_CORE_STANDBY + /* NXP-NCI standby enable setting + * Refer to NFC controller User Manual for more details + */ + uint8_t NxpNci_CORE_STANDBY[] = {0x2F, 0x00, 0x01, 0x01}; /* last byte indicates enable/disable */ +#endif - NCIStartDiscovery_length = (TechTabSize * 2) + 4; - (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); - getMessage(); +#if NXP_TVDD_CONF + /* NXP-NCI TVDD configuration + * Refer to NFC controller Hardware Design Guide document for more details + */ + /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ + uint8_t NxpNci_TVDD_CONF_1stGen[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x13, 0x01, 0x00}; - if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) - return ERROR; - else - return SUCCESS; -} + /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ +#if (NXP_TVDD_CONF == 1) + /* CFG1: Vbat is used to generate the VDD(TX) through TXLDO */ + uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x02, 0x09, 0x00}; +#else + /* CFG2: external 5V is used to generate the VDD(TX) through TXLDO */ + uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x06, 0x64, 0x00}; +#endif +#endif -void Electroniccats_PN7150::ProcessCardMode(RfIntf_t RfIntf) -{ - uint8_t Answer[MAX_NCI_FRAME_SIZE]; +#if NXP_RF_CONF + /* NXP-NCI RF configuration + * Refer to NFC controller Antenna Design and Tuning Guidelines document for more details + */ + /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ + /* Following configuration is the default settings of PN7120 NFC Controller */ + uint8_t NxpNci_RF_CONF_1stGen[] = { + 0x20, 0x02, 0x38, 0x07, + 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x01, 0x00, 0xF1, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x44, 0xA3, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0xDC, 0x50, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x04, 0x06, 0x03, 0x00, 0x70, /* RF_CLIF_CFG_TARGET CLIF_TRANSCEIVE_CONTROL_REG */ + 0xA0, 0x0D, 0x03, 0x06, 0x16, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_UNDERSHOOT_CONFIG_REG */ + 0xA0, 0x0D, 0x03, 0x06, 0x15, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_OVERSHOOT_CONFIG_REG */ + 0xA0, 0x0D, 0x06, 0x32, 0x4A, 0x53, 0x07, 0x01, 0x1B /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_SHAPE_CONTROL_REG */ + }; + + /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ + /* Following configuration relates to performance optimization of OM5578/PN7150 NFC Controller demo kit */ + uint8_t NxpNci_RF_CONF_2ndGen[] = { + 0x20, 0x02, 0x94, 0x11, + 0xA0, 0x0D, 0x06, 0x04, 0x35, 0x90, 0x01, 0xF4, 0x01, /* RF_CLIF_CFG_INITIATOR CLIF_AGC_INPUT_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x30, 0x01, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_SIGPRO_ADCBCM_THRESHOLD_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x02, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x20, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TECHNO_I_TX15693 CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x04, 0x22, 0x44, 0x23, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x22, 0x2D, 0x50, 0x34, 0x0C, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x32, 0x42, 0xF8, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0x24, 0x37, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x33, 0x86, 0x80, 0x00, 0x70, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_AGC_CONFIG0_REG */ + 0xA0, 0x0D, 0x04, 0x34, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x42, 0x2D, 0x15, 0x45, 0x0D, 0x00, /* RF_CLIF_CFG_BR_848_I_RXA CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x04, 0x46, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x46, 0x2D, 0x05, 0x59, 0x0E, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x44, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXB CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x56, 0x2D, 0x05, 0x9F, 0x0C, 0x00, /* RF_CLIF_CFG_BR_212_I_RXF_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x54, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_212_I_TXF CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x0A, 0x33, 0x80, 0x86, 0x00, 0x70 /* RF_CLIF_CFG_I_ACTIVE CLIF_AGC_CONFIG0_REG */ + }; +#endif - uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; - bool FirstCmd = true; +#if NXP_CLK_CONF + /* NXP-NCI CLOCK configuration + * Refer to NFC controller Hardware Design Guide document for more details + */ +#if (NXP_CLK_CONF == 1) + /* Xtal configuration */ + uint8_t NxpNci_CLK_CONF[] = { + 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x03, 0x01, 0x08 /* CLOCK_SEL_CFG */ + }; +#else + /* PLL configuration */ + uint8_t NxpNci_CLK_CONF[] = { + 0x20, 0x02, 0x09, 0x02, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x03, 0x01, 0x11, /* CLOCK_SEL_CFG */ + 0xA0, 0x04, 0x01, 0x01 /* CLOCK_TO_CFG */ + }; +#endif +#endif - /* Reset Card emulation state */ - T4T_NDEF_EMU_Reset(); + uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x00}; + uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; + bool gRfSettingsRestored_flag = false; - (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); - getMessage(2000); - //NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_2S) == NXPNCI_SUCCESS - - while (rxMessageLength > 0) - { - /* is RF_DEACTIVATE_NTF ? */ - if ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x06)) - { - if (FirstCmd) - { - /* Restart the discovery loop */ - //NxpNci_HostTransceive(NCIStopDiscovery, sizeof(NCIStopDiscovery), Answer, sizeof(Answer), &AnswerSize); - (void)writeData(NCIStartDiscovery, sizeof(NCIStopDiscovery)); - getMessage(); - do - { - if ((rxBuffer[0] == 0x41) && (rxBuffer[1] == 0x06)) - break; - //NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS); - (void)writeData(rxBuffer, rxMessageLength); - getMessage(100); - } while (rxMessageLength != 0); - //NxpNci_HostTransceive(NCIStartDiscovery, NCIStartDiscovery_length, Answer, sizeof(Answer), &AnswerSize); - (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); - getMessage(); - } - /* Come back to discovery state */ - break; - } - /* is DATA_PACKET ? */ - else if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) - { - /* DATA_PACKET */ - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; - uint16_t CmdSize; +#if (NXP_TVDD_CONF | NXP_RF_CONF) + uint8_t *NxpNci_CONF; + uint16_t NxpNci_CONF_size = 0; +#endif +#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) + uint8_t currentTS[32] = __TIMESTAMP__; + uint8_t NCIReadTS[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x14}; + uint8_t NCIWriteTS[7 + 32] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x14, 0x20}; +#endif + bool isResetRequired = false; - T4T_NDEF_EMU_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); + /* Apply settings */ +#if NXP_CORE_CONF + if (sizeof(NxpNci_CORE_CONF) != 0) { + isResetRequired = true; + (void)writeData(NxpNci_CORE_CONF, sizeof(NxpNci_CORE_CONF)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_CONF :D"); +#endif + return ERROR; + } + } +#endif - Cmd[0] = 0x00; - Cmd[1] = (CmdSize & 0xFF00) >> 8; - Cmd[2] = CmdSize & 0x00FF; +#if NXP_CORE_STANDBY + if (sizeof(NxpNci_CORE_STANDBY) != 0) { + (void)(writeData(NxpNci_CORE_STANDBY, sizeof(NxpNci_CORE_STANDBY))); + getMessage(); + if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_STANDBY"); +#endif + return ERROR; + } + } +#endif - //NxpNci_HostTransceive(Cmd, CmdSize+3, Answer, sizeof(Answer), &AnswerSize); - (void)writeData(Cmd, CmdSize + 3); - getMessage(); - } - FirstCmd = false; + /* All further settings are not versatile, so configuration only applied if there are changes (application build timestamp) + or in case of PN7150B0HN/C11004 Anti-tearing recovery procedure inducing RF setings were restored to their default value */ +#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) + /* First read timestamp stored in NFC Controller */ + if (gNfcController_generation == 1) + NCIReadTS[5] = 0x0F; + (void)writeData(NCIReadTS, sizeof(NCIReadTS)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("read timestamp "); +#endif + return ERROR; + } + /* Then compare with current build timestamp, and check RF setting restauration flag */ + /*if(!memcmp(&rxBuffer[8], currentTS, sizeof(currentTS)) && (gRfSettingsRestored_flag == false)) + { + // No change, nothing to do + } + else + { + */ + /* Apply settings */ +#if NXP_CORE_CONF_EXTN + if (sizeof(NxpNci_CORE_CONF_EXTN) != 0) { + (void)writeData(NxpNci_CORE_CONF_EXTN, sizeof(NxpNci_CORE_CONF_EXTN)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_CONF_EXTN"); +#endif + return ERROR; } -} + } +#endif -bool Electroniccats_PN7150::CardModeSend(unsigned char *pData, unsigned char DataSize) -{ - bool status; - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; - - /* Compute and send DATA_PACKET */ - Cmd[0] = 0x00; - Cmd[1] = 0x00; - Cmd[2] = DataSize; - memcpy(&Cmd[3], pData, DataSize); - (void)writeData(Cmd, DataSize + 3); - return status; -} +#if NXP_CLK_CONF + if (sizeof(NxpNci_CLK_CONF) != 0) { + isResetRequired = true; -bool Electroniccats_PN7150::CardModeReceive(unsigned char *pData, unsigned char *pDataSize) -{ - #ifdef DEBUG2 - Serial.println("[DEBUG] cardModeReceive exec"); - #endif - bool status = NFC_ERROR; - uint8_t Ans[MAX_NCI_FRAME_SIZE]; + (void)writeData(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF)); + getMessage(); + // NxpNci_HostTransceive(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF), Answer, sizeof(Answer), &AnswerSize); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CLK_CONF"); +#endif + return ERROR; + } + } +#endif - (void)writeData(Ans, 255); - getMessage(2000); +#if NXP_TVDD_CONF + if (NxpNci_CONF_size != 0) { + (void)writeData(NxpNci_TVDD_CONF_2ndGen, sizeof(NxpNci_TVDD_CONF_2ndGen)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CONF_size"); +#endif + return ERROR; + } + } +#endif - /* Is data packet ? */ - if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) - { +#if NXP_RF_CONF + if (NxpNci_CONF_size != 0) { + (void)writeData(NxpNci_RF_CONF_2ndGen, sizeof(NxpNci_RF_CONF_2ndGen)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CONF_size"); +#endif + return ERROR; + } + } +#endif + /* Store curent timestamp to NFC Controller memory for further checks */ + if (gNfcController_generation == 1) + NCIWriteTS[5] = 0x0F; + memcpy(&NCIWriteTS[7], currentTS, sizeof(currentTS)); + (void)writeData(NCIWriteTS, sizeof(NCIWriteTS)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NFC Controller memory"); +#endif + return ERROR; + } + //} +#endif - #ifdef DEBUG2 - Serial.println(rxBuffer[2]); - #endif - *pDataSize = rxBuffer[2]; - memcpy(pData, &rxBuffer[3], *pDataSize); - status = NFC_SUCCESS; + if (isResetRequired) { + /* Reset the NFC Controller to insure new settings apply */ + (void)writeData(NCICoreReset, sizeof(NCICoreReset)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("insure new settings apply"); +#endif + return ERROR; } - else - { - status = NFC_ERROR; + + (void)writeData(NCICoreInit, sizeof(NCICoreInit)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("insure new settings apply 2"); +#endif + return ERROR; } - return status; + } + return SUCCESS; } -void Electroniccats_PN7150::FillInterfaceInfo(RfIntf_t *pRfIntf, uint8_t *pBuf) -{ - uint8_t i, temp; - - switch (pRfIntf->ModeTech) - { - case (MODE_POLL | TECH_PASSIVE_NFCA): - memcpy(pRfIntf->Info.NFC_APP.SensRes, &pBuf[0], 2); - temp = 2; - pRfIntf->Info.NFC_APP.NfcIdLen = pBuf[temp]; - temp++; - memcpy(pRfIntf->Info.NFC_APP.NfcId, &pBuf[3], pRfIntf->Info.NFC_APP.NfcIdLen); - temp += pBuf[2]; - pRfIntf->Info.NFC_APP.SelResLen = pBuf[temp]; - temp++; - - if (pRfIntf->Info.NFC_APP.SelResLen == 1) - pRfIntf->Info.NFC_APP.SelRes[0] = pBuf[temp]; - - temp += 4; - if (pBuf[temp] != 0) - { - temp++; - pRfIntf->Info.NFC_APP.RatsLen = pBuf[temp]; - memcpy(pRfIntf->Info.NFC_APP.Rats, &pBuf[temp + 1], pBuf[temp]); - } - else - { - pRfIntf->Info.NFC_APP.RatsLen = 0; - } - break; - - case (MODE_POLL | TECH_PASSIVE_NFCB): - pRfIntf->Info.NFC_BPP.SensResLen = pBuf[0]; - memcpy(pRfIntf->Info.NFC_BPP.SensRes, &pBuf[1], pRfIntf->Info.NFC_BPP.SensResLen); - temp = pBuf[0] + 4; - if (pBuf[temp] != 0) - { - temp++; - pRfIntf->Info.NFC_BPP.AttribResLen = pBuf[temp]; - memcpy(pRfIntf->Info.NFC_BPP.AttribRes, &pBuf[temp + 1], pBuf[temp]); - } - else - { - pRfIntf->Info.NFC_BPP.AttribResLen = 0; - } - break; +// Deprecated, use configureSettings(void) instead +bool Electroniccats_PN7150::ConfigureSettings(void) { + return Electroniccats_PN7150::configureSettings(); +} + +bool Electroniccats_PN7150::configureSettings(uint8_t *uidcf, uint8_t uidlen) { +#if NXP_CORE_CONF + /* NCI standard dedicated settings + * Refer to NFC Forum NCI standard for more details + */ + uint8_t NxpNci_CORE_CONF[20] = { + 0x20, 0x02, 0x05, 0x01, // CORE_SET_CONFIG_CMD + 0x00, 0x02, 0x00, 0x01 // TOTAL_DURATION + }; + + if (uidlen == 0) + uidlen = 8; + else { + uidlen += 10; + memcpy(&NxpNci_CORE_CONF[0], uidcf, uidlen); + } - case (MODE_POLL | TECH_PASSIVE_NFCF): - pRfIntf->Info.NFC_FPP.BitRate = pBuf[0]; - pRfIntf->Info.NFC_FPP.SensResLen = pBuf[1]; - memcpy(pRfIntf->Info.NFC_FPP.SensRes, &pBuf[2], pRfIntf->Info.NFC_FPP.SensResLen); - break; +#endif - case (MODE_POLL | TECH_PASSIVE_15693): - pRfIntf->Info.NFC_VPP.AFI = pBuf[0]; - pRfIntf->Info.NFC_VPP.DSFID = pBuf[1]; +#if NXP_CORE_CONF_EXTN + /* NXP-NCI extension dedicated setting + * Refer to NFC controller User Manual for more details + */ + uint8_t NxpNci_CORE_CONF_EXTN[] = { + 0x20, 0x02, 0x0D, 0x03, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x40, 0x01, 0x00, /* TAG_DETECTOR_CFG */ + 0xA0, 0x41, 0x01, 0x04, /* TAG_DETECTOR_THRESHOLD_CFG */ + 0xA0, 0x43, 0x01, 0x00 /* TAG_DETECTOR_FALLBACK_CNT_CFG */ + }; +#endif - for (i = 0; i < 8; i++) - pRfIntf->Info.NFC_VPP.ID[7 - i] = pBuf[2 + i]; +#if NXP_CORE_STANDBY + /* NXP-NCI standby enable setting + * Refer to NFC controller User Manual for more details + */ + uint8_t NxpNci_CORE_STANDBY[] = {0x2F, 0x00, 0x01, 0x01}; /* last byte indicates enable/disable */ +#endif - break; +#if NXP_TVDD_CONF + /* NXP-NCI TVDD configuration + * Refer to NFC controller Hardware Design Guide document for more details + */ + /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ + uint8_t NxpNci_TVDD_CONF_1stGen[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x13, 0x01, 0x00}; - default: - break; - } -} + /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ +#if (NXP_TVDD_CONF == 1) + /* CFG1: Vbat is used to generate the VDD(TX) through TXLDO */ + uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x02, 0x09, 0x00}; +#else + /* CFG2: external 5V is used to generate the VDD(TX) through TXLDO */ + uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x06, 0x64, 0x00}; +#endif +#endif -bool Electroniccats_PN7150::ReaderTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize) -{ - bool status = ERROR; - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; +#if NXP_RF_CONF + /* NXP-NCI RF configuration + * Refer to NFC controller Antenna Design and Tuning Guidelines document for more details + */ + /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ + /* Following configuration is the default settings of PN7120 NFC Controller */ + uint8_t NxpNci_RF_CONF_1stGen[] = { + 0x20, 0x02, 0x38, 0x07, + 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x01, 0x00, 0xF1, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x44, 0xA3, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0xDC, 0x50, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x04, 0x06, 0x03, 0x00, 0x70, /* RF_CLIF_CFG_TARGET CLIF_TRANSCEIVE_CONTROL_REG */ + 0xA0, 0x0D, 0x03, 0x06, 0x16, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_UNDERSHOOT_CONFIG_REG */ + 0xA0, 0x0D, 0x03, 0x06, 0x15, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_OVERSHOOT_CONFIG_REG */ + 0xA0, 0x0D, 0x06, 0x32, 0x4A, 0x53, 0x07, 0x01, 0x1B /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_SHAPE_CONTROL_REG */ + }; + + /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ + /* Following configuration relates to performance optimization of OM5578/PN7150 NFC Controller demo kit */ + uint8_t NxpNci_RF_CONF_2ndGen[] = { + 0x20, 0x02, 0x94, 0x11, + 0xA0, 0x0D, 0x06, 0x04, 0x35, 0x90, 0x01, 0xF4, 0x01, /* RF_CLIF_CFG_INITIATOR CLIF_AGC_INPUT_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x30, 0x01, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_SIGPRO_ADCBCM_THRESHOLD_REG */ + 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x02, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x20, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TECHNO_I_TX15693 CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x04, 0x22, 0x44, 0x23, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x22, 0x2D, 0x50, 0x34, 0x0C, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x32, 0x42, 0xF8, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0x24, 0x37, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x34, 0x33, 0x86, 0x80, 0x00, 0x70, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_AGC_CONFIG0_REG */ + 0xA0, 0x0D, 0x04, 0x34, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x42, 0x2D, 0x15, 0x45, 0x0D, 0x00, /* RF_CLIF_CFG_BR_848_I_RXA CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x04, 0x46, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_ANA_RX_REG */ + 0xA0, 0x0D, 0x06, 0x46, 0x2D, 0x05, 0x59, 0x0E, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x44, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXB CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x56, 0x2D, 0x05, 0x9F, 0x0C, 0x00, /* RF_CLIF_CFG_BR_212_I_RXF_P CLIF_SIGPRO_RM_CONFIG1_REG */ + 0xA0, 0x0D, 0x06, 0x54, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_212_I_TXF CLIF_ANA_TX_AMPLITUDE_REG */ + 0xA0, 0x0D, 0x06, 0x0A, 0x33, 0x80, 0x86, 0x00, 0x70 /* RF_CLIF_CFG_I_ACTIVE CLIF_AGC_CONFIG0_REG */ + }; +#endif - /* Compute and send DATA_PACKET */ - Cmd[0] = 0x00; - Cmd[1] = 0x00; - Cmd[2] = CommandSize; - memcpy(&Cmd[3], pCommand, CommandSize); +#if NXP_CLK_CONF + /* NXP-NCI CLOCK configuration + * Refer to NFC controller Hardware Design Guide document for more details + */ +#if (NXP_CLK_CONF == 1) + /* Xtal configuration */ + uint8_t NxpNci_CLK_CONF[] = { + 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x03, 0x01, 0x08 /* CLOCK_SEL_CFG */ + }; +#else + /* PLL configuration */ + uint8_t NxpNci_CLK_CONF[] = { + 0x20, 0x02, 0x09, 0x02, /* CORE_SET_CONFIG_CMD */ + 0xA0, 0x03, 0x01, 0x11, /* CLOCK_SEL_CFG */ + 0xA0, 0x04, 0x01, 0x01 /* CLOCK_TO_CFG */ + }; +#endif +#endif - (void)writeData(Cmd, CommandSize + 3); - getMessage(); - getMessage(1000); - /* Wait for Answer 1S */ + uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x00}; + uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; + bool gRfSettingsRestored_flag = false; - if ((rxBuffer[0] == 0x0) && (rxBuffer[1] == 0x0)) - status = SUCCESS; +#if (NXP_TVDD_CONF | NXP_RF_CONF) + uint8_t *NxpNci_CONF; + uint16_t NxpNci_CONF_size = 0; +#endif +#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) + uint8_t currentTS[32] = __TIMESTAMP__; + uint8_t NCIReadTS[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x14}; + uint8_t NCIWriteTS[7 + 32] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x14, 0x20}; +#endif + bool isResetRequired = false; - *pAnswerSize = rxBuffer[2]; - memcpy(pAnswer, &rxBuffer[3], *pAnswerSize); + /* Apply settings */ +#if NXP_CORE_CONF + if (uidlen != 0) // sizeof(NxpNci_CORE_CONF) != 0) + { + isResetRequired = true; + (void)writeData(NxpNci_CORE_CONF, uidlen); // sizeof(NxpNci_CORE_CONF)); + getMessage(100); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_CONF"); +#endif + return ERROR; + } + } +#endif - return status; -} +#if NXP_CORE_STANDBY + if (sizeof(NxpNci_CORE_STANDBY) != 0) { + (void)(writeData(NxpNci_CORE_STANDBY, sizeof(NxpNci_CORE_STANDBY))); + getMessage(); + if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_STANDBY"); +#endif + return ERROR; + } + } +#endif -bool Electroniccats_PN7150::WaitForDiscoveryNotification(RfIntf_t *pRfIntf, uint8_t tout) -{ - uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x01, PROT_ISODEP, INTF_ISODEP}; + /* All further settings are not versatile, so configuration only applied if there are changes (application build timestamp) + or in case of PN7150B0HN/C11004 Anti-tearing recovery procedure inducing RF setings were restored to their default value */ +#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) + /* First read timestamp stored in NFC Controller */ + if (gNfcController_generation == 1) + NCIReadTS[5] = 0x0F; + (void)writeData(NCIReadTS, sizeof(NCIReadTS)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("read timestamp "); +#endif + return ERROR; + } + /* Then compare with current build timestamp, and check RF setting restauration flag */ + /*if(!memcmp(&rxBuffer[8], currentTS, sizeof(currentTS)) && (gRfSettingsRestored_flag == false)) + { + // No change, nothing to do + } + else + { + */ + /* Apply settings */ +#if NXP_CORE_CONF_EXTN + if (sizeof(NxpNci_CORE_CONF_EXTN) != 0) { + (void)writeData(NxpNci_CORE_CONF_EXTN, sizeof(NxpNci_CORE_CONF_EXTN)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CORE_CONF_EXTN"); +#endif + return ERROR; + } + } +#endif - //P2P Support - uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; - uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03}; - uint8_t saved_NTF[7]; +#if NXP_CLK_CONF + if (sizeof(NxpNci_CLK_CONF) != 0) { + isResetRequired = true; - gNextTag_Protocol = PROT_UNDETERMINED; - bool getFlag = false; -wait: - do - { - getFlag = getMessage( - tout > 0 ? tout : 1337 - ); //Infinite loop, waiting for response - } while (((rxBuffer[0] != 0x61) || ((rxBuffer[1] != 0x05) && (rxBuffer[1] != 0x03))) && (getFlag == true)); - gNextTag_Protocol = PROT_UNDETERMINED; - - /* Is RF_INTF_ACTIVATED_NTF ? */ - if (rxBuffer[1] == 0x05) - { - pRfIntf->Interface = rxBuffer[4]; - pRfIntf->Protocol = rxBuffer[5]; - pRfIntf->ModeTech = rxBuffer[6]; - pRfIntf->MoreTags = false; - FillInterfaceInfo(pRfIntf, &rxBuffer[10]); - - //P2P - /* Verifying if not a P2P device also presenting T4T emulation */ - if ((pRfIntf->Interface == INTF_ISODEP) && (pRfIntf->Protocol == PROT_ISODEP) && ((pRfIntf->ModeTech & MODE_LISTEN) != MODE_LISTEN)) - { - memcpy(saved_NTF, rxBuffer, sizeof(saved_NTF)); - while (1) - { - /* Restart the discovery loop */ - (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); - getMessage(); - getMessage(100); - /* Wait for discovery */ - do - { - getMessage(1000); //Infinite loop, waiting for response - } while ((rxMessageLength == 4) && (rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x07)); - - if ((rxMessageLength != 0) && (rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x05)) - { - /* Is same device detected ? */ - if (memcmp(saved_NTF, rxBuffer, sizeof(saved_NTF)) == 0) - break; - /* Is P2P detected ? */ - if (rxBuffer[5] == PROT_NFCDEP) - { - pRfIntf->Interface = rxBuffer[4]; - pRfIntf->Protocol = rxBuffer[5]; - pRfIntf->ModeTech = rxBuffer[6]; - pRfIntf->MoreTags = false; - FillInterfaceInfo(pRfIntf, &rxBuffer[10]); - break; - } - } - else - { - if (rxMessageLength != 0) - { - /* Flush any other notification */ - while (rxMessageLength != 0) - getMessage(100); - - /* Restart the discovery loop */ - (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); - getMessage(); - getMessage(100); - } - goto wait; - } - } - } + (void)writeData(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF)); + getMessage(); + // NxpNci_HostTransceive(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF), Answer, sizeof(Answer), &AnswerSize); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CLK_CONF"); +#endif + return ERROR; } - else - { /* RF_DISCOVER_NTF */ - pRfIntf->Interface = INTF_UNDETERMINED; - pRfIntf->Protocol = rxBuffer[4]; - pRfIntf->ModeTech = rxBuffer[5]; - pRfIntf->MoreTags = true; - - /* Get next NTF for further activation */ - do - { - if (!getMessage(100)) - return ERROR; - } while ((rxBuffer[0] != 0x61) || (rxBuffer[1] != 0x03)); - gNextTag_Protocol = rxBuffer[4]; - - /* Remaining NTF ? */ - - while (rxBuffer[rxMessageLength - 1] == 0x02) - getMessage(100); + } +#endif - /* In case of multiple cards, select the first one */ - NCIRfDiscoverSelect[4] = pRfIntf->Protocol; - if (pRfIntf->Protocol == PROT_ISODEP) - NCIRfDiscoverSelect[5] = INTF_ISODEP; - else if (pRfIntf->Protocol == PROT_NFCDEP) - NCIRfDiscoverSelect[5] = INTF_NFCDEP; - else if (pRfIntf->Protocol == PROT_MIFARE) - NCIRfDiscoverSelect[5] = INTF_TAGCMD; - else - NCIRfDiscoverSelect[5] = INTF_FRAME; - - (void)writeData(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect)); - getMessage(100); +#if NXP_TVDD_CONF + if (NxpNci_CONF_size != 0) { + (void)writeData(NxpNci_TVDD_CONF_2ndGen, sizeof(NxpNci_TVDD_CONF_2ndGen)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CONF_size"); +#endif + return ERROR; + } + } +#endif - if ((rxBuffer[0] == 0x41) || (rxBuffer[1] == 0x04) || (rxBuffer[3] == 0x00)) - { - (void)writeData(rxBuffer, rxMessageLength); - getMessage(100); +#if NXP_RF_CONF + if (NxpNci_CONF_size != 0) { + (void)writeData(NxpNci_RF_CONF_2ndGen, sizeof(NxpNci_RF_CONF_2ndGen)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NxpNci_CONF_size"); +#endif + return ERROR; + } + } +#endif + /* Store curent timestamp to NFC Controller memory for further checks */ + if (gNfcController_generation == 1) + NCIWriteTS[5] = 0x0F; + memcpy(&NCIWriteTS[7], currentTS, sizeof(currentTS)); + (void)writeData(NCIWriteTS, sizeof(NCIWriteTS)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) { +#ifdef SerialUSB + Serial.println("NFC Controller memory"); +#endif + return ERROR; + } + //} +#endif - if ((rxBuffer[0] == 0x61) || (rxBuffer[1] == 0x05)) - { - pRfIntf->Interface = rxBuffer[4]; - pRfIntf->Protocol = rxBuffer[5]; - pRfIntf->ModeTech = rxBuffer[6]; - FillInterfaceInfo(pRfIntf, &rxBuffer[10]); - } - - /* In case of P2P target detected but lost, inform application to restart discovery */ - else if (pRfIntf->Protocol == PROT_NFCDEP) - { - /* Restart the discovery loop */ - (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); - getMessage(); - getMessage(100); - - (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); - getMessage(); - - goto wait; - } - } + if (isResetRequired) { + /* Reset the NFC Controller to insure new settings apply */ + (void)writeData(NCICoreReset, sizeof(NCICoreReset)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("insure new settings apply"); +#endif + return ERROR; } - /* In case of unknown target align protocol information */ - if (pRfIntf->Interface == INTF_UNDETERMINED) - pRfIntf->Protocol = PROT_UNDETERMINED; + (void)writeData(NCICoreInit, sizeof(NCICoreInit)); + getMessage(); + if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) { +#ifdef SerialUSB + Serial.println("insure new settings apply 2"); +#endif + return ERROR; + } + } + return SUCCESS; +} + +// Deprecated, use configureSettings() instead +bool Electroniccats_PN7150::ConfigureSettings(uint8_t *uidcf, uint8_t uidlen) { + return Electroniccats_PN7150::configureSettings(uidcf, uidlen); +} +uint8_t Electroniccats_PN7150::StartDiscovery(uint8_t modeSE) { + int mode = Electroniccats_PN7150::getMode(); + if (mode != modeSE) { + Electroniccats_PN7150::setMode(modeSE); + Electroniccats_PN7150::configMode(); + } + + unsigned char TechTabSize = (modeSE == 1 ? sizeof(DiscoveryTechnologiesRW) : modeSE == 2 ? sizeof(DiscoveryTechnologiesCE) + : sizeof(DiscoveryTechnologiesP2P)); + + NCIStartDiscovery_length = 0; + NCIStartDiscovery[0] = 0x21; + NCIStartDiscovery[1] = 0x03; + NCIStartDiscovery[2] = (TechTabSize * 2) + 1; + NCIStartDiscovery[3] = TechTabSize; + for (uint8_t i = 0; i < TechTabSize; i++) { + NCIStartDiscovery[(i * 2) + 4] = (modeSE == 1 ? DiscoveryTechnologiesRW[i] : modeSE == 2 ? DiscoveryTechnologiesCE[i] + : DiscoveryTechnologiesP2P[i]); + + NCIStartDiscovery[(i * 2) + 5] = 0x01; + } + + NCIStartDiscovery_length = (TechTabSize * 2) + 4; + (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); + getMessage(); + + if ((rxBuffer[0] != 0x41) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) + return ERROR; + else return SUCCESS; } -void Electroniccats_PN7150::ProcessP2pMode(RfIntf_t RfIntf) -{ - uint8_t status = ERROR; - bool restart = false; - uint8_t NCILlcpSymm[] = {0x00, 0x00, 0x02, 0x00, 0x00}; - uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03}; - - /* Reset P2P_NDEF state */ - P2P_NDEF_Reset(); - - /* Is Initiator mode ? */ - if ((RfIntf.ModeTech & MODE_LISTEN) != MODE_LISTEN) - { - /* Initiate communication (SYMM PDU) */ - (void)writeData(NCILlcpSymm, sizeof(NCILlcpSymm)); - getMessage(); +uint8_t Electroniccats_PN7150::startDiscovery() { + int mode = Electroniccats_PN7150::getMode(); + return Electroniccats_PN7150::StartDiscovery(mode); +} - /* Save status for discovery restart */ - restart = true; - } - status = ERROR; - getMessage(2000); - if (rxMessageLength > 0) - status = SUCCESS; +bool Electroniccats_PN7150::stopDiscovery() { + uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; - /* Get frame from remote peer */ - while (status == SUCCESS) - { - /* is DATA_PACKET ? */ - if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) - { - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; - uint16_t CmdSize; - /* Handle P2P communication */ - P2P_NDEF_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); - /* Compute DATA_PACKET to answer */ - Cmd[0] = 0x00; - Cmd[1] = (CmdSize & 0xFF00) >> 8; - Cmd[2] = CmdSize & 0x00FF; - status = ERROR; - (void)writeData(Cmd, CmdSize + 3); - getMessage(); - if (rxMessageLength > 0) - status = SUCCESS; - } - /* is CORE_INTERFACE_ERROR_NTF ?*/ - else if ((rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x08)) - { - /* Come back to discovery state */ - break; - } - /* is RF_DEACTIVATE_NTF ? */ - else if ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x06)) - { - /* Come back to discovery state */ - break; - } - /* is RF_DISCOVERY_NTF ? */ - else if ((rxBuffer[0] == 0x61) && ((rxBuffer[1] == 0x05) || (rxBuffer[1] == 0x03))) - { - do - { - if ((rxBuffer[0] == 0x61) && ((rxBuffer[1] == 0x05) || (rxBuffer[1] == 0x03))) - { - if ((rxBuffer[6] & MODE_LISTEN) != MODE_LISTEN) - restart = true; - else - restart = false; - } - status = ERROR; - (void)writeData(rxBuffer, rxMessageLength); - getMessage(); - if (rxMessageLength > 0) - status = SUCCESS; - } while (rxMessageLength != 0); - /* Come back to discovery state */ - break; - } + (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); + getMessage(); + getMessage(1000); - /* Wait for next frame from remote P2P, or notification event */ - status = ERROR; - (void)writeData(rxBuffer, rxMessageLength); - getMessage(); - if (rxMessageLength > 0) - status = SUCCESS; - } + return SUCCESS; +} - /* Is Initiator mode ? */ - if (restart) - { - /* Communication ended, restart discovery loop */ - (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); - getMessage(); - getMessage(100); - } +// Deprecated, use stopDiscovery() instead +bool Electroniccats_PN7150::StopDiscovery() { + return Electroniccats_PN7150::stopDiscovery(); } -void Electroniccats_PN7150::ReadNdef(RfIntf_t RfIntf) -{ - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; - uint16_t CmdSize = 0; +bool Electroniccats_PN7150::WaitForDiscoveryNotification(RfIntf_t *pRfIntf, uint16_t tout) { + uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x01, protocol.ISODEP, interface.ISODEP}; - RW_NDEF_Reset(RfIntf.Protocol); + // P2P Support + uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; + uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03}; + uint8_t saved_NTF[7]; - while (1) - { - RW_NDEF_Read_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); - if (CmdSize == 0) - { - /// End of the Read operation + gNextTag_Protocol = PROT_UNDETERMINED; + bool getFlag = false; +wait: + do { + getFlag = getMessage( + tout > 0 ? tout : 1337); // Infinite loop, waiting for response + } while (((rxBuffer[0] != 0x61) || ((rxBuffer[1] != 0x05) && (rxBuffer[1] != 0x03))) && (getFlag == true)); + gNextTag_Protocol = PROT_UNDETERMINED; + + /* Is RF_INTF_ACTIVATED_NTF ? */ + if (rxBuffer[1] == 0x05) { + pRfIntf->Interface = rxBuffer[4]; + remoteDevice.setInterface(rxBuffer[4]); + pRfIntf->Protocol = rxBuffer[5]; + remoteDevice.setProtocol(rxBuffer[5]); + pRfIntf->ModeTech = rxBuffer[6]; + remoteDevice.setModeTech(rxBuffer[6]); + pRfIntf->MoreTags = false; + remoteDevice.setMoreTagsAvailable(false); + remoteDevice.setInfo(pRfIntf, &rxBuffer[10]); + + // P2P + /* Verifying if not a P2P device also presenting T4T emulation */ + if ((pRfIntf->Interface == INTF_ISODEP) && (pRfIntf->Protocol == PROT_ISODEP) && ((pRfIntf->ModeTech & MODE_LISTEN) != MODE_LISTEN)) { + memcpy(saved_NTF, rxBuffer, sizeof(saved_NTF)); + while (1) { + /* Restart the discovery loop */ + (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); + getMessage(); + getMessage(100); + /* Wait for discovery */ + do { + getMessage(1000); // Infinite loop, waiting for response + } while ((rxMessageLength == 4) && (rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x07)); + + if ((rxMessageLength != 0) && (rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x05)) { + /* Is same device detected ? */ + if (memcmp(saved_NTF, rxBuffer, sizeof(saved_NTF)) == 0) break; - } - else - { - // Compute and send DATA_PACKET - Cmd[0] = 0x00; - Cmd[1] = (CmdSize & 0xFF00) >> 8; - Cmd[2] = CmdSize & 0x00FF; - - (void)writeData(Cmd, CmdSize + 3); + /* Is P2P detected ? */ + if (rxBuffer[5] == PROT_NFCDEP) { + pRfIntf->Interface = rxBuffer[4]; + remoteDevice.setInterface(rxBuffer[4]); + pRfIntf->Protocol = rxBuffer[5]; + remoteDevice.setProtocol(rxBuffer[5]); + pRfIntf->ModeTech = rxBuffer[6]; + remoteDevice.setModeTech(rxBuffer[6]); + pRfIntf->MoreTags = false; + remoteDevice.setMoreTagsAvailable(false); + remoteDevice.setInfo(pRfIntf, &rxBuffer[10]); + break; + } + } else { + if (rxMessageLength != 0) { + /* Flush any other notification */ + while (rxMessageLength != 0) + getMessage(100); + + /* Restart the discovery loop */ + (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); getMessage(); - getMessage(1000); - - // Manage chaining in case of T4T - if ((RfIntf.Interface = INTF_ISODEP) && rxBuffer[0] == 0x10) - { - uint8_t tmp[MAX_NCI_FRAME_SIZE]; - uint8_t tmpSize = 0; - while (rxBuffer[0] == 0x10) - { - memcpy(&tmp[tmpSize], &rxBuffer[3], rxBuffer[2]); - tmpSize += rxBuffer[2]; - getMessage(100); - } - memcpy(&tmp[tmpSize], &rxBuffer[3], rxBuffer[2]); - tmpSize += rxBuffer[2]; - //* Compute all chained frame into one unique answer - memcpy(&rxBuffer[3], tmp, tmpSize); - rxBuffer[2] = tmpSize; - } + getMessage(100); + } + goto wait; } + } } -} + } else { /* RF_DISCOVER_NTF */ + pRfIntf->Interface = INTF_UNDETERMINED; + remoteDevice.setInterface(interface.UNDETERMINED); + pRfIntf->Protocol = rxBuffer[4]; + remoteDevice.setProtocol(rxBuffer[4]); + pRfIntf->ModeTech = rxBuffer[5]; + remoteDevice.setModeTech(rxBuffer[5]); + pRfIntf->MoreTags = true; + remoteDevice.setMoreTagsAvailable(true); + + /* Get next NTF for further activation */ + do { + if (!getMessage(100)) + return ERROR; + } while ((rxBuffer[0] != 0x61) || (rxBuffer[1] != 0x03)); + gNextTag_Protocol = rxBuffer[4]; + + /* Remaining NTF ? */ + + while (rxBuffer[rxMessageLength - 1] == 0x02) + getMessage(100); + + /* In case of multiple cards, select the first one */ + NCIRfDiscoverSelect[4] = remoteDevice.getProtocol(); + if (remoteDevice.getProtocol() == protocol.ISODEP) + NCIRfDiscoverSelect[5] = interface.ISODEP; + else if (remoteDevice.getProtocol() == protocol.NFCDEP) + NCIRfDiscoverSelect[5] = interface.NFCDEP; + else if (remoteDevice.getProtocol() == protocol.MIFARE) + NCIRfDiscoverSelect[5] = interface.TAGCMD; + else + NCIRfDiscoverSelect[5] = interface.FRAME; -void Electroniccats_PN7150::WriteNdef(RfIntf_t RfIntf) -{ + (void)writeData(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect)); + getMessage(100); - uint8_t Cmd[MAX_NCI_FRAME_SIZE]; - uint16_t CmdSize = 0; + if ((rxBuffer[0] == 0x41) || (rxBuffer[1] == 0x04) || (rxBuffer[3] == 0x00)) { + (void)writeData(rxBuffer, rxMessageLength); + getMessage(100); - RW_NDEF_Reset(RfIntf.Protocol); + if ((rxBuffer[0] == 0x61) || (rxBuffer[1] == 0x05)) { + pRfIntf->Interface = rxBuffer[4]; + remoteDevice.setInterface(rxBuffer[4]); + pRfIntf->Protocol = rxBuffer[5]; + remoteDevice.setProtocol(rxBuffer[5]); + pRfIntf->ModeTech = rxBuffer[6]; + remoteDevice.setModeTech(rxBuffer[6]); + remoteDevice.setInfo(pRfIntf, &rxBuffer[10]); + } + + /* In case of P2P target detected but lost, inform application to restart discovery */ + else if (remoteDevice.getProtocol() == protocol.NFCDEP) { + /* Restart the discovery loop */ + (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); + getMessage(); + getMessage(100); - while (1) - { - RW_NDEF_Write_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); - if (CmdSize == 0) - { - // End of the Write operation - break; - } - else - { - // Compute and send DATA_PACKET - Cmd[0] = 0x00; - Cmd[1] = (CmdSize & 0xFF00) >> 8; - Cmd[2] = CmdSize & 0x00FF; - - (void)writeData(Cmd, CmdSize + 3); - getMessage(); - getMessage(2000); - } - } -} + (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); + getMessage(); -void Electroniccats_PN7150::ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation) -{ - switch (Operation) - { - case READ_NDEF: - ReadNdef(RfIntf); - break; - case WRITE_NDEF: - WriteNdef(RfIntf); - break; - case PRESENCE_CHECK: - PresenceCheck(RfIntf); - break; - default: - break; + goto wait; + } } + } + + /* In case of unknown target align protocol information */ + if (remoteDevice.getInterface() == interface.UNDETERMINED) { + pRfIntf->Protocol = PROT_UNDETERMINED; + remoteDevice.setProtocol(protocol.UNDETERMINED); + } + + return SUCCESS; } -void Electroniccats_PN7150::PresenceCheck(RfIntf_t RfIntf) -{ - bool status; - uint8_t i; - - uint8_t NCIPresCheckT1T[] = {0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t NCIPresCheckT2T[] = {0x00, 0x00, 0x02, 0x30, 0x00}; - uint8_t NCIPresCheckT3T[] = {0x21, 0x08, 0x04, 0xFF, 0xFF, 0x00, 0x01}; - uint8_t NCIPresCheckIsoDep[] = {0x2F, 0x11, 0x00}; - uint8_t NCIPresCheckIso15693[] = {0x00, 0x00, 0x0B, 0x26, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01}; - uint8_t NCISelectMIFARE[] = {0x21, 0x04, 0x03, 0x01, 0x80, 0x80}; - - switch (RfIntf.Protocol) - { - case PROT_T1T: - do - { - delay(500); - (void)writeData(NCIPresCheckT1T, sizeof(NCIPresCheckT1T)); - getMessage(); - getMessage(100); - } while ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)); - break; +bool Electroniccats_PN7150::isTagDetected(uint16_t tout) { + return !Electroniccats_PN7150::WaitForDiscoveryNotification(&this->dummyRfInterface, tout); +} - case PROT_T2T: - do - { - delay(500); - (void)writeData(NCIPresCheckT2T, sizeof(NCIPresCheckT2T)); - getMessage(); - getMessage(100); - } while ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00) && (rxBuffer[2] == 0x11)); - break; +bool Electroniccats_PN7150::cardModeSend(unsigned char *pData, unsigned char DataSize) { + bool status; + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; + + /* Compute and send DATA_PACKET */ + Cmd[0] = 0x00; + Cmd[1] = 0x00; + Cmd[2] = DataSize; + memcpy(&Cmd[3], pData, DataSize); + (void)writeData(Cmd, DataSize + 3); + return status; +} - case PROT_T3T: - do - { - delay(500); - (void)writeData(NCIPresCheckT3T, sizeof(NCIPresCheckT3T)); - getMessage(); - getMessage(100); - } while ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x08) && ((rxBuffer[3] == 0x00) || (rxBuffer[4] > 0x00))); - break; +// Deprecated, use cardModeSend() instead +bool Electroniccats_PN7150::CardModeSend(unsigned char *pData, unsigned char DataSize) { + return Electroniccats_PN7150::cardModeSend(pData, DataSize); +} - case PROT_ISODEP: - do - { - delay(500); - (void)writeData(NCIPresCheckIsoDep, sizeof(NCIPresCheckIsoDep)); - getMessage(); - getMessage(100); - } while ((rxBuffer[0] == 0x6F) && (rxBuffer[1] == 0x11) && (rxBuffer[2] == 0x01) && (rxBuffer[3] == 0x01)); - break; +bool Electroniccats_PN7150::cardModeReceive(unsigned char *pData, unsigned char *pDataSize) { +#ifdef DEBUG2 + Serial.println("[DEBUG] cardModeReceive exec"); +#endif +#ifdef DEBUG3 + Serial.println("[DEBUG] cardModeReceive exec"); +#endif - case PROT_ISO15693: - do - { - delay(500); - for (i = 0; i < 8; i++) - NCIPresCheckIso15693[i + 6] = RfIntf.Info.NFC_VPP.ID[7 - i]; - (void)writeData(NCIPresCheckIso15693, sizeof(NCIPresCheckIso15693)); - getMessage(); - getMessage(100); - status = ERROR; - if (rxMessageLength) - status = SUCCESS; - } while ((status == SUCCESS) && (rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00) && (rxBuffer[rxMessageLength - 1] == 0x00)); - break; + delay(1); - case PROT_MIFARE: - do - { - delay(500); - /* Deactivate target */ - (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); - getMessage(); - getMessage(100); + bool status = NFC_ERROR; + uint8_t Ans[MAX_NCI_FRAME_SIZE]; - /* Reactivate target */ - (void)writeData(NCISelectMIFARE, sizeof(NCISelectMIFARE)); - getMessage(); - getMessage(100); - } while ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x05)); - break; + (void)writeData(Ans, 255); + getMessage(2000); - default: - /* Nothing to do */ - break; - } + /* Is data packet ? */ + if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) { +#ifdef DEBUG2 + Serial.println(rxBuffer[2]); +#endif + *pDataSize = rxBuffer[2]; + memcpy(pData, &rxBuffer[3], *pDataSize); + status = NFC_SUCCESS; + } else { + status = NFC_ERROR; + } + return status; } -bool Electroniccats_PN7150::ReaderReActivate(RfIntf_t *pRfIntf) -{ - uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01}; - uint8_t NCIActivate[] = {0x21, 0x04, 0x03, 0x01, 0x00, 0x00}; +// Deprecated, use cardModeReceive() instead +bool Electroniccats_PN7150::CardModeReceive(unsigned char *pData, unsigned char *pDataSize) { + return Electroniccats_PN7150::cardModeReceive(pData, pDataSize); +} - /* First de-activate the target */ - (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); - getMessage(); - getMessage(100); +void Electroniccats_PN7150::ProcessCardMode(RfIntf_t RfIntf) { + uint8_t Answer[MAX_NCI_FRAME_SIZE]; - /* Then re-activate the target */ - NCIActivate[4] = pRfIntf->Protocol; - NCIActivate[5] = pRfIntf->Interface; + uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; + bool FirstCmd = true; - (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); - getMessage(); - getMessage(100); + /* Reset Card emulation state */ + T4T_NDEF_EMU_Reset(); - if ((rxBuffer[0] != 0x61) || (rxBuffer[1] != 0x05)) - return ERROR; - return SUCCESS; -} + getMessage(2000); -bool Electroniccats_PN7150::ReaderActivateNext(RfIntf_t *pRfIntf) -{ - uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x01}; - uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x02, PROT_ISODEP, INTF_ISODEP}; + while (rxMessageLength > 0) { + getMessage(2000); + /* is RF_DEACTIVATE_NTF ? */ + if ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x06)) { + if (FirstCmd) { + /* Restart the discovery loop */ + (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); + getMessage(); + do { + if ((rxBuffer[0] == 0x41) && (rxBuffer[1] == 0x06)) + break; + getMessage(100); + } while (rxMessageLength != 0); + (void)writeData(NCIStartDiscovery, NCIStartDiscovery_length); + getMessage(); + } + /* Come back to discovery state */ + } + /* is DATA_PACKET ? */ + else if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) { + /* DATA_PACKET */ + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; + uint16_t CmdSize; - bool status = ERROR; + T4T_NDEF_EMU_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); - pRfIntf->MoreTags = false; + Cmd[0] = 0x00; + Cmd[1] = (CmdSize & 0xFF00) >> 8; + Cmd[2] = CmdSize & 0x00FF; - if (gNextTag_Protocol == PROT_UNDETERMINED) - { - pRfIntf->Interface = INTF_UNDETERMINED; - pRfIntf->Protocol = PROT_UNDETERMINED; - return ERROR; + (void)writeData(Cmd, CmdSize + 3); + getMessage(); } + FirstCmd = false; + } +} - /* First disconnect current tag */ - (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); - getMessage(); +void Electroniccats_PN7150::handleCardEmulation() { + Electroniccats_PN7150::ProcessCardMode(this->dummyRfInterface); +} - if ((rxBuffer[0] != 0x41) && (rxBuffer[1] != 0x06) && (rxBuffer[3] != 0x00)) - return ERROR; - getMessage(100); +void Electroniccats_PN7150::processReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation) { + switch (Operation) { + case READ_NDEF: + readNdef(RfIntf); + break; + case WRITE_NDEF: + writeNdef(RfIntf); + break; + case PRESENCE_CHECK: + presenceCheck(RfIntf); + break; + default: + break; + } +} - if ((rxBuffer[0] != 0x61) && (rxBuffer[1] != 0x06)) - return ERROR; +// Deprecated, use processReaderMode() instead +void Electroniccats_PN7150::ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation) { + Electroniccats_PN7150::processReaderMode(RfIntf, Operation); +} - NCIRfDiscoverSelect[4] = gNextTag_Protocol; - if (gNextTag_Protocol == PROT_ISODEP) - NCIRfDiscoverSelect[5] = INTF_ISODEP; - else if (gNextTag_Protocol == PROT_ISODEP) - NCIRfDiscoverSelect[5] = INTF_NFCDEP; - else if (gNextTag_Protocol == PROT_MIFARE) - NCIRfDiscoverSelect[5] = INTF_TAGCMD; - else - NCIRfDiscoverSelect[5] = INTF_FRAME; +void Electroniccats_PN7150::processP2pMode(RfIntf_t RfIntf) { + uint8_t status = ERROR; + bool restart = false; + uint8_t NCILlcpSymm[] = {0x00, 0x00, 0x02, 0x00, 0x00}; + uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03}; - (void)writeData(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect)); + /* Reset P2P_NDEF state */ + P2P_NDEF_Reset(); + + /* Is Initiator mode ? */ + if ((RfIntf.ModeTech & MODE_LISTEN) != MODE_LISTEN) { + /* Initiate communication (SYMM PDU) */ + (void)writeData(NCILlcpSymm, sizeof(NCILlcpSymm)); getMessage(); - if ((rxBuffer[0] == 0x41) && (rxBuffer[1] == 0x04) && (rxBuffer[3] == 0x00)) - { - getMessage(100); - if ((rxBuffer[0] == 0x61) || (rxBuffer[1] == 0x05)) - { - pRfIntf->Interface = rxBuffer[4]; - pRfIntf->Protocol = rxBuffer[5]; - pRfIntf->ModeTech = rxBuffer[6]; - FillInterfaceInfo(pRfIntf, &rxBuffer[10]); - status = SUCCESS; + /* Save status for discovery restart */ + restart = true; + } + status = ERROR; + getMessage(2000); + if (rxMessageLength > 0) + status = SUCCESS; + + /* Get frame from remote peer */ + while (status == SUCCESS) { + /* is DATA_PACKET ? */ + if ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)) { + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; + uint16_t CmdSize; + /* Handle P2P communication */ + P2P_NDEF_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); + /* Compute DATA_PACKET to answer */ + Cmd[0] = 0x00; + Cmd[1] = (CmdSize & 0xFF00) >> 8; + Cmd[2] = CmdSize & 0x00FF; + status = ERROR; + (void)writeData(Cmd, CmdSize + 3); + getMessage(); + if (rxMessageLength > 0) + status = SUCCESS; + } + /* is CORE_INTERFACE_ERROR_NTF ?*/ + else if ((rxBuffer[0] == 0x60) && (rxBuffer[1] == 0x08)) { + /* Come back to discovery state */ + break; + } + /* is RF_DEACTIVATE_NTF ? */ + else if ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x06)) { + /* Come back to discovery state */ + break; + } + /* is RF_DISCOVERY_NTF ? */ + else if ((rxBuffer[0] == 0x61) && ((rxBuffer[1] == 0x05) || (rxBuffer[1] == 0x03))) { + do { + if ((rxBuffer[0] == 0x61) && ((rxBuffer[1] == 0x05) || (rxBuffer[1] == 0x03))) { + if ((rxBuffer[6] & MODE_LISTEN) != MODE_LISTEN) + restart = true; + else + restart = false; } + status = ERROR; + (void)writeData(rxBuffer, rxMessageLength); + getMessage(); + if (rxMessageLength > 0) + status = SUCCESS; + } while (rxMessageLength != 0); + /* Come back to discovery state */ + break; } - return status; -} - -bool Electroniccats_PN7150::StopDiscovery(void) -{ - uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00}; - - (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); + /* Wait for next frame from remote P2P, or notification event */ + status = ERROR; + (void)writeData(rxBuffer, rxMessageLength); getMessage(); - getMessage(1000); + if (rxMessageLength > 0) + status = SUCCESS; + } - return SUCCESS; + /* Is Initiator mode ? */ + if (restart) { + /* Communication ended, restart discovery loop */ + (void)writeData(NCIRestartDiscovery, sizeof(NCIRestartDiscovery)); + getMessage(); + getMessage(100); + } } -bool Electroniccats_PN7150::ConfigureSettings(void) -{ - -#if NXP_CORE_CONF - /* NCI standard dedicated settings - * Refer to NFC Forum NCI standard for more details - */ - uint8_t NxpNci_CORE_CONF[] = { - 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ - 0x00, 0x02, 0x00, 0x01 /* TOTAL_DURATION */ - }; -#endif - -#if NXP_CORE_CONF_EXTN - /* NXP-NCI extension dedicated setting - * Refer to NFC controller User Manual for more details - */ - uint8_t NxpNci_CORE_CONF_EXTN[] = { - 0x20, 0x02, 0x0D, 0x03, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x40, 0x01, 0x00, /* TAG_DETECTOR_CFG */ - 0xA0, 0x41, 0x01, 0x04, /* TAG_DETECTOR_THRESHOLD_CFG */ - 0xA0, 0x43, 0x01, 0x00 /* TAG_DETECTOR_FALLBACK_CNT_CFG */ - }; -#endif - -#if NXP_CORE_STANDBY - /* NXP-NCI standby enable setting - * Refer to NFC controller User Manual for more details - */ - uint8_t NxpNci_CORE_STANDBY[] = {0x2F, 0x00, 0x01, 0x01}; /* last byte indicates enable/disable */ -#endif - -#if NXP_TVDD_CONF - /* NXP-NCI TVDD configuration - * Refer to NFC controller Hardware Design Guide document for more details - */ - /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ - uint8_t NxpNci_TVDD_CONF_1stGen[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x13, 0x01, 0x00}; +// Deprecated, use processP2pMode() instead +void Electroniccats_PN7150::ProcessP2pMode(RfIntf_t RfIntf) { + Electroniccats_PN7150::processP2pMode(RfIntf); +} - /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ -#if (NXP_TVDD_CONF == 1) - /* CFG1: Vbat is used to generate the VDD(TX) through TXLDO */ - uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x02, 0x09, 0x00}; -#else - /* CFG2: external 5V is used to generate the VDD(TX) through TXLDO */ - uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x06, 0x64, 0x00}; -#endif -#endif +void Electroniccats_PN7150::presenceCheck(RfIntf_t RfIntf) { + bool status; + uint8_t i; -#if NXP_RF_CONF - /* NXP-NCI RF configuration - * Refer to NFC controller Antenna Design and Tuning Guidelines document for more details - */ - /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ - /* Following configuration is the default settings of PN7120 NFC Controller */ - uint8_t NxpNci_RF_CONF_1stGen[] = { - 0x20, 0x02, 0x38, 0x07, - 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x01, 0x00, 0xF1, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x44, 0xA3, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0xDC, 0x50, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x04, 0x06, 0x03, 0x00, 0x70, /* RF_CLIF_CFG_TARGET CLIF_TRANSCEIVE_CONTROL_REG */ - 0xA0, 0x0D, 0x03, 0x06, 0x16, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_UNDERSHOOT_CONFIG_REG */ - 0xA0, 0x0D, 0x03, 0x06, 0x15, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_OVERSHOOT_CONFIG_REG */ - 0xA0, 0x0D, 0x06, 0x32, 0x4A, 0x53, 0x07, 0x01, 0x1B /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_SHAPE_CONTROL_REG */ - }; - - /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ - /* Following configuration relates to performance optimization of OM5578/PN7150 NFC Controller demo kit */ - uint8_t NxpNci_RF_CONF_2ndGen[] = { - 0x20, 0x02, 0x94, 0x11, - 0xA0, 0x0D, 0x06, 0x04, 0x35, 0x90, 0x01, 0xF4, 0x01, /* RF_CLIF_CFG_INITIATOR CLIF_AGC_INPUT_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x30, 0x01, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_SIGPRO_ADCBCM_THRESHOLD_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x02, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x20, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TECHNO_I_TX15693 CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x04, 0x22, 0x44, 0x23, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x22, 0x2D, 0x50, 0x34, 0x0C, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x32, 0x42, 0xF8, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0x24, 0x37, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x33, 0x86, 0x80, 0x00, 0x70, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_AGC_CONFIG0_REG */ - 0xA0, 0x0D, 0x04, 0x34, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x42, 0x2D, 0x15, 0x45, 0x0D, 0x00, /* RF_CLIF_CFG_BR_848_I_RXA CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x04, 0x46, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x46, 0x2D, 0x05, 0x59, 0x0E, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x44, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXB CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x56, 0x2D, 0x05, 0x9F, 0x0C, 0x00, /* RF_CLIF_CFG_BR_212_I_RXF_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x54, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_212_I_TXF CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x0A, 0x33, 0x80, 0x86, 0x00, 0x70 /* RF_CLIF_CFG_I_ACTIVE CLIF_AGC_CONFIG0_REG */ - }; -#endif + uint8_t NCIPresCheckT1T[] = {0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t NCIPresCheckT2T[] = {0x00, 0x00, 0x02, 0x30, 0x00}; + uint8_t NCIPresCheckT3T[] = {0x21, 0x08, 0x04, 0xFF, 0xFF, 0x00, 0x01}; + uint8_t NCIPresCheckIsoDep[] = {0x2F, 0x11, 0x00}; + uint8_t NCIPresCheckIso15693[] = {0x00, 0x00, 0x0B, 0x26, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01}; + uint8_t NCISelectMIFARE[] = {0x21, 0x04, 0x03, 0x01, 0x80, 0x80}; -#if NXP_CLK_CONF - /* NXP-NCI CLOCK configuration - * Refer to NFC controller Hardware Design Guide document for more details - */ -#if (NXP_CLK_CONF == 1) - /* Xtal configuration */ - uint8_t NxpNci_CLK_CONF[] = { - 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x03, 0x01, 0x08 /* CLOCK_SEL_CFG */ - }; -#else - /* PLL configuration */ - uint8_t NxpNci_CLK_CONF[] = { - 0x20, 0x02, 0x09, 0x02, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x03, 0x01, 0x11, /* CLOCK_SEL_CFG */ - 0xA0, 0x04, 0x01, 0x01 /* CLOCK_TO_CFG */ - }; -#endif -#endif + switch (remoteDevice.getProtocol()) { + case PROT_T1T: + do { + delay(500); + (void)writeData(NCIPresCheckT1T, sizeof(NCIPresCheckT1T)); + getMessage(); + getMessage(100); + } while ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00)); + break; - uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x00}; - uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; - bool gRfSettingsRestored_flag = false; + case PROT_T2T: + do { + delay(500); + (void)writeData(NCIPresCheckT2T, sizeof(NCIPresCheckT2T)); + getMessage(); + getMessage(100); + } while ((rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00) && (rxBuffer[2] == 0x11)); + break; -#if (NXP_TVDD_CONF | NXP_RF_CONF) - uint8_t *NxpNci_CONF; - uint16_t NxpNci_CONF_size = 0; -#endif -#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) - uint8_t currentTS[32] = __TIMESTAMP__; - uint8_t NCIReadTS[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x14}; - uint8_t NCIWriteTS[7 + 32] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x14, 0x20}; -#endif - bool isResetRequired = false; + case PROT_T3T: + do { + delay(500); + (void)writeData(NCIPresCheckT3T, sizeof(NCIPresCheckT3T)); + getMessage(); + getMessage(100); + } while ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x08) && ((rxBuffer[3] == 0x00) || (rxBuffer[4] > 0x00))); + break; - /* Apply settings */ -#if NXP_CORE_CONF - if (sizeof(NxpNci_CORE_CONF) != 0) - { - isResetRequired = true; - (void)writeData(NxpNci_CORE_CONF, sizeof(NxpNci_CORE_CONF)); + case PROT_ISODEP: + do { + delay(500); + (void)writeData(NCIPresCheckIsoDep, sizeof(NCIPresCheckIsoDep)); getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_CONF"); -#endif - return ERROR; - } - } -#endif + getMessage(100); + } while ((rxBuffer[0] == 0x6F) && (rxBuffer[1] == 0x11) && (rxBuffer[2] == 0x01) && (rxBuffer[3] == 0x01)); + break; -#if NXP_CORE_STANDBY - if (sizeof(NxpNci_CORE_STANDBY) != 0) - { + case PROT_ISO15693: + do { + delay(500); + for (i = 0; i < 8; i++) { + NCIPresCheckIso15693[i + 6] = remoteDevice.getID()[7 - i]; + } + (void)writeData(NCIPresCheckIso15693, sizeof(NCIPresCheckIso15693)); + getMessage(); + getMessage(100); + status = ERROR; + if (rxMessageLength) + status = SUCCESS; + } while ((status == SUCCESS) && (rxBuffer[0] == 0x00) && (rxBuffer[1] == 0x00) && (rxBuffer[rxMessageLength - 1] == 0x00)); + break; - (void)(writeData(NxpNci_CORE_STANDBY, sizeof(NxpNci_CORE_STANDBY))); + case PROT_MIFARE: + do { + delay(500); + /* Deactivate target */ + (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); getMessage(); - if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_STANDBY"); -#endif - return ERROR; - } - } -#endif + getMessage(100); - /* All further settings are not versatile, so configuration only applied if there are changes (application build timestamp) - or in case of PN7150B0HN/C11004 Anti-tearing recovery procedure inducing RF setings were restored to their default value */ -#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) - /* First read timestamp stored in NFC Controller */ - if (gNfcController_generation == 1) - NCIReadTS[5] = 0x0F; - (void)writeData(NCIReadTS, sizeof(NCIReadTS)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("read timestamp "); -#endif - return ERROR; - } - /* Then compare with current build timestamp, and check RF setting restauration flag */ - /*if(!memcmp(&rxBuffer[8], currentTS, sizeof(currentTS)) && (gRfSettingsRestored_flag == false)) - { - // No change, nothing to do - } - else - { - */ - /* Apply settings */ -#if NXP_CORE_CONF_EXTN - if (sizeof(NxpNci_CORE_CONF_EXTN) != 0) - { - (void)writeData(NxpNci_CORE_CONF_EXTN, sizeof(NxpNci_CORE_CONF_EXTN)); + /* Reactivate target */ + (void)writeData(NCISelectMIFARE, sizeof(NCISelectMIFARE)); getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_CONF_EXTN"); -#endif - return ERROR; - } - } -#endif + getMessage(100); + } while ((rxBuffer[0] == 0x61) && (rxBuffer[1] == 0x05)); + break; -#if NXP_CLK_CONF - if (sizeof(NxpNci_CLK_CONF) != 0) - { - isResetRequired = true; + default: + /* Nothing to do */ + break; + } +} - (void)writeData(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF)); - getMessage(); - //NxpNci_HostTransceive(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF), Answer, sizeof(Answer), &AnswerSize); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CLK_CONF"); -#endif - return ERROR; - } - } -#endif +void Electroniccats_PN7150::waitForTagRemoval() { + Electroniccats_PN7150::presenceCheck(this->dummyRfInterface); +} -#if NXP_TVDD_CONF - if (NxpNci_CONF_size != 0) - { +// Deprecated, use waitForTagRemoval() instead +void Electroniccats_PN7150::PresenceCheck(RfIntf_t RfIntf) { + Electroniccats_PN7150::presenceCheck(RfIntf); +} - (void)writeData(NxpNci_TVDD_CONF_2ndGen, sizeof(NxpNci_TVDD_CONF_2ndGen)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CONF_size"); -#endif - return ERROR; - } - } -#endif +bool Electroniccats_PN7150::readerTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize) { + bool status = ERROR; + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; -#if NXP_RF_CONF - if (NxpNci_CONF_size != 0) - { + /* Compute and send DATA_PACKET */ + Cmd[0] = 0x00; + Cmd[1] = 0x00; + Cmd[2] = CommandSize; + memcpy(&Cmd[3], pCommand, CommandSize); - (void)writeData(NxpNci_RF_CONF_2ndGen, sizeof(NxpNci_RF_CONF_2ndGen)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CONF_size"); -#endif - return ERROR; - } - } -#endif - /* Store curent timestamp to NFC Controller memory for further checks */ - if (gNfcController_generation == 1) - NCIWriteTS[5] = 0x0F; - memcpy(&NCIWriteTS[7], currentTS, sizeof(currentTS)); - (void)writeData(NCIWriteTS, sizeof(NCIWriteTS)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NFC Controller memory"); -#endif - return ERROR; - } - //} -#endif + (void)writeData(Cmd, CommandSize + 3); + getMessage(); + getMessage(1000); + /* Wait for Answer 1S */ - if (isResetRequired) - { - /* Reset the NFC Controller to insure new settings apply */ - (void)writeData(NCICoreReset, sizeof(NCICoreReset)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("insure new settings apply"); -#endif - return ERROR; - } + if ((rxBuffer[0] == 0x0) && (rxBuffer[1] == 0x0)) + status = SUCCESS; - (void)writeData(NCICoreInit, sizeof(NCICoreInit)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("insure new settings apply 2"); -#endif - return ERROR; - } - } - return SUCCESS; + *pAnswerSize = rxBuffer[2]; + memcpy(pAnswer, &rxBuffer[3], *pAnswerSize); + + return status; } -bool Electroniccats_PN7150::ConfigureSettings(uint8_t *uidcf, uint8_t uidlen) -{ +// Deprecated, use readerTagCmd() instead +bool Electroniccats_PN7150::ReaderTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize) { + return Electroniccats_PN7150::readerTagCmd(pCommand, CommandSize, pAnswer, pAnswerSize); +} -#if NXP_CORE_CONF - /* NCI standard dedicated settings - * Refer to NFC Forum NCI standard for more details - */ - uint8_t NxpNci_CORE_CONF[20] = { - 0x20, 0x02, 0x05, 0x01, // CORE_SET_CONFIG_CMD - 0x00, 0x02, 0x00, 0x01 // TOTAL_DURATION - }; - - if(uidlen == 0) - uidlen = 8; - else { - uidlen+= 10; - memcpy(&NxpNci_CORE_CONF[0], uidcf, uidlen); - } +bool Electroniccats_PN7150::readerReActivate() { + uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01}; + uint8_t NCIActivate[] = {0x21, 0x04, 0x03, 0x01, 0x00, 0x00}; -#endif + /* First de-activate the target */ + (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); + getMessage(); + getMessage(100); -#if NXP_CORE_CONF_EXTN - /* NXP-NCI extension dedicated setting - * Refer to NFC controller User Manual for more details - */ - uint8_t NxpNci_CORE_CONF_EXTN[] = { - 0x20, 0x02, 0x0D, 0x03, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x40, 0x01, 0x00, /* TAG_DETECTOR_CFG */ - 0xA0, 0x41, 0x01, 0x04, /* TAG_DETECTOR_THRESHOLD_CFG */ - 0xA0, 0x43, 0x01, 0x00 /* TAG_DETECTOR_FALLBACK_CNT_CFG */ - }; -#endif + /* Then re-activate the target */ + NCIActivate[4] = remoteDevice.getProtocol(); + NCIActivate[5] = remoteDevice.getInterface(); -#if NXP_CORE_STANDBY - /* NXP-NCI standby enable setting - * Refer to NFC controller User Manual for more details - */ - uint8_t NxpNci_CORE_STANDBY[] = {0x2F, 0x00, 0x01, 0x01}; /* last byte indicates enable/disable */ -#endif + (void)writeData(NCIDeactivate, sizeof(NCIDeactivate)); + getMessage(); + getMessage(100); -#if NXP_TVDD_CONF - /* NXP-NCI TVDD configuration - * Refer to NFC controller Hardware Design Guide document for more details - */ - /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ - uint8_t NxpNci_TVDD_CONF_1stGen[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x13, 0x01, 0x00}; + if ((rxBuffer[0] != 0x61) || (rxBuffer[1] != 0x05)) + return ERROR; + return SUCCESS; +} - /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ -#if (NXP_TVDD_CONF == 1) - /* CFG1: Vbat is used to generate the VDD(TX) through TXLDO */ - uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x02, 0x09, 0x00}; -#else - /* CFG2: external 5V is used to generate the VDD(TX) through TXLDO */ - uint8_t NxpNci_TVDD_CONF_2ndGen[] = {0x20, 0x02, 0x07, 0x01, 0xA0, 0x0E, 0x03, 0x06, 0x64, 0x00}; -#endif -#endif +// Deprecated, use readerReActivate() instead +bool Electroniccats_PN7150::ReaderReActivate(RfIntf_t *pRfIntf) { + return Electroniccats_PN7150::readerReActivate(); +} -#if NXP_RF_CONF - /* NXP-NCI RF configuration - * Refer to NFC controller Antenna Design and Tuning Guidelines document for more details - */ - /* RF configuration related to 1st generation of NXP-NCI controller (e.g PN7120) */ - /* Following configuration is the default settings of PN7120 NFC Controller */ - uint8_t NxpNci_RF_CONF_1stGen[] = { - 0x20, 0x02, 0x38, 0x07, - 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x01, 0x00, 0xF1, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x44, 0xA3, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0xDC, 0x50, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x04, 0x06, 0x03, 0x00, 0x70, /* RF_CLIF_CFG_TARGET CLIF_TRANSCEIVE_CONTROL_REG */ - 0xA0, 0x0D, 0x03, 0x06, 0x16, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_UNDERSHOOT_CONFIG_REG */ - 0xA0, 0x0D, 0x03, 0x06, 0x15, 0x00, /* RF_CLIF_CFG_TARGET CLIF_TX_OVERSHOOT_CONFIG_REG */ - 0xA0, 0x0D, 0x06, 0x32, 0x4A, 0x53, 0x07, 0x01, 0x1B /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_SHAPE_CONTROL_REG */ - }; - - /* RF configuration related to 2nd generation of NXP-NCI controller (e.g PN7150)*/ - /* Following configuration relates to performance optimization of OM5578/PN7150 NFC Controller demo kit */ - uint8_t NxpNci_RF_CONF_2ndGen[] = { - 0x20, 0x02, 0x94, 0x11, - 0xA0, 0x0D, 0x06, 0x04, 0x35, 0x90, 0x01, 0xF4, 0x01, /* RF_CLIF_CFG_INITIATOR CLIF_AGC_INPUT_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x30, 0x01, 0x90, 0x03, 0x00, /* RF_CLIF_CFG_TARGET CLIF_SIGPRO_ADCBCM_THRESHOLD_REG */ - 0xA0, 0x0D, 0x06, 0x06, 0x42, 0x02, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TARGET CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x20, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_TECHNO_I_TX15693 CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x04, 0x22, 0x44, 0x23, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x22, 0x2D, 0x50, 0x34, 0x0C, 0x00, /* RF_CLIF_CFG_TECHNO_I_RX15693 CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x32, 0x42, 0xF8, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXA CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x2D, 0x24, 0x37, 0x0C, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x34, 0x33, 0x86, 0x80, 0x00, 0x70, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_AGC_CONFIG0_REG */ - 0xA0, 0x0D, 0x04, 0x34, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXA_P CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x42, 0x2D, 0x15, 0x45, 0x0D, 0x00, /* RF_CLIF_CFG_BR_848_I_RXA CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x04, 0x46, 0x44, 0x22, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_ANA_RX_REG */ - 0xA0, 0x0D, 0x06, 0x46, 0x2D, 0x05, 0x59, 0x0E, 0x00, /* RF_CLIF_CFG_BR_106_I_RXB CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x44, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_106_I_TXB CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x56, 0x2D, 0x05, 0x9F, 0x0C, 0x00, /* RF_CLIF_CFG_BR_212_I_RXF_P CLIF_SIGPRO_RM_CONFIG1_REG */ - 0xA0, 0x0D, 0x06, 0x54, 0x42, 0x88, 0x00, 0xFF, 0xFF, /* RF_CLIF_CFG_BR_212_I_TXF CLIF_ANA_TX_AMPLITUDE_REG */ - 0xA0, 0x0D, 0x06, 0x0A, 0x33, 0x80, 0x86, 0x00, 0x70 /* RF_CLIF_CFG_I_ACTIVE CLIF_AGC_CONFIG0_REG */ - }; -#endif +bool Electroniccats_PN7150::ReaderActivateNext(RfIntf_t *pRfIntf) { + uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x01}; + uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x02, PROT_ISODEP, INTF_ISODEP}; -#if NXP_CLK_CONF - /* NXP-NCI CLOCK configuration - * Refer to NFC controller Hardware Design Guide document for more details - */ -#if (NXP_CLK_CONF == 1) - /* Xtal configuration */ - uint8_t NxpNci_CLK_CONF[] = { - 0x20, 0x02, 0x05, 0x01, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x03, 0x01, 0x08 /* CLOCK_SEL_CFG */ - }; -#else - /* PLL configuration */ - uint8_t NxpNci_CLK_CONF[] = { - 0x20, 0x02, 0x09, 0x02, /* CORE_SET_CONFIG_CMD */ - 0xA0, 0x03, 0x01, 0x11, /* CLOCK_SEL_CFG */ - 0xA0, 0x04, 0x01, 0x01 /* CLOCK_TO_CFG */ - }; -#endif -#endif + bool status = ERROR; - uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x00}; - uint8_t NCICoreInit[] = {0x20, 0x01, 0x00}; - bool gRfSettingsRestored_flag = false; + pRfIntf->MoreTags = false; + remoteDevice.setMoreTagsAvailable(false); -#if (NXP_TVDD_CONF | NXP_RF_CONF) - uint8_t *NxpNci_CONF; - uint16_t NxpNci_CONF_size = 0; -#endif -#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) - uint8_t currentTS[32] = __TIMESTAMP__; - uint8_t NCIReadTS[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x14}; - uint8_t NCIWriteTS[7 + 32] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x14, 0x20}; -#endif - bool isResetRequired = false; + if (gNextTag_Protocol == protocol.UNDETERMINED) { + pRfIntf->Interface = INTF_UNDETERMINED; + remoteDevice.setInterface(interface.UNDETERMINED); + pRfIntf->Protocol = PROT_UNDETERMINED; + remoteDevice.setProtocol(protocol.UNDETERMINED); + return ERROR; + } - /* Apply settings */ -#if NXP_CORE_CONF - if (uidlen != 0) //sizeof(NxpNci_CORE_CONF) != 0) - { - isResetRequired = true; - (void)writeData(NxpNci_CORE_CONF, uidlen); //sizeof(NxpNci_CORE_CONF)); - getMessage(100); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_CONF"); -#endif - return ERROR; - } - } -#endif + /* First disconnect current tag */ + (void)writeData(NCIStopDiscovery, sizeof(NCIStopDiscovery)); + getMessage(); -#if NXP_CORE_STANDBY - if (sizeof(NxpNci_CORE_STANDBY) != 0) - { + if ((rxBuffer[0] != 0x41) && (rxBuffer[1] != 0x06) && (rxBuffer[3] != 0x00)) + return ERROR; + getMessage(100); - (void)(writeData(NxpNci_CORE_STANDBY, sizeof(NxpNci_CORE_STANDBY))); - getMessage(); - if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_STANDBY"); -#endif - return ERROR; - } - } -#endif + if ((rxBuffer[0] != 0x61) && (rxBuffer[1] != 0x06)) + return ERROR; - /* All further settings are not versatile, so configuration only applied if there are changes (application build timestamp) - or in case of PN7150B0HN/C11004 Anti-tearing recovery procedure inducing RF setings were restored to their default value */ -#if (NXP_CORE_CONF_EXTN | NXP_CLK_CONF | NXP_TVDD_CONF | NXP_RF_CONF) - /* First read timestamp stored in NFC Controller */ - if (gNfcController_generation == 1) - NCIReadTS[5] = 0x0F; - (void)writeData(NCIReadTS, sizeof(NCIReadTS)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x03) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("read timestamp "); -#endif - return ERROR; - } - /* Then compare with current build timestamp, and check RF setting restauration flag */ - /*if(!memcmp(&rxBuffer[8], currentTS, sizeof(currentTS)) && (gRfSettingsRestored_flag == false)) - { - // No change, nothing to do - } - else - { - */ - /* Apply settings */ -#if NXP_CORE_CONF_EXTN - if (sizeof(NxpNci_CORE_CONF_EXTN) != 0) - { - (void)writeData(NxpNci_CORE_CONF_EXTN, sizeof(NxpNci_CORE_CONF_EXTN)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CORE_CONF_EXTN"); -#endif - return ERROR; - } - } -#endif + NCIRfDiscoverSelect[4] = gNextTag_Protocol; + if (gNextTag_Protocol == PROT_ISODEP) + NCIRfDiscoverSelect[5] = INTF_ISODEP; + else if (gNextTag_Protocol == PROT_ISODEP) + NCIRfDiscoverSelect[5] = INTF_NFCDEP; + else if (gNextTag_Protocol == PROT_MIFARE) + NCIRfDiscoverSelect[5] = INTF_TAGCMD; + else + NCIRfDiscoverSelect[5] = INTF_FRAME; -#if NXP_CLK_CONF - if (sizeof(NxpNci_CLK_CONF) != 0) - { - isResetRequired = true; + (void)writeData(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect)); + getMessage(); - (void)writeData(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF)); - getMessage(); - //NxpNci_HostTransceive(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF), Answer, sizeof(Answer), &AnswerSize); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CLK_CONF"); -#endif - return ERROR; - } + if ((rxBuffer[0] == 0x41) && (rxBuffer[1] == 0x04) && (rxBuffer[3] == 0x00)) { + getMessage(100); + if ((rxBuffer[0] == 0x61) || (rxBuffer[1] == 0x05)) { + pRfIntf->Interface = rxBuffer[4]; + remoteDevice.setInterface(rxBuffer[4]); + pRfIntf->Protocol = rxBuffer[5]; + remoteDevice.setProtocol(rxBuffer[5]); + pRfIntf->ModeTech = rxBuffer[6]; + remoteDevice.setModeTech(rxBuffer[6]); + remoteDevice.setInfo(pRfIntf, &rxBuffer[10]); + status = SUCCESS; } -#endif + } -#if NXP_TVDD_CONF - if (NxpNci_CONF_size != 0) - { + return status; +} - (void)writeData(NxpNci_TVDD_CONF_2ndGen, sizeof(NxpNci_TVDD_CONF_2ndGen)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CONF_size"); -#endif - return ERROR; +bool Electroniccats_PN7150::activateNextTagDiscovery() { + return !Electroniccats_PN7150::ReaderActivateNext(&this->dummyRfInterface); +} + +void Electroniccats_PN7150::readNdef(RfIntf_t RfIntf) { + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; + uint16_t CmdSize = 0; + + RW_NDEF_Reset(remoteDevice.getProtocol()); + + while (1) { + RW_NDEF_Read_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); + if (CmdSize == 0) { + /// End of the Read operation + break; + } else { + // Compute and send DATA_PACKET + Cmd[0] = 0x00; + Cmd[1] = (CmdSize & 0xFF00) >> 8; + Cmd[2] = CmdSize & 0x00FF; + + (void)writeData(Cmd, CmdSize + 3); + getMessage(); + getMessage(1000); + + // Manage chaining in case of T4T + if (remoteDevice.getInterface() == INTF_ISODEP && rxBuffer[0] == 0x10) { + uint8_t tmp[MAX_NCI_FRAME_SIZE]; + uint8_t tmpSize = 0; + while (rxBuffer[0] == 0x10) { + memcpy(&tmp[tmpSize], &rxBuffer[3], rxBuffer[2]); + tmpSize += rxBuffer[2]; + getMessage(100); } + memcpy(&tmp[tmpSize], &rxBuffer[3], rxBuffer[2]); + tmpSize += rxBuffer[2]; + //* Compute all chained frame into one unique answer + memcpy(&rxBuffer[3], tmp, tmpSize); + rxBuffer[2] = tmpSize; + } } -#endif + } +} -#if NXP_RF_CONF - if (NxpNci_CONF_size != 0) - { +void Electroniccats_PN7150::readNdefMessage(void) { + Electroniccats_PN7150::readNdef(this->dummyRfInterface); +} - (void)writeData(NxpNci_RF_CONF_2ndGen, sizeof(NxpNci_RF_CONF_2ndGen)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NxpNci_CONF_size"); -#endif - return ERROR; - } - } -#endif - /* Store curent timestamp to NFC Controller memory for further checks */ - if (gNfcController_generation == 1) - NCIWriteTS[5] = 0x0F; - memcpy(&NCIWriteTS[7], currentTS, sizeof(currentTS)); - (void)writeData(NCIWriteTS, sizeof(NCIWriteTS)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x02) || (rxBuffer[3] != 0x00) || (rxBuffer[4] != 0x00)) - { -#ifdef SerialUSB - Serial.println("NFC Controller memory"); -#endif - return ERROR; +// Deprecated, use readNdef() instead +void Electroniccats_PN7150::ReadNdef(RfIntf_t RfIntf) { + Electroniccats_PN7150::readNdef(RfIntf); +} + +void Electroniccats_PN7150::writeNdef(RfIntf_t RfIntf) { + uint8_t Cmd[MAX_NCI_FRAME_SIZE]; + uint16_t CmdSize = 0; + + RW_NDEF_Reset(remoteDevice.getProtocol()); + + while (1) { + RW_NDEF_Write_Next(&rxBuffer[3], rxBuffer[2], &Cmd[3], (unsigned short *)&CmdSize); + if (CmdSize == 0) { + // End of the Write operation + break; + } else { + // Compute and send DATA_PACKET + Cmd[0] = 0x00; + Cmd[1] = (CmdSize & 0xFF00) >> 8; + Cmd[2] = CmdSize & 0x00FF; + + (void)writeData(Cmd, CmdSize + 3); + getMessage(); + getMessage(2000); } - //} -#endif + } +} - if (isResetRequired) - { - /* Reset the NFC Controller to insure new settings apply */ - (void)writeData(NCICoreReset, sizeof(NCICoreReset)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x00) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("insure new settings apply"); -#endif - return ERROR; - } +void Electroniccats_PN7150::writeNdefMessage(void) { + Electroniccats_PN7150::writeNdef(this->dummyRfInterface); +} - (void)writeData(NCICoreInit, sizeof(NCICoreInit)); - getMessage(); - if ((rxBuffer[0] != 0x40) || (rxBuffer[1] != 0x01) || (rxBuffer[3] != 0x00)) - { -#ifdef SerialUSB - Serial.println("insure new settings apply 2"); -#endif - return ERROR; - } - } - return SUCCESS; +// Deprecated, use writeNdefMessage() instead +void Electroniccats_PN7150::WriteNdef(RfIntf_t RfIntf) { + Electroniccats_PN7150::writeNdef(RfIntf); } -//#if defined P2P_SUPPORT || defined RW_SUPPORT -void Electroniccats_PN7150::NdefPull_Cb(unsigned char *pNdefMessage, unsigned short NdefMessageSize) -{ - unsigned char *pNdefRecord = pNdefMessage; - NdefRecord_t NdefRecord; - unsigned char save; - - if (pNdefMessage == NULL) - { - Serial.println("--- Provisioned buffer size too small or NDEF message empty"); - return; - } +bool Electroniccats_PN7150::nciFactoryTestPrbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate) { + uint8_t NCIPrbs_1stGen[] = {0x2F, 0x30, 0x04, 0x00, 0x00, 0x01, 0x01}; + uint8_t NCIPrbs_2ndGen[] = {0x2F, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}; + uint8_t *NxpNci_cmd; + uint16_t NxpNci_cmd_size = 0; + + if (gNfcController_generation == 1) { + NxpNci_cmd = NCIPrbs_1stGen; + NxpNci_cmd_size = sizeof(NCIPrbs_1stGen); + NxpNci_cmd[3] = type; + NxpNci_cmd[4] = bitrate; + } else if (gNfcController_generation == 2) { + NxpNci_cmd = NCIPrbs_2ndGen; + NxpNci_cmd_size = sizeof(NCIPrbs_2ndGen); + NxpNci_cmd[5] = type; + NxpNci_cmd[6] = bitrate; + } + + if (NxpNci_cmd_size != 0) { + (void)writeData(NxpNci_cmd, sizeof(NxpNci_cmd)); + getMessage(); + if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x30) || (rxBuffer[3] != 0x00)) + return ERROR; + } else { + return ERROR; + } - while (pNdefRecord != NULL) - { - Serial.println("--- NDEF record received:"); - - NdefRecord = DetectNdefRecordType(pNdefRecord); - - switch (NdefRecord.recordType) - { - case MEDIA_VCARD: - { - save = NdefRecord.recordPayload[NdefRecord.recordPayloadSize]; - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = '\0'; - Serial.print("vCard:"); - //Serial.println(NdefRecord.recordPayload); - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = save; - } - break; - - case WELL_KNOWN_SIMPLE_TEXT: - { - save = NdefRecord.recordPayload[NdefRecord.recordPayloadSize]; - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = '\0'; - Serial.print("Text record:"); - //Serial.println(&NdefRecord.recordPayload[NdefRecord.recordPayload[0]+1]); - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = save; - } - break; - - case WELL_KNOWN_SIMPLE_URI: - { - save = NdefRecord.recordPayload[NdefRecord.recordPayloadSize]; - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = '\0'; - Serial.print("URI record: "); - //Serial.println(ndef_helper_UriHead(NdefRecord.recordPayload[0]), &NdefRecord.recordPayload[1]); - NdefRecord.recordPayload[NdefRecord.recordPayloadSize] = save; - } - break; - - case MEDIA_HANDOVER_WIFI: - { - unsigned char index = 0, i; - - Serial.println("--- Received WIFI credentials:"); - if ((NdefRecord.recordPayload[index] == 0x10) && (NdefRecord.recordPayload[index + 1] == 0x0e)) - index += 4; - while (index < NdefRecord.recordPayloadSize) - { - if (NdefRecord.recordPayload[index] == 0x10) - { - if (NdefRecord.recordPayload[index + 1] == 0x45) - { - Serial.print("- SSID = "); - for (i = 0; i < NdefRecord.recordPayload[index + 3]; i++) - Serial.print(NdefRecord.recordPayload[index + 4 + i]); - Serial.println(""); - } - else if (NdefRecord.recordPayload[index + 1] == 0x03) - { - Serial.print("- Authenticate Type = "); - Serial.println(ndef_helper_WifiAuth(NdefRecord.recordPayload[index + 5])); - } - else if (NdefRecord.recordPayload[index + 1] == 0x0f) - { - Serial.print("- Encryption Type = "); - Serial.println(ndef_helper_WifiEnc(NdefRecord.recordPayload[index + 5])); - } - else if (NdefRecord.recordPayload[index + 1] == 0x27) - { - Serial.print("- Network key = "); - for (i = 0; i < NdefRecord.recordPayload[index + 3]; i++) - Serial.print("#"); - Serial.println(""); - } - index += 4 + NdefRecord.recordPayload[index + 3]; - } - else - continue; - } - } - break; + return SUCCESS; +} - case WELL_KNOWN_HANDOVER_SELECT: - Serial.print("Handover select version "); - Serial.print(NdefRecord.recordPayload[0] >> 4); - Serial.println(NdefRecord.recordPayload[0] & 0xF); - break; +// Deprecated, use nciFactoryTestPrbs instead +bool Electroniccats_PN7150::NxpNci_FactoryTest_Prbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate) { + return Electroniccats_PN7150::nciFactoryTestPrbs(type, bitrate); +} - case WELL_KNOWN_HANDOVER_REQUEST: - Serial.print("Handover request version "); - Serial.print(NdefRecord.recordPayload[0] >> 4); - Serial.println(NdefRecord.recordPayload[0] & 0xF); - break; +bool Electroniccats_PN7150::nciFactoryTestRfOn() { + uint8_t NCIRfOn[] = {0x2F, 0x3D, 0x02, 0x20, 0x01}; - case MEDIA_HANDOVER_BT: - Serial.print("BT Handover payload = "); - //Serial.print(NdefRecord.recordPayload); - //Serial.println(NdefRecord.recordPayloadSize); - break; + (void)writeData(NCIRfOn, sizeof(NCIRfOn)); + getMessage(); + if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x3D) || (rxBuffer[3] != 0x00)) + return ERROR; - case MEDIA_HANDOVER_BLE: - Serial.print("BLE Handover payload = "); - //Serial.print(NdefRecord.recordPayload); - //Serial.println(NdefRecord.recordPayloadSize); - break; + return SUCCESS; +} - case MEDIA_HANDOVER_BLE_SECURE: - Serial.print(" BLE secure Handover payload = "); - //Serial.println(NdefRecord.recordPayload, NdefRecord.recordPayloadSize); - break; +// Deprecated, use nciFactoryTestRfOn instead +bool Electroniccats_PN7150::NxpNci_FactoryTest_RfOn() { + return Electroniccats_PN7150::nciFactoryTestRfOn(); +} - default: - Serial.println("Unsupported NDEF record, cannot parse"); - break; - } - pNdefRecord = GetNextRecord(pNdefRecord); +bool Electroniccats_PN7150::reset() { + if (Electroniccats_PN7150::stopDiscovery()) { + return false; + } + + // Configure settings only if we have not detected a tag yet + if (remoteDevice.getProtocol() == protocol.UNDETERMINED) { + if (Electroniccats_PN7150::configureSettings()) { + return false; } + } + + if (Electroniccats_PN7150::configMode()) { + return false; + } - Serial.println(""); + if (Electroniccats_PN7150::startDiscovery()) { + return false; + } + + return true; } -//#endif // if defined P2P_SUPPORT || defined RW_SUPPORT - -//#if defined P2P_SUPPORT || defined CARDEMU_SUPPORT -const char NDEF_MESSAGE[] = {0xD1, // MB/ME/CF/1/IL/TNF - 0x01, // TYPE LENGTH - 0x07, // PAYLOAD LENTGH - 'T', // TYPE - 0x02, // Status - 'e', 'n', // Language - 'T', 'e', 's', 't'}; - -void Electroniccats_PN7150::NdefPush_Cb(unsigned char *pNdefRecord, unsigned short NdefRecordSize) -{ - Serial.println("--- NDEF Record sent"); + +bool Electroniccats_PN7150::setReaderWriterMode() { + Electroniccats_PN7150::setMode(mode.READER_WRITER); + if (!Electroniccats_PN7150::reset()) { + return false; + } + return true; } -//#endif // if defined P2P_SUPPORT || defined CARDEMU_SUPPORT - -bool Electroniccats_PN7150::NxpNci_FactoryTest_Prbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate) -{ - uint8_t NCIPrbs_1stGen[] = {0x2F, 0x30, 0x04, 0x00, 0x00, 0x01, 0x01}; - uint8_t NCIPrbs_2ndGen[] = {0x2F, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}; - uint8_t *NxpNci_cmd; - uint16_t NxpNci_cmd_size = 0; - - if (gNfcController_generation == 1) - { - NxpNci_cmd = NCIPrbs_1stGen; - NxpNci_cmd_size = sizeof(NCIPrbs_1stGen); - NxpNci_cmd[3] = type; - NxpNci_cmd[4] = bitrate; - } - else if (gNfcController_generation == 2) - { - NxpNci_cmd = NCIPrbs_2ndGen; - NxpNci_cmd_size = sizeof(NCIPrbs_2ndGen); - NxpNci_cmd[5] = type; - NxpNci_cmd[6] = bitrate; - } - if (NxpNci_cmd_size != 0) - { - (void)writeData(NxpNci_cmd, sizeof(NxpNci_cmd)); - getMessage(); - if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x30) || (rxBuffer[3] != 0x00)) - return ERROR; - } - else - { - return ERROR; - } +bool Electroniccats_PN7150::setEmulationMode() { + Electroniccats_PN7150::setMode(mode.EMULATION); + if (!Electroniccats_PN7150::reset()) { + return false; + } + return true; +} - return SUCCESS; +bool Electroniccats_PN7150::setP2PMode() { + Electroniccats_PN7150::setMode(mode.P2P); + if (!Electroniccats_PN7150::reset()) { + return false; + } + return true; } -bool Electroniccats_PN7150::NxpNci_FactoryTest_RfOn(void) -{ - uint8_t NCIRfOn[] = {0x2F, 0x3D, 0x02, 0x20, 0x01}; +void Electroniccats_PN7150::setReadMsgCallback(CustomCallback_t function) { + registerNdefReceivedCallback(function); +} - (void)writeData(NCIRfOn, sizeof(NCIRfOn)); - getMessage(); - //NxpNci_HostTransceive(NCIRfOn, sizeof(NCIRfOn), Answer, sizeof(Answer), &AnswerSize); - if ((rxBuffer[0] != 0x4F) || (rxBuffer[1] != 0x3D) || (rxBuffer[3] != 0x00)) - return ERROR; +bool Electroniccats_PN7150::isReaderDetected() { + static unsigned char STATUSOK[] = {0x90, 0x00}, Cmd[256], CmdSize; + bool status = false; - return SUCCESS; + if (cardModeReceive(Cmd, &CmdSize) == 0) { // Data in buffer? + if ((CmdSize >= 2) && (Cmd[0] == 0x00)) { // Expect at least two bytes + if (Cmd[1] == 0xA4) { + status = true; + } + Electroniccats_PN7150::closeCommunication(); + } + } + + return status; +} + +void Electroniccats_PN7150::closeCommunication() { + unsigned char STATUSOK[] = {0x90, 0x00}; + Electroniccats_PN7150::cardModeSend(STATUSOK, sizeof(STATUSOK)); +} + +void Electroniccats_PN7150::sendMessage() { + Electroniccats_PN7150::handleCardEmulation(); + Electroniccats_PN7150::closeCommunication(); } diff --git a/src/Electroniccats_PN7150.h b/src/Electroniccats_PN7150.h index e6fdeef..04781fe 100644 --- a/src/Electroniccats_PN7150.h +++ b/src/Electroniccats_PN7150.h @@ -1,30 +1,37 @@ -#ifndef Electroniccats_PN7150_H -#define Electroniccats_PN7150_H /** * NXP PN7150 Driver - * Porting uthors: + * Porting authors: * Salvador Mendoza - @Netxing - salmg.net - * Andres Sabas - Electronic Cats - Electroniccats.com + * Andres Sabas - Electronic Cats - electroniccats.com + * Francisco Torres - Electronic Cats - electroniccats.com * - * November 2020 + * August 2023 * * This code is beerware; if you see me (or any other collaborator * member) at the local, and you've found our code helpful, * please buy us a round! * Distributed as-is; no warranty is given. * - * A few methods and ideas were extract from - * https://github.com/Strooom/PN7150 - * + * Some methods and ideas were extracted from https://github.com/Strooom/PN7150 */ -#include // Gives us access to all typical Arduino types and functions - // The HW interface between The PN7150 and the DeviceHost is I2C, so we need the I2C library.library -//#include "RW_NDEF.h" +#ifndef Electroniccats_PN7150_H +#define Electroniccats_PN7150_H + +#include // Gives us access to all typical Arduino types and functions + // The HW interface between The PN7150 and the DeviceHost is I2C, so we need the I2C library.library +#include "Mode.h" +#include "NdefMessage.h" +#include "NdefRecord.h" #include "P2P_NDEF.h" +#include "RemoteDevice.h" +#include "T4T_NDEF_emu.h" -#if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6 : Special, more optimized I2C library for Teensy boards -#include // Credits Brian "nox771" : see https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3 +// #define DEBGU2 +// #define DEBUG3 + +#if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6 : Special, more optimized I2C library for Teensy boards +#include // Credits Brian "nox771" : see https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3 #else #include #endif @@ -36,8 +43,8 @@ #define NXP_CORE_CONF 1 #define NXP_CORE_STANDBY 1 #define NXP_CORE_CONF_EXTN 1 -#define NXP_CLK_CONF 1 // 1=Xtal, 2=PLL -#define NXP_TVDD_CONF 2 // 1=CFG1, 2=CFG2 +#define NXP_CLK_CONF 1 // 1=Xtal, 2=PLL +#define NXP_TVDD_CONF 2 // 1=CFG1, 2=CFG2 #define NXP_RF_CONF 1 #define NFC_FACTORY_TEST 1 @@ -56,45 +63,7 @@ #define MODE_P2P (1 << 1) #define MODE_RW (1 << 2) -/* - * Flag definition used as Mode values - */ -#define MODE_POLL 0x00 -#define MODE_LISTEN 0x80 -#define MODE_MASK 0xF0 - -/* - * Flag definition used as Technologies values - */ -#define TECH_PASSIVE_NFCA 0 -#define TECH_PASSIVE_NFCB 1 -#define TECH_PASSIVE_NFCF 2 -#define TECH_ACTIVE_NFCA 3 -#define TECH_ACTIVE_NFCF 5 -#define TECH_PASSIVE_15693 6 - -/* - * Flag definition used as Protocol values - */ -#define PROT_UNDETERMINED 0x0 -#define PROT_T1T 0x1 -#define PROT_T2T 0x2 -#define PROT_T3T 0x3 -#define PROT_ISODEP 0x4 -#define PROT_NFCDEP 0x5 -#define PROT_ISO15693 0x6 -#define PROT_MIFARE 0x80 - -/* - * Flag definition used as Interface values - */ -#define INTF_UNDETERMINED 0x0 -#define INTF_FRAME 0x1 -#define INTF_ISODEP 0x2 -#define INTF_NFCDEP 0x3 -#define INTF_TAGCMD 0x80 - -#define MaxPayloadSize 255 // See NCI specification V1.0, section 3.1 +#define MaxPayloadSize 255 // See NCI specification V1.0, section 3.1 #define MsgHeaderSize 3 /***** Factory Test dedicated APIs *********************************************/ @@ -103,192 +72,114 @@ /* * Definition of technology types */ -typedef enum -{ - NFC_A, - NFC_B, - NFC_F +typedef enum { + NFC_A, + NFC_B, + NFC_F } NxpNci_TechType_t; /* * Definition of bitrate */ -typedef enum -{ - BR_106, - BR_212, - BR_424, - BR_848 +typedef enum { + BR_106, + BR_212, + BR_424, + BR_848 } NxpNci_Bitrate_t; #endif -/* - * Definition of discovered remote device properties information - */ - -/* POLL passive type A */ -struct RfIntf_info_APP_t -{ - unsigned char SensRes[2]; - unsigned char NfcIdLen; - unsigned char NfcId[10]; - unsigned char SelResLen; - unsigned char SelRes[1]; - unsigned char RatsLen; - unsigned char Rats[20]; -}; - -/* POLL passive type B */ -struct RfIntf_info_BPP_t -{ - unsigned char SensResLen; - unsigned char SensRes[12]; - unsigned char AttribResLen; - unsigned char AttribRes[17]; -}; - -/* POLL passive type F */ -struct RfIntf_info_FPP_t -{ - unsigned char BitRate; - unsigned char SensResLen; - unsigned char SensRes[18]; -}; - -/* POLL passive type ISO15693 */ -struct RfIntf_info_VPP_t -{ - unsigned char AFI; - unsigned char DSFID; - unsigned char ID[8]; -}; - -typedef union -{ - RfIntf_info_APP_t NFC_APP; - RfIntf_info_BPP_t NFC_BPP; - RfIntf_info_FPP_t NFC_FPP; - RfIntf_info_VPP_t NFC_VPP; -} RfIntf_Info_t; - -/* - * Definition of discovered remote device properties - */ -struct RfIntf_t -{ - unsigned char Interface; - unsigned char Protocol; - unsigned char ModeTech; - bool MoreTags; - RfIntf_Info_t Info; -}; /* * Definition of operations handled when processing Reader mode */ -typedef enum -{ +typedef enum { #ifndef NO_NDEF_SUPPORT - READ_NDEF, - WRITE_NDEF, + READ_NDEF, + WRITE_NDEF, #endif - PRESENCE_CHECK + PRESENCE_CHECK } RW_Operation_t; -/* - * Definition of discovered remote device properties information - */ -/* POLL passive type A */ -typedef struct -{ - unsigned char SensRes[2]; - unsigned char NfcIdLen; - unsigned char NfcId[10]; - unsigned char SelResLen; - unsigned char SelRes[1]; - unsigned char RatsLen; - unsigned char Rats[20]; -} NxpNci_RfIntf_info_APP_t; - -/* POLL passive type B */ -typedef struct -{ - unsigned char SensResLen; - unsigned char SensRes[12]; - unsigned char AttribResLen; - unsigned char AttribRes[17]; -} NxpNci_RfIntf_info_BPP_t; - -/* POLL passive type F */ -typedef struct -{ - unsigned char BitRate; - unsigned char SensResLen; - unsigned char SensRes[18]; -} NxpNci_RfIntf_info_FPP_t; - -/* POLL passive type ISO15693 */ -typedef struct -{ - unsigned char AFI; - unsigned char DSFID; - unsigned char ID[8]; -} NxpNci_RfIntf_info_VPP_t; - -typedef union -{ - NxpNci_RfIntf_info_APP_t NFC_APP; - NxpNci_RfIntf_info_BPP_t NFC_BPP; - NxpNci_RfIntf_info_FPP_t NFC_FPP; - NxpNci_RfIntf_info_VPP_t NFC_VPP; -} NxpNci_RfIntf_Info_t; - -class Electroniccats_PN7150 -{ -private: - uint8_t _IRQpin, _VENpin, _I2Caddress; - TwoWire *_wire; - uint8_t rxBuffer[MaxPayloadSize + MsgHeaderSize]; // buffer where we store bytes received until they form a complete message - void setTimeOut(unsigned long); // set a timeOut for an expected next event, eg reception of Response after sending a Command - bool isTimeOut() const; - bool getMessage(uint16_t timeout = 5); // 5 miliseconds as default to wait for interrupt responses - unsigned long timeOut; - unsigned long timeOutStartTime; - uint32_t rxMessageLength; // length of the last message received. As these are not 0x00 terminated, we need to remember the length - uint8_t gNfcController_generation = 0; - uint8_t gNfcController_fw_version[3] = {0}; - -public: - Electroniccats_PN7150(uint8_t IRQpin, uint8_t VENpin, uint8_t I2Caddress, TwoWire *wire = &Wire); - int GetFwVersion(); - uint8_t begin(void); - uint8_t writeData(uint8_t data[], uint32_t dataLength) const; // write data from DeviceHost to PN7150. Returns success (0) or Fail (> 0) - uint32_t readData(uint8_t data[]) const; // read data from PN7150, returns the amount of bytes read - bool hasMessage() const; - uint8_t ConfigMode(uint8_t modeSE); - uint8_t StartDiscovery(uint8_t modeSE); - uint8_t connectNCI(); - uint8_t wakeupNCI(); - bool CardModeSend(unsigned char *pData, unsigned char DataSize); - bool CardModeReceive(unsigned char *pData, unsigned char *pDataSize); - bool WaitForDiscoveryNotification(RfIntf_t *pRfIntf, uint8_t tout = 0); - void FillInterfaceInfo(RfIntf_t *pRfIntf, uint8_t *pBuf); - bool ReaderTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize); - bool StopDiscovery(void); - void ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); - void PresenceCheck(RfIntf_t RfIntf); - bool ReaderReActivate(RfIntf_t *pRfIntf); - void PrintBuf(const byte *data, const uint32_t numBytes); - bool ReaderActivateNext(RfIntf_t *pRfIntf); - bool ConfigureSettings(void); - bool ConfigureSettings(uint8_t *nfcuid, uint8_t uidlen); - void NdefPull_Cb(unsigned char *pNdefMessage, unsigned short NdefMessageSize); - void NdefPush_Cb(unsigned char *pNdefRecord, unsigned short NdefRecordSize); - bool NxpNci_FactoryTest_Prbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate); - bool NxpNci_FactoryTest_RfOn(void); - void ProcessP2pMode(RfIntf_t RfIntf); - void ReadNdef(RfIntf_t RfIntf); - void WriteNdef(RfIntf_t RfIntf); - void ProcessCardMode(RfIntf_t RfIntf); +class Electroniccats_PN7150 : public Mode { + private: + bool _hasBeenInitialized; + uint8_t _IRQpin, _VENpin, _I2Caddress; + TwoWire *_wire; + RfIntf_t dummyRfInterface; + uint8_t rxBuffer[MaxPayloadSize + MsgHeaderSize]; // buffer where we store bytes received until they form a complete message + unsigned long timeOut; + unsigned long timeOutStartTime; + uint32_t rxMessageLength; // length of the last message received. As these are not 0x00 terminated, we need to remember the length + uint8_t gNfcController_generation = 0; + uint8_t gNfcController_fw_version[3] = {0}; + void setTimeOut(unsigned long); // set a timeOut for an expected next event, eg reception of Response after sending a Command + bool isTimeOut() const; + uint8_t wakeupNCI(); + bool getMessage(uint16_t timeout = 5); // 5 miliseconds as default to wait for interrupt responses + + public: + Electroniccats_PN7150(uint8_t IRQpin, uint8_t VENpin, uint8_t I2Caddress, TwoWire *wire = &Wire); + uint8_t begin(void); + RemoteDevice remoteDevice; + Protocol protocol; + Tech tech; + ModeTech modeTech; + Interface interface; + bool hasMessage() const; + uint8_t writeData(uint8_t data[], uint32_t dataLength) const; // write data from DeviceHost to PN7150. Returns success (0) or Fail (> 0) + uint32_t readData(uint8_t data[]) const; // read data from PN7150, returns the amount of bytes read + int getFirmwareVersion(); + int GetFwVersion(); // Deprecated, use getFirmwareVersion() instead + uint8_t connectNCI(); + uint8_t ConfigMode(uint8_t modeSE); // Deprecated, use configMode(void) instead + uint8_t configMode(void); + bool setReaderWriterMode(); + bool setEmulationMode(); + bool setP2PMode(); + bool configureSettings(void); + bool ConfigureSettings(void); // Deprecated, use configureSettings(void) instead + bool configureSettings(uint8_t *nfcuid, uint8_t uidlen); + bool ConfigureSettings(uint8_t *nfcuid, uint8_t uidlen); // Deprecated, use configureSettings() instead + uint8_t startDiscovery(); + uint8_t StartDiscovery(uint8_t modeSE); // Deprecated, use startDiscovery() instead + bool stopDiscovery(); + bool StopDiscovery(); // Deprecated, use stopDiscovery() instead + bool WaitForDiscoveryNotification(RfIntf_t *pRfIntf, uint16_t tout = 0); // Deprecated, use isTagDetected() instead + bool isTagDetected(uint16_t tout = 500); + bool cardModeSend(unsigned char *pData, unsigned char DataSize); + bool CardModeSend(unsigned char *pData, unsigned char DataSize); // Deprecated, use cardModeSend() instead + bool cardModeReceive(unsigned char *pData, unsigned char *pDataSize); + bool CardModeReceive(unsigned char *pData, unsigned char *pDataSize); // Deprecated, use cardModeReceive() instead + void handleCardEmulation(); + void ProcessCardMode(RfIntf_t RfIntf); // Deprecated, use handleCardEmulation() instead + void processReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); // Deprecated, use waitForTagRemoval(), readNdefMessage() or writeNdefMessage() and readNdefMessage() instead + void ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); // Deprecated, use processReaderMode() instead + void processP2pMode(RfIntf_t RfIntf); // TODO: rename it + void ProcessP2pMode(RfIntf_t RfIntf); // Deprecated, use processP2pMode() instead + void presenceCheck(RfIntf_t RfIntf); // Deprecated, use waitForTagRemoval() instead + void PresenceCheck(RfIntf_t RfIntf); // Deprecated, use waitForTagRemoval() instead + void waitForTagRemoval(); + bool readerTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize); + bool ReaderTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize); // Deprecated, use readerTagCmd() instead + bool readerReActivate(); + bool ReaderReActivate(RfIntf_t *pRfIntf); // Deprecated, use readerReActivate() instead + bool activateNextTagDiscovery(); + bool ReaderActivateNext(RfIntf_t *pRfIntf); // Deprecated, use activateNextTagDiscovery() instead + void readNdef(RfIntf_t RfIntf); // TODO: remove it + void readNdefMessage(); + void ReadNdef(RfIntf_t RfIntf); // Deprecated, use readNdefMessage() instead + void writeNdef(RfIntf_t RfIntf); // TODO: remove it + void writeNdefMessage(); + void WriteNdef(RfIntf_t RfIntf); // Deprecated, use writeNdefMessage() instead + bool nciFactoryTestPrbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate); + bool NxpNci_FactoryTest_Prbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate); // Deprecated, use nciFactoryTestPrbs() instead + bool nciFactoryTestRfOn(); + bool NxpNci_FactoryTest_RfOn(); // Deprecated, use nciFactoryTestRfOn() instead + bool reset(); + void setReadMsgCallback(CustomCallback_t function); + bool isReaderDetected(); + void closeCommunication(); + void sendMessage(); }; #endif diff --git a/src/Interface.h b/src/Interface.h new file mode 100644 index 0000000..7bd1a73 --- /dev/null +++ b/src/Interface.h @@ -0,0 +1,37 @@ +/** + * Library to get the interface type of the NFC card + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef Interface_H +#define Interface_H + +/* + * Flag definition used as Interface values + */ +#define INTF_UNDETERMINED 0x0 +#define INTF_FRAME 0x1 +#define INTF_ISODEP 0x2 +#define INTF_NFCDEP 0x3 +#define INTF_TAGCMD 0x80 + +class Interface { + public: + enum Value { + UNDETERMINED = 0x0, + FRAME = 0x1, + ISODEP = 0x2, + NFCDEP = 0x3, + TAGCMD = 0x80 + }; +}; + +#endif \ No newline at end of file diff --git a/src/Mode.cpp b/src/Mode.cpp new file mode 100644 index 0000000..40b665f --- /dev/null +++ b/src/Mode.cpp @@ -0,0 +1,31 @@ +/** + * Library to manage the mode of the NFC chip + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include "Mode.h" + +Mode::Mode() { + this->_mode = mode.READER_WRITER; +} + +bool Mode::setMode(int mode) { + if (mode < 1 || mode > 3) { + return false; + } + + this->_mode = mode; + return true; +} + +int Mode::getMode() { + return this->_mode; +} diff --git a/src/Mode.h b/src/Mode.h new file mode 100644 index 0000000..70cad10 --- /dev/null +++ b/src/Mode.h @@ -0,0 +1,40 @@ +/** + * Library to manage the mode of the NFC chip + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef Mode_H +#define Mode_H + +#include "Arduino.h" + +struct Mode_t { + enum { + READER_WRITER = 1, + EMULATION = 2, + P2P = 3 + }; +}; + +class Mode { + private: + int _mode; + + protected: + bool setMode(int mode); // Only for internal use + + public: + Mode(); + Mode_t mode; + int getMode(); +}; + +#endif \ No newline at end of file diff --git a/src/ModeTech.h b/src/ModeTech.h new file mode 100644 index 0000000..ad432b4 --- /dev/null +++ b/src/ModeTech.h @@ -0,0 +1,33 @@ +/** + * Library to get the mode tech of the NFC card + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef ModeTech_H +#define ModeTech_H + +/* + * Flag definition used as Mode values + */ +#define MODE_POLL 0x00 +#define MODE_LISTEN 0x80 +#define MODE_MASK 0xF0 + +class ModeTech { + public: + enum Value { + POLL = 0x00, + LISTEN = 0x80, + MASK = 0xF0 + }; +}; + +#endif \ No newline at end of file diff --git a/src/NdefMessage.cpp b/src/NdefMessage.cpp new file mode 100644 index 0000000..c7961ad --- /dev/null +++ b/src/NdefMessage.cpp @@ -0,0 +1,75 @@ +/** + * Library to manage the NDEF message + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include "NdefMessage.h" + +unsigned char *NdefMessage::content; +unsigned short NdefMessage::contentSize; + +NdefMessage::NdefMessage() { + content = NULL; + contentSize = 0; +} + +void NdefMessage::begin() { + registerUpdateNdefMessageCallback(NdefMessage::update); +} + +void NdefMessage::update(unsigned char *message, unsigned short messageSize) { + if (content != NULL) { + free(content); + } + content = (unsigned char *)malloc(messageSize); + memcpy(content, message, messageSize); + contentSize = messageSize; +} + +unsigned char *NdefMessage::getContent() { + return content; +} + +unsigned short NdefMessage::getContentSize() { + return contentSize; +} + +void NdefMessage::setContent(unsigned char *content, unsigned short contentSize) { + NdefMessage::content = content; + NdefMessage::contentSize = contentSize; +} + +NdefRecord_t NdefMessage::getRecord() { + NdefRecord_t ndefRecord = DetectNdefRecordType(content); + + if (NdefMessage::isEmpty()) { + return ndefRecord; + } + + NdefMessage::getNextRecord(); + return ndefRecord; +} + +void NdefMessage::getNextRecord() { + content = GetNextRecord(content); +} + +bool NdefMessage::isEmpty() { + return NdefMessage::getContent() == NULL; +} + +bool NdefMessage::isNotEmpty() { + return NdefMessage::getContent() != NULL; +} + +bool NdefMessage::hasRecord() { + return NdefMessage::isNotEmpty(); +} diff --git a/src/NdefMessage.h b/src/NdefMessage.h new file mode 100644 index 0000000..c921cb7 --- /dev/null +++ b/src/NdefMessage.h @@ -0,0 +1,41 @@ +/** + * Library to manage the NDEF message + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef NdefMessage_H +#define NdefMessage_H + +#include + +#include "RW_NDEF.h" +#include "ndef_helper.h" + +class NdefMessage { + private: + static unsigned char *content; + static unsigned short contentSize; + static void update(unsigned char *message, unsigned short messageSize); + void getNextRecord(); + + public: + NdefMessage(); + void begin(); + static unsigned char *getContent(); + static unsigned short getContentSize(); + static void setContent(unsigned char *content, unsigned short contentSize); + NdefRecord_t getRecord(); + bool isEmpty(); + bool isNotEmpty(); + bool hasRecord(); +}; + +#endif \ No newline at end of file diff --git a/src/NdefRecord.cpp b/src/NdefRecord.cpp new file mode 100644 index 0000000..026adcc --- /dev/null +++ b/src/NdefRecord.cpp @@ -0,0 +1,235 @@ +/** + * Library to manage the NDEF record + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include "NdefRecord.h" + +NdefRecord::NdefRecord() { + this->type = UNSUPPORTED_NDEF_RECORD; + this->payload = NULL; + this->payloadSize = 0; + this->newString = "null"; +} + +void NdefRecord::create(NdefRecord_t record) { + this->type = record.recordType; + this->payload = record.recordPayload; + this->payloadSize = record.recordPayloadSize; +} + +String NdefRecord::getHexRepresentation(const byte *data, const uint32_t dataSize) { + String hexString; + + if (dataSize == 0) { + hexString = newString; + } + + for (uint32_t index = 0; index < dataSize; index++) { + if (data[index] <= 0xF) + hexString += "0"; + String hexValue = String(data[index] & 0xFF, HEX); + hexValue.toUpperCase(); + hexString += hexValue; + if ((dataSize > 1) && (index != dataSize - 1)) { + hexString += ":"; + } + } + return hexString; +} + +bool NdefRecord::isEmpty() { + return this->payload == NULL; +} + +bool NdefRecord::isNotEmpty() { + return this->payload != NULL; +} + +NdefRecordType_e NdefRecord::getType() { + return this->type; +} + +unsigned char *NdefRecord::getPayload() { + return this->payload; +} + +unsigned short NdefRecord::getPayloadSize() { + return this->payloadSize; +} + +String NdefRecord::getText() { + unsigned char save = payload[payloadSize]; + payload[payloadSize] = '\0'; + String text = newString; + + if (getType() == WELL_KNOWN_SIMPLE_TEXT) { + text = reinterpret_cast(&payload[payload[0] + 1]); + } + + payload[payloadSize] = save; + + return text; +} + +String NdefRecord::getBluetoothName() { + String bluetoothName = newString; + + if (getType() != MEDIA_HANDOVER_BT) { + return bluetoothName; + } else { + bluetoothName = ""; + } + + for (unsigned int i = 10; i < payloadSize; i++) { + if (payload[i] == 0x04) { + break; + } + bluetoothName += (char)payload[i]; + } + + return bluetoothName; +} + +String NdefRecord::getBluetoothAddress() { + String bluetoothAddress = newString; + + if (getType() != MEDIA_HANDOVER_BT) { + return bluetoothAddress; + } else { + bluetoothAddress = ""; + } + + for (unsigned int i = 7; i >= 2; i--) { + bluetoothAddress += getHexRepresentation(&payload[i], 1); + if (i > 2) { + bluetoothAddress += ":"; + } + } + + return bluetoothAddress; +} + +String NdefRecord::getWiFiSSID() { + String ssid = newString; + + if (getType() != MEDIA_HANDOVER_WIFI) { + return ssid; + } + + for (unsigned int i = 0; i < payloadSize; i++) { + if (payload[i] == 0x45) { + ssid = reinterpret_cast(&payload[i + 3]); + break; + } + } + + return ssid; +} + +String NdefRecord::getWiFiAuthenticationType() { + String authenticationType = newString; + unsigned char index = 0; + + if (getType() != MEDIA_HANDOVER_WIFI) { + return authenticationType; + } + + if ((getPayload()[index] == 0x10) && (getPayload()[index + 1] == 0x0e)) { + index += 4; + } + + while (index < getPayloadSize()) { + if (getPayload()[index] == 0x10) { + if (getPayload()[index + 1] == 0x03) { + authenticationType = ndef_helper_WifiAuth(getPayload()[index + 5]); + } + index += 4 + getPayload()[index + 3]; + } + } + + return authenticationType; +} + +String NdefRecord::getWiFiEncryptionType() { + String encryptionType = newString; + unsigned char index = 0; + + if (getType() != MEDIA_HANDOVER_WIFI) { + return encryptionType; + } + + if ((getPayload()[index] == 0x10) && (getPayload()[index + 1] == 0x0e)) { + index += 4; + } + + while (index < getPayloadSize()) { + if (getPayload()[index] == 0x10) { + if (getPayload()[index + 1] == 0x0f) { + encryptionType = ndef_helper_WifiEnc(getPayload()[index + 5]); + } + index += 4 + getPayload()[index + 3]; + } + } + + return encryptionType; +} + +String NdefRecord::getWiFiPassword() { + String networkKey = newString; + unsigned char index = 0; + + if (getType() != MEDIA_HANDOVER_WIFI) { + return networkKey; + } + + if ((getPayload()[index] == 0x10) && (getPayload()[index + 1] == 0x0e)) { + index += 4; + } + + while (index < getPayloadSize()) { + if (getPayload()[index] == 0x10) { + if (getPayload()[index + 1] == 0x27) { + networkKey = reinterpret_cast(&getPayload()[index + 4]); + } + index += 4 + getPayload()[index + 3]; + } + } + + return networkKey; +} + +String NdefRecord::getVCardContent() { + String content = newString; + + if (getType() != MEDIA_VCARD) { + return content; + } + + content = reinterpret_cast(getPayload()); + + return content; +} + +String NdefRecord::getUri() { + String uri = newString; + + if (getType() != WELL_KNOWN_SIMPLE_URI) { + return uri; + } + + unsigned char save = payload[payloadSize]; + payload[payloadSize] = '\0'; + uri = reinterpret_cast(ndef_helper_UriHead(payload[0]), &payload[1]); + payload[payloadSize] = save; + + return uri; +} diff --git a/src/NdefRecord.h b/src/NdefRecord.h new file mode 100644 index 0000000..0a5e777 --- /dev/null +++ b/src/NdefRecord.h @@ -0,0 +1,49 @@ +/** + * Library to manage the NDEF record + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef NdefRecord_H +#define NdefRecord_H + +#include + +#include "ndef_helper.h" + +class NdefRecord { + private: + NdefRecord_t content; + NdefRecordType_e type; + unsigned char *payload; + unsigned short payloadSize; + String getHexRepresentation(const byte *data, const uint32_t dataSize); + String newString; + + public: + NdefRecord(); + void create(NdefRecord_t record); + bool isEmpty(); + bool isNotEmpty(); + NdefRecordType_e getType(); + unsigned char *getPayload(); + unsigned short getPayloadSize(); + String getText(); + String getBluetoothName(); + String getBluetoothAddress(); + String getWiFiSSID(); + String getWiFiAuthenticationType(); + String getWiFiEncryptionType(); + String getWiFiPassword(); + String getVCardContent(); + String getUri(); +}; + +#endif \ No newline at end of file diff --git a/src/P2P_NDEF.cpp b/src/P2P_NDEF.cpp index 7317273..7da6d0d 100644 --- a/src/P2P_NDEF.cpp +++ b/src/P2P_NDEF.cpp @@ -1,21 +1,22 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef P2P_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef P2P_SUPPORT #include "P2P_NDEF.h" +#include "tool.h" + /* Well-known LLCP SAP Values */ #define SAP_SDP 1 #define SAP_SNEP 4 @@ -65,27 +66,26 @@ unsigned short NdefMessage_size = 0; /* Defines at which frequency the symmetry is exchange (in ms) */ #define SYMM_FREQ 500 -typedef enum -{ - Idle, - Initial, - DelayingPush, - SnepClientConnecting, - SnepClientConnected, - NdefMsgSent +typedef enum { + Idle, + Initial, + DelayingPush, + SnepClientConnecting, + SnepClientConnected, + NdefMsgSent } P2P_SnepClient_state_t; typedef struct { - unsigned char Dsap; - unsigned char Pdu; - unsigned char Ssap; - unsigned char Version; - unsigned short Miux; - unsigned short Wks; - unsigned char Lto; - unsigned char Rw; - unsigned char Sn[30]; + unsigned char Dsap; + unsigned char Pdu; + unsigned char Ssap; + unsigned char Version; + unsigned short Miux; + unsigned short Wks; + unsigned char Lto; + unsigned char Rw; + unsigned char Sn[30]; } P2P_NDEF_LlcpHeader_t; typedef void P2P_NDEF_Callback_t(unsigned char *, unsigned short); @@ -95,211 +95,182 @@ static P2P_NDEF_Callback_t *pP2P_NDEF_PushCb = NULL; static P2P_NDEF_Callback_t *pP2P_NDEF_PullCb = NULL; static unsigned short P2P_SnepClient_DelayCount = NDEF_PUSH_DELAY_COUNT; -static void ParseLlcp(unsigned char *pBuf, unsigned short BufSize, P2P_NDEF_LlcpHeader_t *pLlcpHeader) -{ - uint8_t i = 2; - - pLlcpHeader->Dsap = pBuf[0] >> 2; - pLlcpHeader->Pdu = ((pBuf[0] & 3) << 2) + (pBuf[1] >> 6); - pLlcpHeader->Ssap = pBuf[1] & 0x3F; - - while (i < BufSize) - { - switch (pBuf[i]) - { - case VERSION: - pLlcpHeader->Version = pBuf[i + 2]; - break; - case MIUX: - pLlcpHeader->Miux = (pBuf[i + 2] << 8) + pBuf[i + 3]; - break; - case WKS: - pLlcpHeader->Wks = (pBuf[i + 2] << 8) + pBuf[i + 3]; - break; - case LTO: - pLlcpHeader->Lto = pBuf[i + 2]; - break; - case RW: - pLlcpHeader->Rw = pBuf[i + 2]; - break; - case SN: - memcpy(pLlcpHeader->Sn, &pBuf[i + 2], pBuf[i + 1] < sizeof(pLlcpHeader->Sn) ? pBuf[i + 1] : sizeof(pLlcpHeader->Sn)); - break; - default: - break; - } - i += pBuf[i + 1] + 2; +static void ParseLlcp(unsigned char *pBuf, unsigned short BufSize, P2P_NDEF_LlcpHeader_t *pLlcpHeader) { + uint8_t i = 2; + + pLlcpHeader->Dsap = pBuf[0] >> 2; + pLlcpHeader->Pdu = ((pBuf[0] & 3) << 2) + (pBuf[1] >> 6); + pLlcpHeader->Ssap = pBuf[1] & 0x3F; + + while (i < BufSize) { + switch (pBuf[i]) { + case VERSION: + pLlcpHeader->Version = pBuf[i + 2]; + break; + case MIUX: + pLlcpHeader->Miux = (pBuf[i + 2] << 8) + pBuf[i + 3]; + break; + case WKS: + pLlcpHeader->Wks = (pBuf[i + 2] << 8) + pBuf[i + 3]; + break; + case LTO: + pLlcpHeader->Lto = pBuf[i + 2]; + break; + case RW: + pLlcpHeader->Rw = pBuf[i + 2]; + break; + case SN: + memcpy(pLlcpHeader->Sn, &pBuf[i + 2], pBuf[i + 1] < sizeof(pLlcpHeader->Sn) ? pBuf[i + 1] : sizeof(pLlcpHeader->Sn)); + break; + default: + break; } + i += pBuf[i + 1] + 2; + } } -static void FillLlcp(P2P_NDEF_LlcpHeader_t LlcpHeader, unsigned char *pBuf) -{ - pBuf[0] = (LlcpHeader.Ssap << 2) + ((LlcpHeader.Pdu >> 2) & 3); - pBuf[1] = (LlcpHeader.Pdu << 6) + LlcpHeader.Dsap; +static void FillLlcp(P2P_NDEF_LlcpHeader_t LlcpHeader, unsigned char *pBuf) { + pBuf[0] = (LlcpHeader.Ssap << 2) + ((LlcpHeader.Pdu >> 2) & 3); + pBuf[1] = (LlcpHeader.Pdu << 6) + LlcpHeader.Dsap; } -bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) -{ - if (Message_size <= P2P_NDEF_MAX_NDEF_MESSAGE_SIZE) - { - pNdefMessage = pMessage; - NdefMessage_size = Message_size; - pP2P_NDEF_PushCb = (P2P_NDEF_Callback_t *)pCb; - /* Trigger sending dynamically new message */ - if (eP2P_SnepClient_State == NdefMsgSent) - { - eP2P_SnepClient_State = SnepClientConnected; - } - return true; - } - else - { - NdefMessage_size = 0; - pP2P_NDEF_PushCb = NULL; - return false; +bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) { + if (Message_size <= P2P_NDEF_MAX_NDEF_MESSAGE_SIZE) { + pNdefMessage = pMessage; + NdefMessage_size = Message_size; + pP2P_NDEF_PushCb = (P2P_NDEF_Callback_t *)pCb; + /* Trigger sending dynamically new message */ + if (eP2P_SnepClient_State == NdefMsgSent) { + eP2P_SnepClient_State = SnepClientConnected; } + return true; + } else { + NdefMessage_size = 0; + pP2P_NDEF_PushCb = NULL; + return false; + } } -void P2P_NDEF_RegisterPullCallback(void *pCb) -{ - pP2P_NDEF_PullCb = (P2P_NDEF_Callback_t *)pCb; +void P2P_NDEF_RegisterPullCallback(void *pCb) { + pP2P_NDEF_PullCb = (P2P_NDEF_Callback_t *)pCb; } -void P2P_NDEF_Reset(void) -{ - if (NdefMessage_size != 0) - { - eP2P_SnepClient_State = Initial; - } - else - { - eP2P_SnepClient_State = Idle; - } +void P2P_NDEF_Reset(void) { + if (NdefMessage_size != 0) { + eP2P_SnepClient_State = Initial; + } else { + eP2P_SnepClient_State = Idle; + } } -void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size) -{ - P2P_NDEF_LlcpHeader_t LlcpHeader; +void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size) { + P2P_NDEF_LlcpHeader_t LlcpHeader; - /* Initialize answer */ - *pRsp_size = 0; + /* Initialize answer */ + *pRsp_size = 0; - ParseLlcp(pCmd, Cmd_size, &LlcpHeader); + ParseLlcp(pCmd, Cmd_size, &LlcpHeader); - switch (LlcpHeader.Pdu) - { + switch (LlcpHeader.Pdu) { case CONNECT: - /* Is connection from SNEP Client ? */ - if ((LlcpHeader.Dsap == SAP_SNEP) || (memcmp(LlcpHeader.Sn, "urn:nfc:sn:snep", 15) == 0)) - { - /* Only accept the connection is application is registered for NDEF reception */ - if (pP2P_NDEF_PullCb != NULL) - { - LlcpHeader.Pdu = CC; - FillLlcp(LlcpHeader, pRsp); - *pRsp_size = 2; - } - } - else - { - /* Refuse any other connection request */ - LlcpHeader.Pdu = DM; - FillLlcp(LlcpHeader, pRsp); - *pRsp_size = 2; + /* Is connection from SNEP Client ? */ + if ((LlcpHeader.Dsap == SAP_SNEP) || (memcmp(LlcpHeader.Sn, "urn:nfc:sn:snep", 15) == 0)) { + /* Only accept the connection is application is registered for NDEF reception */ + if (pP2P_NDEF_PullCb != NULL) { + LlcpHeader.Pdu = CC; + FillLlcp(LlcpHeader, pRsp); + *pRsp_size = 2; } - break; + } else { + /* Refuse any other connection request */ + LlcpHeader.Pdu = DM; + FillLlcp(LlcpHeader, pRsp); + *pRsp_size = 2; + } + break; case I: - /* Is SNEP PUT ? */ - if ((pCmd[3] == SNEP_VER10) && (pCmd[4] == SNEP_PUT)) - { - /* Notify application of the NDEF reception */ - if (pP2P_NDEF_PullCb != NULL) - pP2P_NDEF_PullCb(&pCmd[9], pCmd[8]); - - /* Acknowledge the PUT request */ - LlcpHeader.Pdu = I; - FillLlcp(LlcpHeader, pRsp); - pRsp[2] = (pCmd[2] >> 4) + 1; // N(R) - memcpy(&pRsp[3], SNEP_PUT_SUCCESS, sizeof(SNEP_PUT_SUCCESS)); - *pRsp_size = 9; - } - break; + /* Is SNEP PUT ? */ + if ((pCmd[3] == SNEP_VER10) && (pCmd[4] == SNEP_PUT)) { + /* Notify application of the NDEF reception */ + if (pP2P_NDEF_PullCb != NULL) + pP2P_NDEF_PullCb(&pCmd[9], pCmd[8]); + + /* Acknowledge the PUT request */ + LlcpHeader.Pdu = I; + FillLlcp(LlcpHeader, pRsp); + pRsp[2] = (pCmd[2] >> 4) + 1; // N(R) + memcpy(&pRsp[3], SNEP_PUT_SUCCESS, sizeof(SNEP_PUT_SUCCESS)); + *pRsp_size = 9; + } + break; case CC: - /* Connection to remote SNEP server completed, send NDEF message inside SNEP PUT request */ - eP2P_SnepClient_State = SnepClientConnected; - break; + /* Connection to remote SNEP server completed, send NDEF message inside SNEP PUT request */ + eP2P_SnepClient_State = SnepClientConnected; + break; default: + break; + } + + /* No answer was set */ + if (*pRsp_size == 0) { + switch (eP2P_SnepClient_State) { + case Initial: + if ((pP2P_NDEF_PullCb == NULL) || (NDEF_PUSH_DELAY_COUNT == 0)) { + memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP)); + *pRsp_size = sizeof(LLCP_CONNECT_SNEP); + eP2P_SnepClient_State = SnepClientConnecting; + } else { + P2P_SnepClient_DelayCount = 1; + eP2P_SnepClient_State = DelayingPush; + /* Wait then send a SYMM */ + Sleep(SYMM_FREQ); + memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); + *pRsp_size = sizeof(LLCP_SYMM); + } break; - } - /* No answer was set */ - if (*pRsp_size == 0) - { - switch (eP2P_SnepClient_State) - { - case Initial: - if ((pP2P_NDEF_PullCb == NULL) || (NDEF_PUSH_DELAY_COUNT == 0)) - { - memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP)); - *pRsp_size = sizeof(LLCP_CONNECT_SNEP); - eP2P_SnepClient_State = SnepClientConnecting; - } - else - { - P2P_SnepClient_DelayCount = 1; - eP2P_SnepClient_State = DelayingPush; - /* Wait then send a SYMM */ - Sleep(SYMM_FREQ); - memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); - *pRsp_size = sizeof(LLCP_SYMM); - } - break; - - case DelayingPush: - if (P2P_SnepClient_DelayCount == NDEF_PUSH_DELAY_COUNT) - { - memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP)); - *pRsp_size = sizeof(LLCP_CONNECT_SNEP); - eP2P_SnepClient_State = SnepClientConnecting; - } - else - { - P2P_SnepClient_DelayCount++; - /* Wait then send a SYMM */ - Sleep(SYMM_FREQ); - memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); - *pRsp_size = sizeof(LLCP_SYMM); - } - break; - - case SnepClientConnected: - LlcpHeader.Pdu = I; - FillLlcp(LlcpHeader, pRsp); - pRsp[2] = 0; // N(R) - pRsp[3] = SNEP_VER10; - pRsp[4] = SNEP_PUT; - pRsp[5] = 0; - pRsp[6] = 0; - pRsp[7] = 0; - pRsp[8] = (unsigned char)NdefMessage_size; - memcpy(&pRsp[9], pNdefMessage, NdefMessage_size); - *pRsp_size = 9 + NdefMessage_size; - eP2P_SnepClient_State = NdefMsgSent; - /* Notify application of the NDEF push */ - if (pP2P_NDEF_PushCb != NULL) - pP2P_NDEF_PushCb(pNdefMessage, NdefMessage_size); - break; - - default: - /* Wait then send a SYMM */ - Sleep(SYMM_FREQ); - memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); - *pRsp_size = sizeof(LLCP_SYMM); - break; + case DelayingPush: + if (P2P_SnepClient_DelayCount == NDEF_PUSH_DELAY_COUNT) { + memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP)); + *pRsp_size = sizeof(LLCP_CONNECT_SNEP); + eP2P_SnepClient_State = SnepClientConnecting; + } else { + P2P_SnepClient_DelayCount++; + /* Wait then send a SYMM */ + Sleep(SYMM_FREQ); + memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); + *pRsp_size = sizeof(LLCP_SYMM); } + break; + + case SnepClientConnected: + LlcpHeader.Pdu = I; + FillLlcp(LlcpHeader, pRsp); + pRsp[2] = 0; // N(R) + pRsp[3] = SNEP_VER10; + pRsp[4] = SNEP_PUT; + pRsp[5] = 0; + pRsp[6] = 0; + pRsp[7] = 0; + pRsp[8] = (unsigned char)NdefMessage_size; + memcpy(&pRsp[9], pNdefMessage, NdefMessage_size); + *pRsp_size = 9 + NdefMessage_size; + eP2P_SnepClient_State = NdefMsgSent; + /* Notify application of the NDEF push */ + if (pP2P_NDEF_PushCb != NULL) + pP2P_NDEF_PushCb(pNdefMessage, NdefMessage_size); + break; + + default: + /* Wait then send a SYMM */ + Sleep(SYMM_FREQ); + memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM)); + *pRsp_size = sizeof(LLCP_SYMM); + break; } + } } -//#endif +// #endif diff --git a/src/P2P_NDEF.h b/src/P2P_NDEF.h index 865a191..b67ebd8 100644 --- a/src/P2P_NDEF.h +++ b/src/P2P_NDEF.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ #include #define P2P_NDEF_MAX_NDEF_MESSAGE_SIZE 240 @@ -19,4 +19,4 @@ void P2P_NDEF_Reset(void); void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); void P2P_NDEF_RegisterPullCallback(void *pCb); bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb); -//void Sleep (unsigned int ms); +// void Sleep (unsigned int ms); diff --git a/src/Protocol.h b/src/Protocol.h new file mode 100644 index 0000000..eefefec --- /dev/null +++ b/src/Protocol.h @@ -0,0 +1,43 @@ +/** + * Library to get the protocol of the NFC card + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef Protocol_H +#define Protocol_H + +/* + * Flag definition used as Protocol values + */ +#define PROT_UNDETERMINED 0x0 +#define PROT_T1T 0x1 // NFC FORUM Type 1 Tag (based on Topaz/Jewel) ISO 14443A +#define PROT_T2T 0x2 // NFC Type 2 Tag ISO 14443B +#define PROT_T3T 0x3 // NFC Type 3 Tag Sony FeliCa standard +#define PROT_ISODEP 0x4 // NFC Type 4 Tag ISO14443-4 +#define PROT_NFCDEP 0x5 // NFC Data Exchange Protocol +#define PROT_ISO15693 0x6 // NFC-V +#define PROT_MIFARE 0x80 // NFC Type 5 MIFARE Classic + +class Protocol { + public: + enum Value { + UNDETERMINED = 0x0, + T1T = 0x1, + T2T = 0x2, + T3T = 0x3, + ISODEP = 0x4, + NFCDEP = 0x5, + ISO15693 = 0x6, + MIFARE = 0x80 + }; +}; + +#endif \ No newline at end of file diff --git a/src/RW_NDEF.cpp b/src/RW_NDEF.cpp index b12cc50..a8b6951 100644 --- a/src/RW_NDEF.cpp +++ b/src/RW_NDEF.cpp @@ -1,25 +1,24 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" + +#include "RW_NDEF_MIFARE.h" #include "RW_NDEF_T1T.h" #include "RW_NDEF_T2T.h" #include "RW_NDEF_T3T.h" #include "RW_NDEF_T4T.h" -#include "RW_NDEF_MIFARE.h" /* Allocate buffer for NDEF operations */ unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE]; @@ -31,77 +30,76 @@ unsigned short RW_NdefMessage_size; RW_NDEF_Callback_t *pRW_NDEF_PullCb; RW_NDEF_Callback_t *pRW_NDEF_PushCb; +RW_NDEF_Callback_t *updateNdefMessageCallback; +CustomCallback_t *ndefReceivedCallback; static RW_NDEF_Fct_t *pReadFct = NULL; static RW_NDEF_Fct_t *pWriteFct = NULL; -bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) -{ - if (Message_size <= RW_MAX_NDEF_FILE_SIZE) - { - pRW_NdefMessage = pMessage; - RW_NdefMessage_size = Message_size; - pRW_NDEF_PushCb = (RW_NDEF_Callback_t *)pCb; - return true; - } - else - { - RW_NdefMessage_size = 0; - pRW_NDEF_PushCb = NULL; - return false; - } +bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) { + if (Message_size <= RW_MAX_NDEF_FILE_SIZE) { + pRW_NdefMessage = pMessage; + RW_NdefMessage_size = Message_size; + pRW_NDEF_PushCb = (RW_NDEF_Callback_t *)pCb; + return true; + } else { + RW_NdefMessage_size = 0; + pRW_NDEF_PushCb = NULL; + return false; + } +} + +void RW_NDEF_RegisterPullCallback(void *pCb) { + pRW_NDEF_PullCb = (RW_NDEF_Callback_t *)pCb; +} + +void registerUpdateNdefMessageCallback(RW_NDEF_Callback_t function) { + updateNdefMessageCallback = function; } -void RW_NDEF_RegisterPullCallback(void *pCb) -{ - pRW_NDEF_PullCb = (RW_NDEF_Callback_t *)pCb; +void registerNdefReceivedCallback(CustomCallback_t function) { + ndefReceivedCallback = function; } -void RW_NDEF_Reset(unsigned char type) -{ - pReadFct = NULL; - pWriteFct = NULL; +void RW_NDEF_Reset(unsigned char type) { + pReadFct = NULL; + pWriteFct = NULL; - switch (type) - { + switch (type) { case RW_NDEF_TYPE_T1T: - RW_NDEF_T1T_Reset(); - pReadFct = RW_NDEF_T1T_Read_Next; - break; + RW_NDEF_T1T_Reset(); + pReadFct = RW_NDEF_T1T_Read_Next; + break; case RW_NDEF_TYPE_T2T: - RW_NDEF_T2T_Reset(); - pReadFct = RW_NDEF_T2T_Read_Next; - pWriteFct = RW_NDEF_T2T_Write_Next; - break; + RW_NDEF_T2T_Reset(); + pReadFct = RW_NDEF_T2T_Read_Next; + pWriteFct = RW_NDEF_T2T_Write_Next; + break; case RW_NDEF_TYPE_T3T: - RW_NDEF_T3T_Reset(); - pReadFct = RW_NDEF_T3T_Read_Next; - break; + RW_NDEF_T3T_Reset(); + pReadFct = RW_NDEF_T3T_Read_Next; + break; case RW_NDEF_TYPE_T4T: - RW_NDEF_T4T_Reset(); - pReadFct = RW_NDEF_T4T_Read_Next; - pWriteFct = RW_NDEF_T4T_Write_Next; - break; + RW_NDEF_T4T_Reset(); + pReadFct = RW_NDEF_T4T_Read_Next; + pWriteFct = RW_NDEF_T4T_Write_Next; + break; case RW_NDEF_TYPE_MIFARE: - RW_NDEF_MIFARE_Reset(); - pReadFct = RW_NDEF_MIFARE_Read_Next; - pWriteFct = RW_NDEF_MIFARE_Write_Next; - break; + RW_NDEF_MIFARE_Reset(); + pReadFct = RW_NDEF_MIFARE_Read_Next; + pWriteFct = RW_NDEF_MIFARE_Write_Next; + break; default: - break; - } + break; + } } -void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) -{ - if (pReadFct != NULL) - pReadFct(pCmd, Cmd_size, Rsp, pRsp_size); +void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) { + if (pReadFct != NULL) + pReadFct(pCmd, Cmd_size, Rsp, pRsp_size); } -void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) -{ - if (pWriteFct != NULL) - pWriteFct(pCmd, Cmd_size, Rsp, pRsp_size); +void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) { + if (pWriteFct != NULL) + pWriteFct(pCmd, Cmd_size, Rsp, pRsp_size); } -//#endif -//#endif diff --git a/src/RW_NDEF.h b/src/RW_NDEF.h index 615a434..71898ee 100644 --- a/src/RW_NDEF.h +++ b/src/RW_NDEF.h @@ -1,28 +1,29 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ #include #define RW_MAX_NDEF_FILE_SIZE 500 extern unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE]; -typedef void RW_NDEF_Callback_t (unsigned char*, unsigned short); +typedef void RW_NDEF_Callback_t(unsigned char *, unsigned short); +typedef void CustomCallback_t(void); -#define RW_NDEF_TYPE_T1T 0x1 -#define RW_NDEF_TYPE_T2T 0x2 -#define RW_NDEF_TYPE_T3T 0x3 -#define RW_NDEF_TYPE_T4T 0x4 +#define RW_NDEF_TYPE_T1T 0x1 +#define RW_NDEF_TYPE_T2T 0x2 +#define RW_NDEF_TYPE_T3T 0x3 +#define RW_NDEF_TYPE_T4T 0x4 #define RW_NDEF_TYPE_MIFARE 0x80 extern unsigned char *pRW_NdefMessage; @@ -30,7 +31,13 @@ extern unsigned short RW_NdefMessage_size; extern RW_NDEF_Callback_t *pRW_NDEF_PullCb; extern RW_NDEF_Callback_t *pRW_NDEF_PushCb; +extern RW_NDEF_Callback_t *updateNdefMessageCallback; +extern CustomCallback_t *ndefReceivedCallback; void RW_NDEF_Reset(unsigned char type); void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); +bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb); +void RW_NDEF_RegisterPullCallback(void *pCb); +void registerUpdateNdefMessageCallback(RW_NDEF_Callback_t function); +void registerNdefReceivedCallback(CustomCallback_t function); diff --git a/src/RW_NDEF_MIFARE.cpp b/src/RW_NDEF_MIFARE.cpp index 0de89fd..0f6fa21 100644 --- a/src/RW_NDEF_MIFARE.cpp +++ b/src/RW_NDEF_MIFARE.cpp @@ -1,21 +1,21 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef RW_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" +#include "tool.h" /* TODO: Only simplified scenario is implemented yet: @@ -26,342 +26,324 @@ #define MIFARE_NFC_CLUSTER 0x03 #define MIFARE_NDEF_TLV 0x03 -typedef enum -{ - Initial, - Authenticated0, - Reading_GPB, - Authenticated, - Reading_FirstBlk, - Reading_Data, - Writing_Data1, - Writing_Data2, - Writing_Data +typedef enum { + Initial, + Authenticated0, + Reading_GPB, + Authenticated, + Reading_FirstBlk, + Reading_Data, + Writing_Data1, + Writing_Data2, + Writing_Data } RW_NDEF_MIFARE_state_t; typedef struct { - bool WriteOp; - unsigned char BlkNb; - unsigned short MessagePtr; - unsigned short MessageSize; - unsigned char *pMessage; + bool WriteOp; + unsigned char BlkNb; + unsigned short MessagePtr; + unsigned short MessageSize; + unsigned char *pMessage; } RW_NDEF_MIFARE_Ndef_t; static RW_NDEF_MIFARE_state_t eRW_NDEF_MIFARE_State = Initial; static RW_NDEF_MIFARE_Ndef_t RW_NDEF_MIFARE_Ndef; -void RW_NDEF_MIFARE_Reset(void) -{ - eRW_NDEF_MIFARE_State = Initial; - RW_NDEF_MIFARE_Ndef.pMessage = NdefBuffer; +void RW_NDEF_MIFARE_Reset(void) { + eRW_NDEF_MIFARE_State = Initial; + RW_NDEF_MIFARE_Ndef.pMessage = NdefBuffer; } -void RW_NDEF_MIFARE_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_MIFARE_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_MIFARE_State) - { + switch (eRW_NDEF_MIFARE_State) { case Initial: - /* Authenticating first sector */ - pCmd[0] = 0x40; - pCmd[1] = 0x00; - pCmd[2] = 0x00; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Authenticated0; - break; + /* Authenticating first sector */ + pCmd[0] = 0x40; + pCmd[1] = 0x00; + pCmd[2] = 0x00; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Authenticated0; + break; case Authenticated0: - if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Read GPB */ - pCmd[0] = 0x10; - pCmd[1] = 0x30; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Reading_GPB; - } - break; + if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Read GPB */ + pCmd[0] = 0x10; + pCmd[1] = 0x30; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Reading_GPB; + } + break; case Reading_GPB: - if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF format ?*/ - if ((pRsp[3] == MIFARE_NFC_CLUSTER) && (pRsp[4] == MIFARE_FUNCTION_CLUSTER)) - { - pCmd[0] = 0x40; - pCmd[1] = 0x01; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Authenticated; - - RW_NDEF_MIFARE_Ndef.BlkNb = 4; - } + if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF format ?*/ + if ((pRsp[3] == MIFARE_NFC_CLUSTER) && (pRsp[4] == MIFARE_FUNCTION_CLUSTER)) { + pCmd[0] = 0x40; + pCmd[1] = 0x01; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Authenticated; + + RW_NDEF_MIFARE_Ndef.BlkNb = 4; } - break; + } + break; case Authenticated: - if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* First NDEF data block to read ?*/ - if (RW_NDEF_MIFARE_Ndef.BlkNb == 4) - { - eRW_NDEF_MIFARE_State = Reading_FirstBlk; - } - else - { - RW_NDEF_MIFARE_Ndef.BlkNb++; - eRW_NDEF_MIFARE_State = Reading_Data; - } - - /* Read block */ - pCmd[0] = 0x10; - pCmd[1] = 0x30; - pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; - *pCmd_size = 3; + if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) { + /* First NDEF data block to read ?*/ + if (RW_NDEF_MIFARE_Ndef.BlkNb == 4) { + eRW_NDEF_MIFARE_State = Reading_FirstBlk; + } else { + RW_NDEF_MIFARE_Ndef.BlkNb++; + eRW_NDEF_MIFARE_State = Reading_Data; } - break; + + /* Read block */ + pCmd[0] = 0x10; + pCmd[1] = 0x30; + pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; + *pCmd_size = 3; + } + break; case Reading_FirstBlk: - if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) - { - unsigned char Tmp = 1; - /* If not NDEF Type skip TLV */ - while (pRsp[Tmp] != MIFARE_NDEF_TLV) - { - Tmp += 2 + pRsp[Tmp + 1]; - if (Tmp > Rsp_size) - return; - } - - if (pRsp[Tmp + 1] == 0xFF) - { - RW_NDEF_MIFARE_Ndef.MessageSize = (pRsp[Tmp + 2] << 8) + pRsp[Tmp + 3]; - Tmp += 2; - } - else - RW_NDEF_MIFARE_Ndef.MessageSize = pRsp[Tmp + 1]; - - /* If provisioned buffer is not large enough or message is empty, notify the application and stop reading */ - if ((RW_NDEF_MIFARE_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_MIFARE_Ndef.MessageSize == 0)) - { - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(NULL, 0); - break; - } - - /* Is NDEF read already completed ? */ - if (RW_NDEF_MIFARE_Ndef.MessageSize <= ((Rsp_size - 1) - Tmp - 2)) - { - memcpy(RW_NDEF_MIFARE_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_MIFARE_Ndef.MessageSize); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); - } - else - { - RW_NDEF_MIFARE_Ndef.MessagePtr = (Rsp_size - 1) - Tmp - 2; - memcpy(RW_NDEF_MIFARE_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_MIFARE_Ndef.MessagePtr); - RW_NDEF_MIFARE_Ndef.BlkNb++; - - /* Read next block */ - pCmd[0] = 0x10; - pCmd[1] = 0x30; - pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Reading_Data; - } + if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) { + unsigned char Tmp = 1; + /* If not NDEF Type skip TLV */ + while (pRsp[Tmp] != MIFARE_NDEF_TLV) { + Tmp += 2 + pRsp[Tmp + 1]; + if (Tmp > Rsp_size) + return; + } + + if (pRsp[Tmp + 1] == 0xFF) { + RW_NDEF_MIFARE_Ndef.MessageSize = (pRsp[Tmp + 2] << 8) + pRsp[Tmp + 3]; + Tmp += 2; + } else + RW_NDEF_MIFARE_Ndef.MessageSize = pRsp[Tmp + 1]; + + /* If provisioned buffer is not large enough or message is empty, notify the application and stop reading */ + if ((RW_NDEF_MIFARE_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_MIFARE_Ndef.MessageSize == 0)) { + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(NULL, 0); + + // Run custom callbacks + if (updateNdefMessageCallback != NULL) { + updateNdefMessageCallback(NULL, 0); + } + + if (ndefReceivedCallback != NULL) { + ndefReceivedCallback(); + } + + break; } - break; + + /* Is NDEF read already completed ? */ + if (RW_NDEF_MIFARE_Ndef.MessageSize <= ((Rsp_size - 1) - Tmp - 2)) { + memcpy(RW_NDEF_MIFARE_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_MIFARE_Ndef.MessageSize); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) { + pRW_NDEF_PullCb(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); + } + + // Run custom callbacks + if (updateNdefMessageCallback != NULL) { + updateNdefMessageCallback(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); + } + + if (ndefReceivedCallback != NULL) { + ndefReceivedCallback(); + } + } else { + RW_NDEF_MIFARE_Ndef.MessagePtr = (Rsp_size - 1) - Tmp - 2; + memcpy(RW_NDEF_MIFARE_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_MIFARE_Ndef.MessagePtr); + RW_NDEF_MIFARE_Ndef.BlkNb++; + + /* Read next block */ + pCmd[0] = 0x10; + pCmd[1] = 0x30; + pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Reading_Data; + } + } + break; case Reading_Data: - if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF read already completed ? */ - if ((RW_NDEF_MIFARE_Ndef.MessageSize - RW_NDEF_MIFARE_Ndef.MessagePtr) < 16) - { - memcpy(&RW_NDEF_MIFARE_Ndef.pMessage[RW_NDEF_MIFARE_Ndef.MessagePtr], pRsp + 1, RW_NDEF_MIFARE_Ndef.MessageSize - RW_NDEF_MIFARE_Ndef.MessagePtr); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); - } - else - { - memcpy(&RW_NDEF_MIFARE_Ndef.pMessage[RW_NDEF_MIFARE_Ndef.MessagePtr], pRsp + 1, 16); - RW_NDEF_MIFARE_Ndef.MessagePtr += 16; - RW_NDEF_MIFARE_Ndef.BlkNb++; - - /* Is Blk on next sector ?*/ - if (((RW_NDEF_MIFARE_Ndef.BlkNb + 1) % 4) == 0) - { - /* Authenticate next block */ - pCmd[0] = 0x40; - pCmd[1] = (RW_NDEF_MIFARE_Ndef.BlkNb + 1) / 4; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Authenticated; - } - else - { - /* Read next block */ - pCmd[0] = 0x10; - pCmd[1] = 0x30; - pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; - *pCmd_size = 3; - } - } + if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF read already completed ? */ + if ((RW_NDEF_MIFARE_Ndef.MessageSize - RW_NDEF_MIFARE_Ndef.MessagePtr) < 16) { + memcpy(&RW_NDEF_MIFARE_Ndef.pMessage[RW_NDEF_MIFARE_Ndef.MessagePtr], pRsp + 1, RW_NDEF_MIFARE_Ndef.MessageSize - RW_NDEF_MIFARE_Ndef.MessagePtr); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) { + pRW_NDEF_PullCb(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); + } + + // Run custom callbacks + if (updateNdefMessageCallback != NULL) { + updateNdefMessageCallback(RW_NDEF_MIFARE_Ndef.pMessage, RW_NDEF_MIFARE_Ndef.MessageSize); + } + + if (ndefReceivedCallback != NULL) { + ndefReceivedCallback(); + } + } else { + memcpy(&RW_NDEF_MIFARE_Ndef.pMessage[RW_NDEF_MIFARE_Ndef.MessagePtr], pRsp + 1, 16); + RW_NDEF_MIFARE_Ndef.MessagePtr += 16; + RW_NDEF_MIFARE_Ndef.BlkNb++; + + /* Is Blk on next sector ?*/ + if (((RW_NDEF_MIFARE_Ndef.BlkNb + 1) % 4) == 0) { + /* Authenticate next block */ + pCmd[0] = 0x40; + pCmd[1] = (RW_NDEF_MIFARE_Ndef.BlkNb + 1) / 4; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Authenticated; + } else { + /* Read next block */ + pCmd[0] = 0x10; + pCmd[1] = 0x30; + pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; + *pCmd_size = 3; + } } - break; + } + break; default: - break; - } + break; + } } -void RW_NDEF_MIFARE_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_MIFARE_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_MIFARE_State) - { + switch (eRW_NDEF_MIFARE_State) { case Initial: - /* Authenticating first sector */ - pCmd[0] = 0x40; - pCmd[1] = 0x00; - pCmd[2] = 0x00; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Authenticated0; - break; + /* Authenticating first sector */ + pCmd[0] = 0x40; + pCmd[1] = 0x00; + pCmd[2] = 0x00; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Authenticated0; + break; case Authenticated0: - if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Read MAD */ - pCmd[0] = 0x10; - pCmd[1] = 0x30; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Reading_GPB; - } - break; + if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Read MAD */ + pCmd[0] = 0x10; + pCmd[1] = 0x30; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Reading_GPB; + } + break; case Reading_GPB: - if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF format ?*/ - if ((pRsp[3] == MIFARE_NFC_CLUSTER) && (pRsp[4] == MIFARE_FUNCTION_CLUSTER)) - { - pCmd[0] = 0x40; - pCmd[1] = 0x01; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Writing_Data1; - RW_NDEF_MIFARE_Ndef.MessagePtr = 0; - RW_NDEF_MIFARE_Ndef.BlkNb = 4; - } + if ((Rsp_size == 18) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF format ?*/ + if ((pRsp[3] == MIFARE_NFC_CLUSTER) && (pRsp[4] == MIFARE_FUNCTION_CLUSTER)) { + pCmd[0] = 0x40; + pCmd[1] = 0x01; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Writing_Data1; + RW_NDEF_MIFARE_Ndef.MessagePtr = 0; + RW_NDEF_MIFARE_Ndef.BlkNb = 4; } - break; + } + break; case Writing_Data1: - if ((pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF write already completed ? */ - if (RW_NdefMessage_size <= RW_NDEF_MIFARE_Ndef.MessagePtr) - { - /* Notify application of the NDEF send completion */ - if (pRW_NDEF_PushCb != NULL) - pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); - } - else if (((RW_NDEF_MIFARE_Ndef.BlkNb + 1) % 4) == 0) - { - /* Authenticate next block */ - pCmd[0] = 0x40; - pCmd[1] = (RW_NDEF_MIFARE_Ndef.BlkNb + 1) / 4; - pCmd[2] = 0x01; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Writing_Data1; - RW_NDEF_MIFARE_Ndef.BlkNb++; - } - else - { - pCmd[0] = 0x10; - pCmd[1] = 0xA0; - pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; - *pCmd_size = 3; - eRW_NDEF_MIFARE_State = Writing_Data2; - } + if ((pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF write already completed ? */ + if (RW_NdefMessage_size <= RW_NDEF_MIFARE_Ndef.MessagePtr) { + /* Notify application of the NDEF send completion */ + if (pRW_NDEF_PushCb != NULL) + pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); + } else if (((RW_NDEF_MIFARE_Ndef.BlkNb + 1) % 4) == 0) { + /* Authenticate next block */ + pCmd[0] = 0x40; + pCmd[1] = (RW_NDEF_MIFARE_Ndef.BlkNb + 1) / 4; + pCmd[2] = 0x01; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Writing_Data1; + RW_NDEF_MIFARE_Ndef.BlkNb++; + } else { + pCmd[0] = 0x10; + pCmd[1] = 0xA0; + pCmd[2] = RW_NDEF_MIFARE_Ndef.BlkNb; + *pCmd_size = 3; + eRW_NDEF_MIFARE_State = Writing_Data2; } - break; + } + break; case Writing_Data2: - if ((Rsp_size == 3) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* First block to write ? */ - if (RW_NDEF_MIFARE_Ndef.BlkNb == 4) - { - pCmd[0] = 0x10; - pCmd[1] = 0x00; - pCmd[2] = 0x00; - pCmd[3] = 0x03; - if (RW_NdefMessage_size > 0xFF) - { - pCmd[4] = 0xFF; - pCmd[5] = (RW_NdefMessage_size & 0xFF00) >> 8; - pCmd[6] = RW_NdefMessage_size & 0xFF; - memcpy(&pCmd[7], pRW_NdefMessage, 10); - RW_NDEF_MIFARE_Ndef.MessagePtr = 10; - } - else - { - pCmd[4] = (unsigned char)RW_NdefMessage_size; - memcpy(&pCmd[5], pRW_NdefMessage, 12); - RW_NDEF_MIFARE_Ndef.MessagePtr = 12; - } - } - else - { - pCmd[0] = 0x10; - memcpy(&pCmd[1], pRW_NdefMessage + RW_NDEF_MIFARE_Ndef.MessagePtr, 16); - RW_NDEF_MIFARE_Ndef.MessagePtr += 16; - } - *pCmd_size = 17; - RW_NDEF_MIFARE_Ndef.BlkNb++; - eRW_NDEF_MIFARE_State = Writing_Data1; + if ((Rsp_size == 3) && (pRsp[Rsp_size - 1] == 0x00)) { + /* First block to write ? */ + if (RW_NDEF_MIFARE_Ndef.BlkNb == 4) { + pCmd[0] = 0x10; + pCmd[1] = 0x00; + pCmd[2] = 0x00; + pCmd[3] = 0x03; + if (RW_NdefMessage_size > 0xFF) { + pCmd[4] = 0xFF; + pCmd[5] = (RW_NdefMessage_size & 0xFF00) >> 8; + pCmd[6] = RW_NdefMessage_size & 0xFF; + memcpy(&pCmd[7], pRW_NdefMessage, 10); + RW_NDEF_MIFARE_Ndef.MessagePtr = 10; + } else { + pCmd[4] = (unsigned char)RW_NdefMessage_size; + memcpy(&pCmd[5], pRW_NdefMessage, 12); + RW_NDEF_MIFARE_Ndef.MessagePtr = 12; + } + } else { + pCmd[0] = 0x10; + memcpy(&pCmd[1], pRW_NdefMessage + RW_NDEF_MIFARE_Ndef.MessagePtr, 16); + RW_NDEF_MIFARE_Ndef.MessagePtr += 16; } - break; + *pCmd_size = 17; + RW_NDEF_MIFARE_Ndef.BlkNb++; + eRW_NDEF_MIFARE_State = Writing_Data1; + } + break; case Writing_Data: - if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF write already completed ? */ - if (RW_NdefMessage_size <= RW_NDEF_MIFARE_Ndef.MessagePtr) - { - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PushCb != NULL) - pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); - } - else - { - /* Write NDEF content */ - pCmd[0] = 0xA2; - pCmd[1] = RW_NDEF_MIFARE_Ndef.BlkNb; - memcpy(&pCmd[2], pRW_NdefMessage + RW_NDEF_MIFARE_Ndef.MessagePtr, 4); - *pCmd_size = 6; - - RW_NDEF_MIFARE_Ndef.MessagePtr += 4; - RW_NDEF_MIFARE_Ndef.BlkNb++; - } + if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF write already completed ? */ + if (RW_NdefMessage_size <= RW_NDEF_MIFARE_Ndef.MessagePtr) { + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PushCb != NULL) + pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); + } else { + /* Write NDEF content */ + pCmd[0] = 0xA2; + pCmd[1] = RW_NDEF_MIFARE_Ndef.BlkNb; + memcpy(&pCmd[2], pRW_NdefMessage + RW_NDEF_MIFARE_Ndef.MessagePtr, 4); + *pCmd_size = 6; + + RW_NDEF_MIFARE_Ndef.MessagePtr += 4; + RW_NDEF_MIFARE_Ndef.BlkNb++; } - break; + } + break; default: - break; - } + break; + } } -//#endif -//#endif +// #endif +// #endif diff --git a/src/RW_NDEF_MIFARE.h b/src/RW_NDEF_MIFARE.h index ff7c50b..13b312b 100644 --- a/src/RW_NDEF_MIFARE.h +++ b/src/RW_NDEF_MIFARE.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ void RW_NDEF_MIFARE_Reset(void); void RW_NDEF_MIFARE_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); diff --git a/src/RW_NDEF_T1T.cpp b/src/RW_NDEF_T1T.cpp index 7168cdb..f3cfe0a 100644 --- a/src/RW_NDEF_T1T.cpp +++ b/src/RW_NDEF_T1T.cpp @@ -1,21 +1,21 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef RW_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" +#include "tool.h" #define T1T_MAGIC_NUMBER 0xE1 #define T1T_NDEF_TLV 0x03 @@ -24,152 +24,136 @@ const unsigned char T1T_RID[] = {0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char T1T_RALL[] = {0x00, 0x00, 0x00}; const unsigned char T1T_READ8[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -typedef enum -{ - Initial, - Getting_ID, - Reading_CardContent, - Reading_NDEF +typedef enum { + Initial, + Getting_ID, + Reading_CardContent, + Reading_NDEF } RW_NDEF_T1T_state_t; typedef struct { - unsigned char HR0; - unsigned char HR1; - unsigned char UID[4]; - unsigned char BlkNb; - unsigned short MessagePtr; - unsigned short MessageSize; - unsigned char *pMessage; + unsigned char HR0; + unsigned char HR1; + unsigned char UID[4]; + unsigned char BlkNb; + unsigned short MessagePtr; + unsigned short MessageSize; + unsigned char *pMessage; } RW_NDEF_T1T_Ndef_t; static RW_NDEF_T1T_state_t eRW_NDEF_T1T_State = Initial; static RW_NDEF_T1T_Ndef_t RW_NDEF_T1T_Ndef; -void RW_NDEF_T1T_Reset(void) -{ - eRW_NDEF_T1T_State = Initial; - RW_NDEF_T1T_Ndef.pMessage = NdefBuffer; +void RW_NDEF_T1T_Reset(void) { + eRW_NDEF_T1T_State = Initial; + RW_NDEF_T1T_Ndef.pMessage = NdefBuffer; } -void RW_NDEF_T1T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T1T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T1T_State) - { + switch (eRW_NDEF_T1T_State) { case Initial: - /* Send T1T_RID */ - memcpy(pCmd, T1T_RID, sizeof(T1T_RID)); - *pCmd_size = 7; - eRW_NDEF_T1T_State = Getting_ID; - break; + /* Send T1T_RID */ + memcpy(pCmd, T1T_RID, sizeof(T1T_RID)); + *pCmd_size = 7; + eRW_NDEF_T1T_State = Getting_ID; + break; case Getting_ID: - /* Is CC Read and Is Ndef ?*/ - if ((Rsp_size == 7) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Fill File structure */ - RW_NDEF_T1T_Ndef.HR0 = pRsp[0]; - RW_NDEF_T1T_Ndef.HR1 = pRsp[1]; - memcpy(RW_NDEF_T1T_Ndef.UID, &pRsp[2], sizeof(RW_NDEF_T1T_Ndef.UID)); - - /* Read full card content */ - memcpy(pCmd, T1T_RALL, sizeof(T1T_RALL)); - memcpy(&pCmd[3], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); - *pCmd_size = sizeof(T1T_RALL) + sizeof(RW_NDEF_T1T_Ndef.UID); - eRW_NDEF_T1T_State = Reading_CardContent; - } - break; + /* Is CC Read and Is Ndef ?*/ + if ((Rsp_size == 7) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Fill File structure */ + RW_NDEF_T1T_Ndef.HR0 = pRsp[0]; + RW_NDEF_T1T_Ndef.HR1 = pRsp[1]; + memcpy(RW_NDEF_T1T_Ndef.UID, &pRsp[2], sizeof(RW_NDEF_T1T_Ndef.UID)); + + /* Read full card content */ + memcpy(pCmd, T1T_RALL, sizeof(T1T_RALL)); + memcpy(&pCmd[3], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); + *pCmd_size = sizeof(T1T_RALL) + sizeof(RW_NDEF_T1T_Ndef.UID); + eRW_NDEF_T1T_State = Reading_CardContent; + } + break; case Reading_CardContent: - /* Is Read success ?*/ - if ((Rsp_size == 123) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Check CC */ - if (pRsp[10] == T1T_MAGIC_NUMBER) - { - unsigned char Tmp = 14; - unsigned char data_size; - - /* If not NDEF Type skip TLV */ - while (pRsp[Tmp] != T1T_NDEF_TLV) - { - Tmp += 2 + pRsp[Tmp + 1]; - if (Tmp > Rsp_size) - return; - } - - RW_NDEF_T1T_Ndef.MessageSize = pRsp[Tmp + 1]; - data_size = (Rsp_size - 1) - 16 - Tmp - 2; - - /* If provisioned buffer is not large enough, notify the application and stop reading */ - if (RW_NDEF_T1T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) - { - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(NULL, 0); - break; - } - - /* Is NDEF read already completed ? */ - if (RW_NDEF_T1T_Ndef.MessageSize <= data_size) - { - memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessageSize); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); - } - else - { - RW_NDEF_T1T_Ndef.MessagePtr = data_size; - memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessagePtr); - RW_NDEF_T1T_Ndef.BlkNb = 0x10; - - /* Read NDEF content */ - memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); - pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; - memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); - *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); - - eRW_NDEF_T1T_State = Reading_NDEF; - } - } + /* Is Read success ?*/ + if ((Rsp_size == 123) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Check CC */ + if (pRsp[10] == T1T_MAGIC_NUMBER) { + unsigned char Tmp = 14; + unsigned char data_size; + + /* If not NDEF Type skip TLV */ + while (pRsp[Tmp] != T1T_NDEF_TLV) { + Tmp += 2 + pRsp[Tmp + 1]; + if (Tmp > Rsp_size) + return; + } + + RW_NDEF_T1T_Ndef.MessageSize = pRsp[Tmp + 1]; + data_size = (Rsp_size - 1) - 16 - Tmp - 2; + + /* If provisioned buffer is not large enough, notify the application and stop reading */ + if (RW_NDEF_T1T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) { + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(NULL, 0); + break; + } + + /* Is NDEF read already completed ? */ + if (RW_NDEF_T1T_Ndef.MessageSize <= data_size) { + memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessageSize); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); + } else { + RW_NDEF_T1T_Ndef.MessagePtr = data_size; + memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessagePtr); + RW_NDEF_T1T_Ndef.BlkNb = 0x10; + + /* Read NDEF content */ + memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); + pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; + memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); + *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); + + eRW_NDEF_T1T_State = Reading_NDEF; + } } - break; + } + break; case Reading_NDEF: - /* Is Read success ?*/ - if ((Rsp_size == 10) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF read already completed ? */ - if ((RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr) < 8) - { - memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); - } - else - { - memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], 8); - RW_NDEF_T1T_Ndef.MessagePtr += 8; - RW_NDEF_T1T_Ndef.BlkNb++; - - /* Read NDEF content */ - memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); - pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; - memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); - *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); - } + /* Is Read success ?*/ + if ((Rsp_size == 10) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF read already completed ? */ + if ((RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr) < 8) { + memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); + } else { + memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], 8); + RW_NDEF_T1T_Ndef.MessagePtr += 8; + RW_NDEF_T1T_Ndef.BlkNb++; + + /* Read NDEF content */ + memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); + pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; + memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); + *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); } - break; + } + break; default: - break; - } + break; + } } -//#endif -//#endif +// #endif +// #endif diff --git a/src/RW_NDEF_T1T.h b/src/RW_NDEF_T1T.h index f64a0f0..1ca0641 100644 --- a/src/RW_NDEF_T1T.h +++ b/src/RW_NDEF_T1T.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ void RW_NDEF_T1T_Reset(void); void RW_NDEF_T1T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); diff --git a/src/RW_NDEF_T2T.cpp b/src/RW_NDEF_T2T.cpp index bca1452..b242c04 100644 --- a/src/RW_NDEF_T2T.cpp +++ b/src/RW_NDEF_T2T.cpp @@ -1,240 +1,212 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef RW_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" +#include "tool.h" /* TODO: No support for tag larger than 1024 bytes (requiring SECTOR_SELECT command use) */ #define T2T_MAGIC_NUMBER 0xE1 #define T2T_NDEF_TLV 0x03 -typedef enum -{ - Initial, - Reading_CC, - Reading_Data, - Reading_NDEF, - Writing_Data +typedef enum { + Initial, + Reading_CC, + Reading_Data, + Reading_NDEF, + Writing_Data } RW_NDEF_T2T_state_t; typedef struct { - unsigned char BlkNb; - unsigned short MessagePtr; - unsigned short MessageSize; - unsigned char *pMessage; + unsigned char BlkNb; + unsigned short MessagePtr; + unsigned short MessageSize; + unsigned char *pMessage; } RW_NDEF_T2T_Ndef_t; static RW_NDEF_T2T_state_t eRW_NDEF_T2T_State = Initial; static RW_NDEF_T2T_Ndef_t RW_NDEF_T2T_Ndef; -void RW_NDEF_T2T_Reset(void) -{ - eRW_NDEF_T2T_State = Initial; - RW_NDEF_T2T_Ndef.pMessage = NdefBuffer; +void RW_NDEF_T2T_Reset(void) { + eRW_NDEF_T2T_State = Initial; + RW_NDEF_T2T_Ndef.pMessage = NdefBuffer; } -void RW_NDEF_T2T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T2T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T2T_State) - { + switch (eRW_NDEF_T2T_State) { case Initial: - /* Read CC */ + /* Read CC */ + pCmd[0] = 0x30; + pCmd[1] = 0x03; + *pCmd_size = 2; + eRW_NDEF_T2T_State = Reading_CC; + break; + + case Reading_CC: + /* Is CC Read and Is Ndef ?*/ + if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER)) { + /* Read First data */ pCmd[0] = 0x30; - pCmd[1] = 0x03; + pCmd[1] = 0x04; *pCmd_size = 2; - eRW_NDEF_T2T_State = Reading_CC; - break; - case Reading_CC: - /* Is CC Read and Is Ndef ?*/ - if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER)) - { - /* Read First data */ - pCmd[0] = 0x30; - pCmd[1] = 0x04; - *pCmd_size = 2; - - eRW_NDEF_T2T_State = Reading_Data; - } - break; + eRW_NDEF_T2T_State = Reading_Data; + } + break; case Reading_Data: - /* Is Read success ?*/ - if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) - { - unsigned char Tmp = 0; - /* If not NDEF Type skip TLV */ - while (pRsp[Tmp] != T2T_NDEF_TLV) - { - Tmp += 2 + pRsp[Tmp + 1]; - if (Tmp > Rsp_size) - return; - } - - if (pRsp[Tmp + 1] == 0xFF) - { - RW_NDEF_T2T_Ndef.MessageSize = (pRsp[Tmp + 2] << 8) + pRsp[Tmp + 3]; - Tmp += 2; - } - else - RW_NDEF_T2T_Ndef.MessageSize = pRsp[Tmp + 1]; - - /* If provisioned buffer is not large enough or message is empty, notify the application and stop reading */ - if ((RW_NDEF_T2T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T2T_Ndef.MessageSize == 0)) - { - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(NULL, 0); - break; - } - - /* Is NDEF read already completed ? */ - if (RW_NDEF_T2T_Ndef.MessageSize <= ((Rsp_size - 1) - Tmp - 2)) - { - memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessageSize); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); - } - else - { - RW_NDEF_T2T_Ndef.MessagePtr = (Rsp_size - 1) - Tmp - 2; - memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessagePtr); - RW_NDEF_T2T_Ndef.BlkNb = 8; - - /* Read NDEF content */ - pCmd[0] = 0x30; - pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; - *pCmd_size = 2; - eRW_NDEF_T2T_State = Reading_NDEF; - } + /* Is Read success ?*/ + if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) { + unsigned char Tmp = 0; + /* If not NDEF Type skip TLV */ + while (pRsp[Tmp] != T2T_NDEF_TLV) { + Tmp += 2 + pRsp[Tmp + 1]; + if (Tmp > Rsp_size) + return; + } + + if (pRsp[Tmp + 1] == 0xFF) { + RW_NDEF_T2T_Ndef.MessageSize = (pRsp[Tmp + 2] << 8) + pRsp[Tmp + 3]; + Tmp += 2; + } else + RW_NDEF_T2T_Ndef.MessageSize = pRsp[Tmp + 1]; + + /* If provisioned buffer is not large enough or message is empty, notify the application and stop reading */ + if ((RW_NDEF_T2T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T2T_Ndef.MessageSize == 0)) { + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(NULL, 0); + break; + } + + /* Is NDEF read already completed ? */ + if (RW_NDEF_T2T_Ndef.MessageSize <= ((Rsp_size - 1) - Tmp - 2)) { + memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessageSize); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); + } else { + RW_NDEF_T2T_Ndef.MessagePtr = (Rsp_size - 1) - Tmp - 2; + memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessagePtr); + RW_NDEF_T2T_Ndef.BlkNb = 8; + + /* Read NDEF content */ + pCmd[0] = 0x30; + pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; + *pCmd_size = 2; + eRW_NDEF_T2T_State = Reading_NDEF; } - break; + } + break; case Reading_NDEF: - /* Is Read success ?*/ - if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF read already completed ? */ - if ((RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr) < 16) - { - memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr); - - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); - } - else - { - memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, 16); - RW_NDEF_T2T_Ndef.MessagePtr += 16; - RW_NDEF_T2T_Ndef.BlkNb += 4; - - /* Read NDEF content */ - pCmd[0] = 0x30; - pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; - *pCmd_size = 2; - } + /* Is Read success ?*/ + if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF read already completed ? */ + if ((RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr) < 16) { + memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr); + + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); + } else { + memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, 16); + RW_NDEF_T2T_Ndef.MessagePtr += 16; + RW_NDEF_T2T_Ndef.BlkNb += 4; + + /* Read NDEF content */ + pCmd[0] = 0x30; + pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; + *pCmd_size = 2; } - break; + } + break; default: - break; - } + break; + } } -void RW_NDEF_T2T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T2T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T2T_State) - { + switch (eRW_NDEF_T2T_State) { case Initial: - /* Read CC */ - pCmd[0] = 0x30; - pCmd[1] = 0x03; - *pCmd_size = 2; - eRW_NDEF_T2T_State = Reading_CC; - break; + /* Read CC */ + pCmd[0] = 0x30; + pCmd[1] = 0x03; + *pCmd_size = 2; + eRW_NDEF_T2T_State = Reading_CC; + break; case Reading_CC: - /* Is CC Read, Is Ndef and is R/W ?*/ - if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER) && (pRsp[3] == 0x00)) - { - /* Is size enough ? */ - if (pRsp[2] * 8 >= RW_NdefMessage_size) - { - /* Write First data */ - pCmd[0] = 0xA2; - pCmd[1] = 0x04; - pCmd[2] = 0x03; - if (RW_NdefMessage_size > 0xFF) - { - pCmd[3] = 0xFF; - pCmd[4] = (RW_NdefMessage_size & 0xFF00) >> 8; - pCmd[5] = RW_NdefMessage_size & 0xFF; - RW_NDEF_T2T_Ndef.MessagePtr = 0; - } - else - { - pCmd[3] = (unsigned char)RW_NdefMessage_size; - memcpy(&pCmd[4], pRW_NdefMessage, 2); - RW_NDEF_T2T_Ndef.MessagePtr = 2; - } - RW_NDEF_T2T_Ndef.BlkNb = 5; - *pCmd_size = 6; - eRW_NDEF_T2T_State = Writing_Data; - } + /* Is CC Read, Is Ndef and is R/W ?*/ + if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER) && (pRsp[3] == 0x00)) { + /* Is size enough ? */ + if (pRsp[2] * 8 >= RW_NdefMessage_size) { + /* Write First data */ + pCmd[0] = 0xA2; + pCmd[1] = 0x04; + pCmd[2] = 0x03; + if (RW_NdefMessage_size > 0xFF) { + pCmd[3] = 0xFF; + pCmd[4] = (RW_NdefMessage_size & 0xFF00) >> 8; + pCmd[5] = RW_NdefMessage_size & 0xFF; + RW_NDEF_T2T_Ndef.MessagePtr = 0; + } else { + pCmd[3] = (unsigned char)RW_NdefMessage_size; + memcpy(&pCmd[4], pRW_NdefMessage, 2); + RW_NDEF_T2T_Ndef.MessagePtr = 2; + } + RW_NDEF_T2T_Ndef.BlkNb = 5; + *pCmd_size = 6; + eRW_NDEF_T2T_State = Writing_Data; } - break; + } + break; case Writing_Data: - /* Is Write success ?*/ - if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) - { - /* Is NDEF write already completed ? */ - if (RW_NdefMessage_size <= RW_NDEF_T2T_Ndef.MessagePtr) - { - /* Notify application of the NDEF send completion */ - if (pRW_NDEF_PushCb != NULL) - pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); - } - else - { - /* Write NDEF content */ - pCmd[0] = 0xA2; - pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; - memcpy(&pCmd[2], pRW_NdefMessage + RW_NDEF_T2T_Ndef.MessagePtr, 4); - *pCmd_size = 6; - - RW_NDEF_T2T_Ndef.MessagePtr += 4; - RW_NDEF_T2T_Ndef.BlkNb++; - } + /* Is Write success ?*/ + if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) { + /* Is NDEF write already completed ? */ + if (RW_NdefMessage_size <= RW_NDEF_T2T_Ndef.MessagePtr) { + /* Notify application of the NDEF send completion */ + if (pRW_NDEF_PushCb != NULL) + pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); + } else { + /* Write NDEF content */ + pCmd[0] = 0xA2; + pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; + memcpy(&pCmd[2], pRW_NdefMessage + RW_NDEF_T2T_Ndef.MessagePtr, 4); + *pCmd_size = 6; + + RW_NDEF_T2T_Ndef.MessagePtr += 4; + RW_NDEF_T2T_Ndef.BlkNb++; } - break; + } + break; default: - break; - } + break; + } } -//#endif -//#endif +// #endif +// #endif diff --git a/src/RW_NDEF_T2T.h b/src/RW_NDEF_T2T.h index b6bb928..106c08f 100644 --- a/src/RW_NDEF_T2T.h +++ b/src/RW_NDEF_T2T.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ void RW_NDEF_T2T_Reset(void); void RW_NDEF_T2T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); diff --git a/src/RW_NDEF_T3T.cpp b/src/RW_NDEF_T3T.cpp index a9e58c1..56d1ab2 100644 --- a/src/RW_NDEF_T3T.cpp +++ b/src/RW_NDEF_T3T.cpp @@ -1,127 +1,115 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef RW_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" +#include "tool.h" #define T3T_MAGIC_NUMBER 0xE1 #define T3T_NDEF_TLV 0x03 unsigned char T3T_Check[] = {0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x1, 0x80, 0x00}; -typedef enum -{ - Initial, - Getting_AttributeInfo, - Reading_CardContent +typedef enum { + Initial, + Getting_AttributeInfo, + Reading_CardContent } RW_NDEF_T3T_state_t; -typedef struct -{ - unsigned char IDm[8]; - unsigned char BlkNb; - unsigned short Ptr; - unsigned short Size; - unsigned char *p; +typedef struct { + unsigned char IDm[8]; + unsigned char BlkNb; + unsigned short Ptr; + unsigned short Size; + unsigned char *p; } RW_NDEF_T3T_Ndef_t; static RW_NDEF_T3T_state_t eRW_NDEF_T3T_State = Initial; static RW_NDEF_T3T_Ndef_t RW_NDEF_T3T_Ndef; -void RW_NDEF_T3T_Reset(void) -{ - eRW_NDEF_T3T_State = Initial; - RW_NDEF_T3T_Ndef.p = NdefBuffer; +void RW_NDEF_T3T_Reset(void) { + eRW_NDEF_T3T_State = Initial; + RW_NDEF_T3T_Ndef.p = NdefBuffer; } -void RW_NDEF_T3T_SetIDm(unsigned char *pIDm) -{ - memcpy(RW_NDEF_T3T_Ndef.IDm, pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); - memcpy(&T3T_Check[2], pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); +void RW_NDEF_T3T_SetIDm(unsigned char *pIDm) { + memcpy(RW_NDEF_T3T_Ndef.IDm, pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); + memcpy(&T3T_Check[2], pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); } -void RW_NDEF_T3T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T3T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T3T_State) - { + switch (eRW_NDEF_T3T_State) { case Initial: - /* Get AttributeInfo */ - memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); - *pCmd_size = sizeof(T3T_Check); - eRW_NDEF_T3T_State = Getting_AttributeInfo; - break; + /* Get AttributeInfo */ + memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); + *pCmd_size = sizeof(T3T_Check); + eRW_NDEF_T3T_State = Getting_AttributeInfo; + break; case Getting_AttributeInfo: - /* Is Check success ?*/ - if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) - { - /* Fill File structure */ - RW_NDEF_T3T_Ndef.Size = (pRsp[24] << 16) + (pRsp[25] << 16) + pRsp[26]; - - /* If provisioned buffer is not large enough or size is null, notify the application and stop reading */ - if ((RW_NDEF_T3T_Ndef.Size > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T3T_Ndef.Size == 0)) - { - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(NULL, 0); - break; - } - - RW_NDEF_T3T_Ndef.Ptr = 0; - RW_NDEF_T3T_Ndef.BlkNb = 1; - - /* Read first NDEF block */ - memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); - pCmd[15] = 0x01; - *pCmd_size = sizeof(T3T_Check); - eRW_NDEF_T3T_State = Reading_CardContent; + /* Is Check success ?*/ + if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) { + /* Fill File structure */ + RW_NDEF_T3T_Ndef.Size = (pRsp[24] << 16) + (pRsp[25] << 16) + pRsp[26]; + + /* If provisioned buffer is not large enough or size is null, notify the application and stop reading */ + if ((RW_NDEF_T3T_Ndef.Size > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T3T_Ndef.Size == 0)) { + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(NULL, 0); + break; } - break; + + RW_NDEF_T3T_Ndef.Ptr = 0; + RW_NDEF_T3T_Ndef.BlkNb = 1; + + /* Read first NDEF block */ + memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); + pCmd[15] = 0x01; + *pCmd_size = sizeof(T3T_Check); + eRW_NDEF_T3T_State = Reading_CardContent; + } + break; case Reading_CardContent: - /* Is Check success ?*/ - if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) - { - /* Is NDEF message read completed ?*/ - if ((RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr) <= 16) - { - memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], (RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr)); - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T3T_Ndef.p, RW_NDEF_T3T_Ndef.Size); - } - else - { - memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], 16); - RW_NDEF_T3T_Ndef.Ptr += 16; - RW_NDEF_T3T_Ndef.BlkNb++; - - /* Read next NDEF block */ - memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); - pCmd[15] = RW_NDEF_T3T_Ndef.BlkNb; - *pCmd_size = sizeof(T3T_Check); - } + /* Is Check success ?*/ + if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) { + /* Is NDEF message read completed ?*/ + if ((RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr) <= 16) { + memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], (RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr)); + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T3T_Ndef.p, RW_NDEF_T3T_Ndef.Size); + } else { + memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], 16); + RW_NDEF_T3T_Ndef.Ptr += 16; + RW_NDEF_T3T_Ndef.BlkNb++; + + /* Read next NDEF block */ + memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); + pCmd[15] = RW_NDEF_T3T_Ndef.BlkNb; + *pCmd_size = sizeof(T3T_Check); } - break; + } + break; default: - break; - } + break; + } } -//#endif -//#endif +// #endif +// #endif diff --git a/src/RW_NDEF_T3T.h b/src/RW_NDEF_T3T.h index a1fdc23..18b639f 100644 --- a/src/RW_NDEF_T3T.h +++ b/src/RW_NDEF_T3T.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ void RW_NDEF_T3T_Reset(void); void RW_NDEF_T3T_SetIDm(unsigned char *pIDm); diff --git a/src/RW_NDEF_T4T.cpp b/src/RW_NDEF_T4T.cpp index 97b4619..7244d2e 100644 --- a/src/RW_NDEF_T4T.cpp +++ b/src/RW_NDEF_T4T.cpp @@ -1,21 +1,21 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef RW_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef RW_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "RW_NDEF.h" +#include "tool.h" const unsigned char RW_NDEF_T4T_APP_Select20[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00}; const unsigned char RW_NDEF_T4T_APP_Select10[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00}; @@ -28,339 +28,304 @@ const unsigned char RW_NDEF_T4T_OK[] = {0x90, 0x00}; #define WRITE_SZ 54 -typedef enum -{ - Initial, - Selecting_NDEF_Application20, - Selecting_NDEF_Application10, - Selecting_CC, - Reading_CC, - Selecting_NDEF, - Reading_NDEF_Size, - Reading_NDEF, - Writing_NDEF, - Writing_NDEFsize, - Write_NDEFcomplete +typedef enum { + Initial, + Selecting_NDEF_Application20, + Selecting_NDEF_Application10, + Selecting_CC, + Reading_CC, + Selecting_NDEF, + Reading_NDEF_Size, + Reading_NDEF, + Writing_NDEF, + Writing_NDEFsize, + Write_NDEFcomplete } RW_NDEF_T4T_state_t; typedef struct { - unsigned char MappingVersion; - unsigned short MLe; - unsigned short MLc; - unsigned char FileID[2]; - unsigned short MaxNdefFileSize; - unsigned char RdAccess; - unsigned char WrAccess; - unsigned short MessagePtr; - unsigned short MessageSize; - unsigned char *pMessage; + unsigned char MappingVersion; + unsigned short MLe; + unsigned short MLc; + unsigned char FileID[2]; + unsigned short MaxNdefFileSize; + unsigned char RdAccess; + unsigned char WrAccess; + unsigned short MessagePtr; + unsigned short MessageSize; + unsigned char *pMessage; } RW_NDEF_T4T_Ndef_t; static RW_NDEF_T4T_state_t eRW_NDEF_T4T_State = Initial; static RW_NDEF_T4T_Ndef_t RW_NDEF_T4T_Ndef; -void RW_NDEF_T4T_Reset(void) -{ - eRW_NDEF_T4T_State = Initial; - RW_NDEF_T4T_Ndef.pMessage = NdefBuffer; +void RW_NDEF_T4T_Reset(void) { + eRW_NDEF_T4T_State = Initial; + RW_NDEF_T4T_Ndef.pMessage = NdefBuffer; } -void RW_NDEF_T4T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T4T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T4T_State) - { + switch (eRW_NDEF_T4T_State) { case Initial: - /* Select NDEF Application in version 2.0 */ - memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20)); - *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20); - eRW_NDEF_T4T_State = Selecting_NDEF_Application20; - break; + /* Select NDEF Application in version 2.0 */ + memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20)); + *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20); + eRW_NDEF_T4T_State = Selecting_NDEF_Application20; + break; case Selecting_NDEF_Application20: - /* Is NDEF Application Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Select CC */ - memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); - *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); - eRW_NDEF_T4T_State = Selecting_CC; - } - else - { - /* Select NDEF Application in version 1.0 */ - memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10)); - *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10); - eRW_NDEF_T4T_State = Selecting_NDEF_Application10; - } - break; + /* Is NDEF Application Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Select CC */ + memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); + *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); + eRW_NDEF_T4T_State = Selecting_CC; + } else { + /* Select NDEF Application in version 1.0 */ + memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10)); + *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10); + eRW_NDEF_T4T_State = Selecting_NDEF_Application10; + } + break; case Selecting_NDEF_Application10: - /* Is NDEF Application Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Select CC */ - memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); - pCmd[3] = 0x00; - *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); - eRW_NDEF_T4T_State = Selecting_CC; - } - break; + /* Is NDEF Application Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Select CC */ + memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); + pCmd[3] = 0x00; + *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); + eRW_NDEF_T4T_State = Selecting_CC; + } + break; case Selecting_CC: - /* Is CC Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Read CC */ - memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); - *pCmd_size = sizeof(RW_NDEF_T4T_Read); - eRW_NDEF_T4T_State = Reading_CC; - } - break; + /* Is CC Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Read CC */ + memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); + *pCmd_size = sizeof(RW_NDEF_T4T_Read); + eRW_NDEF_T4T_State = Reading_CC; + } + break; case Reading_CC: - /* Is CC Read ?*/ - if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2)) - { - /* Fill CC structure */ - RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2]; - RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4]; - RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6]; - RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9]; - RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10]; - RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12]; - RW_NDEF_T4T_Ndef.RdAccess = pRsp[13]; - RW_NDEF_T4T_Ndef.WrAccess = pRsp[14]; - - /* Select NDEF */ - memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select)); - if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) - pCmd[3] = 0x00; - pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0]; - pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1]; - *pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select); - eRW_NDEF_T4T_State = Selecting_NDEF; - } - break; + /* Is CC Read ?*/ + if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2)) { + /* Fill CC structure */ + RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2]; + RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4]; + RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6]; + RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9]; + RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10]; + RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12]; + RW_NDEF_T4T_Ndef.RdAccess = pRsp[13]; + RW_NDEF_T4T_Ndef.WrAccess = pRsp[14]; + + /* Select NDEF */ + memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select)); + if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) + pCmd[3] = 0x00; + pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0]; + pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1]; + *pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select); + eRW_NDEF_T4T_State = Selecting_NDEF; + } + break; case Selecting_NDEF: - /* Is NDEF Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Get NDEF file size */ - memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); - *pCmd_size = sizeof(RW_NDEF_T4T_Read); - pCmd[4] = 2; - eRW_NDEF_T4T_State = Reading_NDEF_Size; - } - break; + /* Is NDEF Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Get NDEF file size */ + memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); + *pCmd_size = sizeof(RW_NDEF_T4T_Read); + pCmd[4] = 2; + eRW_NDEF_T4T_State = Reading_NDEF_Size; + } + break; case Reading_NDEF_Size: - /* Is Read Success ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - RW_NDEF_T4T_Ndef.MessageSize = (pRsp[0] << 8) + pRsp[1]; - - /* If provisioned buffer is not large enough, notify the application and stop reading */ - if (RW_NDEF_T4T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) - { - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(NULL, 0); - break; - } - - RW_NDEF_T4T_Ndef.MessagePtr = 0; - - /* Read NDEF data */ - memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); - pCmd[3] = 2; - pCmd[4] = (RW_NDEF_T4T_Ndef.MessageSize > RW_NDEF_T4T_Ndef.MLe - 1) ? RW_NDEF_T4T_Ndef.MLe - 1 : (unsigned char)RW_NDEF_T4T_Ndef.MessageSize; - *pCmd_size = sizeof(RW_NDEF_T4T_Read); - eRW_NDEF_T4T_State = Reading_NDEF; + /* Is Read Success ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + RW_NDEF_T4T_Ndef.MessageSize = (pRsp[0] << 8) + pRsp[1]; + + /* If provisioned buffer is not large enough, notify the application and stop reading */ + if (RW_NDEF_T4T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) { + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(NULL, 0); + break; } - break; + + RW_NDEF_T4T_Ndef.MessagePtr = 0; + + /* Read NDEF data */ + memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); + pCmd[3] = 2; + pCmd[4] = (RW_NDEF_T4T_Ndef.MessageSize > RW_NDEF_T4T_Ndef.MLe - 1) ? RW_NDEF_T4T_Ndef.MLe - 1 : (unsigned char)RW_NDEF_T4T_Ndef.MessageSize; + *pCmd_size = sizeof(RW_NDEF_T4T_Read); + eRW_NDEF_T4T_State = Reading_NDEF; + } + break; case Reading_NDEF: - /* Is Read Success ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - memcpy(&RW_NDEF_T4T_Ndef.pMessage[RW_NDEF_T4T_Ndef.MessagePtr], pRsp, Rsp_size - 2); - RW_NDEF_T4T_Ndef.MessagePtr += Rsp_size - 2; - - /* Is NDEF message read completed ?*/ - if (RW_NDEF_T4T_Ndef.MessagePtr == RW_NDEF_T4T_Ndef.MessageSize) - { - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PullCb != NULL) - pRW_NDEF_PullCb(RW_NDEF_T4T_Ndef.pMessage, RW_NDEF_T4T_Ndef.MessageSize); - } - else - { - /* Read NDEF data */ - memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); - pCmd[3] = RW_NDEF_T4T_Ndef.MessagePtr + 2; - pCmd[4] = ((RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr) > RW_NDEF_T4T_Ndef.MLe - 1) ? RW_NDEF_T4T_Ndef.MLe - 1 : (unsigned char)(RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr); - *pCmd_size = sizeof(RW_NDEF_T4T_Read); - } + /* Is Read Success ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + memcpy(&RW_NDEF_T4T_Ndef.pMessage[RW_NDEF_T4T_Ndef.MessagePtr], pRsp, Rsp_size - 2); + RW_NDEF_T4T_Ndef.MessagePtr += Rsp_size - 2; + + /* Is NDEF message read completed ?*/ + if (RW_NDEF_T4T_Ndef.MessagePtr == RW_NDEF_T4T_Ndef.MessageSize) { + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PullCb != NULL) + pRW_NDEF_PullCb(RW_NDEF_T4T_Ndef.pMessage, RW_NDEF_T4T_Ndef.MessageSize); + } else { + /* Read NDEF data */ + memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); + pCmd[3] = RW_NDEF_T4T_Ndef.MessagePtr + 2; + pCmd[4] = ((RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr) > RW_NDEF_T4T_Ndef.MLe - 1) ? RW_NDEF_T4T_Ndef.MLe - 1 : (unsigned char)(RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr); + *pCmd_size = sizeof(RW_NDEF_T4T_Read); } - break; + } + break; default: - break; - } + break; + } } -void RW_NDEF_T4T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) -{ - /* By default no further command to be sent */ - *pCmd_size = 0; +void RW_NDEF_T4T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) { + /* By default no further command to be sent */ + *pCmd_size = 0; - switch (eRW_NDEF_T4T_State) - { + switch (eRW_NDEF_T4T_State) { case Initial: - /* Select NDEF Application in version 2.0 */ - memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20)); - *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20); - eRW_NDEF_T4T_State = Selecting_NDEF_Application20; - break; + /* Select NDEF Application in version 2.0 */ + memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20)); + *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20); + eRW_NDEF_T4T_State = Selecting_NDEF_Application20; + break; case Selecting_NDEF_Application20: - /* Is NDEF Application Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Select CC */ - memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); - *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); - eRW_NDEF_T4T_State = Selecting_CC; - } - else - { - /* Select NDEF Application in version 1.0 */ - memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10)); - *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10); - eRW_NDEF_T4T_State = Selecting_NDEF_Application10; - } - break; + /* Is NDEF Application Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Select CC */ + memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); + *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); + eRW_NDEF_T4T_State = Selecting_CC; + } else { + /* Select NDEF Application in version 1.0 */ + memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10)); + *pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10); + eRW_NDEF_T4T_State = Selecting_NDEF_Application10; + } + break; case Selecting_NDEF_Application10: - /* Is NDEF Application Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Select CC */ - memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); - pCmd[3] = 0x00; - *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); - eRW_NDEF_T4T_State = Selecting_CC; - } - break; + /* Is NDEF Application Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Select CC */ + memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select)); + pCmd[3] = 0x00; + *pCmd_size = sizeof(RW_NDEF_T4T_CC_Select); + eRW_NDEF_T4T_State = Selecting_CC; + } + break; case Selecting_CC: - /* Is CC Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Read CC */ - memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); - *pCmd_size = sizeof(RW_NDEF_T4T_Read); - eRW_NDEF_T4T_State = Reading_CC; - } - break; + /* Is CC Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Read CC */ + memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read)); + *pCmd_size = sizeof(RW_NDEF_T4T_Read); + eRW_NDEF_T4T_State = Reading_CC; + } + break; case Reading_CC: - /* Is CC Read ?*/ - if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2)) - { - /* Fill CC structure */ - RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2]; - RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4]; - RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6]; - RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9]; - RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10]; - RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12]; - RW_NDEF_T4T_Ndef.RdAccess = pRsp[13]; - RW_NDEF_T4T_Ndef.WrAccess = pRsp[14]; - - /* Select NDEF */ - memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select)); - if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) - pCmd[3] = 0x00; - pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0]; - pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1]; - *pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select); - eRW_NDEF_T4T_State = Selecting_NDEF; - } - break; + /* Is CC Read ?*/ + if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2)) { + /* Fill CC structure */ + RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2]; + RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4]; + RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6]; + RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9]; + RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10]; + RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12]; + RW_NDEF_T4T_Ndef.RdAccess = pRsp[13]; + RW_NDEF_T4T_Ndef.WrAccess = pRsp[14]; + + /* Select NDEF */ + memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select)); + if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) + pCmd[3] = 0x00; + pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0]; + pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1]; + *pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select); + eRW_NDEF_T4T_State = Selecting_NDEF; + } + break; case Selecting_NDEF: - /* Is NDEF Selected ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Clearing NDEF message size*/ - memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); - pCmd[4] = 2; - pCmd[5] = 0; - pCmd[6] = 0; - *pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2; - RW_NDEF_T4T_Ndef.MessagePtr = 0; - eRW_NDEF_T4T_State = Writing_NDEF; - } - break; + /* Is NDEF Selected ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Clearing NDEF message size*/ + memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); + pCmd[4] = 2; + pCmd[5] = 0; + pCmd[6] = 0; + *pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2; + RW_NDEF_T4T_Ndef.MessagePtr = 0; + eRW_NDEF_T4T_State = Writing_NDEF; + } + break; case Writing_NDEF: - /* Is Write Success ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Writing NDEF message */ - memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); - pCmd[2] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) >> 8; - pCmd[3] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) & 0xFF; - if ((RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr) < WRITE_SZ) - { - pCmd[4] = (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr); - memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr)); - *pCmd_size = sizeof(RW_NDEF_T4T_Write) + (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr); - eRW_NDEF_T4T_State = Writing_NDEFsize; - } - else - { - pCmd[4] = WRITE_SZ; - memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, WRITE_SZ); - *pCmd_size = sizeof(RW_NDEF_T4T_Write) + WRITE_SZ; - RW_NDEF_T4T_Ndef.MessagePtr += WRITE_SZ; - eRW_NDEF_T4T_State = Writing_NDEF; - } + /* Is Write Success ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Writing NDEF message */ + memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); + pCmd[2] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) >> 8; + pCmd[3] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) & 0xFF; + if ((RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr) < WRITE_SZ) { + pCmd[4] = (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr); + memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr)); + *pCmd_size = sizeof(RW_NDEF_T4T_Write) + (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr); + eRW_NDEF_T4T_State = Writing_NDEFsize; + } else { + pCmd[4] = WRITE_SZ; + memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, WRITE_SZ); + *pCmd_size = sizeof(RW_NDEF_T4T_Write) + WRITE_SZ; + RW_NDEF_T4T_Ndef.MessagePtr += WRITE_SZ; + eRW_NDEF_T4T_State = Writing_NDEF; } - break; + } + break; case Writing_NDEFsize: - /* Is Write Success ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); - pCmd[4] = 2; - pCmd[5] = RW_NdefMessage_size >> 8; - pCmd[6] = RW_NdefMessage_size & 0xFF; - *pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2; - eRW_NDEF_T4T_State = Write_NDEFcomplete; - } - break; + /* Is Write Success ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write)); + pCmd[4] = 2; + pCmd[5] = RW_NdefMessage_size >> 8; + pCmd[6] = RW_NdefMessage_size & 0xFF; + *pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2; + eRW_NDEF_T4T_State = Write_NDEFcomplete; + } + break; case Write_NDEFcomplete: - /* Is Write Success ?*/ - if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) - { - /* Notify application of the NDEF reception */ - if (pRW_NDEF_PushCb != NULL) - pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); - } - break; + /* Is Write Success ?*/ + if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) { + /* Notify application of the NDEF reception */ + if (pRW_NDEF_PushCb != NULL) + pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); + } + break; default: - break; - } + break; + } } - -//#endif -//#endif diff --git a/src/RW_NDEF_T4T.h b/src/RW_NDEF_T4T.h index 064245c..e17955b 100644 --- a/src/RW_NDEF_T4T.h +++ b/src/RW_NDEF_T4T.h @@ -1,16 +1,16 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ void RW_NDEF_T4T_Reset(void); void RW_NDEF_T4T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); diff --git a/src/RemoteDevice.cpp b/src/RemoteDevice.cpp new file mode 100644 index 0000000..35ae223 --- /dev/null +++ b/src/RemoteDevice.cpp @@ -0,0 +1,352 @@ +/** + * Library to manage the remote device properties, a remote device can be a tag or a reader + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#include "RemoteDevice.h" + +unsigned char RemoteDevice::getInterface() const { + return this->remoteDeviceStruct.interface; +} + +unsigned char RemoteDevice::getProtocol() const { + return this->remoteDeviceStruct.protocol; +} + +unsigned char RemoteDevice::getModeTech() const { + return this->remoteDeviceStruct.modeTech; +} + +bool RemoteDevice::hasMoreTags() const { + return this->remoteDeviceStruct.moreTagsAvailable; +} + +// Getters for device information + +const unsigned char* RemoteDevice::getSensRes() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.sensRes; + break; + + case (tech.PASSIVE_NFCB): + return this->remoteDeviceStruct.info.nfcBPP.sensRes; + break; + + case (tech.PASSIVE_NFCF): + return this->remoteDeviceStruct.info.nfcFPP.sensRes; + break; + + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getSensResLen() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.sensResLen; + break; + + case (tech.PASSIVE_NFCB): + return this->remoteDeviceStruct.info.nfcBPP.sensResLen; + break; + + case (tech.PASSIVE_NFCF): + return this->remoteDeviceStruct.info.nfcFPP.sensResLen; + break; + + case (tech.PASSIVE_NFCV): + default: + return 0; + break; + } +} + +const unsigned char* RemoteDevice::getNFCID() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.nfcId; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getNFCIDLen() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.nfcIdLen; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return 0; + break; + } +} + +const unsigned char* RemoteDevice::getSelRes() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.selRes; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getSelResLen() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.selResLen; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return 0; + break; + } +} + +const unsigned char* RemoteDevice::getRats() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.rats; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getRatsLen() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + return this->remoteDeviceStruct.info.nfcAPP.ratsLen; + break; + + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return 0; + break; + } +} + +const unsigned char* RemoteDevice::getAttribRes() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCB): + return this->remoteDeviceStruct.info.nfcBPP.attribRes; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getAttribResLen() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCB): + return this->remoteDeviceStruct.info.nfcBPP.attribResLen; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCF): + case (tech.PASSIVE_NFCV): + default: + return 0; + break; + } +} + +unsigned char RemoteDevice::getBitRate() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCF): + return this->remoteDeviceStruct.info.nfcFPP.bitRate; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCV): + default: + return NULL; + break; + } +} + +unsigned char RemoteDevice::getAFI() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCV): + return this->remoteDeviceStruct.info.nfcVPP.afi; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + default: + return 0; + break; + } +} + +unsigned char RemoteDevice::getDSFID() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCV): + return this->remoteDeviceStruct.info.nfcVPP.dsfid; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + default: + return 0; + break; + } +} + +const unsigned char* RemoteDevice::getID() const { + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCV): + return this->remoteDeviceStruct.info.nfcVPP.id; + break; + + case (tech.PASSIVE_NFCA): + case (tech.PASSIVE_NFCB): + case (tech.PASSIVE_NFCF): + default: + return NULL; + break; + } +} + +void RemoteDevice::setInterface(unsigned char interface) { + this->remoteDeviceStruct.interface = interface; +} + +void RemoteDevice::setProtocol(unsigned char protocol) { + this->remoteDeviceStruct.protocol = protocol; +} + +void RemoteDevice::setModeTech(unsigned char modeTech) { + this->remoteDeviceStruct.modeTech = modeTech; +} + +void RemoteDevice::setMoreTagsAvailable(bool moreTags) { + this->remoteDeviceStruct.moreTagsAvailable = moreTags; +} + +void RemoteDevice::setInfo(RfIntf_t *pRfIntf, uint8_t *pBuf) { + uint8_t i, temp; + + switch (remoteDeviceStruct.modeTech) { + case (tech.PASSIVE_NFCA): + memcpy(pRfIntf->Info.NFC_APP.SensRes, &pBuf[0], 2); + memcpy(remoteDeviceStruct.info.nfcAPP.sensRes, &pBuf[0], 2); + remoteDeviceStruct.info.nfcAPP.sensResLen = 2; + temp = 2; + pRfIntf->Info.NFC_APP.NfcIdLen = pBuf[temp]; + remoteDeviceStruct.info.nfcAPP.nfcIdLen = pBuf[temp]; + temp++; + memcpy(pRfIntf->Info.NFC_APP.NfcId, &pBuf[3], pRfIntf->Info.NFC_APP.NfcIdLen); + memcpy(remoteDeviceStruct.info.nfcAPP.nfcId, &pBuf[3], remoteDeviceStruct.info.nfcAPP.nfcIdLen); + temp += pBuf[2]; + pRfIntf->Info.NFC_APP.SelResLen = pBuf[temp]; + remoteDeviceStruct.info.nfcAPP.selResLen = pBuf[temp]; + temp++; + + if (remoteDeviceStruct.info.nfcAPP.selResLen == 1) { + pRfIntf->Info.NFC_APP.SelRes[0] = pBuf[temp]; + remoteDeviceStruct.info.nfcAPP.selRes[0] = pBuf[temp]; + } + + temp += 4; + if (pBuf[temp] != 0) { + temp++; + pRfIntf->Info.NFC_APP.RatsLen = pBuf[temp]; + remoteDeviceStruct.info.nfcAPP.ratsLen = pBuf[temp]; + memcpy(pRfIntf->Info.NFC_APP.Rats, &pBuf[temp + 1], pBuf[temp]); + memcpy(remoteDeviceStruct.info.nfcAPP.rats, &pBuf[temp + 1], pBuf[temp]); + } else { + pRfIntf->Info.NFC_APP.RatsLen = 0; + remoteDeviceStruct.info.nfcAPP.ratsLen = 0; + } + break; + + case (tech.PASSIVE_NFCB): + pRfIntf->Info.NFC_BPP.SensResLen = pBuf[0]; + remoteDeviceStruct.info.nfcBPP.sensResLen = pBuf[0]; + memcpy(pRfIntf->Info.NFC_BPP.SensRes, &pBuf[1], pRfIntf->Info.NFC_BPP.SensResLen); + memcpy(remoteDeviceStruct.info.nfcBPP.sensRes, &pBuf[1], remoteDeviceStruct.info.nfcBPP.sensResLen); + temp = pBuf[0] + 4; + if (pBuf[temp] != 0) { + temp++; + pRfIntf->Info.NFC_BPP.AttribResLen = pBuf[temp]; + remoteDeviceStruct.info.nfcBPP.attribResLen = pBuf[temp]; + memcpy(pRfIntf->Info.NFC_BPP.AttribRes, &pBuf[temp + 1], pBuf[temp]); + memcpy(remoteDeviceStruct.info.nfcBPP.attribRes, &pBuf[temp + 1], pBuf[temp]); + } else { + pRfIntf->Info.NFC_BPP.AttribResLen = 0; + remoteDeviceStruct.info.nfcBPP.attribResLen = 0; + } + break; + + case (tech.PASSIVE_NFCF): + pRfIntf->Info.NFC_FPP.BitRate = pBuf[0]; + remoteDeviceStruct.info.nfcFPP.bitRate = pBuf[0]; + pRfIntf->Info.NFC_FPP.SensResLen = pBuf[1]; + remoteDeviceStruct.info.nfcFPP.sensResLen = pBuf[1]; + memcpy(pRfIntf->Info.NFC_FPP.SensRes, &pBuf[2], pRfIntf->Info.NFC_FPP.SensResLen); + memcpy(remoteDeviceStruct.info.nfcFPP.sensRes, &pBuf[2], remoteDeviceStruct.info.nfcFPP.sensResLen); + break; + + case (tech.PASSIVE_NFCV): + pRfIntf->Info.NFC_VPP.AFI = pBuf[0]; + remoteDeviceStruct.info.nfcVPP.afi = pBuf[0]; + pRfIntf->Info.NFC_VPP.DSFID = pBuf[1]; + remoteDeviceStruct.info.nfcVPP.dsfid = pBuf[1]; + + for (i = 0; i < 8; i++) { + pRfIntf->Info.NFC_VPP.ID[7 - i] = pBuf[2 + i]; + remoteDeviceStruct.info.nfcVPP.id[7 - i] = pBuf[2 + i]; + } + + break; + + default: + break; + } +} \ No newline at end of file diff --git a/src/RemoteDevice.h b/src/RemoteDevice.h new file mode 100644 index 0000000..a066ab0 --- /dev/null +++ b/src/RemoteDevice.h @@ -0,0 +1,163 @@ +/** + * Library to manage the remote device properties, a remote device can be a tag or a reader + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef RemoteDevice_H +#define RemoteDevice_H + +#include "Arduino.h" +#include "Interface.h" +#include "ModeTech.h" +#include "Protocol.h" +#include "Tech.h" + +/* + * Definition of discovered remote device properties information + */ + +/* POLL passive type A */ +struct RfIntf_info_APP_t { + unsigned char SensRes[2]; + unsigned char NfcId[10]; + unsigned char NfcIdLen; + unsigned char SelRes[1]; + unsigned char SelResLen; + unsigned char Rats[20]; + unsigned char RatsLen; +}; + +/* POLL passive type A camelCase */ +struct RfIntfInfoAppCC_t { + unsigned char sensRes[2]; + unsigned char sensResLen; + unsigned char nfcId[10]; + unsigned char nfcIdLen; + unsigned char selRes[1]; + unsigned char selResLen; + unsigned char rats[20]; + unsigned char ratsLen; +}; + +/* POLL passive type B */ +struct RfIntf_info_BPP_t { + unsigned char SensRes[12]; + unsigned char SensResLen; + unsigned char AttribRes[17]; + unsigned char AttribResLen; +}; + +/* POLL passive type B camelCase */ +struct RfIntfInfoBppCC_t { + unsigned char sensRes[12]; + unsigned char sensResLen; + unsigned char attribRes[17]; + unsigned char attribResLen; +}; + +/* POLL passive type F */ +struct RfIntf_info_FPP_t { + unsigned char BitRate; + unsigned char SensRes[18]; + unsigned char SensResLen; +}; + +/* POLL passive type F camelCase */ +struct RfIntfInfoFppCC_t { + unsigned char bitRate; + unsigned char sensRes[18]; + unsigned char sensResLen; +}; + +/* POLL passive type ISO15693 */ +struct RfIntf_info_VPP_t { + unsigned char AFI; + unsigned char DSFID; + unsigned char ID[8]; +}; + +/* POLL passive type ISO15693 camelCase */ +struct RfIntfInfoVppCC_t { + unsigned char afi; + unsigned char dsfid; + unsigned char id[8]; +}; + +typedef union { + RfIntf_info_APP_t NFC_APP; + RfIntf_info_BPP_t NFC_BPP; + RfIntf_info_FPP_t NFC_FPP; + RfIntf_info_VPP_t NFC_VPP; +} RfIntf_Info_t; + +typedef union { + RfIntfInfoAppCC_t nfcAPP; + RfIntfInfoBppCC_t nfcBPP; + RfIntfInfoFppCC_t nfcFPP; + RfIntfInfoVppCC_t nfcVPP; +} RfIntfInfoCC_t; + +/* + * Definition of discovered remote device properties + */ +struct RfIntf_t { + unsigned char Interface; + unsigned char Protocol; + unsigned char ModeTech; + bool MoreTags; + RfIntf_Info_t Info; +}; + +// Definition of discovered remote device properties using camelCase +struct RfIntfCC_t { + unsigned char interface; + unsigned char protocol; + unsigned char modeTech; + bool moreTagsAvailable; + RfIntfInfoCC_t info; +}; + +class RemoteDevice { + private: + RfIntfCC_t remoteDeviceStruct; + Tech tech; + ModeTech modeTech; + + public: + // Getters for device properties + unsigned char getInterface() const; + unsigned char getProtocol() const; + unsigned char getModeTech() const; + bool hasMoreTags() const; + // Getters for device information properties + const unsigned char* getSensRes() const; + unsigned char getSensResLen() const; + const unsigned char* getNFCID() const; + unsigned char getNFCIDLen() const; + const unsigned char* getSelRes() const; + unsigned char getSelResLen() const; + const unsigned char* getRats() const; + unsigned char getRatsLen() const; + const unsigned char* getAttribRes() const; + unsigned char getAttribResLen() const; + unsigned char getBitRate() const; + unsigned char getAFI() const; + unsigned char getDSFID() const; + const unsigned char* getID() const; + // Setters + void setInterface(unsigned char interface); + void setProtocol(unsigned char protocol); + void setModeTech(unsigned char modeTech); + void setMoreTagsAvailable(bool moreTags); + void setInfo(RfIntf_t *pRfIntf, uint8_t *pBuf); +}; + +#endif \ No newline at end of file diff --git a/src/T4T_NDEF_emu.cpp b/src/T4T_NDEF_emu.cpp index 461d887..12fffff 100644 --- a/src/T4T_NDEF_emu.cpp +++ b/src/T4T_NDEF_emu.cpp @@ -1,22 +1,23 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ - -//#ifdef CARDEMU_SUPPORT -//#ifndef NO_NDEF_SUPPORT -#include "tool.h" + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +// #ifdef CARDEMU_SUPPORT +// #ifndef NO_NDEF_SUPPORT #include "T4T_NDEF_emu.h" +#include "tool.h" + const unsigned char T4T_NDEF_EMU_APP_Select[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00}; const unsigned char T4T_NDEF_EMU_CC[] = {0x00, 0x0F, 0x20, 0x00, 0xFF, 0x00, 0xFF, 0x04, 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00}; const unsigned char T4T_NDEF_EMU_CC_Select[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x03}; @@ -31,13 +32,12 @@ unsigned short T4T_NdefMessage_size = 0; unsigned char T4T_NdefMessageWritten[256]; -typedef enum -{ - Ready, - NDEF_Application_Selected, - CC_Selected, - NDEF_Selected, - DESFire_prod +typedef enum { + Ready, + NDEF_Application_Selected, + CC_Selected, + NDEF_Selected, + DESFire_prod } T4T_NDEF_EMU_state_t; typedef void T4T_NDEF_EMU_Callback_t(unsigned char *, unsigned short); @@ -46,130 +46,99 @@ static T4T_NDEF_EMU_state_t eT4T_NDEF_EMU_State = Ready; static T4T_NDEF_EMU_Callback_t *pT4T_NDEF_EMU_PushCb = NULL; -static void T4T_NDEF_EMU_FillRsp(unsigned char *pRsp, unsigned short offset, unsigned char length) -{ - if (offset == 0) - { - pRsp[0] = (T4T_NdefMessage_size & 0xFF00) >> 8; - pRsp[1] = (T4T_NdefMessage_size & 0x00FF); - if (length > 2) - memcpy(&pRsp[2], &pT4T_NdefMessage[0], length - 2); - } - else if (offset == 1) - { - pRsp[0] = (T4T_NdefMessage_size & 0x00FF); - if (length > 1) - memcpy(&pRsp[1], &pT4T_NdefMessage[0], length - 1); - } - else - { - memcpy(pRsp, &pT4T_NdefMessage[offset - 2], length); - } - - /* Did we reached the end of NDEF message ?*/ - if ((offset + length) >= (T4T_NdefMessage_size + 2)) - { - /* Notify application of the NDEF send */ - if (pT4T_NDEF_EMU_PushCb != NULL) - pT4T_NDEF_EMU_PushCb(pT4T_NdefMessage, T4T_NdefMessage_size); - } +static void T4T_NDEF_EMU_FillRsp(unsigned char *pRsp, unsigned short offset, unsigned char length) { + if (offset == 0) { + pRsp[0] = (T4T_NdefMessage_size & 0xFF00) >> 8; + pRsp[1] = (T4T_NdefMessage_size & 0x00FF); + if (length > 2) + memcpy(&pRsp[2], &pT4T_NdefMessage[0], length - 2); + } else if (offset == 1) { + pRsp[0] = (T4T_NdefMessage_size & 0x00FF); + if (length > 1) + memcpy(&pRsp[1], &pT4T_NdefMessage[0], length - 1); + } else { + memcpy(pRsp, &pT4T_NdefMessage[offset - 2], length); + } + + /* Did we reached the end of NDEF message ?*/ + if ((offset + length) >= (T4T_NdefMessage_size + 2)) { + /* Notify application of the NDEF send */ + if (pT4T_NDEF_EMU_PushCb != NULL) + pT4T_NDEF_EMU_PushCb(pT4T_NdefMessage, T4T_NdefMessage_size); + } } -bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) -{ - pT4T_NdefMessage = pMessage; - T4T_NdefMessage_size = Message_size; - pT4T_NDEF_EMU_PushCb = (T4T_NDEF_EMU_Callback_t *)pCb; +bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) { + pT4T_NdefMessage = pMessage; + T4T_NdefMessage_size = Message_size; + pT4T_NDEF_EMU_PushCb = (T4T_NDEF_EMU_Callback_t *)pCb; - return true; + return true; } -void T4T_NDEF_EMU_Reset(void) -{ - eT4T_NDEF_EMU_State = Ready; +void T4T_NDEF_EMU_Reset(void) { + eT4T_NDEF_EMU_State = Ready; } -void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size) -{ - bool eStatus = false; - - if (!memcmp(pCmd, T4T_NDEF_EMU_APP_Select, sizeof(T4T_NDEF_EMU_APP_Select))) - { - *pRsp_size = 0; - eStatus = true; - eT4T_NDEF_EMU_State = NDEF_Application_Selected; +void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size) { + bool eStatus = false; + + if (!memcmp(pCmd, T4T_NDEF_EMU_APP_Select, sizeof(T4T_NDEF_EMU_APP_Select))) { + *pRsp_size = 0; + eStatus = true; + eT4T_NDEF_EMU_State = NDEF_Application_Selected; + } else if (!memcmp(pCmd, T4T_NDEF_EMU_CC_Select, sizeof(T4T_NDEF_EMU_CC_Select))) { + if (eT4T_NDEF_EMU_State == NDEF_Application_Selected) { + *pRsp_size = 0; + eStatus = true; + eT4T_NDEF_EMU_State = CC_Selected; } - else if (!memcmp(pCmd, T4T_NDEF_EMU_CC_Select, sizeof(T4T_NDEF_EMU_CC_Select))) - { - if (eT4T_NDEF_EMU_State == NDEF_Application_Selected) - { - *pRsp_size = 0; - eStatus = true; - eT4T_NDEF_EMU_State = CC_Selected; - } + } else if (!memcmp(pCmd, T4T_NDEF_EMU_NDEF_Select, sizeof(T4T_NDEF_EMU_NDEF_Select))) { + *pRsp_size = 0; + eStatus = true; + eT4T_NDEF_EMU_State = NDEF_Selected; + } else if (!memcmp(pCmd, T4T_NDEF_EMU_Read, sizeof(T4T_NDEF_EMU_Read))) { + if (eT4T_NDEF_EMU_State == CC_Selected) { + unsigned short offset = (pCmd[2] << 8) + pCmd[3]; + unsigned char length = pCmd[4]; + + if (length <= (sizeof(T4T_NDEF_EMU_CC) + offset + 2)) { + memcpy(pRsp, &T4T_NDEF_EMU_CC[offset], length); + *pRsp_size = length; + eStatus = true; + } + } else if (eT4T_NDEF_EMU_State == NDEF_Selected) { + unsigned short offset = (pCmd[2] << 8) + pCmd[3]; + unsigned char length = pCmd[4]; + + if (length <= (T4T_NdefMessage_size + offset + 2)) { + T4T_NDEF_EMU_FillRsp(pRsp, offset, length); + *pRsp_size = length; + eStatus = true; + } } - else if (!memcmp(pCmd, T4T_NDEF_EMU_NDEF_Select, sizeof(T4T_NDEF_EMU_NDEF_Select))) - { + } else if (!memcmp(pCmd, T4T_NDEF_EMU_Write, sizeof(T4T_NDEF_EMU_Write))) { + if (eT4T_NDEF_EMU_State == NDEF_Selected) { + unsigned short offset = (pCmd[2] << 8) + pCmd[3]; + unsigned char length = pCmd[4]; + if (offset + length <= sizeof(T4T_NdefMessageWritten)) { + memcpy(&T4T_NdefMessageWritten[offset - 2], &pCmd[5], length); + pT4T_NdefMessage = T4T_NdefMessageWritten; + T4T_NdefMessage_size = (pCmd[5] << 8) + pCmd[6]; *pRsp_size = 0; eStatus = true; - eT4T_NDEF_EMU_State = NDEF_Selected; - } - else if (!memcmp(pCmd, T4T_NDEF_EMU_Read, sizeof(T4T_NDEF_EMU_Read))) - { - if (eT4T_NDEF_EMU_State == CC_Selected) - { - unsigned short offset = (pCmd[2] << 8) + pCmd[3]; - unsigned char length = pCmd[4]; - - if (length <= (sizeof(T4T_NDEF_EMU_CC) + offset + 2)) - { - memcpy(pRsp, &T4T_NDEF_EMU_CC[offset], length); - *pRsp_size = length; - eStatus = true; - } - } - else if (eT4T_NDEF_EMU_State == NDEF_Selected) - { - unsigned short offset = (pCmd[2] << 8) + pCmd[3]; - unsigned char length = pCmd[4]; - - if (length <= (T4T_NdefMessage_size + offset + 2)) - { - T4T_NDEF_EMU_FillRsp(pRsp, offset, length); - *pRsp_size = length; - eStatus = true; - } - } - } - else if (!memcmp(pCmd, T4T_NDEF_EMU_Write, sizeof(T4T_NDEF_EMU_Write))) - { - if (eT4T_NDEF_EMU_State == NDEF_Selected) - { - - unsigned short offset = (pCmd[2] << 8) + pCmd[3]; - unsigned char length = pCmd[4]; - if (offset + length <= sizeof(T4T_NdefMessageWritten)) - { - memcpy(&T4T_NdefMessageWritten[offset - 2], &pCmd[5], length); - pT4T_NdefMessage = T4T_NdefMessageWritten; - T4T_NdefMessage_size = (pCmd[5] << 8) + pCmd[6]; - *pRsp_size = 0; - eStatus = true; - } - } - } - - if (eStatus == true) - { - memcpy(&pRsp[*pRsp_size], T4T_NDEF_EMU_OK, sizeof(T4T_NDEF_EMU_OK)); - *pRsp_size += sizeof(T4T_NDEF_EMU_OK); - } - else - { - memcpy(pRsp, T4T_NDEF_EMU_NOK, sizeof(T4T_NDEF_EMU_NOK)); - *pRsp_size = sizeof(T4T_NDEF_EMU_NOK); - T4T_NDEF_EMU_Reset(); + } } + } + + if (eStatus == true) { + memcpy(&pRsp[*pRsp_size], T4T_NDEF_EMU_OK, sizeof(T4T_NDEF_EMU_OK)); + *pRsp_size += sizeof(T4T_NDEF_EMU_OK); + } else { + memcpy(pRsp, T4T_NDEF_EMU_NOK, sizeof(T4T_NDEF_EMU_NOK)); + *pRsp_size = sizeof(T4T_NDEF_EMU_NOK); + T4T_NDEF_EMU_Reset(); + } } -//#endif -//#endif +// #endif +// #endif diff --git a/src/T4T_NDEF_emu.h b/src/T4T_NDEF_emu.h index 09363ae..2506a90 100644 --- a/src/T4T_NDEF_emu.h +++ b/src/T4T_NDEF_emu.h @@ -12,5 +12,8 @@ * arising from its use. */ +#include + void T4T_NDEF_EMU_Reset(void); +bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb); void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); diff --git a/src/Tech.h b/src/Tech.h new file mode 100644 index 0000000..df91eaf --- /dev/null +++ b/src/Tech.h @@ -0,0 +1,40 @@ +/** + * Library to get the technology of the NFC card + * Authors: + * Francisco Torres - Electronic Cats - electroniccats.com + * + * August 2023 + * + * This code is beerware; if you see me (or any other collaborator + * member) at the local, and you've found our code helpful, + * please buy us a round! + * Distributed as-is; no warranty is given. + */ + +#ifndef Technology_H +#define Technology_H + +/* + * Flag definition used as Technologies values + */ +#define TECH_PASSIVE_NFCA 0 +#define TECH_PASSIVE_NFCB 1 +#define TECH_PASSIVE_NFCF 2 +#define TECH_ACTIVE_NFCA 3 +#define TECH_ACTIVE_NFCF 5 +#define TECH_PASSIVE_15693 6 + +class Tech { + public: + enum Value { + PASSIVE_NFCA = 0, + PASSIVE_NFCB = 1, + PASSIVE_NFCF = 2, + ACTIVE_NFCA = 3, + ACTIVE_NFCF = 5, + PASSIVE_15693 = 6, + PASSIVE_NFCV = 6 + }; +}; + +#endif \ No newline at end of file diff --git a/src/ndef_helper.cpp b/src/ndef_helper.cpp index d734462..2c55d53 100644 --- a/src/ndef_helper.cpp +++ b/src/ndef_helper.cpp @@ -1,226 +1,185 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ + +#include "ndef_helper.h" -#include #include +#include #include -#include "ndef_helper.h" -const char *ndef_helper_WifiAuth(unsigned char auth) -{ - switch (auth) - { +const char *ndef_helper_WifiAuth(unsigned char auth) { + switch (auth) { case 0x01: - return "Open"; + return "Open"; case 0x02: - return "WPA-Personal"; + return "WPA-Personal"; case 0x04: - return "Shared"; + return "Shared"; case 0x08: - return "WPA-Enterprise"; + return "WPA-Enterprise"; case 0x10: - return "WPA2-Enterprise"; + return "WPA2-Enterprise"; case 0x20: - return "WPA2-Personal"; + return "WPA2-Personal"; default: - return "unknown"; - } + return "unknown"; + } } -const char *ndef_helper_WifiEnc(unsigned char enc) -{ - switch (enc) - { +const char *ndef_helper_WifiEnc(unsigned char enc) { + switch (enc) { case 0x01: - return "None"; + return "None"; case 0x02: - return "WEP"; + return "WEP"; case 0x04: - return "TKIP"; + return "TKIP"; case 0x08: - return "AES"; + return "AES"; case 0x10: - return "AES/TKIP"; + return "AES/TKIP"; default: - return "unknown"; - } + return "unknown"; + } } -const char *ndef_helper_UriHead(unsigned char head) -{ - switch (head) - { +const char *ndef_helper_UriHead(unsigned char head) { + switch (head) { case 0: - return (""); + return (""); case 1: - return ("http://www."); + return ("http://www."); case 2: - return ("https://www."); + return ("https://www."); case 3: - return ("http://"); + return ("http://"); case 4: - return ("https://"); + return ("https://"); case 5: - return ("tel:"); + return ("tel:"); case 6: - return ("mailto:"); + return ("mailto:"); default: - return ("!!!unknown!!!"); - } + return ("!!!unknown!!!"); + } } -NdefRecord_t DetectNdefRecordType(unsigned char *pNdefRecord) -{ - NdefRecord_t record; +NdefRecord_t DetectNdefRecordType(unsigned char *pNdefRecord) { + NdefRecord_t record; - uint8_t typeField; + if (pNdefRecord == NULL) { + record.recordType = UNSUPPORTED_NDEF_RECORD; + record.recordPayload = NULL; + record.recordPayloadSize = 0; + return record; + } - /* Short or normal record ?*/ - if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) - { - record.recordPayloadSize = pNdefRecord[2]; - typeField = 3; - } - else - { - record.recordPayloadSize = (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]; - typeField = 6; - } + uint8_t typeField; - /* ID present ?*/ - if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) - { - record.recordPayload = pNdefRecord + typeField + pNdefRecord[1] + 1 + pNdefRecord[typeField]; - typeField++; - } - else - { - record.recordPayload = pNdefRecord + typeField + pNdefRecord[1]; - } + /* Short or normal record ?*/ + if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) { + record.recordPayloadSize = pNdefRecord[2]; + typeField = 3; + } else { + record.recordPayloadSize = (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]; + typeField = 6; + } - /* Well known Record Type ?*/ - if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_WELL_KNOWN) - { - if (pNdefRecord[1] == 0x1) - { - switch (pNdefRecord[typeField]) - { - case 'T': - record.recordType = WELL_KNOWN_SIMPLE_TEXT; - break; - case 'U': - record.recordType = WELL_KNOWN_SIMPLE_URI; - break; - default: - record.recordType = UNSUPPORTED_NDEF_RECORD; - break; - } - } - else if (pNdefRecord[1] == 0x2) - { - if (memcmp(&pNdefRecord[typeField], "Sp", pNdefRecord[1]) == 0x0) - { - record.recordType = WELL_KNOWN_SMART_POSTER; - } - else if (memcmp(&pNdefRecord[typeField], "Hs", pNdefRecord[1]) == 0x0) - { - record.recordType = WELL_KNOWN_HANDOVER_SELECT; - } - else if (memcmp(&pNdefRecord[typeField], "Hr", pNdefRecord[1]) == 0x0) - { - record.recordType = WELL_KNOWN_HANDOVER_REQUEST; - } - else if (memcmp(&pNdefRecord[typeField], "ac", pNdefRecord[1]) == 0x0) - { - record.recordType = WELL_KNOWN_ALTERNATIVE_CARRIER; - } - else if (memcmp(&pNdefRecord[typeField], "cr", pNdefRecord[1]) == 0x0) - { - record.recordType = WELL_KNOWN_COLLISION_RESOLUTION; - } - else - { - record.recordType = UNSUPPORTED_NDEF_RECORD; - } - } - } - /* Media Record Type ?*/ - else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_MEDIA) - { - if ((memcmp(&pNdefRecord[typeField], "text/x-vCard", pNdefRecord[1]) == 0x0) || - (memcmp(&pNdefRecord[typeField], "text/vcard", pNdefRecord[1]) == 0x0)) - { - record.recordType = MEDIA_VCARD; - } - else if (memcmp(&pNdefRecord[typeField], "application/vnd.wfa.wsc", pNdefRecord[1]) == 0x0) - { - record.recordType = MEDIA_HANDOVER_WIFI; - } - else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.ep.oob", pNdefRecord[1]) == 0x0) - { - record.recordType = MEDIA_HANDOVER_BT; - } - else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.le.oob", pNdefRecord[1]) == 0x0) - { - record.recordType = MEDIA_HANDOVER_BLE; - } - else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.secure.le.oob", pNdefRecord[1]) == 0x0) - { - record.recordType = MEDIA_HANDOVER_BLE_SECURE; - } - else - { - record.recordType = UNSUPPORTED_NDEF_RECORD; - } - } - /* Absolute URI Record Type ?*/ - else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_ABSOLUTE_URI) - { - record.recordType = ABSOLUTE_URI; - } - else - { + /* ID present ?*/ + if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) { + record.recordPayload = pNdefRecord + typeField + pNdefRecord[1] + 1 + pNdefRecord[typeField]; + typeField++; + } else { + record.recordPayload = pNdefRecord + typeField + pNdefRecord[1]; + } + + /* Well known Record Type ?*/ + if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_WELL_KNOWN) { + if (pNdefRecord[1] == 0x1) { + switch (pNdefRecord[typeField]) { + case 'T': + record.recordType = WELL_KNOWN_SIMPLE_TEXT; + break; + case 'U': + record.recordType = WELL_KNOWN_SIMPLE_URI; + break; + default: + record.recordType = UNSUPPORTED_NDEF_RECORD; + break; + } + } else if (pNdefRecord[1] == 0x2) { + if (memcmp(&pNdefRecord[typeField], "Sp", pNdefRecord[1]) == 0x0) { + record.recordType = WELL_KNOWN_SMART_POSTER; + } else if (memcmp(&pNdefRecord[typeField], "Hs", pNdefRecord[1]) == 0x0) { + record.recordType = WELL_KNOWN_HANDOVER_SELECT; + } else if (memcmp(&pNdefRecord[typeField], "Hr", pNdefRecord[1]) == 0x0) { + record.recordType = WELL_KNOWN_HANDOVER_REQUEST; + } else if (memcmp(&pNdefRecord[typeField], "ac", pNdefRecord[1]) == 0x0) { + record.recordType = WELL_KNOWN_ALTERNATIVE_CARRIER; + } else if (memcmp(&pNdefRecord[typeField], "cr", pNdefRecord[1]) == 0x0) { + record.recordType = WELL_KNOWN_COLLISION_RESOLUTION; + } else { record.recordType = UNSUPPORTED_NDEF_RECORD; + } + } + } + /* Media Record Type ?*/ + else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_MEDIA) { + if ((memcmp(&pNdefRecord[typeField], "text/x-vCard", pNdefRecord[1]) == 0x0) || + (memcmp(&pNdefRecord[typeField], "text/vcard", pNdefRecord[1]) == 0x0)) { + record.recordType = MEDIA_VCARD; + } else if (memcmp(&pNdefRecord[typeField], "application/vnd.wfa.wsc", pNdefRecord[1]) == 0x0) { + record.recordType = MEDIA_HANDOVER_WIFI; + } else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.ep.oob", pNdefRecord[1]) == 0x0) { + record.recordType = MEDIA_HANDOVER_BT; + } else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.le.oob", pNdefRecord[1]) == 0x0) { + record.recordType = MEDIA_HANDOVER_BLE; + } else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.secure.le.oob", pNdefRecord[1]) == 0x0) { + record.recordType = MEDIA_HANDOVER_BLE_SECURE; + } else { + record.recordType = UNSUPPORTED_NDEF_RECORD; } + } + /* Absolute URI Record Type ?*/ + else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_ABSOLUTE_URI) { + record.recordType = ABSOLUTE_URI; + } else { + record.recordType = UNSUPPORTED_NDEF_RECORD; + } - return record; + return record; } -unsigned char *GetNextRecord(unsigned char *pNdefRecord) -{ - unsigned char *temp = NULL; +unsigned char *GetNextRecord(unsigned char *pNdefRecord) { + unsigned char *temp = NULL; - /* Message End ?*/ - if (!(pNdefRecord[0] & NDEF_RECORD_ME_MASK)) - { - /* Short or normal record ?*/ - if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) - { - /* ID present ?*/ - if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) - temp = (pNdefRecord + 4 + pNdefRecord[1] + pNdefRecord[2] + pNdefRecord[3]); - else - temp = (pNdefRecord + 3 + pNdefRecord[1] + pNdefRecord[2]); - } - else - { - /* ID present ?*/ - if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) - temp = (pNdefRecord + 7 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5] + pNdefRecord[6]); - else - temp = (pNdefRecord + 6 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]); - } + /* Message End ?*/ + if (!(pNdefRecord[0] & NDEF_RECORD_ME_MASK)) { + /* Short or normal record ?*/ + if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) { + /* ID present ?*/ + if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) + temp = (pNdefRecord + 4 + pNdefRecord[1] + pNdefRecord[2] + pNdefRecord[3]); + else + temp = (pNdefRecord + 3 + pNdefRecord[1] + pNdefRecord[2]); + } else { + /* ID present ?*/ + if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) + temp = (pNdefRecord + 7 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5] + pNdefRecord[6]); + else + temp = (pNdefRecord + 6 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]); } - return temp; + } + return temp; } diff --git a/src/ndef_helper.h b/src/ndef_helper.h index dc4c316..9338ccd 100644 --- a/src/ndef_helper.h +++ b/src/ndef_helper.h @@ -1,16 +1,18 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ +#ifndef NdefHelper_H +#define NdefHelper_H #define NDEF_EMPTY 0x00 #define NDEF_WELL_KNOWN 0x01 @@ -28,29 +30,27 @@ #define NDEF_RECORD_IL_MASK 0x08 #define NDEF_RECORD_TNF_MASK 0x07 -typedef enum -{ - WELL_KNOWN_SIMPLE_TEXT, - WELL_KNOWN_SIMPLE_URI, - WELL_KNOWN_SMART_POSTER, - WELL_KNOWN_HANDOVER_SELECT, - WELL_KNOWN_HANDOVER_REQUEST, - WELL_KNOWN_ALTERNATIVE_CARRIER, - WELL_KNOWN_COLLISION_RESOLUTION, - MEDIA_VCARD, - MEDIA_HANDOVER_WIFI, - MEDIA_HANDOVER_BT, - MEDIA_HANDOVER_BLE, - MEDIA_HANDOVER_BLE_SECURE, - ABSOLUTE_URI, - UNSUPPORTED_NDEF_RECORD = 0xFF +typedef enum { + WELL_KNOWN_SIMPLE_TEXT, + WELL_KNOWN_SIMPLE_URI, + WELL_KNOWN_SMART_POSTER, + WELL_KNOWN_HANDOVER_SELECT, + WELL_KNOWN_HANDOVER_REQUEST, + WELL_KNOWN_ALTERNATIVE_CARRIER, + WELL_KNOWN_COLLISION_RESOLUTION, + MEDIA_VCARD, + MEDIA_HANDOVER_WIFI, + MEDIA_HANDOVER_BT, + MEDIA_HANDOVER_BLE, + MEDIA_HANDOVER_BLE_SECURE, + ABSOLUTE_URI, + UNSUPPORTED_NDEF_RECORD = 0xFF } NdefRecordType_e; -typedef struct -{ - NdefRecordType_e recordType; - unsigned char *recordPayload; - unsigned int recordPayloadSize; +typedef struct { + NdefRecordType_e recordType; + unsigned char *recordPayload; + unsigned int recordPayloadSize; } NdefRecord_t; const char *ndef_helper_WifiAuth(unsigned char auth); @@ -58,3 +58,5 @@ const char *ndef_helper_WifiEnc(unsigned char enc); const char *ndef_helper_UriHead(unsigned char head); NdefRecord_t DetectNdefRecordType(unsigned char *pNdefRecord); unsigned char *GetNextRecord(unsigned char *pNdefRecord); + +#endif \ No newline at end of file diff --git a/src/tool.cpp b/src/tool.cpp index ed4419d..619a572 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -1,40 +1,36 @@ /* -* Copyright (c), NXP Semiconductors Caen / France -* -* (C)NXP Semiconductors -* All rights are reserved. Reproduction in whole or in part is -* prohibited without the written consent of the copyright owner. -* NXP reserves the right to make changes without notice at any time. -* NXP makes no warranty, expressed, implied or statutory, including but -* not limited to any implied warranty of merchantability or fitness for any -*particular purpose, or that the use will not infringe any third party patent, -* copyright or trademark. NXP must not be liable for any loss or damage -* arising from its use. -*/ + * Copyright (c), NXP Semiconductors Caen / France + * + * (C)NXP Semiconductors + * All rights are reserved. Reproduction in whole or in part is + * prohibited without the written consent of the copyright owner. + * NXP reserves the right to make changes without notice at any time. + * NXP makes no warranty, expressed, implied or statutory, including but + * not limited to any implied warranty of merchantability or fitness for any + *particular purpose, or that the use will not infringe any third party patent, + * copyright or trademark. NXP must not be liable for any loss or damage + * arising from its use. + */ -//#include +// #include /* LOOP_REF and CLOCK_CALL_TIME must be adapted according to the CPU execution time */ #define LOOP_REF 6800 #define CLOCK_CALL_TIME 40 -void Sleep(unsigned int ms) -{ - int i; +void Sleep(unsigned int ms) { + int i; #ifndef DEBUG_SEMIHOSTING - for (i = 0; i < (ms * LOOP_REF); i++) - asm("nop"); + for (i = 0; i < (ms * LOOP_REF); i++) + asm("nop"); #else - if (ms <= CLOCK_CALL_TIME) - { - for (i = 0; i < (ms * LOOP_REF); i++) - asm("nop"); - } - else - { - clock_t time = clock() + ((ms - CLOCK_CALL_TIME) / 10); - while (clock() <= time) - ; - } + if (ms <= CLOCK_CALL_TIME) { + for (i = 0; i < (ms * LOOP_REF); i++) + asm("nop"); + } else { + clock_t time = clock() + ((ms - CLOCK_CALL_TIME) / 10); + while (clock() <= time) + ; + } #endif }