├── .DS_Store ├── Firmware ├── .DS_Store ├── Arduino │ ├── .DS_Store │ ├── Example_NFC_Read │ │ └── Example_NFC_Read.ino │ ├── Example_Websocket │ │ ├── .DS_Store │ │ ├── Example_WebSocket.ino │ │ ├── bep_host_if.c │ │ ├── bep_host_if.h │ │ ├── chhavi_fingerprint_v001.bin │ │ ├── com_app_cleartext.c │ │ ├── com_app_cleartext.h │ │ ├── com_common.c │ │ ├── com_common.h │ │ ├── debug.cfg │ │ ├── debug_custom.json │ │ ├── display.ino │ │ ├── esp32.svd │ │ ├── fpc_bep_types.h │ │ ├── fpc_com_chain.h │ │ ├── fpc_com_link.c │ │ ├── fpc_com_link.h │ │ ├── fpc_com_packets.h │ │ ├── fpc_com_result.h │ │ ├── fpc_com_transport.c │ │ ├── fpc_com_transport.h │ │ ├── fpc_crc.c │ │ ├── fpc_crc.h │ │ ├── fpc_hcp.c │ │ ├── fpc_hcp.h │ │ ├── fpc_hcp_common.h │ │ ├── images.h │ │ ├── main.c │ │ ├── platform.c │ │ ├── platform.h │ │ └── udp.ino │ └── NFC_LIB │ │ ├── .DS_Store │ │ ├── API.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── datasheets │ │ ├── NFC Forum │ │ │ └── NFC Controller Interface Specification V1.0.pdf │ │ └── NXP PN7150 │ │ │ ├── PN7150 Datasheet.pdf │ │ │ └── PN7150 User Manual - Host Interface - UM10936.pdf │ │ ├── examples │ │ ├── .DS_Store │ │ ├── DetectTags │ │ │ └── DetectTags.ino │ │ ├── DetectingReaders │ │ │ └── DetectingReaders.ino │ │ ├── ISO14443-3A_read_block │ │ │ └── ISO14443-3A_read_block.ino │ │ ├── ISO14443-3A_write_block │ │ │ └── ISO14443-3A_write_block.ino │ │ ├── ISO15693_read_block │ │ │ └── ISO15693_read_block.ino │ │ ├── ISO15693_write_block │ │ │ └── ISO15693_write_block.ino │ │ ├── MifareClassic_read_block │ │ │ └── MifareClassic_read_block.ino │ │ ├── MifareClassic_write_block │ │ │ └── MifareClassic_write_block.ino │ │ └── P2P_Discovery │ │ │ └── P2P_Discovery.ino │ │ ├── keywords.txt │ │ ├── library.properties │ │ └── src │ │ ├── Electroniccats_PN7150.cpp │ │ ├── Electroniccats_PN7150.h │ │ ├── P2P_NDEF.cpp │ │ ├── P2P_NDEF.h │ │ ├── RW_NDEF.cpp │ │ ├── RW_NDEF.h │ │ ├── RW_NDEF_MIFARE.cpp │ │ ├── RW_NDEF_MIFARE.h │ │ ├── RW_NDEF_T1T.cpp │ │ ├── RW_NDEF_T1T.h │ │ ├── RW_NDEF_T2T.cpp │ │ ├── RW_NDEF_T2T.h │ │ ├── RW_NDEF_T3T.cpp │ │ ├── RW_NDEF_T3T.h │ │ ├── RW_NDEF_T4T.cpp │ │ ├── RW_NDEF_T4T.h │ │ ├── T4T_NDEF_emu.cpp │ │ ├── T4T_NDEF_emu.h │ │ ├── ndef_helper.cpp │ │ ├── ndef_helper.h │ │ ├── tool.cpp │ │ └── tool.h └── UserGuide.md └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/.DS_Store -------------------------------------------------------------------------------- /Firmware/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/.DS_Store -------------------------------------------------------------------------------- /Firmware/Arduino/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/.DS_Store -------------------------------------------------------------------------------- /Firmware/Arduino/Example_NFC_Read/Example_NFC_Read.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example detect tags and show their unique ID 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (23) 17 | #define PN7150_VEN (19) 18 | #define PN7150_ADDR (0x28) 19 | 20 | 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 21 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 22 | 23 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 24 | 25 | int ResetMode(){ //Reset the configuration mode after each reading 26 | Serial.println("Re-initializing..."); 27 | nfc.ConfigMode(mode); 28 | nfc.StartDiscovery(mode); 29 | } 30 | 31 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 32 | uint32_t szPos; 33 | for (szPos=0; szPos < numBytes; szPos++) 34 | { 35 | Serial.print(F("0x")); 36 | // Append leading 0 for small values 37 | if (data[szPos] <= 0xF) 38 | Serial.print(F("0")); 39 | Serial.print(data[szPos]&0xff, HEX); 40 | if ((numBytes > 1) && (szPos != numBytes - 1)) 41 | { 42 | Serial.print(F(" ")); 43 | } 44 | } 45 | Serial.println(); 46 | } 47 | void displayCardInfo(RfIntf_t RfIntf){ //Funtion in charge to show the card/s in te field 48 | char tmp[16]; 49 | while (1){ 50 | switch(RfIntf.Protocol){ //Indetify card protocol 51 | case PROT_T1T: 52 | case PROT_T2T: 53 | case PROT_T3T: 54 | case PROT_ISODEP: 55 | Serial.print(" - POLL MODE: Remote activated tag type: "); 56 | Serial.println(RfIntf.Protocol); 57 | break; 58 | case PROT_ISO15693: 59 | Serial.println(" - POLL MODE: Remote ISO15693 card activated"); 60 | break; 61 | case PROT_MIFARE: 62 | Serial.println(" - POLL MODE: Remote MIFARE card activated"); 63 | break; 64 | default: 65 | Serial.println(" - POLL MODE: Undetermined target"); 66 | return; 67 | } 68 | 69 | switch(RfIntf.ModeTech) { //Indetify card technology 70 | case (MODE_POLL | TECH_PASSIVE_NFCA): 71 | Serial.print("\tSENS_RES = "); 72 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[0]); 73 | Serial.print(tmp); Serial.print(" "); 74 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[1]); 75 | Serial.print(tmp); Serial.println(" "); 76 | 77 | Serial.print("\tNFCID = "); 78 | PrintBuf(RfIntf.Info.NFC_APP.NfcId, RfIntf.Info.NFC_APP.NfcIdLen); 79 | 80 | if(RfIntf.Info.NFC_APP.SelResLen != 0) { 81 | Serial.print("\tSEL_RES = "); 82 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SelRes[0]); 83 | Serial.print(tmp); Serial.println(" "); 84 | 85 | } 86 | break; 87 | 88 | case (MODE_POLL | TECH_PASSIVE_NFCB): 89 | if(RfIntf.Info.NFC_BPP.SensResLen != 0) { 90 | Serial.print("\tSENS_RES = "); 91 | PrintBuf(RfIntf.Info.NFC_BPP.SensRes,RfIntf.Info.NFC_BPP.SensResLen); 92 | } 93 | break; 94 | 95 | case (MODE_POLL | TECH_PASSIVE_NFCF): 96 | Serial.print("\tBitrate = "); 97 | Serial.println((RfIntf.Info.NFC_FPP.BitRate == 1) ? "212" : "424"); 98 | 99 | if(RfIntf.Info.NFC_FPP.SensResLen != 0) { 100 | Serial.print("\tSENS_RES = "); 101 | PrintBuf(RfIntf.Info.NFC_FPP.SensRes,RfIntf.Info.NFC_FPP.SensResLen); 102 | } 103 | break; 104 | 105 | case (MODE_POLL | TECH_PASSIVE_15693): 106 | Serial.print("\tID = "); 107 | PrintBuf(RfIntf.Info.NFC_VPP.ID,sizeof(RfIntf.Info.NFC_VPP.ID)); 108 | 109 | Serial.print("\ntAFI = "); 110 | Serial.println(RfIntf.Info.NFC_VPP.AFI); 111 | 112 | Serial.print("\tDSFID = "); 113 | Serial.println(RfIntf.Info.NFC_VPP.DSFID,HEX); 114 | break; 115 | 116 | default: 117 | break; 118 | } 119 | if(RfIntf.MoreTags) { // It will try to identify more NFC cards if they are the same technology 120 | if(nfc.ReaderActivateNext(&RfIntf) == NFC_ERROR) break; 121 | } 122 | else break; 123 | } 124 | } 125 | 126 | void setup(){ 127 | digitalWrite(PN7150_VEN , HIGH); 128 | Serial.begin(9600); 129 | while(!Serial); 130 | Serial.println("Detect NFC tags with PN7150"); 131 | 132 | Serial.println("Initializing..."); 133 | if (nfc.connectNCI()) { //Wake up the board 134 | Serial.println("Error while setting up the mode, check connections!"); 135 | while (1); 136 | } 137 | 138 | if (nfc.ConfigureSettings()) { 139 | Serial.println("The Configure Settings is failed!"); 140 | while (1); 141 | } 142 | 143 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 144 | Serial.println("The Configure Mode is failed!!"); 145 | while (1); 146 | } 147 | nfc.StartDiscovery(mode); //NCI Discovery mode 148 | Serial.println("Waiting for an Card ..."); 149 | } 150 | 151 | void loop(){ 152 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 153 | displayCardInfo(RfInterface); 154 | switch(RfInterface.Protocol) { 155 | case PROT_T1T: 156 | case PROT_T2T: 157 | case PROT_T3T: 158 | case PROT_ISODEP: 159 | nfc.ProcessReaderMode(RfInterface, READ_NDEF); 160 | break; 161 | 162 | case PROT_ISO15693: 163 | break; 164 | 165 | case PROT_MIFARE: 166 | nfc.ProcessReaderMode(RfInterface, READ_NDEF); 167 | break; 168 | 169 | default: 170 | break; 171 | } 172 | 173 | //* It can detect multiple cards at the same time if they use the same protocol 174 | if(RfInterface.MoreTags) { 175 | nfc.ReaderActivateNext(&RfInterface); 176 | } 177 | //* Wait for card removal 178 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 179 | Serial.println("CARD REMOVED!"); 180 | 181 | nfc.StopDiscovery(); 182 | nfc.StartDiscovery(mode); 183 | } 184 | ResetMode(); 185 | delay(500); 186 | } 187 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/Example_Websocket/.DS_Store -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/bep_host_if.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BEP_HOST_IF_H 18 | #define BEP_HOST_IF_H 19 | 20 | /** 21 | * @file bep_host_if.h 22 | * @brief BEP Host Interface API 23 | */ 24 | 25 | #include 26 | #include 27 | #include "fpc_bep_types.h" 28 | #include "fpc_com_chain.h" 29 | 30 | #define REMOVE_ID_ALL_TEMPLATES 0U 31 | 32 | /** 33 | * @brief Sends HCP commands for capturing an image in Bio MCU 34 | * 35 | * @param[in] chain HCP com chain 36 | * @param[in] timeout Timeout in ms 37 | * @return ::fpc_bep_result_t 38 | */ 39 | fpc_bep_result_t bep_capture(fpc_com_chain_t *chain, uint16_t timeout); 40 | 41 | /** 42 | * @brief Sends HCP commands for enrolling a finger in Bio MCU 43 | * 44 | * @param[in] chain HCP com chain 45 | * @return ::fpc_bep_result_t 46 | */ 47 | fpc_bep_result_t bep_enroll_finger(fpc_com_chain_t *chain); 48 | 49 | /** 50 | * @brief Sends HCP commands for identifying a finger in Bio MCU 51 | * 52 | * @param[in] chain HCP com chain 53 | * @param[out] template_id Template id that was identified (only valid if match is true) 54 | * @param[out] match True if match 55 | * @return ::fpc_bep_result_t 56 | */ 57 | fpc_bep_result_t bep_identify_finger(fpc_com_chain_t *chain, uint16_t *template_id, bool *match); 58 | 59 | 60 | /** 61 | * @brief Sends HCP commands for saving template of an enrolled finger in Bio MCU 62 | * 63 | * @param[in] chain HCP com chain 64 | * @param[in] template_id Template id to save 65 | * @return ::fpc_bep_result_t 66 | */ 67 | fpc_bep_result_t bep_save_template(fpc_com_chain_t *chain, uint16_t template_id); 68 | 69 | /** 70 | * @brief Remove template(s) stored 71 | * 72 | * @param[in] chain HCP com chain 73 | * @param[in] template_id template id to remove, if =REMOVE_ID_ALL_TEMPLATES removes all templates 74 | * @return ::fpc_bep_result_t 75 | */ 76 | fpc_bep_result_t bep_delete_template(fpc_com_chain_t *chain, uint16_t template_id); 77 | 78 | /** 79 | * @brief Gets all template ids from Bio MCU 80 | * 81 | * @param[in] chain HCP com chain 82 | * @param[out] template_ids Should be allocated by the caller for storing template ids and should 83 | * have capacity to hold bio_get_template_count 84 | * @param[in] nof_templates This should be acquired using bio_get_template_count 85 | * @return ::fpc_bep_result_t 86 | */ 87 | fpc_bep_result_t bep_get_template_ids(fpc_com_chain_t *chain, uint16_t *template_ids, 88 | uint32_t nof_templates); 89 | 90 | /** 91 | * @brief Get the number of templates in Bio MCU 92 | * 93 | * @param[in] chain HCP com chain 94 | * @param[out] template_count 95 | * @return ::fpc_bep_result_t 96 | */ 97 | fpc_bep_result_t bep_get_template_count(fpc_com_chain_t *chain, uint32_t *template_count); 98 | 99 | 100 | /** 101 | * @brief Sends HCP commands for extracting a template from a previously capture image in Bio MCU 102 | * 103 | * @param[in] chain HCP com chain 104 | * @return ::fpc_bep_result_t 105 | */ 106 | fpc_bep_result_t bep_image_extract(fpc_com_chain_t *chain); 107 | 108 | /** 109 | * @brief Sends HCP commands for getting the image size of a previously capture image in Bio MCU 110 | * 111 | * @param[in] chain HCP com chain 112 | * @return ::fpc_bep_result_t 113 | */ 114 | fpc_bep_result_t bep_image_get_size(fpc_com_chain_t *chain, uint32_t *size); 115 | 116 | /** 117 | * @brief Sends HCP commands for getting the image data of a previously capture image in Bio MCU 118 | * 119 | * @param[in] chain HCP com chain 120 | * @return ::fpc_bep_result_t 121 | */ 122 | fpc_bep_result_t bep_image_get(fpc_com_chain_t *chain, uint8_t *data, uint32_t size); 123 | 124 | /** 125 | * @brief Sends HCP commands for fetching the version of the Bio MCU FW 126 | * 127 | * @param[in] chain HCP com chain 128 | * @param[out] version Version string buffer 129 | * @param[out] len Length of version string buffer 130 | * @return ::fpc_bep_result_t 131 | */ 132 | fpc_bep_result_t bep_version(fpc_com_chain_t *chain, char *version, int len); 133 | 134 | /** 135 | * @brief Sends HCP commands for resetting the Bio MCU 136 | * 137 | * @param[in] chain HCP com chain 138 | * @return ::fpc_bep_result_t 139 | */ 140 | fpc_bep_result_t bep_reset(fpc_com_chain_t *chain); 141 | 142 | /** 143 | * @brief Sends HCP commands for calibrating the sensor in the Bio MCU 144 | * 145 | * @param[in] chain HCP com chain 146 | * @return ::fpc_bep_result_t 147 | */ 148 | fpc_bep_result_t bep_sensor_calibrate(fpc_com_chain_t *chain); 149 | 150 | /** 151 | * @brief Sends HCP commands for removing the sensor calibration in the Bio MCU 152 | * 153 | * @param[in] chain HCP com chain 154 | * @return ::fpc_bep_result_t 155 | */ 156 | fpc_bep_result_t bep_sensor_calibrate_remove(fpc_com_chain_t *chain); 157 | 158 | /** 159 | * @brief Sends HCP commands for setting the sensor in sleep and waiting for finger in the Bio MCU 160 | * 161 | * @param[in] chain HCP com chain 162 | * @param[in] timeout Timeout in ms 163 | * @param[in] sleep_counter Sleep counter interval in ms [4-1020] 164 | * @return ::fpc_bep_result_t 165 | */ 166 | fpc_bep_result_t bep_sensor_wait_for_finger(fpc_com_chain_t *chain, uint16_t timeout, 167 | uint16_t sleep_counter); 168 | 169 | /** 170 | * @brief Sends HCP commands that returns when finger is not on the sensor in the Bio MCU 171 | * 172 | * @param[in] chain HCP com chain 173 | * @param[in] timeout Timeout in ms 174 | * @return ::fpc_bep_result_t 175 | */ 176 | fpc_bep_result_t bep_sensor_wait_finger_not_present(fpc_com_chain_t *chain, uint16_t timeout); 177 | 178 | fpc_bep_result_t receive_result_no_args(fpc_com_chain_t *chain); 179 | 180 | void registerCallBack(char *c); 181 | 182 | void assign_callback_forws(void *ptr); 183 | 184 | #endif /* BEP_HOST_IF_H */ 185 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/chhavi_fingerprint_v001.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/Example_Websocket/chhavi_fingerprint_v001.bin -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/com_app_cleartext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file com_app_cleartext.c 19 | * @brief Support functions for HCP. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "com_app_cleartext.h" 26 | #include "fpc_hcp.h" 27 | 28 | fpc_com_result_t com_app_clr_transmit(fpc_com_chain_t *chain) 29 | { 30 | fpc_com_packet_tsp_t tsp_packet = { 0 }; 31 | uint16_t tsp_offset; 32 | uint16_t link_offset; 33 | 34 | /* Get offsets */ 35 | chain->link_overhead_get(&link_offset); 36 | chain->tsp_overhead_get(&tsp_offset); 37 | 38 | /* Create header */ 39 | tsp_packet.data = chain->phy_mtu_buffer[FPC_COM_CHAIN_TX] + link_offset + tsp_offset; 40 | tsp_packet.size = chain->app_packet_size[FPC_COM_CHAIN_TX]; 41 | tsp_packet.seq_len = chain->private_vars.hcp_seq_len; 42 | tsp_packet.seq_nr = chain->private_vars.hcp_seq_nr; 43 | 44 | return chain->tsp_tx(&tsp_packet, chain); 45 | } 46 | 47 | fpc_com_result_t com_app_clr_receive(fpc_com_chain_t *chain) 48 | { 49 | fpc_com_result_t result; 50 | fpc_com_packet_tsp_t tsp_packet = { 0 }; 51 | 52 | result = chain->tsp_rx(&tsp_packet, chain); 53 | 54 | chain->app_packet_size[FPC_COM_CHAIN_RX] = tsp_packet.size; 55 | 56 | return result; 57 | } 58 | 59 | uint16_t com_app_clr_get_overhead(uint16_t *offset) 60 | { 61 | if (offset) { 62 | *offset = 0; 63 | } 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/com_app_cleartext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file com_app_cleartext.h 19 | * @brief TODO 20 | */ 21 | 22 | #ifndef COM_APP_CLEARTEXT_H 23 | #define COM_APP_CLEARTEXT_H 24 | 25 | #include "fpc_com_chain.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif /* __cplusplus */ 30 | 31 | /** 32 | * Sends a packet over the physical link in blocking mode. 33 | * 34 | * @param packet Packet to transmit. 35 | * @param chain The transmit chain to use. 36 | * @return ::fpc_com_result_t 37 | */ 38 | fpc_com_result_t com_app_clr_transmit(fpc_com_chain_t *chain); 39 | 40 | /** 41 | * Receives a packet from the physical link. 42 | * 43 | * @param packet Packet to populate. 44 | * @param chain The transmit chain to use. 45 | * @return ::fpc_com_result_t 46 | */ 47 | fpc_com_result_t com_app_clr_receive(fpc_com_chain_t *chain); 48 | 49 | /** 50 | * @brief Returns the overhead of the layer. 51 | * @return Overhead size in bytes. 52 | */ 53 | uint16_t com_app_clr_get_overhead(uint16_t *offset); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif /* __cplusplus */ 58 | 59 | #endif /* COM_APP_CLEARTEXT_H */ 60 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/com_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file com_common.c 19 | * @brief Communication common interface. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "fpc_com_transport.h" 27 | #include "fpc_com_link.h" 28 | #include "fpc_hcp.h" 29 | #include "fpc_crc.h" 30 | 31 | #include "platform.h" 32 | #include "com_app_cleartext.h" 33 | #include "com_common.h" 34 | 35 | #ifdef _WIN32 36 | #define __attribute__(x) 37 | #endif 38 | 39 | #define UNUSED(x) (void)(x) 40 | 41 | __attribute__((weak)) void *argument_allocator(fpc_hcp_cmd_t cmd, fpc_hcp_arg_t arg, uint16_t size, 42 | bool *free_data, void *context) 43 | { 44 | void *pointer = NULL; 45 | 46 | UNUSED(cmd); 47 | UNUSED(arg); 48 | UNUSED(context); 49 | 50 | /* Default behavior */ 51 | pointer = malloc(size); 52 | 53 | if (free_data != NULL) { 54 | *free_data = true; 55 | } 56 | 57 | return pointer; 58 | } 59 | 60 | __attribute__((weak)) void argument_free(fpc_hcp_cmd_t cmd, fpc_hcp_arg_data_t *arg_data, 61 | void *context) 62 | { 63 | UNUSED(cmd); 64 | UNUSED(context); 65 | 66 | if (arg_data->free_data) { 67 | free(arg_data->data); 68 | arg_data->data = NULL; 69 | } 70 | } 71 | 72 | __attribute__((weak)) void print_packet(fpc_hcp_packet_t *packet, const char* msg) 73 | { 74 | #if (FPC_LOG_INCLUDE == 1) 75 | if (!packet) { 76 | fpc_log_app_var(FPC_LOG_LEVEL_INFO, "Invalid argument"); 77 | return; 78 | } 79 | 80 | fpc_log_app_var(FPC_LOG_LEVEL_DEBUG, "%sPacket cmd id=0x%04X", msg != NULL ? msg : "", 81 | packet->id); 82 | 83 | for (int i = 0; i < packet->num_args; ++i) { 84 | if (packet->arguments[i].arg != ARG_NONE) { 85 | fpc_log_app_var(FPC_LOG_LEVEL_DEBUG, "\tArg[%02d]: key=0x%04X, size=%d free=%d", i, 86 | packet->arguments[i].arg, packet->arguments[i].size, 87 | packet->arguments[i].free_data); 88 | } 89 | } 90 | #else 91 | UNUSED(packet); 92 | UNUSED(msg); 93 | #endif 94 | } 95 | 96 | void init_com_chain(fpc_com_chain_t *chain, uint8_t *buffer, uint16_t size[2], 97 | void *context) 98 | { 99 | chain->initialized = true; 100 | 101 | /* CRC */ 102 | chain->crc_calc = fpc_crc; 103 | 104 | /* HCP */ 105 | chain->app_tx = com_app_clr_transmit; 106 | chain->app_rx = com_app_clr_receive; 107 | chain->app_overhead_get = com_app_clr_get_overhead; 108 | chain->argument_allocator = argument_allocator; 109 | chain->argument_free = argument_free; 110 | chain->app_packet_size[FPC_COM_CHAIN_TX] = 0; 111 | chain->app_packet_size[FPC_COM_CHAIN_RX] = 0; 112 | chain->app_mtu_buffer[FPC_COM_CHAIN_TX] = NULL; 113 | chain->app_mtu_buffer[FPC_COM_CHAIN_RX] = NULL; 114 | chain->app_mtu_size[FPC_COM_CHAIN_TX] = 0; 115 | chain->app_mtu_size[FPC_COM_CHAIN_RX] = 0; 116 | 117 | /* Transport */ 118 | chain->tsp_tx = fpc_com_transport_transmit; 119 | chain->tsp_rx = fpc_com_transport_receive; 120 | chain->tsp_overhead_get = fpc_com_transport_get_overhead; 121 | 122 | /* Link */ 123 | chain->link_overhead_get = fpc_com_link_get_overhead; 124 | 125 | /* Phy */ 126 | chain->phy_tx = platform_com_send; 127 | chain->phy_rx = platform_com_receive; 128 | chain->phy_mtu_size[FPC_COM_CHAIN_TX] = size[FPC_COM_CHAIN_TX]; 129 | chain->phy_mtu_size[FPC_COM_CHAIN_RX] = size[FPC_COM_CHAIN_RX]; 130 | chain->phy_mtu_buffer[FPC_COM_CHAIN_TX] = buffer; 131 | chain->phy_mtu_buffer[FPC_COM_CHAIN_RX] = buffer + size[FPC_COM_CHAIN_TX]; 132 | chain->phy_timeout_tx = 2000; 133 | chain->phy_timeout_rx = 2000; 134 | 135 | chain->session = NULL; 136 | chain->context = context; 137 | } 138 | 139 | fpc_bep_result_t com_to_bep_result(fpc_com_result_t result) 140 | { 141 | fpc_bep_result_t bep_result; 142 | switch (result) { 143 | case FPC_COM_RESULT_OK : 144 | bep_result = FPC_BEP_RESULT_OK; 145 | break; 146 | case FPC_COM_RESULT_NO_MEMORY: 147 | bep_result = FPC_BEP_RESULT_NO_MEMORY; 148 | break; 149 | case FPC_COM_RESULT_INVALID_ARGUMENT: 150 | bep_result = FPC_BEP_RESULT_INVALID_ARGUMENT; 151 | break; 152 | case FPC_COM_RESULT_NOT_IMPLEMENTED: 153 | bep_result = FPC_BEP_RESULT_NOT_IMPLEMENTED; 154 | break; 155 | case FPC_COM_RESULT_IO_ERROR: 156 | bep_result = FPC_BEP_RESULT_IO_ERROR; 157 | break; 158 | case FPC_COM_RESULT_TIMEOUT: 159 | bep_result = FPC_BEP_RESULT_TIMEOUT; 160 | break; 161 | default: 162 | bep_result = FPC_BEP_RESULT_GENERAL_ERROR; 163 | break; 164 | } 165 | return bep_result; 166 | } 167 | 168 | fpc_bep_result_t arg_add(fpc_hcp_packet_t *cmd, fpc_hcp_arg_t arg, const void *data, uint16_t size) 169 | { 170 | fpc_bep_result_t result = FPC_BEP_RESULT_OK; 171 | uint32_t *pointer; 172 | 173 | if (cmd == NULL || data == NULL || size == 0) { 174 | result = FPC_BEP_RESULT_INVALID_ARGUMENT; 175 | goto exit; 176 | } 177 | 178 | pointer = malloc(size); 179 | if (pointer == NULL) { 180 | result = FPC_BEP_RESULT_NO_MEMORY; 181 | goto exit; 182 | } 183 | 184 | memcpy(pointer, data, size); 185 | if (fpc_hcp_arg_add(cmd, arg, size, true, pointer) == false) { 186 | free(pointer); 187 | result = FPC_BEP_RESULT_NO_RESOURCE; 188 | } 189 | 190 | exit: 191 | return result; 192 | } 193 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/com_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef COM_COMMON_H 18 | #define COM_COMMON_H 19 | 20 | /** 21 | * @file com_common.h 22 | * @brief Communication common interface. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include "fpc_bep_types.h" 29 | #include "fpc_hcp_common.h" 30 | #include "fpc_com_chain.h" 31 | 32 | /** 33 | * @brief Allocates or assigns memory for arguments during HCP packet reassembly. 34 | 35 | * @param[in] cmd HCP command. 36 | * @param[in] arg HCP argument. 37 | * @param[in] size size of allocation. 38 | * @param[out] free_data Should data be freed by caller. 39 | * @param[in] context User defined context pointer. 40 | * 41 | * @return Pointer to allocation or NULL if allocation failed. 42 | */ 43 | void *argument_allocator(fpc_hcp_cmd_t cmd, fpc_hcp_arg_t arg, uint16_t size, bool *free_data, 44 | void *context); 45 | 46 | /** 47 | * @brief Frees memory for arguments during HCP packet destruction. 48 | * 49 | * @param[in] cmd HCP Command. 50 | * @param[in] arg_data Argument data. 51 | * @param[in] context User defined context pointer. 52 | */ 53 | void argument_free(fpc_hcp_cmd_t cmd, fpc_hcp_arg_data_t *arg_data, void *context); 54 | 55 | /** 56 | * @brief Prints packet information to the log. 57 | * 58 | * @param[in] packet Packet to print. 59 | * @param[in] msg Optional message to print. Set NULL if not needed. 60 | */ 61 | void print_packet(fpc_hcp_packet_t *packet, const char *msg); 62 | 63 | /** 64 | * @brief Initialize the chain used during communication with the host. 65 | * 66 | * @param[in, out] chain The chain structure to populate. 67 | * @param[in] buffer The buffer to use during communication. 68 | * @param[in] size An array of two sizes, one for the TX buffer size and one for the RX. 69 | * @param[in] context Application context. 70 | */ 71 | void init_com_chain(fpc_com_chain_t *chain, uint8_t *buffer, uint16_t size[2], void *context); 72 | 73 | /** 74 | * @brief Convert a COM result from HCP to a BEP result. 75 | * 76 | * @param[in] result COM result to convert. 77 | * @return ::fpc_bep_result_t 78 | */ 79 | fpc_bep_result_t com_to_bep_result(fpc_com_result_t result); 80 | 81 | /** 82 | * @brief Allocate and add data to an argument. 83 | * 84 | * @param[in, out] cmd Command to add argument to. 85 | * @param[in] arg Argument to add. 86 | * @param[in] data Data to copy to allocated memory. 87 | * @param[in] size Size of data. 88 | * @return ::fpc_bep_result_t 89 | */ 90 | fpc_bep_result_t arg_add(fpc_hcp_packet_t *cmd, fpc_hcp_arg_t arg, const void *data, uint16_t size); 91 | 92 | #endif /* COM_COMMON_H */ 93 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/debug.cfg: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | # 3 | # Example OpenOCD configuration file for ESP32-WROVER-KIT board. 4 | # 5 | # For example, OpenOCD can be started for ESP32 debugging on 6 | # 7 | # openocd -f board/esp32-wrover-kit-3.3v.cfg 8 | # 9 | 10 | # Source the JTAG interface configuration file 11 | source [find interface/ftdi/esp32_devkitj_v1.cfg] 12 | set ESP32_FLASH_VOLTAGE 3.3 13 | # Source the ESP32 configuration file 14 | source [find target/esp32.cfg] 15 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/debug_custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"Arduino on ESP32", 3 | "toolchainPrefix":"xtensa-esp32-elf", 4 | "svdFile":"esp32.svd", 5 | "request":"attach", 6 | "postAttachCommands":[ 7 | "set remote hardware-watchpoint-limit 2", 8 | "monitor reset halt", 9 | "monitor gdb_sync", 10 | "thb setup", 11 | "c" 12 | ], 13 | "overrideRestartCommands":[ 14 | "monitor reset halt", 15 | "monitor gdb_sync", 16 | "thb setup", 17 | "c" 18 | ] 19 | } -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/display.ino: -------------------------------------------------------------------------------- 1 | void showText(String text_t, int x, int y){ 2 | display.clear(); 3 | display.setTextAlignment(TEXT_ALIGN_LEFT); 4 | display.setFont(ArialMT_Plain_16); 5 | display.drawString(x, y, text_t); 6 | display.display(); 7 | } 8 | 9 | void subText(String text_t){ 10 | 11 | } 12 | 13 | void testdrawchar(void) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_bep_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FPC_BEP_TYPES_H 18 | #define FPC_BEP_TYPES_H 19 | 20 | #include 21 | 22 | /** 23 | * @file fpc_bep_types.h 24 | * @brief Biometric Embedded Platform types. 25 | * 26 | * This is the common types used by Biometric Embedded Platform (BEP) library. 27 | * 28 | * @note This is a work-in-progress specification. Implementers are informed 29 | * that this API may change without providing any backward compatibility. 30 | * However it is FPC's ambition that the API shall remain compatible between 31 | * releases. 32 | */ 33 | 34 | /** @brief Common result returned by BEP functions. */ 35 | typedef enum { 36 | /** No errors occurred. */ 37 | FPC_BEP_RESULT_OK = 0, 38 | /** General error. */ 39 | FPC_BEP_RESULT_GENERAL_ERROR = -1, 40 | /** Internal error. */ 41 | FPC_BEP_RESULT_INTERNAL_ERROR = -2, 42 | /** Invalid argument. */ 43 | FPC_BEP_RESULT_INVALID_ARGUMENT = -3, 44 | /** The functionality is not implemented. */ 45 | FPC_BEP_RESULT_NOT_IMPLEMENTED = -4, 46 | /** The operation was cancelled. */ 47 | FPC_BEP_RESULT_CANCELLED = -5, 48 | /** Out of memory. */ 49 | FPC_BEP_RESULT_NO_MEMORY = -6, 50 | /** Resources are not available. */ 51 | FPC_BEP_RESULT_NO_RESOURCE = -7, 52 | /** An I/O error occurred. */ 53 | FPC_BEP_RESULT_IO_ERROR = -8, 54 | /** Sensor is broken. */ 55 | FPC_BEP_RESULT_BROKEN_SENSOR = -9, 56 | /** The operation cannot be performed in the current state. */ 57 | FPC_BEP_RESULT_WRONG_STATE = -10, 58 | /** The operation timed out. */ 59 | FPC_BEP_RESULT_TIMEOUT = -11, 60 | /** The ID is not unique. */ 61 | FPC_BEP_RESULT_ID_NOT_UNIQUE = -12, 62 | /** The ID is not found. */ 63 | FPC_BEP_RESULT_ID_NOT_FOUND = -13, 64 | /** The format is invalid. */ 65 | FPC_BEP_RESULT_INVALID_FORMAT = -14, 66 | /** An image capture error occurred. */ 67 | FPC_BEP_RESULT_IMAGE_CAPTURE_ERROR = -15, 68 | /** Sensor hardware id or sensor configuration mismatch. */ 69 | FPC_BEP_RESULT_SENSOR_MISMATCH = -16, 70 | /** Invalid parameter. */ 71 | FPC_BEP_RESULT_INVALID_PARAMETER = -17, 72 | /** Missing Template. */ 73 | FPC_BEP_RESULT_MISSING_TEMPLATE = -18, 74 | /** Invalid Calibration.*/ 75 | FPC_BEP_RESULT_INVALID_CALIBRATION = -19, 76 | /** Calibration/template storage not formatted.*/ 77 | FPC_BEP_RESULT_STORAGE_NOT_FORMATTED = -20, 78 | /** Sensor hasn't been initialized. */ 79 | FPC_BEP_RESULT_SENSOR_NOT_INITIALIZED = -21, 80 | /** Enroll fail after too many bad images. */ 81 | FPC_BEP_RESULT_TOO_MANY_BAD_IMAGES = -22, 82 | /** Cryptographic operation failed. */ 83 | FPC_BEP_RESULT_CRYPTO_ERROR = -23, 84 | /** The functionality is not supported. */ 85 | FPC_BEP_RESULT_NOT_SUPPORTED = -24, 86 | /** Finger not stable during image capture. */ 87 | FPC_BEP_FINGER_NOT_STABLE = -25, 88 | /** The functionality could not be used before it's initialized. */ 89 | FPC_BEP_RESULT_NOT_INITIALIZED = -26, 90 | } fpc_bep_result_t; 91 | 92 | #endif /* FPC_BEP_TYPES_H */ 93 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_chain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_chain.h 19 | * @brief Communication chain type definitions. 20 | */ 21 | 22 | #ifndef FPC_COM_CHAIN_H 23 | #define FPC_COM_CHAIN_H 24 | 25 | #include 26 | 27 | #include "fpc_com_result.h" 28 | #include "fpc_hcp_common.h" 29 | #include "fpc_com_packets.h" 30 | 31 | /** 32 | * @brief Communication chain private variables. 33 | */ 34 | typedef struct fpc_com_chain_private fpc_com_chain_private_t; 35 | /** Communication chain private struct */ 36 | struct fpc_com_chain_private { 37 | /** HCP packet */ 38 | fpc_hcp_packet_t *hcp_packet; 39 | /** HCP sequence length */ 40 | uint16_t hcp_seq_len; 41 | /** HCP sequence number */ 42 | uint16_t hcp_seq_nr; 43 | }; 44 | 45 | /** 46 | * @brief Communication chain. 47 | */ 48 | typedef struct fpc_com_chain fpc_com_chain_t; 49 | /** Communication chain struct */ 50 | struct fpc_com_chain { 51 | /** Initialization status */ 52 | bool initialized; 53 | 54 | /** 55 | * @name HCP Layer 56 | * @{ 57 | */ 58 | /** Argument allocator interface function */ 59 | void *(*argument_allocator)(fpc_hcp_cmd_t cmd, fpc_hcp_arg_t arg, uint16_t size, 60 | bool *free_data, void *context); 61 | /** Argument free interface function */ 62 | void (*argument_free)(fpc_hcp_cmd_t cmd, fpc_hcp_arg_data_t *arg_data, void *context); 63 | /** @} */ 64 | 65 | /** CRC calculation interface function */ 66 | uint32_t (*crc_calc)(uint32_t start, const void *data, uint32_t size); 67 | 68 | /** 69 | * @name Application Layer 70 | * @{ 71 | */ 72 | /** Application layer transmit interface function */ 73 | fpc_com_result_t (*app_tx)(fpc_com_chain_t *chain); 74 | /** Application layer receive interface function */ 75 | fpc_com_result_t (*app_rx)(fpc_com_chain_t *chain); 76 | /** Application layer overhead get interface function */ 77 | uint16_t (*app_overhead_get)(uint16_t *offset); 78 | /** Application packet sizes */ 79 | uint16_t app_packet_size[2]; 80 | /** Application MTU sizes */ 81 | uint16_t app_mtu_size[2]; 82 | /** Application MTU buffers */ 83 | uint8_t *app_mtu_buffer[2]; 84 | /** @} */ 85 | 86 | /** 87 | * @name Transport Layer 88 | * @{ 89 | */ 90 | /** Transport layer transmit interface function */ 91 | fpc_com_result_t (*tsp_tx)(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain); 92 | /** Transport layer receive interface function */ 93 | fpc_com_result_t (*tsp_rx)(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain); 94 | /** Transport layer overhead get interface function */ 95 | uint16_t (*tsp_overhead_get)(uint16_t *offset); 96 | /** @} */ 97 | 98 | /** 99 | * @name Link Layer 100 | * @{ 101 | */ 102 | /** Link layer overhead get interface function */ 103 | uint16_t (*link_overhead_get)(uint16_t *offset); 104 | /** Communication channel */ 105 | fpc_com_channel_t channel; 106 | /** @} */ 107 | 108 | /** 109 | * @name Physical Layer 110 | * @{ 111 | */ 112 | /** Physical layer transmit interface function */ 113 | fpc_com_result_t (*phy_tx)(uint16_t size, const uint8_t *buffer, uint32_t timeout, 114 | void *session); 115 | /** Physical layer receive interface function */ 116 | fpc_com_result_t (*phy_rx)(uint16_t size, uint8_t *buffer, uint32_t timeout, 117 | void *session); 118 | /** Physical MTU sizes */ 119 | uint16_t phy_mtu_size[2]; 120 | /** Physical MTU buffers */ 121 | uint8_t *phy_mtu_buffer[2]; 122 | /** Physical transmit timeout */ 123 | uint32_t phy_timeout_tx; 124 | /** Physical receive timeout */ 125 | uint32_t phy_timeout_rx; 126 | /** @} */ 127 | 128 | /** Communication change private variables */ 129 | fpc_com_chain_private_t private_vars; 130 | 131 | /** 132 | * @brief User session pointer. 133 | * User private stuff, to be able to pass necessary info from the layer that 134 | * calls hcp down to the user's TX and RX functions (phy_tx/rx), to enable 135 | * multi threaded applications at the host side. 136 | */ 137 | void *session; 138 | /** 139 | * @brief User context pointer. 140 | * User private stuff, to be able to pass nessecary context to argument_allocator and 141 | * argument_free. 142 | */ 143 | void *context; 144 | }; 145 | 146 | /** 147 | * @brief Communication chain direction type. 148 | */ 149 | typedef enum { 150 | FPC_COM_CHAIN_TX = 0, 151 | FPC_COM_CHAIN_RX = 1, 152 | } fpc_com_chain_dir_t; 153 | 154 | #endif /* FPC_COM_CHAIN_H */ 155 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_link.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_link.c 19 | * @brief Communication link layer implementation. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "fpc_com_link.h" 26 | 27 | fpc_com_result_t fpc_com_link_transmit(fpc_com_packet_link_t *packet, fpc_com_chain_t *chain) 28 | { 29 | uint32_t ack; 30 | uint16_t size; 31 | fpc_com_result_t result; 32 | 33 | if (packet == NULL) { 34 | result = FPC_COM_RESULT_INVALID_ARGUMENT; 35 | goto exit; 36 | } 37 | 38 | /* Calculate CRC for payload */ 39 | packet->crc = chain->crc_calc(0, packet->data, packet->size); 40 | 41 | /* Get total size to be transfered over PHY layer */ 42 | size = packet->size + fpc_com_link_get_overhead(NULL); 43 | 44 | *((fpc_com_channel_t *)chain->phy_mtu_buffer[FPC_COM_CHAIN_TX]) = packet->channel; 45 | *((uint16_t *)(chain->phy_mtu_buffer[FPC_COM_CHAIN_TX] + sizeof(packet->channel))) 46 | = packet->size; 47 | /* Copy CRC to PHY mtu buffer */ 48 | memcpy(packet->data + packet->size, &packet->crc, sizeof(packet->crc)); 49 | // printf("fn::chain->phy_tx \n"); 50 | /* Send Packet */ 51 | result = chain->phy_tx(size, chain->phy_mtu_buffer[FPC_COM_CHAIN_TX], chain->phy_timeout_tx, 52 | chain->session); 53 | 54 | if (result != FPC_COM_RESULT_OK) { 55 | goto exit; 56 | } 57 | platform_delay_us(); 58 | /* Receive ACK */ 59 | result = chain->phy_rx(sizeof(ack), (uint8_t *)&ack, chain->phy_timeout_rx, chain->session); 60 | /* Handle no ack and timeout as IO error */ 61 | if (ack != FPC_COM_ACK || result == FPC_COM_RESULT_TIMEOUT) { 62 | result = FPC_COM_RESULT_IO_ERROR; 63 | goto exit; 64 | } 65 | /* Handle rest as normal error */ 66 | if (result != FPC_COM_RESULT_OK) { 67 | goto exit; 68 | } 69 | 70 | exit: 71 | return result; 72 | } 73 | 74 | fpc_com_result_t fpc_com_link_receive(fpc_com_packet_link_t *packet, fpc_com_chain_t *chain) 75 | { 76 | 77 | // printf("\n fpc_com_link_receive"); 78 | bool status; 79 | uint32_t ack = FPC_COM_ACK; 80 | const uint8_t header_size = sizeof(packet->channel) + sizeof(packet->size); 81 | fpc_com_result_t result; 82 | 83 | if (packet == NULL) { 84 | result = FPC_COM_RESULT_INVALID_ARGUMENT; 85 | goto exit; 86 | } 87 | 88 | // printf("checking header \n"); 89 | 90 | platform_delay_us(); 91 | /* Receive Header */ 92 | result = chain->phy_rx(header_size, chain->phy_mtu_buffer[FPC_COM_CHAIN_RX], 93 | chain->phy_timeout_rx, chain->session); 94 | if (result != FPC_COM_RESULT_OK) { 95 | goto exit; 96 | } 97 | 98 | packet->channel = *((fpc_com_channel_t *)chain->phy_mtu_buffer[FPC_COM_CHAIN_RX]); 99 | packet->size = *((uint16_t *) (chain->phy_mtu_buffer[FPC_COM_CHAIN_RX] 100 | + sizeof(fpc_com_channel_t))); 101 | packet->data = chain->phy_mtu_buffer[FPC_COM_CHAIN_RX] + header_size; 102 | 103 | /* Check if packet size is valid */ 104 | if (chain->phy_mtu_size[FPC_COM_CHAIN_RX] 105 | < (header_size + packet->size + sizeof(packet->crc))) { 106 | // printf("packet size is showing invalid\n"); 107 | result = FPC_COM_RESULT_IO_ERROR; 108 | goto exit; 109 | } 110 | // printf("final result \n"); 111 | platform_delay_us(); 112 | /* Receive Payload */ 113 | result = chain->phy_rx(packet->size + sizeof(packet->crc), packet->data, 114 | chain->phy_timeout_rx, chain->session); 115 | if (result != FPC_COM_RESULT_OK) { 116 | // printf("chain->phy_rx error result != FPC_COM_RESULT_OK \n"); 117 | goto exit; 118 | } 119 | 120 | /* Check incoming packet CRC */ 121 | memcpy(&packet->crc, packet->data + packet->size, sizeof(packet->crc)); 122 | status = (packet->crc == chain->crc_calc(0, packet->data, packet->size)); 123 | if (!status) { 124 | // printf("chain->phy_rx error CRC\n"); 125 | result = FPC_COM_RESULT_IO_ERROR; 126 | goto exit; 127 | } 128 | 129 | /* Send ACK */ 130 | result = chain->phy_tx(sizeof(ack), (uint8_t *)&ack, chain->phy_timeout_tx, chain->session); 131 | 132 | exit: 133 | return result; 134 | } 135 | 136 | uint16_t fpc_com_link_get_overhead(uint16_t *offset) 137 | { 138 | fpc_com_packet_link_t *packet; 139 | static const uint16_t internal_offset = sizeof(packet->channel) + sizeof(packet->size); 140 | 141 | if (offset) { 142 | *offset = internal_offset; 143 | } 144 | return internal_offset + sizeof(packet->crc); 145 | } 146 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_link.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_link.h 19 | * @brief Communication link interface. 20 | */ 21 | 22 | #ifndef FPC_COM_LINK_H 23 | #define FPC_COM_LINK_H 24 | 25 | #include 26 | #include 27 | 28 | #include "fpc_com_result.h" 29 | #include "fpc_com_chain.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif /* __cplusplus */ 34 | 35 | /** 36 | * @brief Sends a packet over the physical link in blocking mode. 37 | * 38 | * @param[in] packet Packet to transmit. 39 | * @param[in] chain The communication chain to use. 40 | * @return ::fpc_com_result_t 41 | */ 42 | fpc_com_result_t fpc_com_link_transmit(fpc_com_packet_link_t *packet, fpc_com_chain_t *chain); 43 | 44 | /** 45 | * @brief Receives a packet from the physical link. 46 | * 47 | * @param[in, out] packet Packet to populate. 48 | * @param[in] chain The communication chain to use. 49 | * @return ::fpc_com_result_t 50 | */ 51 | fpc_com_result_t fpc_com_link_receive(fpc_com_packet_link_t *packet, fpc_com_chain_t *chain); 52 | 53 | /** 54 | * @brief Returns the overhead of the layer. 55 | * 56 | * @param[out] offset The offset to the packet data. 57 | * @return Overhead size in bytes. 58 | */ 59 | uint16_t fpc_com_link_get_overhead(uint16_t *offset); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif /* __cplusplus */ 64 | 65 | #endif /* FPC_COM_LINK_H */ 66 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_packets.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_packets.h 19 | * @brief Communication packet type definitions. 20 | */ 21 | 22 | #ifndef FPC_COM_PACKETS_H 23 | #define FPC_COM_PACKETS_H 24 | 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif /* __cplusplus */ 30 | 31 | /** Communication acknowledge definition */ 32 | #define FPC_COM_ACK 0x7f01ff7f 33 | 34 | /** 35 | * Transport layer packet. 36 | */ 37 | typedef struct fpc_com_packet_transport { 38 | /** Size of packet */ 39 | uint16_t size; 40 | /** Sequence length */ 41 | uint16_t seq_len; 42 | /** Sequence number */ 43 | uint16_t seq_nr; 44 | /** Packet data */ 45 | uint8_t *data; 46 | } fpc_com_packet_tsp_t; 47 | 48 | /** 49 | * Transport packet channels. 50 | */ 51 | enum fpc_com_channel { 52 | FPC_COM_CHANNEL_NONE = 0x00, 53 | FPC_COM_CHANNEL_CLEAR = 0x01, 54 | FPC_COM_CHANNEL_TLS = 0x02, 55 | FPC_COM_CHANNEL_END = 0xFF, 56 | }; 57 | /** Communication channel type */ 58 | typedef uint16_t fpc_com_channel_t; 59 | 60 | /** Link layer packet */ 61 | typedef struct fpc_com_packet_link { 62 | /** Communication channel */ 63 | fpc_com_channel_t channel; 64 | /** Size of packet */ 65 | uint16_t size; 66 | /** Packet data */ 67 | uint8_t *data; 68 | /** CRC of data */ 69 | uint32_t crc; 70 | } fpc_com_packet_link_t; 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif /* __cplusplus */ 75 | 76 | #endif /* FPC_COM_PACKETS_H */ 77 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_result.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_result.h 19 | * @brief Communication result type definitions. 20 | */ 21 | 22 | #ifndef FPC_COM_RESULT_H 23 | #define FPC_COM_RESULT_H 24 | 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif /* __cplusplus */ 30 | 31 | /** Communication result codes */ 32 | enum fpc_com_result { 33 | FPC_COM_RESULT_OK, 34 | FPC_COM_RESULT_NO_MEMORY, 35 | FPC_COM_RESULT_INVALID_ARGUMENT, 36 | FPC_COM_RESULT_NOT_IMPLEMENTED, 37 | FPC_COM_RESULT_IO_ERROR, 38 | FPC_COM_RESULT_TIMEOUT, 39 | }; 40 | /** Communication result type */ 41 | typedef uint8_t fpc_com_result_t; 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif /* __cplusplus */ 46 | 47 | #endif /* FPC_COM_RESULT_H */ 48 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_transport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_transport.c 19 | * @brief Communication transport layer implementation. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "fpc_com_link.h" 26 | #include "fpc_com_transport.h" 27 | 28 | fpc_com_result_t fpc_com_transport_transmit(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain) 29 | { 30 | // printf("fn::fpc_com_transport_transmit\n"); 31 | fpc_com_packet_link_t link_packet = { 0 }; 32 | fpc_com_result_t result; 33 | uint16_t link_offset; 34 | uint16_t offset; 35 | 36 | if (packet == NULL|| chain == NULL) { 37 | result = FPC_COM_RESULT_INVALID_ARGUMENT; 38 | goto exit; 39 | } 40 | 41 | /* Construct header */ 42 | chain->link_overhead_get(&link_offset); 43 | link_packet.data = chain->phy_mtu_buffer[FPC_COM_CHAIN_TX] + link_offset; 44 | 45 | *((uint16_t *)(link_packet.data)) = packet->size; 46 | offset = sizeof(packet->size); 47 | *((uint16_t *)(link_packet.data + offset)) = packet->seq_nr; 48 | offset += sizeof(packet->seq_nr); 49 | *((uint16_t *)(link_packet.data + offset)) = packet->seq_len; 50 | 51 | link_packet.channel = chain->channel; 52 | link_packet.size = packet->size + chain->tsp_overhead_get(NULL); 53 | 54 | /* Send packet */ 55 | result = fpc_com_link_transmit(&link_packet, chain); 56 | 57 | exit: 58 | return result; 59 | } 60 | 61 | fpc_com_result_t fpc_com_transport_receive(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain) 62 | { 63 | fpc_com_packet_link_t link_packet = { 0 }; 64 | fpc_com_result_t result; 65 | uint16_t offset; 66 | 67 | if (packet == NULL|| chain == NULL) { 68 | result = FPC_COM_RESULT_INVALID_ARGUMENT; 69 | goto exit; 70 | } 71 | 72 | result = fpc_com_link_receive(&link_packet, chain); 73 | if (result != FPC_COM_RESULT_OK) { 74 | // printf("fpc_com_transport_receive result != FPC_COM_RESULT_OK \n"); 75 | goto exit; 76 | } 77 | 78 | packet->size = *((uint16_t *)link_packet.data); 79 | offset = sizeof(packet->size); 80 | packet->seq_nr = *((uint16_t *)(link_packet.data + offset)); 81 | offset += sizeof(packet->seq_nr); 82 | packet->seq_len = *((uint16_t *)(link_packet.data + offset)); 83 | offset += sizeof(packet->seq_len); 84 | packet->data = link_packet.data + offset; 85 | 86 | exit: 87 | return result; 88 | } 89 | 90 | uint16_t fpc_com_transport_get_overhead(uint16_t *offset) 91 | { 92 | fpc_com_packet_tsp_t *packet; 93 | static const uint16_t internal_offset = sizeof(packet->size) + sizeof(packet->seq_len) 94 | + sizeof(packet->seq_nr); 95 | 96 | if (offset) { 97 | *offset = internal_offset; 98 | } 99 | 100 | return internal_offset; 101 | } 102 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_com_transport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_com_transport.h 19 | * @brief Communication transport interface. 20 | */ 21 | 22 | #ifndef FPC_COM_TRANSPORT_H 23 | #define FPC_COM_TRANSPORT_H 24 | 25 | #include 26 | 27 | #include "fpc_com_chain.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif /* __cplusplus */ 32 | 33 | /** 34 | * @brief Transmit a transport layer packet. 35 | * 36 | * @param[in] packet The packet to transmit. 37 | * @param[in] chain The chain to use. 38 | * @result ::fpc_com_result_t 39 | */ 40 | fpc_com_result_t fpc_com_transport_transmit(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain); 41 | 42 | /** 43 | * @brief Receive a transport layer packet. 44 | * 45 | * @param[in, out] packet The packet to populate. 46 | * @param[in] chain The chain to use. 47 | * @result ::fpc_com_result_t 48 | */ 49 | fpc_com_result_t fpc_com_transport_receive(fpc_com_packet_tsp_t *packet, fpc_com_chain_t *chain); 50 | 51 | /** 52 | * @brief Returns the overhead of the layer. 53 | * 54 | * @param[out] offset The offset to the packet data. 55 | * @return Overhead size in bytes. 56 | */ 57 | uint16_t fpc_com_transport_get_overhead(uint16_t *offset); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif /* __cplusplus */ 62 | 63 | #endif /* FPC_COM_TRANSPORT_H */ 64 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_crc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_crc.c 19 | * @brief CRC32 calculation. 20 | */ 21 | 22 | #include 23 | 24 | #include "fpc_crc.h" 25 | 26 | /** 27 | * The constants here are for the CRC-32 generator polynomial, as defined in 28 | * the Microsoft Systems Journal, March 1995, pp. 107-108. 29 | */ 30 | static const uint32_t crc32_table[] = { 31 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 32 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 33 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 34 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 35 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 36 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 37 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 38 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 39 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 40 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 41 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 42 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 43 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 44 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 45 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 46 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 47 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 48 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 49 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 50 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 51 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 52 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 53 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 54 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 55 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 56 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 57 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 58 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 59 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 60 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 61 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 62 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 63 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 64 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 65 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 66 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 67 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 68 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 69 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 70 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 71 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 72 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 73 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 74 | }; 75 | 76 | uint32_t fpc_crc(uint32_t crc, const void *buf, uint32_t size) 77 | { 78 | const uint8_t *p; 79 | 80 | p = buf; 81 | crc = crc ^ ~0U; 82 | 83 | while (size--) { 84 | crc = crc32_table[(crc ^ *p++) & 0xFF] ^ (crc >> 8); 85 | } 86 | return crc ^ ~0U; 87 | } 88 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FPC_CRC_H 18 | #define FPC_CRC_H 19 | 20 | /** 21 | * @file fpc_crc.h 22 | * @brief Functionality for calculating CRC-32. 23 | */ 24 | 25 | #include 26 | 27 | /** 28 | * @brief Calculates CRC-32 value for the data in the buffer. 29 | * 30 | * @param crc Accumulated CRC-32 value, must be 0 on first call. 31 | * @param buf Buffer with data to calculate CRC-32 for. 32 | * @param size Size of buffer in number of bytes. 33 | * @return CRC-32 value for the data in buffer. 34 | */ 35 | uint32_t fpc_crc(uint32_t crc, const void *buf, uint32_t size); 36 | 37 | #endif /* FPC_CRC_H */ 38 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_hcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_hcp.h 19 | * @brief Host Communication Protocol interface. 20 | */ 21 | 22 | #ifndef FPC_HCP_H 23 | #define FPC_HCP_H 24 | 25 | #include 26 | #include 27 | 28 | #include "fpc_hcp_common.h" 29 | #include "fpc_com_chain.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif /* __cplusplus */ 34 | 35 | /** 36 | * @brief Transmits an application packet through the supplied transmit chain. 37 | * 38 | * @param[in] packet Application packet to send. 39 | * @param[in] chain The chain to use. 40 | * @return fpc_com_result_t 41 | */ 42 | fpc_com_result_t fpc_hcp_transmit(fpc_hcp_packet_t *packet, fpc_com_chain_t *chain); 43 | 44 | /** 45 | * @brief Receives an application packet through the supplied transmit chain. 46 | * 47 | * @param[in, out] packet Pointer to pre-allocated packet struct. 48 | * @param[in] chain The chain to use. 49 | * @return ::fpc_com_result_t 50 | */ 51 | fpc_com_result_t fpc_hcp_receive(fpc_hcp_packet_t *packet, fpc_com_chain_t *chain); 52 | 53 | /** 54 | * @brief Add argument to packet. 55 | * 56 | * @note This function does not allocate any memory, it will only set the argument variables. 57 | * 58 | * @param[in] packet Packet to add to. 59 | * @param[in] arg Argument id. 60 | * @param[in] size Size of argument data. 61 | * @param[in] free_data Set to true if data should be owned by the argument, false if user still owns 62 | * data. 63 | * @param[in] data Pointer to argument data. 64 | * @return true = success, false = failure. 65 | */ 66 | bool fpc_hcp_arg_add(fpc_hcp_packet_t *packet, fpc_hcp_arg_t arg, uint16_t size, bool free_data, 67 | void *data); 68 | 69 | /** 70 | * @brief Check if command contains selected argument key. 71 | * 72 | * @param[in] packet The packet to scan. 73 | * @param[in] arg Argument to look for. 74 | * @return true if found, false if not found. 75 | */ 76 | bool fpc_hcp_arg_check(fpc_hcp_packet_t *packet, fpc_hcp_arg_t arg); 77 | 78 | /** 79 | * @brief Get Argument with specified key. 80 | * 81 | * @param[in] packet The packet to operate on. 82 | * @param[in] arg The arg to retrieve. 83 | * @return Pointer to ::fpc_hcp_arg_data_t is successful, otherwise NULL. 84 | */ 85 | fpc_hcp_arg_data_t *fpc_hcp_arg_get(fpc_hcp_packet_t *packet, fpc_hcp_arg_t arg); 86 | 87 | /** 88 | * @brief Copy data from an argument with specified key. 89 | * 90 | * Argument data will be copied to specified data buffer. 91 | * Remaining bytes in data will be cleared if the argument data size is less 92 | * than data size when the argument contains data. 93 | * 94 | * @param[in] packet The packet to operate on. 95 | * @param[in] arg The arg to retrieve data from. 96 | * @param[in] data_size Number of bytes to copy. 97 | * @param[in, out] data Pointer to data buffer. 98 | * 99 | * @return True if argument found, false if not found. 100 | */ 101 | bool fpc_hcp_arg_copy_data(fpc_hcp_packet_t *packet, fpc_hcp_arg_t arg, uint16_t data_size, 102 | uint8_t *data); 103 | 104 | /** 105 | * @brief Frees the resources held by the packet i.e. the dynamic data held in the arguments. 106 | * 107 | * @param[in] chain Pointer to the communication chain used to retrieve the packet. 108 | * @param[in] packet Pointer to packet. 109 | */ 110 | void fpc_hcp_free(fpc_com_chain_t *chain, fpc_hcp_packet_t *packet); 111 | 112 | /** 113 | * @brief Calculate serialized packet size. 114 | * 115 | * @param[in] packet Packet to calculate. 116 | * @param[in, out] num_args Will return number of arguments held by the command can be set to NULL. 117 | * @return Serialized size. 118 | */ 119 | uint16_t fpc_hcp_get_size(fpc_hcp_packet_t *packet, uint16_t *num_args); 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif /* __cplusplus */ 124 | 125 | #endif /* FPC_HCP_H */ 126 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/fpc_hcp_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file fpc_hcp_common.h 19 | * @brief Host Communication Protocol common type definitions. 20 | */ 21 | 22 | #ifndef FPC_HCP_COMMON_H 23 | #define FPC_HCP_COMMON_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif /* __cplusplus */ 31 | 32 | /** Returns the smallest of two values. */ 33 | #define HCP_MIN(x, y) (((x) < (y)) ? (x) : (y)) 34 | 35 | /** Program specific commands base number */ 36 | #define CMD_APP_BASE_VAL 0xE000 37 | 38 | /** Program specific arguments base number */ 39 | #define ARG_APP_BASE_VAL 0x7000 40 | 41 | /** HCP Command definitions */ 42 | enum fpc_hcp_cmd { 43 | CMD_NONE = 0x0000, 44 | 45 | /* Biometry */ 46 | CMD_CAPTURE = 0x0001, 47 | CMD_ENROLL = 0x0002, 48 | CMD_IDENTIFY = 0x0003, 49 | CMD_MATCH = 0x0004, 50 | CMD_IMAGE = 0x0005, 51 | CMD_TEMPLATE = 0x0006, 52 | CMD_WAIT = 0x0007, 53 | CMD_SETTINGS = 0x0008, 54 | 55 | /* Sensor */ 56 | CMD_NAVIGATE = 0x1001, 57 | CMD_SENSOR = 0x1002, 58 | CMD_DEADPIXELS = 0x1003, 59 | 60 | /* Security */ 61 | CMD_CONNECT = 0x2001, 62 | CMD_RECONNECT = 0x2002, 63 | 64 | /* Firmware */ 65 | CMD_RESET = 0x3002, 66 | CMD_CANCEL = 0x3003, 67 | CMD_INFO = 0x3004, 68 | 69 | /* Storage */ 70 | CMD_STORAGE_TEMPLATE = 0x4002, 71 | CMD_STORAGE_CALIBRATION = 0x4003, 72 | CMD_STORAGE_LOG = 0x4004, 73 | CMD_STORAGE_SETTINGS = 0x4005, 74 | 75 | /* Hardware */ 76 | CMD_TEST = 0x5001, 77 | CMD_MCU = 0x5002, 78 | CMD_GPIO = 0x5003, 79 | 80 | /* Communication */ 81 | CMD_COMMUNICATION = 0x6001, 82 | 83 | /* Application specific commands */ 84 | CMD_APP_BASE = CMD_APP_BASE_VAL, 85 | 86 | /* Debug */ 87 | CMD_DIAG = 0xF003, 88 | 89 | CMD_FFFF = 0xFFFF, 90 | }; 91 | /** HCP Command type */ 92 | typedef uint16_t fpc_hcp_cmd_t; 93 | 94 | /** HCP Argument definitions */ 95 | enum fpc_hcp_arg { 96 | ARG_NONE = 0x0000, 97 | 98 | /* Biometry */ 99 | ARG_FINGER_DOWN = 0x0001, 100 | ARG_FINGER_UP = 0x0002, 101 | ARG_START = 0x0003, 102 | ARG_ADD = 0x0004, 103 | ARG_FINISH = 0x0005, 104 | ARG_ID = 0x0006, 105 | ARG_ALL = 0x0007, 106 | ARG_EXTRACT = 0x0008, 107 | ARG_MATCH_IMAGE = 0x0009, 108 | ARG_MATCH = 0x000A, 109 | 110 | /* Data */ 111 | ARG_ACQUIRE = 0x1001, 112 | ARG_RELEASE = 0x1002, 113 | ARG_SET = 0x1003, 114 | ARG_GET = 0x1004, 115 | ARG_UPLOAD = 0x1005, 116 | ARG_DOWNLOAD = 0x1006, 117 | ARG_CREATE = 0x1007, 118 | ARG_SAVE = 0x1008, 119 | ARG_DELETE = 0x1009, 120 | ARG_DATA = 0x100A, 121 | ARG_UPDATE = 0x100B, 122 | ARG_SEQ_NR = 0x100C, 123 | ARG_SEQ_LEN = 0x100D, 124 | 125 | /* Results */ 126 | ARG_RESULT = 0x2001, 127 | ARG_COUNT = 0x2002, 128 | ARG_SIZE = 0x2003, 129 | ARG_LEVEL = 0x2004, 130 | ARG_FORMAT = 0x2005, 131 | ARG_FLAG = 0x2006, 132 | ARG_PROPERTIES = 0x2007, 133 | ARG_SPEED = 0x2008, 134 | ARG_PROD_TEST = 0x2009, 135 | 136 | /* Sensor */ 137 | ARG_SENSOR_TYPE = 0x3001, 138 | ARG_WIDTH = 0x3002, 139 | ARG_HEIGHT = 0x3003, 140 | ARG_RESET = 0x3004, 141 | ARG_DPI = 0x3005, 142 | ARG_MAX_SPI_CLOCK = 0x3006, 143 | ARG_NUM_SUB_AREAS_WIDTH = 0x3007, 144 | ARG_NUM_SUB_AREAS_HEIGHT = 0x3008, 145 | ARG_IRQ_STATUS = 0x3009, 146 | ARG_RESET_HARD = 0x300A, 147 | 148 | /* MCU */ 149 | ARG_IDLE = 0x4001, 150 | ARG_SLEEP = 0x4002, 151 | ARG_DEEP_SLEEP = 0x4003, 152 | ARG_POWER_MODE = 0x4004, 153 | ARG_BUSY_WAIT = 0x4005, 154 | 155 | /* Misc */ 156 | ARG_TIMEOUT = 0x5001, 157 | ARG_DONE = 0x5002, 158 | 159 | /* Info */ 160 | ARG_BOOT = 0x6001, 161 | ARG_STATUS = 0x6002, 162 | ARG_VERSION = 0x6003, 163 | ARG_UNIQUE_ID = 0x6004, 164 | 165 | /* Application specific arguments */ 166 | ARG_APP_BASE = ARG_APP_BASE_VAL, 167 | 168 | /* VSM */ 169 | ARG_NONCE = 0x8001, 170 | ARG_MAC = 0x8002, 171 | ARG_RANDOM = 0x8003, 172 | ARG_CLAIM = 0x8004, 173 | ARG_PUBLIC_KEY = 0x8005, 174 | ARG_CIPHERTEXT = 0x8006, 175 | 176 | /* Communication */ 177 | ARG_MTU = 0x9001, 178 | 179 | /* Debug */ 180 | ARG_STACK = 0xE001, 181 | ARG_FILL = 0xE002, 182 | ARG_HEAP = 0xE003, 183 | 184 | /* Log */ 185 | ARG_MODE = 0xF001, 186 | ARG_DEBUG = 0xF002, 187 | 188 | ARG_FFFF = 0xFFFF, 189 | }; 190 | /** HCP Argument type */ 191 | typedef uint16_t fpc_hcp_arg_t; 192 | 193 | /** 194 | * @brief Command Argument 195 | */ 196 | typedef struct fpc_hcp_arg_data { 197 | /** Argument */ 198 | fpc_hcp_arg_t arg; 199 | /** Size of data */ 200 | uint16_t size; 201 | /** Free data inside HCP */ 202 | bool free_data; 203 | /** Pointer to data */ 204 | uint8_t *data; 205 | } fpc_hcp_arg_data_t; 206 | 207 | /** 208 | * @brief Application Command Packet 209 | */ 210 | typedef struct fpc_hcp_packet { 211 | /** Command ID */ 212 | fpc_hcp_cmd_t id; 213 | /** Number of arguments */ 214 | uint16_t num_args; 215 | /** Pointer to argument data */ 216 | fpc_hcp_arg_data_t *arguments; 217 | } fpc_hcp_packet_t; 218 | 219 | #ifdef __cplusplus 220 | } 221 | #endif /* __cplusplus */ 222 | 223 | #endif /* FPC_HCP_COMMON_H */ 224 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/images.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const uint8_t WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Fingerprint Cards AB 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file main.c 19 | * @brief Main file for FPC BEP Host Communication example. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "bep_host_if.h" 30 | #include "com_common.h" 31 | #include "platform.h" 32 | 33 | static void help(void) 34 | { 35 | fprintf(stderr, "BEP Host Communication Application\n"); 36 | fprintf(stderr, "Syntax: bep_host_com [-s speed (khz)] [-t timeout] [-h (help)]\n"); 37 | } 38 | 39 | static const char *result_string(fpc_bep_result_t result) 40 | { 41 | switch (result) { 42 | case FPC_BEP_RESULT_OK: 43 | return "OK"; 44 | case FPC_BEP_RESULT_GENERAL_ERROR: 45 | return "General Error"; 46 | case FPC_BEP_RESULT_INTERNAL_ERROR: 47 | return "Internal Error"; 48 | case FPC_BEP_RESULT_INVALID_ARGUMENT: 49 | return "Invalid Argument"; 50 | case FPC_BEP_RESULT_NOT_IMPLEMENTED: 51 | return "Not Implemented"; 52 | case FPC_BEP_RESULT_CANCELLED: 53 | return "Cancelled"; 54 | case FPC_BEP_RESULT_NO_MEMORY: 55 | return "No Memory"; 56 | case FPC_BEP_RESULT_NO_RESOURCE: 57 | return "No Resource"; 58 | case FPC_BEP_RESULT_IO_ERROR: 59 | return "IO Error"; 60 | case FPC_BEP_RESULT_BROKEN_SENSOR: 61 | return "Broken Sensor"; 62 | case FPC_BEP_RESULT_WRONG_STATE: 63 | return "Wrong State"; 64 | case FPC_BEP_RESULT_TIMEOUT: 65 | return "Timeout"; 66 | case FPC_BEP_RESULT_ID_NOT_UNIQUE: 67 | return "Id Not Unique"; 68 | case FPC_BEP_RESULT_ID_NOT_FOUND: 69 | return "Id Not Found"; 70 | case FPC_BEP_RESULT_INVALID_FORMAT: 71 | return "Invalid Format"; 72 | case FPC_BEP_RESULT_IMAGE_CAPTURE_ERROR: 73 | return "Image Capture Error"; 74 | case FPC_BEP_RESULT_SENSOR_MISMATCH: 75 | return "Sensor Mismatch"; 76 | case FPC_BEP_RESULT_INVALID_PARAMETER: 77 | return "Invalid Parameter"; 78 | case FPC_BEP_RESULT_MISSING_TEMPLATE: 79 | return "Missing Template"; 80 | case FPC_BEP_RESULT_INVALID_CALIBRATION: 81 | return "Invalid Calibration"; 82 | case FPC_BEP_RESULT_STORAGE_NOT_FORMATTED: 83 | return "Storage Not Formatted"; 84 | case FPC_BEP_RESULT_SENSOR_NOT_INITIALIZED: 85 | return "Sensor Not Initialized"; 86 | case FPC_BEP_RESULT_TOO_MANY_BAD_IMAGES: 87 | return "Too Many Bad Images"; 88 | case FPC_BEP_RESULT_NOT_SUPPORTED: 89 | return "Not Supported"; 90 | case FPC_BEP_FINGER_NOT_STABLE: 91 | return "Finger Not Stable"; 92 | case FPC_BEP_RESULT_NOT_INITIALIZED: 93 | return "Not Initialized"; 94 | default: 95 | return "Unknown Error"; 96 | } 97 | return NULL; 98 | } 99 | 100 | int main (int argc, char **argv) 101 | { 102 | char *port = NULL; 103 | int speed = 1000; 104 | int timeout = 5; 105 | int index; 106 | uint8_t buffer[512]; 107 | uint16_t size[2] = { 256, 256 }; 108 | fpc_com_chain_t hcp_chain; 109 | 110 | index = 1; 111 | while (index < argc) { 112 | if (argv[index][0] == '-' || argv[index][0] == '/') { 113 | if (argv[index][1] == 's' && (index + 1) < argc) { 114 | speed = atoi(argv[index + 1]); 115 | index++; 116 | } 117 | else if (argv[index][1] == 't' && (index + 1) < argc) { 118 | timeout = atoi(argv[index + 1]); 119 | index++; 120 | } 121 | else if (argv[index][1] == 'h') { 122 | help(); 123 | exit(1); 124 | } 125 | else { 126 | WRITE("Unknown flag %c\n", argv[index][1]); 127 | return 1; 128 | } 129 | } 130 | else { 131 | WRITE("Unknown option %s\n", argv[index]); 132 | return 1; 133 | } 134 | index++; 135 | } 136 | 137 | /* Cap at 10MHz */ 138 | if (speed > 10000) { 139 | speed = 10000; 140 | } 141 | 142 | if (!platform_com_init(port, &speed, timeout)) { 143 | WRITE("Com initialization failed\n"); 144 | exit(1); 145 | } 146 | 147 | init_com_chain(&hcp_chain, buffer, size, NULL); 148 | 149 | while(1) { 150 | char cmd[100]; 151 | fpc_bep_result_t res = FPC_BEP_RESULT_OK; 152 | uint16_t template_id; 153 | bool match; 154 | 155 | platform_clear_screen(); 156 | WRITE("BEP Host Interface\n"); 157 | WRITE("[speed: %d]\n", speed); 158 | WRITE("Timeout: %ds\n", timeout); 159 | WRITE("-------------------\n\n"); 160 | WRITE("Possible options:\n"); 161 | WRITE("a: Enroll finger\n"); 162 | WRITE("b: Capture and identify finger\n"); 163 | WRITE("c: Remove all templates\n"); 164 | WRITE("d: Save template\n"); 165 | WRITE("e: Remove template\n"); 166 | WRITE("f: Capture image\n"); 167 | WRITE("g: Image upload\n"); 168 | WRITE("h: Get version\n"); 169 | WRITE("i: Wait for finger\n"); 170 | WRITE("q: Exit program\n"); 171 | WRITE("\nOption>> "); 172 | fgets(cmd, sizeof(cmd), stdin); 173 | switch (cmd[0]) { 174 | case 'a': 175 | res = bep_enroll_finger(&hcp_chain); 176 | break; 177 | case 'A': 178 | res = bep_enroll_finger(&hcp_chain); 179 | break; 180 | case 'b': 181 | res = bep_identify_finger(&hcp_chain, &template_id, &match); 182 | if (res == FPC_BEP_RESULT_OK) { 183 | // if (match) { 184 | // char ch[100]; 185 | // sprintf(ch, "Match with template id: %d\n", template_id); 186 | // new_ws_callback(ch); 187 | // } else { 188 | // new_ws_callback("No match\n"); 189 | // } 190 | } 191 | break; 192 | case 'c': 193 | res = bep_delete_template(&hcp_chain, REMOVE_ID_ALL_TEMPLATES); 194 | break; 195 | case 'd': 196 | // WRITE("Template id: "); 197 | // fgets(cmd, sizeof(cmd), stdin); 198 | template_id = 15; 199 | res = bep_save_template(&hcp_chain, template_id); 200 | break; 201 | case 'e': 202 | WRITE("Template id: "); 203 | fgets(cmd, sizeof(cmd), stdin); 204 | template_id = atoi(cmd); 205 | res = bep_delete_template(&hcp_chain, template_id); 206 | break; 207 | case 'f': 208 | WRITE("Timeout: "); 209 | fgets(cmd, sizeof(cmd), stdin); 210 | res = bep_capture(&hcp_chain, atoi(cmd)); 211 | break; 212 | case 'g': { 213 | uint32_t size; 214 | res = bep_image_get_size(&hcp_chain, &size); 215 | if (res == FPC_BEP_RESULT_OK) { 216 | uint8_t *buf = malloc(size); 217 | if (buf) { 218 | res = bep_image_get(&hcp_chain, buf, size); 219 | if (res == FPC_BEP_RESULT_OK) { 220 | FILE *f = fopen("image.raw", "wb"); 221 | if (f) { 222 | fwrite(buf, 1, size, f); 223 | fclose(f); 224 | WRITE("Image saved as image.raw\n"); 225 | } 226 | } 227 | } 228 | 229 | } 230 | break; 231 | } 232 | case 'h': { 233 | char version[100]; 234 | 235 | memset(version, 0, 100); 236 | res = bep_version(&hcp_chain, version, 99); 237 | if (res == FPC_BEP_RESULT_OK) { 238 | WRITE("%s\n", version); 239 | } 240 | break; 241 | } 242 | case 'i': { 243 | uint16_t timeout; 244 | uint16_t sleep_counter; 245 | 246 | WRITE("Timeout: "); 247 | fgets(cmd, sizeof(cmd), stdin); 248 | timeout = atoi(cmd); 249 | WRITE("Sleep polling interval (4-1020 ms): "); 250 | fgets(cmd, sizeof(cmd), stdin); 251 | sleep_counter = atoi(cmd); 252 | 253 | res = bep_sensor_wait_for_finger(&hcp_chain, timeout, sleep_counter); 254 | break; 255 | } 256 | case 'q': 257 | return 0; 258 | default: 259 | WRITE("\nUnknown command\n"); 260 | } 261 | if (res == FPC_BEP_RESULT_OK) { 262 | WRITE("\nCommand succeeded\n"); 263 | } else { 264 | WRITE("\nCommand failed with error code %s (%d)\n", result_string(res), res); 265 | } 266 | WRITE("Press enter to continue..."); 267 | fgets(cmd, sizeof(cmd), stdin); 268 | } 269 | 270 | return 0; 271 | } 272 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/platform.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Fingerprint Cards AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | @file platform 19 | @brief 20 | */ 21 | #include "Arduino.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #ifdef _WIN32 29 | #include 30 | #else 31 | #include 32 | #include 33 | #endif 34 | #include "fpc_com_result.h" 35 | #include "platform.h" 36 | 37 | void (*function_send)(uint16_t size, const uint8_t *data, uint32_t timeout, void *session); 38 | void (*function2_send)(uint16_t size, uint8_t *data, uint32_t timeout, void *session); 39 | void (*new_delay_serial)(); 40 | 41 | 42 | bool platform_com_init(char *port, int *baudrate, int timeout) 43 | { 44 | // Serial.println("platform_com_init"); 45 | // uint32_t status = ftdi_spi_open(baudrate); 46 | // if (status) { 47 | // WRITE("FTDI open failed with status %d\r\n", status); 48 | // #if !defined(_WIN32) && (defined(__unix__) || defined(__unix)) && !defined(__CYGWIN__) 49 | // WRITE("Try sudo rmmod ftdi_sio and sudo rmmod usb_serial"); 50 | // #endif 51 | // return false; 52 | // } 53 | 54 | return true; 55 | } 56 | 57 | void assign_function(void *ptr) { 58 | function_send = ptr; 59 | } 60 | 61 | void assign2_function(void *ptr) { 62 | function2_send = ptr; 63 | } 64 | 65 | void assign3_function(void *ptr) { 66 | new_delay_serial = ptr; 67 | } 68 | 69 | fpc_com_result_t platform_com_send(uint16_t size, const uint8_t *data, uint32_t timeout, 70 | void *session) 71 | { 72 | 73 | // printf("fn::platform_com_send \n"); 74 | fpc_com_result_t res = FPC_COM_RESULT_OK; 75 | function_send(size, data, timeout, session); 76 | return res; 77 | } 78 | 79 | fpc_com_result_t platform_com_receive(uint16_t size, uint8_t *data, uint32_t timeout, 80 | void *session) 81 | { 82 | // printf("fn::platform_com_receive \n"); 83 | fpc_com_result_t res = FPC_COM_RESULT_OK; 84 | function2_send(size, data, timeout, session); 85 | return res; 86 | } 87 | 88 | uint64_t platform_get_time(void) 89 | { 90 | struct timeval current_time; 91 | uint64_t time_in_ms; 92 | 93 | gettimeofday(¤t_time, NULL); 94 | /* Seconds and microseconds are converted to milliseconds */ 95 | time_in_ms = current_time.tv_usec / 1000 + current_time.tv_sec * 1000; 96 | 97 | return time_in_ms; 98 | } 99 | 100 | void platform_delay_us() 101 | { 102 | new_delay_serial(); 103 | } 104 | 105 | void platform_clear_screen(void) 106 | { 107 | // #ifdef _WIN32 108 | // system("cls"); 109 | // #else 110 | // system("clear"); 111 | // #endif 112 | } 113 | 114 | bool platform_check_irq(void) 115 | { 116 | // int irq; 117 | 118 | // (void)ftdi_spi_check_irq(&irq); 119 | 120 | // return !(irq == 0); 121 | } 122 | 123 | void platform_reset(void) 124 | { 125 | // ftdi_set_reset_level(0); 126 | // platform_delay_us(1000); 127 | // ftdi_set_reset_level(1); 128 | } 129 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Fingerprint Cards AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef PLATFORM_H 18 | #define PLATFORM_H 19 | 20 | /** 21 | @file platform.h 22 | @brief Platform specific function interface 23 | */ 24 | 25 | #include 26 | #include 27 | #include "fpc_com_result.h" 28 | 29 | 30 | void assign_function(void *ptr); 31 | void assign2_function(void *ptr); 32 | 33 | /** 34 | @brief Custom printf with flush. 35 | */ 36 | #define WRITE(fmt, ...) { printf(fmt, ##__VA_ARGS__); fflush(stdout); } 37 | 38 | /** 39 | @brief Initializes Physical layer. 40 | 41 | @param[in] port tty port to use. 42 | @param[in] baudrate Baudrate. 43 | @param[in] timeout Timeout in ms. Use 0 for infinity. 44 | */ 45 | bool platform_com_init(char *port, int *baudrate, int timeout); 46 | 47 | /** 48 | @brief Sends data over communication port in blocking mode. 49 | 50 | @param[in] size Number of bytes to send. 51 | @param[in] data Data buffer to send. 52 | @param[in] timeout Timeout in ms. Use 0 for infinity. 53 | 54 | @return ::fpc_com_result_t 55 | */ 56 | fpc_com_result_t platform_com_send(uint16_t size, const uint8_t *data, uint32_t timeout, 57 | void *session); 58 | 59 | /** 60 | @brief Receives data from communication port in blocking mode. 61 | 62 | @param[in] size Number of bytes to receive. 63 | @param[in, out] data Data buffer to fill. 64 | @param[in] timeout Timeout in ms. Use 0 for infinity. 65 | 66 | @return ::fpc_com_result_t 67 | */ 68 | fpc_com_result_t platform_com_receive(uint16_t size, uint8_t *data, uint32_t timeout, 69 | void *session); 70 | 71 | /** 72 | @brief Get time in micro seconds 73 | 74 | @return time in us. 75 | */ 76 | uint64_t platform_get_time(void); 77 | 78 | /** 79 | @brief Clear console screen 80 | */ 81 | void platform_clear_screen(void); 82 | 83 | /** 84 | @brief Check IRQ 85 | */ 86 | bool platform_check_irq(void); 87 | 88 | /** 89 | @brief Send reset 90 | */ 91 | void platform_reset(void); 92 | 93 | void platform_delay_us(); 94 | 95 | void assign3_function(void *ptr); 96 | 97 | #endif /* PLATFORM_H */ 98 | -------------------------------------------------------------------------------- /Firmware/Arduino/Example_Websocket/udp.ino: -------------------------------------------------------------------------------- 1 | void startudp(){ 2 | 3 | } 4 | 5 | void sendlock(){ 6 | Serial.println("Sending message"); 7 | udp.broadcastTo("lock", 1234); 8 | } 9 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/NFC_LIB/.DS_Store -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/API.md: -------------------------------------------------------------------------------- 1 | # Electroniccats_PN7150 API Reference 2 | 3 | The `Electroniccats_PN7150` class enables Arduino library for I2C access to the PN7150 RFID/Near Field Communication chip. 4 | 5 | ### Class: `Electroniccats_PN7150` 6 | 7 | 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 8 | 9 | ```c 10 | #include 11 | 12 | Electroniccats_PN7150 nfc(PN7150_IRQ, PN7150_VEN, PN7150_ADDR); 13 | 14 | ``` 15 | 16 | - `uint8_t PN7150_IRQ`: IRQ pin for data interrupt. 17 | - `uint8_t PN7150_VEN`: "Reset" or "Enable" pin for device. 18 | - `uint8_t PN7150_ADDR`: Hexadecimal address for device, default `0x28` . 19 | 20 | ### Example 21 | 22 | ```c 23 | 24 | #include "Electroniccats_PN7150.h" 25 | #define PN7150_IRQ (8) 26 | #define PN7150_VEN (7) 27 | #define PN7150_ADDR (0x28) 28 | 29 | 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 30 | 31 | void setup(){ 32 | Serial.begin(115200); 33 | while(!Serial); 34 | Serial.println("Detect NFC readers with PN7150"); 35 | uint8_t statusNFC = setupNFC(); 36 | if (!statusNFC) 37 | Serial.println("Set up is ok"); 38 | else 39 | Serial.println("Error while setting up mode, check connections!"); 40 | } 41 | 42 | int setupNFC(){ 43 | Serial.println("Initializing..."); 44 | int setupOK = nfc.connectNCI(); //Wake up the board 45 | if (!setupOK){ 46 | setupOK = nfc.ConfigMode(mode); //Set up the configuration mode 47 | if (!setupOK) setupOK = nfc.StartDiscovery(mode); //NCI Discovery mode 48 | } 49 | return setupOK; 50 | } 51 | ``` 52 | ### Method: `GetFwVersion` 53 | 54 | Get Firmware Version. 55 | 56 | ```c 57 | uint8_t GetFwVersion(); 58 | ``` 59 | 60 | ### Method: `ConfigMode` 61 | 62 | Configure Mode for device 63 | 64 | - `1`: RW Mode. 65 | - `2`: Emulation mode. 66 | 67 | ```c 68 | uint8_t Electroniccats_PN7150::ConfigMode(uint8_t modeSE) 69 | ``` 70 | 71 | ### Method: `StartDiscovery` 72 | 73 | Returns . 74 | 75 | ```c 76 | uint8_t StartDiscovery(mode); 77 | ``` 78 | 79 | ### Method: `CardModeReceive` 80 | 81 | Returns . 82 | 83 | ```c 84 | bool CardModeReceive (unsigned char *pData unsigned char *pDataSize); 85 | ``` 86 | 87 | ### Method: `CardModeSend` 88 | 89 | Return. 90 | 91 | ```c 92 | bool CardModeSend (unsigned char *pData, unsigned char DataSize); 93 | ``` 94 | 95 | ### Method: `ReaderActivateNext` 96 | 97 | Return. 98 | 99 | ```c 100 | bool ReaderActivateNext(RfIntf_t *pRfIntf); 101 | ``` 102 | 103 | ### Method: `WaitForDiscoveryNotification` 104 | 105 | Return. 106 | 107 | ```c 108 | bool WaitForDiscoveryNotification(RfIntf_t *pRfIntf); 109 | ``` 110 | 111 | 112 | ### Method: `ProcessReaderMode` 113 | 114 | Return. 115 | 116 | ```c 117 | void ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); 118 | ``` 119 | 120 | ### Methods: `StopDiscovery` 121 | 122 | Return. 123 | 124 | ```c 125 | bool StopDiscovery(void); 126 | ``` -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ElectronicCats 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/README.md: -------------------------------------------------------------------------------- 1 | ![LibraryBuild](https://github.com/ElectronicCats/ElectronicCats-PN7150/workflows/LibraryBuild/badge.svg?branch=master) 2 | 3 | # Electronic Cats PN7150 4 | Library/Driver for NXP PN7150 NFC device 5 | 6 | Optimized for fast design-in, NXP’s PN7150 NFC solutions fully comply with the NFC Forum, including Linux®, AndroidTM, and WinIoT drivers and support NCI 1.0 host communication. 7 | 8 | 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. 9 | 10 | 11 | ### Quick Installing 12 | 13 | To install, use the Arduino Library Manager and search for "PN7150" and install the library. 14 | 15 | ### Manual Installing 16 | To install this library: 17 | 18 | - install it using the Arduino Library manager ("Sketch" -> "Include 19 | Library" -> "Manage Libraries..."), or 20 | - download a zipfile from github using the "Download ZIP" button and 21 | install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP 22 | Library..." 23 | - clone this git repository into your sketchbook/libraries folder. 24 | 25 | For more info, see https://www.arduino.cc/en/Guide/Libraries 26 | 27 | 28 | ### Maintainer 29 | 30 | 31 | 32 | 33 | 34 | Electronic Cats invests time and resources providing this open source design, please support Electronic Cats and open-source hardware by purchasing products from Electronic Cats! 35 | 36 | ### License 37 | 38 | MIT 39 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/datasheets/NFC Forum/NFC Controller Interface Specification V1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/NFC_LIB/datasheets/NFC Forum/NFC Controller Interface Specification V1.0.pdf -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/datasheets/NXP PN7150/PN7150 Datasheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/NFC_LIB/datasheets/NXP PN7150/PN7150 Datasheet.pdf -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/datasheets/NXP PN7150/PN7150 User Manual - Host Interface - UM10936.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/NFC_LIB/datasheets/NXP PN7150/PN7150 User Manual - Host Interface - UM10936.pdf -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshar001/chhavi/acc84464996fe0974831ab435182744af10ddc8d/Firmware/Arduino/NFC_LIB/examples/.DS_Store -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/DetectTags/DetectTags.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example detect tags and show their unique ID 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | 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 21 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 22 | 23 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 24 | 25 | int ResetMode(){ //Reset the configuration mode after each reading 26 | Serial.println("Re-initializing..."); 27 | nfc.ConfigMode(mode); 28 | nfc.StartDiscovery(mode); 29 | } 30 | 31 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 32 | uint32_t szPos; 33 | for (szPos=0; szPos < numBytes; szPos++) 34 | { 35 | Serial.print(F("0x")); 36 | // Append leading 0 for small values 37 | if (data[szPos] <= 0xF) 38 | Serial.print(F("0")); 39 | Serial.print(data[szPos]&0xff, HEX); 40 | if ((numBytes > 1) && (szPos != numBytes - 1)) 41 | { 42 | Serial.print(F(" ")); 43 | } 44 | } 45 | Serial.println(); 46 | } 47 | void displayCardInfo(RfIntf_t RfIntf){ //Funtion in charge to show the card/s in te field 48 | char tmp[16]; 49 | while (1){ 50 | switch(RfIntf.Protocol){ //Indetify card protocol 51 | case PROT_T1T: 52 | case PROT_T2T: 53 | case PROT_T3T: 54 | case PROT_ISODEP: 55 | Serial.print(" - POLL MODE: Remote activated tag type: "); 56 | Serial.println(RfIntf.Protocol); 57 | break; 58 | case PROT_ISO15693: 59 | Serial.println(" - POLL MODE: Remote ISO15693 card activated"); 60 | break; 61 | case PROT_MIFARE: 62 | Serial.println(" - POLL MODE: Remote MIFARE card activated"); 63 | break; 64 | default: 65 | Serial.println(" - POLL MODE: Undetermined target"); 66 | return; 67 | } 68 | 69 | switch(RfIntf.ModeTech) { //Indetify card technology 70 | case (MODE_POLL | TECH_PASSIVE_NFCA): 71 | Serial.print("\tSENS_RES = "); 72 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[0]); 73 | Serial.print(tmp); Serial.print(" "); 74 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SensRes[1]); 75 | Serial.print(tmp); Serial.println(" "); 76 | 77 | Serial.print("\tNFCID = "); 78 | PrintBuf(RfIntf.Info.NFC_APP.NfcId, RfIntf.Info.NFC_APP.NfcIdLen); 79 | 80 | if(RfIntf.Info.NFC_APP.SelResLen != 0) { 81 | Serial.print("\tSEL_RES = "); 82 | sprintf(tmp, "0x%.2X",RfIntf.Info.NFC_APP.SelRes[0]); 83 | Serial.print(tmp); Serial.println(" "); 84 | 85 | } 86 | break; 87 | 88 | case (MODE_POLL | TECH_PASSIVE_NFCB): 89 | if(RfIntf.Info.NFC_BPP.SensResLen != 0) { 90 | Serial.print("\tSENS_RES = "); 91 | PrintBuf(RfIntf.Info.NFC_BPP.SensRes,RfIntf.Info.NFC_BPP.SensResLen); 92 | } 93 | break; 94 | 95 | case (MODE_POLL | TECH_PASSIVE_NFCF): 96 | Serial.print("\tBitrate = "); 97 | Serial.println((RfIntf.Info.NFC_FPP.BitRate == 1) ? "212" : "424"); 98 | 99 | if(RfIntf.Info.NFC_FPP.SensResLen != 0) { 100 | Serial.print("\tSENS_RES = "); 101 | PrintBuf(RfIntf.Info.NFC_FPP.SensRes,RfIntf.Info.NFC_FPP.SensResLen); 102 | } 103 | break; 104 | 105 | case (MODE_POLL | TECH_PASSIVE_15693): 106 | Serial.print("\tID = "); 107 | PrintBuf(RfIntf.Info.NFC_VPP.ID,sizeof(RfIntf.Info.NFC_VPP.ID)); 108 | 109 | Serial.print("\ntAFI = "); 110 | Serial.println(RfIntf.Info.NFC_VPP.AFI); 111 | 112 | Serial.print("\tDSFID = "); 113 | Serial.println(RfIntf.Info.NFC_VPP.DSFID,HEX); 114 | break; 115 | 116 | default: 117 | break; 118 | } 119 | if(RfIntf.MoreTags) { // It will try to identify more NFC cards if they are the same technology 120 | if(nfc.ReaderActivateNext(&RfIntf) == NFC_ERROR) break; 121 | } 122 | else break; 123 | } 124 | } 125 | 126 | void setup(){ 127 | Serial.begin(9600); 128 | while(!Serial); 129 | Serial.println("Detect NFC tags with PN7150"); 130 | 131 | Serial.println("Initializing..."); 132 | if (nfc.connectNCI()) { //Wake up the board 133 | Serial.println("Error while setting up the mode, check connections!"); 134 | while (1); 135 | } 136 | 137 | if (nfc.ConfigureSettings()) { 138 | Serial.println("The Configure Settings is failed!"); 139 | while (1); 140 | } 141 | 142 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 143 | Serial.println("The Configure Mode is failed!!"); 144 | while (1); 145 | } 146 | nfc.StartDiscovery(mode); //NCI Discovery mode 147 | Serial.println("Waiting for an Card ..."); 148 | } 149 | 150 | void loop(){ 151 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 152 | displayCardInfo(RfInterface); 153 | switch(RfInterface.Protocol) { 154 | case PROT_T1T: 155 | case PROT_T2T: 156 | case PROT_T3T: 157 | case PROT_ISODEP: 158 | nfc.ProcessReaderMode(RfInterface, READ_NDEF); 159 | break; 160 | 161 | case PROT_ISO15693: 162 | break; 163 | 164 | case PROT_MIFARE: 165 | nfc.ProcessReaderMode(RfInterface, READ_NDEF); 166 | break; 167 | 168 | default: 169 | break; 170 | } 171 | 172 | //* It can detect multiple cards at the same time if they use the same protocol 173 | if(RfInterface.MoreTags) { 174 | nfc.ReaderActivateNext(&RfInterface); 175 | } 176 | //* Wait for card removal 177 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 178 | Serial.println("CARD REMOVED!"); 179 | 180 | nfc.StopDiscovery(); 181 | nfc.StartDiscovery(mode); 182 | } 183 | ResetMode(); 184 | delay(500); 185 | } 186 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/DetectingReaders/DetectingReaders.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example detect tags and show their unique ID 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | 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 21 | 22 | unsigned char STATUSOK[] = {0x90, 0x00}, Cmd[256], CmdSize; 23 | 24 | uint8_t mode = 2; // modes: 1 = Reader/ Writer, 2 = Emulation 25 | 26 | void setup(){ 27 | Serial.begin(9600); 28 | while(!Serial); 29 | Serial.println("Detect NFC readers with PN7150"); 30 | Serial.println("Initializing..."); 31 | 32 | if (nfc.connectNCI()) { //Wake up the board 33 | Serial.println("Error while setting up the mode, check connections!"); 34 | while (1); 35 | } 36 | 37 | if (nfc.ConfigureSettings()) { 38 | Serial.println("The Configure Settings is failed!"); 39 | while (1); 40 | } 41 | 42 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 43 | Serial.println("The Configure Mode is failed!!"); 44 | while (1); 45 | } 46 | nfc.StartDiscovery(mode); //NCI Discovery mode 47 | Serial.println("Waiting for an Reader Card ..."); 48 | } 49 | 50 | void loop(){ 51 | if(nfc.CardModeReceive(Cmd, &CmdSize) == 0) { //Data in buffer? 52 | if ((CmdSize >= 2) && (Cmd[0] == 0x00)) { //Expect at least two bytes 53 | switch (Cmd[1]) { 54 | case 0xA4: //Something tries to select a file, meaning that it is a reader 55 | Serial.println("Reader detected!"); 56 | break; 57 | 58 | case 0xB0: //SFI 59 | break; 60 | 61 | case 0xD0: //... 62 | break; 63 | 64 | default: 65 | break; 66 | } 67 | nfc.CardModeSend(STATUSOK, sizeof(STATUSOK)); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/ISO14443-3A_read_block/ISO14443-3A_read_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to read a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * November 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_ISO14443_3A (5) //Block to be read it 21 | 22 | 23 | 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 24 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 25 | 26 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 27 | 28 | int ResetMode(){ //Reset the configuration mode after each reading 29 | Serial.println("Re-initializing..."); 30 | nfc.ConfigMode(mode); 31 | nfc.StartDiscovery(mode); 32 | } 33 | 34 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 35 | uint32_t szPos; 36 | for (szPos=0; szPos < numBytes; szPos++){ 37 | Serial.print(F("0x")); 38 | // Append leading 0 for small values 39 | if (data[szPos] <= 0xF) 40 | Serial.print(F("0")); 41 | Serial.print(data[szPos]&0xff, HEX); 42 | if ((numBytes > 1) && (szPos != numBytes - 1)) 43 | Serial.print(F(" ")); 44 | } 45 | Serial.println(); 46 | } 47 | 48 | void PCD_ISO14443_3A_scenario (void){ 49 | bool status; 50 | unsigned char Resp[256]; 51 | unsigned char RespSize; 52 | /* Read block */ 53 | unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; 54 | 55 | status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); 56 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ 57 | Serial.print("Error reading block: "); 58 | Serial.print(ReadBlock[1],HEX); 59 | Serial.print(" with error: "); 60 | Serial.print(Resp[RespSize-1],HEX); 61 | return; 62 | } 63 | Serial.print("------------------------Block "); 64 | Serial.print(BLK_NB_ISO14443_3A, HEX); 65 | Serial.println("-------------------------"); 66 | PrintBuf(Resp, 4); 67 | } 68 | 69 | void setup(){ 70 | Serial.begin(9600); 71 | while(!Serial); 72 | Serial.println("Read ISO14443-3A(T2T) data block 5 with PN7150"); 73 | 74 | Serial.println("Initializing..."); 75 | if (nfc.connectNCI()) { //Wake up the board 76 | Serial.println("Error while setting up the mode, check connections!"); 77 | while (1); 78 | } 79 | 80 | if (nfc.ConfigureSettings()) { 81 | Serial.println("The Configure Settings failed!"); 82 | while (1); 83 | } 84 | 85 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 86 | Serial.println("The Configure Mode failed!!"); 87 | while (1); 88 | } 89 | nfc.StartDiscovery(mode); //NCI Discovery mode 90 | Serial.println("Waiting for an ISO14443-3A Card ..."); 91 | } 92 | 93 | void loop(){ 94 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 95 | switch(RfInterface.Protocol) { 96 | case PROT_T2T: 97 | Serial.println(" - Found ISO14443-3A(T2T) card"); 98 | switch(RfInterface.ModeTech) { //Indetify card technology 99 | case (MODE_POLL | TECH_PASSIVE_NFCA): 100 | char tmp[16]; 101 | Serial.print("\tSENS_RES = "); 102 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); 103 | Serial.print(tmp); Serial.print(" "); 104 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); 105 | Serial.print(tmp); Serial.println(" "); 106 | 107 | Serial.print("\tNFCID = "); 108 | PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); 109 | 110 | if(RfInterface.Info.NFC_APP.SelResLen != 0) { 111 | Serial.print("\tSEL_RES = "); 112 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); 113 | Serial.print(tmp); Serial.println(" "); 114 | } 115 | break; 116 | } 117 | PCD_ISO14443_3A_scenario(); 118 | break; 119 | 120 | default: 121 | Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); 122 | break; 123 | } 124 | 125 | //* It can detect multiple cards at the same time if they use the same protocol 126 | if(RfInterface.MoreTags) { 127 | nfc.ReaderActivateNext(&RfInterface); 128 | } 129 | //* Wait for card removal 130 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 131 | Serial.println("CARD REMOVED!"); 132 | 133 | nfc.StopDiscovery(); 134 | nfc.StartDiscovery(mode); 135 | } 136 | ResetMode(); 137 | delay(500); 138 | } 139 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/ISO14443-3A_write_block/ISO14443-3A_write_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to write a ISO14443-3A(Tag Type 2 - T2T) block 5 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * November 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_ISO14443_3A (5) //Block to be read it 21 | #define DATA_WRITE_ISO14443_3A 0x11, 0x22, 0x33, 0x44 //Data to write 22 | 23 | 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 24 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 25 | 26 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 27 | 28 | int ResetMode(){ //Reset the configuration mode after each reading 29 | Serial.println("Re-initializing..."); 30 | nfc.ConfigMode(mode); 31 | nfc.StartDiscovery(mode); 32 | } 33 | 34 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 35 | uint32_t szPos; 36 | for (szPos=0; szPos < numBytes; szPos++){ 37 | Serial.print(F("0x")); 38 | // Append leading 0 for small values 39 | if (data[szPos] <= 0xF) 40 | Serial.print(F("0")); 41 | Serial.print(data[szPos]&0xff, HEX); 42 | if ((numBytes > 1) && (szPos != numBytes - 1)) 43 | Serial.print(F(" ")); 44 | } 45 | Serial.println(); 46 | } 47 | 48 | void PCD_ISO14443_3A_scenario (void){ 49 | bool status; 50 | unsigned char Resp[256]; 51 | unsigned char RespSize; 52 | /* Read block */ 53 | unsigned char ReadBlock[] = {0x30, BLK_NB_ISO14443_3A}; 54 | /* Write block */ 55 | unsigned char WriteBlock[] = {0xA2, BLK_NB_ISO14443_3A, DATA_WRITE_ISO14443_3A}; 56 | 57 | // Write 58 | status = nfc.ReaderTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); 59 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) 60 | { 61 | Serial.print("Error writing block: "); 62 | Serial.print(ReadBlock[1],HEX); 63 | Serial.print(" with error: "); 64 | Serial.print(Resp[RespSize-1],HEX); 65 | return; 66 | } 67 | Serial.print("Wrote: "); 68 | Serial.println(WriteBlock[1]); 69 | 70 | //Read block 71 | status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); 72 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ 73 | Serial.print("Error reading block: "); 74 | Serial.print(ReadBlock[1],HEX); 75 | Serial.print(" with error: "); 76 | Serial.print(Resp[RespSize-1],HEX); 77 | return; 78 | } 79 | Serial.print("------------------------Block "); 80 | Serial.print(BLK_NB_ISO14443_3A, HEX); 81 | Serial.println("-------------------------"); 82 | PrintBuf(Resp, 4); 83 | } 84 | 85 | void setup(){ 86 | Serial.begin(9600); 87 | while(!Serial); 88 | Serial.println("Write ISO14443-3A(T2T) data block 5 with PN7150"); 89 | 90 | Serial.println("Initializing..."); 91 | if (nfc.connectNCI()) { //Wake up the board 92 | Serial.println("Error while setting up the mode, check connections!"); 93 | while (1); 94 | } 95 | 96 | if (nfc.ConfigureSettings()) { 97 | Serial.println("The Configure Settings failed!"); 98 | while (1); 99 | } 100 | 101 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 102 | Serial.println("The Configure Mode failed!!"); 103 | while (1); 104 | } 105 | nfc.StartDiscovery(mode); //NCI Discovery mode 106 | Serial.println("Waiting for an ISO14443-3A Card ..."); 107 | } 108 | 109 | void loop(){ 110 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 111 | switch(RfInterface.Protocol) { 112 | case PROT_T2T: 113 | Serial.println(" - Found ISO14443-3A(T2T) card"); 114 | switch(RfInterface.ModeTech) { //Indetify card technology 115 | case (MODE_POLL | TECH_PASSIVE_NFCA): 116 | char tmp[16]; 117 | Serial.print("\tSENS_RES = "); 118 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); 119 | Serial.print(tmp); Serial.print(" "); 120 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); 121 | Serial.print(tmp); Serial.println(" "); 122 | 123 | Serial.print("\tNFCID = "); 124 | PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); 125 | 126 | if(RfInterface.Info.NFC_APP.SelResLen != 0) { 127 | Serial.print("\tSEL_RES = "); 128 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); 129 | Serial.print(tmp); Serial.println(" "); 130 | } 131 | break; 132 | } 133 | PCD_ISO14443_3A_scenario(); 134 | break; 135 | 136 | default: 137 | Serial.println(" - Found a card, but it is not ISO14443-3A(T2T)!"); 138 | break; 139 | } 140 | 141 | //* It can detect multiple cards at the same time if they use the same protocol 142 | if(RfInterface.MoreTags) { 143 | nfc.ReaderActivateNext(&RfInterface); 144 | } 145 | //* Wait for card removal 146 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 147 | Serial.println("CARD REMOVED!"); 148 | 149 | nfc.StopDiscovery(); 150 | nfc.StartDiscovery(mode); 151 | } 152 | ResetMode(); 153 | delay(500); 154 | } 155 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/ISO15693_read_block/ISO15693_read_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to read a ISO15693 block 8 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * November 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_ISO15693 (8) //Block to be read it 21 | 22 | 23 | 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 24 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 25 | 26 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 27 | 28 | int ResetMode(){ //Reset the configuration mode after each reading 29 | Serial.println("Re-initializing..."); 30 | nfc.ConfigMode(mode); 31 | nfc.StartDiscovery(mode); 32 | } 33 | 34 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 35 | uint32_t szPos; 36 | for (szPos=0; szPos < numBytes; szPos++){ 37 | Serial.print(F("0x")); 38 | // Append leading 0 for small values 39 | if (data[szPos] <= 0xF) 40 | Serial.print(F("0")); 41 | Serial.print(data[szPos]&0xff, HEX); 42 | if ((numBytes > 1) && (szPos != numBytes - 1)) 43 | Serial.print(F(" ")); 44 | } 45 | Serial.println(); 46 | } 47 | 48 | void PCD_ISO15693_scenario (void){ 49 | #define BLK_NB_ISO15693 8 50 | 51 | bool status; 52 | unsigned char Resp[256]; 53 | unsigned char RespSize; 54 | unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; 55 | 56 | status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); 57 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ 58 | Serial.print("Error reading block: "); 59 | Serial.print(ReadBlock[2],HEX); 60 | Serial.print(" with error: "); 61 | Serial.print(Resp[RespSize-1],HEX); 62 | return; 63 | } 64 | Serial.print("------------------------Block "); 65 | Serial.print(BLK_NB_ISO15693, HEX); 66 | Serial.println("-------------------------"); 67 | PrintBuf(Resp+1, RespSize-2); 68 | } 69 | 70 | void setup(){ 71 | Serial.begin(9600); 72 | while(!Serial); 73 | Serial.println("Read ISO15693 data block 8 with PN7150"); 74 | 75 | Serial.println("Initializing..."); 76 | if (nfc.connectNCI()) { //Wake up the board 77 | Serial.println("Error while setting up the mode, check connections!"); 78 | while (1); 79 | } 80 | 81 | if (nfc.ConfigureSettings()) { 82 | Serial.println("The Configure Settings is failed!"); 83 | while (1); 84 | } 85 | 86 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 87 | Serial.println("The Configure Mode is failed!!"); 88 | while (1); 89 | } 90 | nfc.StartDiscovery(mode); //NCI Discovery mode 91 | Serial.println("Waiting for an ISO15693 Card ..."); 92 | } 93 | 94 | void loop(){ 95 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 96 | switch(RfInterface.Protocol) { 97 | case PROT_ISO15693: 98 | Serial.println(" - Found ISO15693 card"); 99 | switch(RfInterface.ModeTech) { //Indetify card technology 100 | case (MODE_POLL | TECH_PASSIVE_15693): 101 | char tmp[16]; 102 | Serial.print("\tID = "); 103 | PrintBuf(RfInterface.Info.NFC_VPP.ID, sizeof(RfInterface.Info.NFC_VPP.ID)); 104 | 105 | Serial.print("\tAFI = "); 106 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.AFI); 107 | Serial.print(tmp); Serial.println(" "); 108 | 109 | Serial.print("\tDSFID = "); 110 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.DSFID); 111 | Serial.print(tmp); Serial.println(" "); 112 | break; 113 | } 114 | PCD_ISO15693_scenario(); 115 | break; 116 | 117 | default: 118 | Serial.println(" - Found a card, but it is not ISO15693!"); 119 | break; 120 | } 121 | 122 | //* It can detect multiple cards at the same time if they use the same protocol 123 | if(RfInterface.MoreTags) { 124 | nfc.ReaderActivateNext(&RfInterface); 125 | } 126 | //* Wait for card removal 127 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 128 | Serial.println("CARD REMOVED!"); 129 | 130 | nfc.StopDiscovery(); 131 | nfc.StartDiscovery(mode); 132 | } 133 | ResetMode(); 134 | delay(500); 135 | } 136 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/ISO15693_write_block/ISO15693_write_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to write a ISO15693 block 8 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * November 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_ISO15693 (8) //Block to write 21 | #define DATA_WRITE_ISO15693 0x11, 0x22, 0x33, 0x44 //Data to write 22 | 23 | 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 24 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 25 | 26 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 27 | 28 | void setup(){ 29 | Serial.begin(9600); 30 | while(!Serial); 31 | Serial.println("Write ISO15693 data block 8 with PN7150"); 32 | 33 | Serial.println("Initializing..."); 34 | if (nfc.connectNCI()) { //Wake up the board 35 | Serial.println("Error while setting up the mode, check connections!"); 36 | while (1); 37 | } 38 | 39 | if (nfc.ConfigureSettings()) { 40 | Serial.println("The Configure Settings is failed!"); 41 | while (1); 42 | } 43 | 44 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 45 | Serial.println("The Configure Mode is failed!!"); 46 | while (1); 47 | } 48 | nfc.StartDiscovery(mode); //NCI Discovery mode 49 | Serial.println("Waiting for an ISO15693 Card ..."); 50 | } 51 | 52 | int ResetMode(){ //Reset the configuration mode after each reading 53 | Serial.println("Re-initializing..."); 54 | nfc.ConfigMode(mode); 55 | nfc.StartDiscovery(mode); 56 | } 57 | 58 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 59 | uint32_t szPos; 60 | for (szPos=0; szPos < numBytes; szPos++){ 61 | Serial.print(F("0x")); 62 | // Append leading 0 for small values 63 | if (data[szPos] <= 0xF) 64 | Serial.print(F("0")); 65 | Serial.print(data[szPos]&0xff, HEX); 66 | if ((numBytes > 1) && (szPos != numBytes - 1)) 67 | Serial.print(F(" ")); 68 | } 69 | Serial.println(); 70 | } 71 | 72 | void PCD_ISO15693_scenario (void){ 73 | bool status; 74 | unsigned char Resp[256]; 75 | unsigned char RespSize; 76 | unsigned char ReadBlock[] = {0x02, 0x20, BLK_NB_ISO15693}; 77 | unsigned char WriteBlock[] = {0x02, 0x21, BLK_NB_ISO15693, DATA_WRITE_ISO15693}; 78 | 79 | // Write 80 | status = nfc.ReaderTagCmd(WriteBlock, sizeof(WriteBlock), Resp, &RespSize); 81 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) 82 | { 83 | Serial.print("Error writing block: "); 84 | Serial.print(ReadBlock[2],HEX); 85 | Serial.print(" with error: "); 86 | Serial.print(Resp[RespSize-1],HEX); 87 | return; 88 | } 89 | Serial.print("Wrote: "); 90 | Serial.println(WriteBlock[2]); 91 | 92 | // Read 93 | status = nfc.ReaderTagCmd(ReadBlock, sizeof(ReadBlock), Resp, &RespSize); 94 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0x00)){ 95 | Serial.print("Error reading block: "); 96 | Serial.print(ReadBlock[2],HEX); 97 | Serial.print(" with error: "); 98 | Serial.print(Resp[RespSize-1],HEX); 99 | return; 100 | } 101 | Serial.print("------------------------Block "); 102 | Serial.print(BLK_NB_ISO15693, HEX); 103 | Serial.println("-------------------------"); 104 | PrintBuf(Resp+1, RespSize-2); 105 | } 106 | 107 | void loop(){ 108 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 109 | switch(RfInterface.Protocol) { 110 | case PROT_ISO15693: 111 | Serial.println(" - Found ISO15693 card"); 112 | switch(RfInterface.ModeTech) { //Indetify card technology 113 | case (MODE_POLL | TECH_PASSIVE_15693): 114 | char tmp[16]; 115 | Serial.print("\tID = "); 116 | PrintBuf(RfInterface.Info.NFC_VPP.ID, sizeof(RfInterface.Info.NFC_VPP.ID)); 117 | 118 | Serial.print("\tAFI = "); 119 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.AFI); 120 | Serial.print(tmp); Serial.println(" "); 121 | 122 | Serial.print("\tDSFID = "); 123 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_VPP.DSFID); 124 | Serial.print(tmp); Serial.println(" "); 125 | break; 126 | } 127 | PCD_ISO15693_scenario(); 128 | break; 129 | 130 | default: 131 | Serial.println(" - Found a card, but it is not ISO15693!"); 132 | break; 133 | } 134 | 135 | //* It can detect multiple cards at the same time if they use the same protocol 136 | if(RfInterface.MoreTags) { 137 | nfc.ReaderActivateNext(&RfInterface); 138 | } 139 | //* Wait for card removal 140 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 141 | Serial.println("CARD REMOVED!"); 142 | 143 | nfc.StopDiscovery(); 144 | nfc.StartDiscovery(mode); 145 | } 146 | ResetMode(); 147 | delay(500); 148 | } 149 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/MifareClassic_read_block/MifareClassic_read_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to read a Mifare Classic block 4 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_MFC 4 // Block tat wants to be read 21 | #define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key 22 | 23 | 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 24 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 25 | 26 | uint8_t mode = 1; 27 | // modes: 1 = Reader/ Writer, 2 = Emulation 28 | int ResetMode(){ //Reset the configuration mode after each reading 29 | Serial.println("Re-initializing..."); 30 | nfc.ConfigMode(mode); 31 | nfc.StartDiscovery(mode); 32 | } 33 | 34 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 35 | uint32_t szPos; 36 | for (szPos=0; szPos < numBytes; szPos++) 37 | { 38 | Serial.print(F("0x")); 39 | // Append leading 0 for small values 40 | if (data[szPos] <= 0xF) 41 | Serial.print(F("0")); 42 | Serial.print(data[szPos]&0xff, HEX); 43 | if ((numBytes > 1) && (szPos != numBytes - 1)) 44 | { 45 | Serial.print(F(" ")); 46 | } 47 | } 48 | Serial.println(); 49 | } 50 | 51 | void PCD_MIFARE_scenario (void){ 52 | Serial.println("Start reading process..."); 53 | bool status; 54 | unsigned char Resp[256]; 55 | unsigned char RespSize; 56 | /* Authenticate sector 1 with generic keys */ 57 | unsigned char Auth[] = {0x40, BLK_NB_MFC/4, 0x10, KEY_MFC}; 58 | /* Read block 4 */ 59 | unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; 60 | 61 | /* Authenticate */ 62 | status = nfc.ReaderTagCmd(Auth, sizeof(Auth), Resp, &RespSize); 63 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) 64 | Serial.println("Auth error!"); 65 | 66 | /* Read block */ 67 | status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); 68 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) 69 | Serial.print("Error reading sector!"); 70 | 71 | Serial.print("------------------------Sector "); 72 | Serial.print(BLK_NB_MFC/4, DEC); 73 | Serial.println("-------------------------"); 74 | 75 | PrintBuf(Resp+1, RespSize-2); 76 | } 77 | 78 | void setup(){ 79 | Serial.begin(9600); 80 | while(!Serial); 81 | Serial.println("Read mifare classic data block 4 with PN7150"); 82 | 83 | Serial.println("Initializing..."); 84 | if (nfc.connectNCI()) { //Wake up the board 85 | Serial.println("Error while setting up the mode, check connections!"); 86 | while (1); 87 | } 88 | 89 | if (nfc.ConfigureSettings()) { 90 | Serial.println("The Configure Settings is failed!"); 91 | while (1); 92 | } 93 | 94 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 95 | Serial.println("The Configure Mode is failed!!"); 96 | while (1); 97 | } 98 | nfc.StartDiscovery(mode); //NCI Discovery mode 99 | Serial.println("Waiting for an Mifare Classic Card ..."); 100 | } 101 | 102 | void loop(){ 103 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 104 | switch(RfInterface.Protocol) { 105 | case PROT_MIFARE: 106 | Serial.println(" - Found MIFARE card"); 107 | switch(RfInterface.ModeTech) { //Indetify card technology 108 | case (MODE_POLL | TECH_PASSIVE_NFCA): 109 | char tmp[16]; 110 | Serial.print("\tSENS_RES = "); 111 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); 112 | Serial.print(tmp); Serial.print(" "); 113 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); 114 | Serial.print(tmp); Serial.println(" "); 115 | 116 | Serial.print("\tNFCID = "); 117 | PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); 118 | 119 | if(RfInterface.Info.NFC_APP.SelResLen != 0) { 120 | Serial.print("\tSEL_RES = "); 121 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); 122 | Serial.print(tmp); Serial.println(" "); 123 | } 124 | break; 125 | } 126 | PCD_MIFARE_scenario(); 127 | break; 128 | 129 | default: 130 | Serial.println(" - Found a card, but it is not Mifare"); 131 | break; 132 | } 133 | 134 | //* It can detect multiple cards at the same time if they use the same protocol 135 | if(RfInterface.MoreTags) { 136 | nfc.ReaderActivateNext(&RfInterface); 137 | } 138 | //* Wait for card removal 139 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 140 | Serial.println("CARD REMOVED!"); 141 | 142 | nfc.StopDiscovery(); 143 | nfc.StartDiscovery(mode); 144 | } 145 | ResetMode(); 146 | delay(500); 147 | } 148 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/MifareClassic_write_block/MifareClassic_write_block.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to write a Mifare Classic block 4 and show its information 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | #define BLK_NB_MFC 4 // Block that wants to be read 21 | #define KEY_MFC 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // Default Mifare Classic key 22 | 23 | // Data to be written in the Mifare Classic block 24 | #define DATA_WRITE_MFC 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff 25 | 26 | 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 27 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 28 | 29 | uint8_t mode = 1; // modes: 1 = Reader/ Writer, 2 = Emulation 30 | 31 | int ResetMode(){ //Reset the configuration mode after each reading 32 | Serial.println("Re-initializing..."); 33 | nfc.ConfigMode(mode); 34 | nfc.StartDiscovery(mode); 35 | } 36 | 37 | void PrintBuf(const byte * data, const uint32_t numBytes){ //Print hex data buffer in format 38 | uint32_t szPos; 39 | for (szPos=0; szPos < numBytes; szPos++) 40 | { 41 | Serial.print(F("0x")); 42 | // Append leading 0 for small values 43 | if (data[szPos] <= 0xF) 44 | Serial.print(F("0")); 45 | Serial.print(data[szPos]&0xff, HEX); 46 | if ((numBytes > 1) && (szPos != numBytes - 1)) 47 | { 48 | Serial.print(F(" ")); 49 | } 50 | } 51 | Serial.println(); 52 | } 53 | 54 | uint8_t PCD_MIFARE_scenario (void){ 55 | Serial.println("Start reading process..."); 56 | bool status; 57 | unsigned char Resp[256]; 58 | unsigned char RespSize; 59 | /* Authenticate sector 1 with generic keys */ 60 | unsigned char Auth[] = {0x40, BLK_NB_MFC/4, 0x10, KEY_MFC}; 61 | /* Read block 4 */ 62 | unsigned char Read[] = {0x10, 0x30, BLK_NB_MFC}; 63 | /* Write block 4 */ 64 | unsigned char WritePart1[] = {0x10, 0xA0, BLK_NB_MFC}; 65 | unsigned char WritePart2[] = {0x10, DATA_WRITE_MFC}; 66 | 67 | /* Authenticate */ 68 | status = nfc.ReaderTagCmd(Auth, sizeof(Auth), Resp, &RespSize); 69 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ 70 | Serial.println("Auth error!"); 71 | return 1; 72 | } 73 | 74 | /* Read block */ 75 | status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); 76 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ 77 | Serial.print("Error reading block!"); 78 | return 2; 79 | } 80 | Serial.print("------------------------Sector "); 81 | Serial.print(BLK_NB_MFC/4, DEC); 82 | Serial.println("-------------------------"); 83 | Serial.print("-------------------------Block "); 84 | Serial.print(BLK_NB_MFC, DEC); 85 | Serial.println("-------------------------"); 86 | PrintBuf(Resp+1, RespSize-2); 87 | 88 | /* Write block */ 89 | status = nfc.ReaderTagCmd(WritePart1, sizeof(WritePart1), Resp, &RespSize); 90 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ 91 | Serial.print("Error writing block!"); 92 | return 3; 93 | } 94 | status = nfc.ReaderTagCmd(WritePart2, sizeof(WritePart2), Resp, &RespSize); 95 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)){ 96 | Serial.print("Error writing block!"); 97 | return 4; 98 | } 99 | /* Read block again to see te changes*/ 100 | status = nfc.ReaderTagCmd(Read, sizeof(Read), Resp, &RespSize); 101 | if((status == NFC_ERROR) || (Resp[RespSize-1] != 0)) 102 | { 103 | Serial.print("Error reading block!"); 104 | return 5; 105 | } 106 | Serial.print("------------------------Sector "); 107 | Serial.print(BLK_NB_MFC/4, DEC); 108 | Serial.println("-------------------------"); 109 | Serial.print("----------------- New Data in Block "); 110 | Serial.print(BLK_NB_MFC, DEC); 111 | Serial.println("-----------------"); 112 | PrintBuf(Resp+1, RespSize-2); 113 | return 0; 114 | } 115 | 116 | void setup(){ 117 | Serial.begin(9600); 118 | while(!Serial); 119 | Serial.println("Write mifare classic data block 4 with PN7150"); 120 | 121 | if (nfc.connectNCI()) { //Wake up the board 122 | Serial.println("Error while setting up the mode, check connections!"); 123 | while (1); 124 | } 125 | 126 | if (nfc.ConfigureSettings()) { 127 | Serial.println("The Configure Settings is failed!"); 128 | while (1); 129 | } 130 | 131 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 132 | Serial.println("The Configure Mode is failed!!"); 133 | while (1); 134 | } 135 | nfc.StartDiscovery(mode); //NCI Discovery mode 136 | Serial.println("Waiting for an Mifare Classic Card ..."); 137 | } 138 | 139 | void loop(){ 140 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect cards 141 | switch(RfInterface.Protocol) { 142 | case PROT_MIFARE: 143 | Serial.println(" - Found MIFARE card"); 144 | switch(RfInterface.ModeTech) { //Indetify card technology 145 | case (MODE_POLL | TECH_PASSIVE_NFCA): 146 | char tmp[16]; 147 | Serial.print("\tSENS_RES = "); 148 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[0]); 149 | Serial.print(tmp); Serial.print(" "); 150 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SensRes[1]); 151 | Serial.print(tmp); Serial.println(" "); 152 | 153 | Serial.print("\tNFCID = "); 154 | PrintBuf(RfInterface.Info.NFC_APP.NfcId, RfInterface.Info.NFC_APP.NfcIdLen); 155 | 156 | if(RfInterface.Info.NFC_APP.SelResLen != 0) { 157 | Serial.print("\tSEL_RES = "); 158 | sprintf(tmp, "0x%.2X",RfInterface.Info.NFC_APP.SelRes[0]); 159 | Serial.print(tmp); Serial.println(" "); 160 | } 161 | break; 162 | } 163 | PCD_MIFARE_scenario(); 164 | break; 165 | 166 | default: 167 | Serial.println(" - Found a card, but it is not Mifare"); 168 | break; 169 | } 170 | 171 | //* It can detect multiple cards at the same time if they use the same protocol 172 | if(RfInterface.MoreTags) { 173 | nfc.ReaderActivateNext(&RfInterface); 174 | } 175 | //* Wait for card removal 176 | nfc.ProcessReaderMode(RfInterface, PRESENCE_CHECK); 177 | Serial.println("CARD REMOVED!"); 178 | 179 | nfc.StopDiscovery(); 180 | nfc.StartDiscovery(mode); 181 | } 182 | ResetMode(); 183 | delay(500); 184 | } 185 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/examples/P2P_Discovery/P2P_Discovery.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Example to detect P2P device 3 | * Authors: 4 | * Salvador Mendoza - @Netxing - salmg.net 5 | * For Electronic Cats - electroniccats.com 6 | * 7 | * March 2020 8 | * 9 | * This code is beerware; if you see me (or any other collaborator 10 | * member) at the local, and you've found our code helpful, 11 | * please buy us a round! 12 | * Distributed as-is; no warranty is given. 13 | */ 14 | 15 | #include "Electroniccats_PN7150.h" 16 | #define PN7150_IRQ (15) 17 | #define PN7150_VEN (14) 18 | #define PN7150_ADDR (0x28) 19 | 20 | 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 21 | RfIntf_t RfInterface; //Intarface to save data for multiple tags 22 | 23 | uint8_t mode = 3; // modes: 1 = Reader/ Writer, 2 = Emulation, 3 = Peer to peer P2P 24 | 25 | int ResetMode(){ //Reset the configuration mode after each reading 26 | Serial.println("Re-initializing..."); 27 | nfc.ConfigMode(mode); 28 | nfc.StartDiscovery(mode); 29 | } 30 | 31 | 32 | void setup(){ 33 | Serial.begin(9600); 34 | while(!Serial); 35 | Serial.println("Detect P2P devices with PN7150"); 36 | 37 | Serial.println("Initializing..."); 38 | if (nfc.connectNCI()) { //Wake up the board 39 | Serial.println("Error while setting up the mode, check connections!"); 40 | while (1); 41 | } 42 | 43 | if (nfc.ConfigureSettings()) { 44 | Serial.println("The Configure Settings failed!"); 45 | while (1); 46 | } 47 | 48 | if(nfc.ConfigMode(mode)){ //Set up the configuration mode 49 | Serial.println("The Configure Mode failed!!"); 50 | while (1); 51 | } 52 | nfc.StartDiscovery(mode); //NCI Discovery mode 53 | Serial.println("Waiting for a P2P device..."); 54 | } 55 | 56 | void loop(){ 57 | if(!nfc.WaitForDiscoveryNotification(&RfInterface)){ // Waiting to detect 58 | if (RfInterface.Interface == INTF_NFCDEP) { 59 | if ((RfInterface.ModeTech & MODE_LISTEN) == MODE_LISTEN) 60 | Serial.println(" - P2P TARGET MODE: Activated from remote Initiator"); 61 | else 62 | Serial.println(" - P2P INITIATOR MODE: Remote Target activated"); 63 | 64 | /* Process with SNEP for NDEF exchange */ 65 | nfc.ProcessP2pMode(RfInterface); 66 | Serial.println("Peer lost!"); 67 | } 68 | ResetMode(); 69 | } 70 | delay(500); 71 | } 72 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ElectronicCats PN7150 3 | ####################################### 4 | # # Class (KEYWORD1) 5 | ####################################### 6 | 7 | Electroniccats_PN7150 KEYWORD1 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | GetFwVersion KEYWORD2 14 | begin KEYWORD2 15 | writeData KEYWORD2 16 | readData KEYWORD2 17 | hasMessage KEYWORD2 18 | ConfigMode KEYWORD2 19 | StartDiscovery KEYWORD2 20 | connectNCI KEYWORD2 21 | wakeupNCI KEYWORD2 22 | CardModeSend KEYWORD2 23 | CardModeReceive KEYWORD2 24 | WaitForDiscoveryNotification KEYWORD2 25 | FillInterfaceInfo KEYWORD2 26 | ReaderTagCmd KEYWORD2 27 | StopDiscovery KEYWORD2 28 | ProcessReaderMode KEYWORD2 29 | PresenceCheck KEYWORD2 30 | ReaderReActivate KEYWORD2 31 | PrintBuf KEYWORD2 32 | ReaderActivateNext KEYWORD2 33 | 34 | ####################################### 35 | 36 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/library.properties: -------------------------------------------------------------------------------- 1 | name=Electronic Cats PN7150 2 | version=1.5.1 3 | author=Electronic Cats and Salvador Mendoza 4 | maintainer=Electronic Cats 5 | sentence=Arduino library for SPI and I2C access to the PN7150 RFID/Near Field Communication chip. 6 | paragraph=Arduino library for SPI and I2C access to the PN7150 RFID/Near Field Communication chip 7 | category=Communication 8 | url=https://github.com/ElectronicCats/ElectronicCats-PN7150 9 | architectures=* 10 | 11 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/Electroniccats_PN7150.h: -------------------------------------------------------------------------------- 1 | #ifndef Electroniccats_PN7150_H 2 | #define Electroniccats_PN7150_H 3 | /** 4 | * NXP PN7150 Driver 5 | * Porting uthors: 6 | * Salvador Mendoza - @Netxing - salmg.net 7 | * Andres Sabas - Electronic Cats - Electroniccats.com 8 | * 9 | * November 2020 10 | * 11 | * This code is beerware; if you see me (or any other collaborator 12 | * member) at the local, and you've found our code helpful, 13 | * please buy us a round! 14 | * Distributed as-is; no warranty is given. 15 | * 16 | * A few methods and ideas were extract from 17 | * https://github.com/Strooom/PN7150 18 | * 19 | */ 20 | 21 | #include // Gives us access to all typical Arduino types and functions 22 | // The HW interface between The PN7150 and the DeviceHost is I2C, so we need the I2C library.library 23 | //#include "RW_NDEF.h" 24 | #include "P2P_NDEF.h" 25 | 26 | #if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6 : Special, more optimized I2C library for Teensy boards 27 | #include // Credits Brian "nox771" : see https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3 28 | #else 29 | #include 30 | #if defined(__AVR__) || defined(__i386__) || defined(ARDUINO_ARCH_SAMD) || defined(ESP8266) || defined(ARDUINO_ARCH_STM32) 31 | #define WIRE Wire 32 | #else // Arduino Due 33 | #define WIRE Wire1 34 | #endif // TODO : i2c_t3.h ensures a maximum I2C message of 259, which is sufficient. Other I2C implementations have shorter buffers (32 bytes) 35 | #endif 36 | 37 | /* Following definitions specifies which settings will apply when NxpNci_ConfigureSettings() 38 | * API is called from the application 39 | */ 40 | #define NXP_CORE_CONF 1 41 | #define NXP_CORE_STANDBY 1 42 | #define NXP_CORE_CONF_EXTN 1 43 | #define NXP_CLK_CONF 1 // 1=Xtal, 2=PLL 44 | #define NXP_TVDD_CONF 2 // 1=CFG1, 2=CFG2 45 | #define NXP_RF_CONF 1 46 | 47 | #define NFC_FACTORY_TEST 1 48 | 49 | #define NFC_SUCCESS 0 50 | #define NFC_ERROR 1 51 | #define TIMEOUT_2S 2000 52 | #define SUCCESS NFC_SUCCESS 53 | #define ERROR NFC_ERROR 54 | #define MAX_NCI_FRAME_SIZE 258 55 | 56 | /* 57 | * Flag definition used for NFC library configuration 58 | */ 59 | #define MODE_CARDEMU (1 << 0) 60 | #define MODE_P2P (1 << 1) 61 | #define MODE_RW (1 << 2) 62 | 63 | /* 64 | * Flag definition used as Mode values 65 | */ 66 | #define MODE_POLL 0x00 67 | #define MODE_LISTEN 0x80 68 | #define MODE_MASK 0xF0 69 | 70 | /* 71 | * Flag definition used as Technologies values 72 | */ 73 | #define TECH_PASSIVE_NFCA 0 74 | #define TECH_PASSIVE_NFCB 1 75 | #define TECH_PASSIVE_NFCF 2 76 | #define TECH_ACTIVE_NFCA 3 77 | #define TECH_ACTIVE_NFCF 5 78 | #define TECH_PASSIVE_15693 6 79 | 80 | /* 81 | * Flag definition used as Protocol values 82 | */ 83 | #define PROT_UNDETERMINED 0x0 84 | #define PROT_T1T 0x1 85 | #define PROT_T2T 0x2 86 | #define PROT_T3T 0x3 87 | #define PROT_ISODEP 0x4 88 | #define PROT_NFCDEP 0x5 89 | #define PROT_ISO15693 0x6 90 | #define PROT_MIFARE 0x80 91 | 92 | /* 93 | * Flag definition used as Interface values 94 | */ 95 | #define INTF_UNDETERMINED 0x0 96 | #define INTF_FRAME 0x1 97 | #define INTF_ISODEP 0x2 98 | #define INTF_NFCDEP 0x3 99 | #define INTF_TAGCMD 0x80 100 | 101 | #define MaxPayloadSize 255 // See NCI specification V1.0, section 3.1 102 | #define MsgHeaderSize 3 103 | 104 | /***** Factory Test dedicated APIs *********************************************/ 105 | #ifdef NFC_FACTORY_TEST 106 | 107 | /* 108 | * Definition of technology types 109 | */ 110 | typedef enum 111 | { 112 | NFC_A, 113 | NFC_B, 114 | NFC_F 115 | } NxpNci_TechType_t; 116 | 117 | /* 118 | * Definition of bitrate 119 | */ 120 | typedef enum 121 | { 122 | BR_106, 123 | BR_212, 124 | BR_424, 125 | BR_848 126 | } NxpNci_Bitrate_t; 127 | #endif 128 | /* 129 | * Definition of discovered remote device properties information 130 | */ 131 | 132 | /* POLL passive type A */ 133 | struct RfIntf_info_APP_t 134 | { 135 | unsigned char SensRes[2]; 136 | unsigned char NfcIdLen; 137 | unsigned char NfcId[10]; 138 | unsigned char SelResLen; 139 | unsigned char SelRes[1]; 140 | unsigned char RatsLen; 141 | unsigned char Rats[20]; 142 | }; 143 | 144 | /* POLL passive type B */ 145 | struct RfIntf_info_BPP_t 146 | { 147 | unsigned char SensResLen; 148 | unsigned char SensRes[12]; 149 | unsigned char AttribResLen; 150 | unsigned char AttribRes[17]; 151 | }; 152 | 153 | /* POLL passive type F */ 154 | struct RfIntf_info_FPP_t 155 | { 156 | unsigned char BitRate; 157 | unsigned char SensResLen; 158 | unsigned char SensRes[18]; 159 | }; 160 | 161 | /* POLL passive type ISO15693 */ 162 | struct RfIntf_info_VPP_t 163 | { 164 | unsigned char AFI; 165 | unsigned char DSFID; 166 | unsigned char ID[8]; 167 | }; 168 | 169 | typedef union 170 | { 171 | RfIntf_info_APP_t NFC_APP; 172 | RfIntf_info_BPP_t NFC_BPP; 173 | RfIntf_info_FPP_t NFC_FPP; 174 | RfIntf_info_VPP_t NFC_VPP; 175 | } RfIntf_Info_t; 176 | 177 | /* 178 | * Definition of discovered remote device properties 179 | */ 180 | struct RfIntf_t 181 | { 182 | unsigned char Interface; 183 | unsigned char Protocol; 184 | unsigned char ModeTech; 185 | bool MoreTags; 186 | RfIntf_Info_t Info; 187 | }; 188 | 189 | /* 190 | * Definition of operations handled when processing Reader mode 191 | */ 192 | typedef enum 193 | { 194 | #ifndef NO_NDEF_SUPPORT 195 | READ_NDEF, 196 | WRITE_NDEF, 197 | #endif 198 | PRESENCE_CHECK 199 | } RW_Operation_t; 200 | 201 | /* 202 | * Definition of discovered remote device properties information 203 | */ 204 | /* POLL passive type A */ 205 | typedef struct 206 | { 207 | unsigned char SensRes[2]; 208 | unsigned char NfcIdLen; 209 | unsigned char NfcId[10]; 210 | unsigned char SelResLen; 211 | unsigned char SelRes[1]; 212 | unsigned char RatsLen; 213 | unsigned char Rats[20]; 214 | } NxpNci_RfIntf_info_APP_t; 215 | 216 | /* POLL passive type B */ 217 | typedef struct 218 | { 219 | unsigned char SensResLen; 220 | unsigned char SensRes[12]; 221 | unsigned char AttribResLen; 222 | unsigned char AttribRes[17]; 223 | } NxpNci_RfIntf_info_BPP_t; 224 | 225 | /* POLL passive type F */ 226 | typedef struct 227 | { 228 | unsigned char BitRate; 229 | unsigned char SensResLen; 230 | unsigned char SensRes[18]; 231 | } NxpNci_RfIntf_info_FPP_t; 232 | 233 | /* POLL passive type ISO15693 */ 234 | typedef struct 235 | { 236 | unsigned char AFI; 237 | unsigned char DSFID; 238 | unsigned char ID[8]; 239 | } NxpNci_RfIntf_info_VPP_t; 240 | 241 | typedef union 242 | { 243 | NxpNci_RfIntf_info_APP_t NFC_APP; 244 | NxpNci_RfIntf_info_BPP_t NFC_BPP; 245 | NxpNci_RfIntf_info_FPP_t NFC_FPP; 246 | NxpNci_RfIntf_info_VPP_t NFC_VPP; 247 | } NxpNci_RfIntf_Info_t; 248 | 249 | class Electroniccats_PN7150 250 | { 251 | private: 252 | uint8_t _IRQpin, _VENpin, _I2Caddress; 253 | uint8_t rxBuffer[MaxPayloadSize + MsgHeaderSize]; // buffer where we store bytes received until they form a complete message 254 | void setTimeOut(unsigned long); // set a timeOut for an expected next event, eg reception of Response after sending a Command 255 | bool isTimeOut() const; 256 | bool getMessage(uint16_t timeout = 5); // 5 miliseconds as default to wait for interrupt responses 257 | unsigned long timeOut; 258 | unsigned long timeOutStartTime; 259 | uint32_t rxMessageLength; // length of the last message received. As these are not 0x00 terminated, we need to remember the length 260 | uint8_t gNfcController_generation = 0; 261 | uint8_t gNfcController_fw_version[3] = {0}; 262 | 263 | public: 264 | Electroniccats_PN7150(uint8_t IRQpin, uint8_t VENpin, uint8_t I2Caddress); 265 | int GetFwVersion(); 266 | uint8_t begin(void); 267 | uint8_t writeData(uint8_t data[], uint32_t dataLength) const; // write data from DeviceHost to PN7150. Returns success (0) or Fail (> 0) 268 | uint32_t readData(uint8_t data[]) const; // read data from PN7150, returns the amount of bytes read 269 | bool hasMessage() const; 270 | uint8_t ConfigMode(uint8_t modeSE); 271 | uint8_t StartDiscovery(uint8_t modeSE); 272 | uint8_t connectNCI(); 273 | uint8_t wakeupNCI(); 274 | bool CardModeSend(unsigned char *pData, unsigned char DataSize); 275 | bool CardModeReceive(unsigned char *pData, unsigned char *pDataSize); 276 | bool WaitForDiscoveryNotification(RfIntf_t *pRfIntf, uint8_t tout = 0); 277 | void FillInterfaceInfo(RfIntf_t *pRfIntf, uint8_t *pBuf); 278 | bool ReaderTagCmd(unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize); 279 | bool StopDiscovery(void); 280 | void ProcessReaderMode(RfIntf_t RfIntf, RW_Operation_t Operation); 281 | void PresenceCheck(RfIntf_t RfIntf); 282 | bool ReaderReActivate(RfIntf_t *pRfIntf); 283 | void PrintBuf(const byte *data, const uint32_t numBytes); 284 | bool ReaderActivateNext(RfIntf_t *pRfIntf); 285 | bool ConfigureSettings(void); 286 | void NdefPull_Cb(unsigned char *pNdefMessage, unsigned short NdefMessageSize); 287 | void NdefPush_Cb(unsigned char *pNdefRecord, unsigned short NdefRecordSize); 288 | bool NxpNci_FactoryTest_Prbs(NxpNci_TechType_t type, NxpNci_Bitrate_t bitrate); 289 | bool NxpNci_FactoryTest_RfOn(void); 290 | void ProcessP2pMode(RfIntf_t RfIntf); 291 | void ReadNdef(RfIntf_t RfIntf); 292 | void WriteNdef(RfIntf_t RfIntf); 293 | void ProcessCardMode(RfIntf_t RfIntf); 294 | }; 295 | 296 | #endif 297 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/P2P_NDEF.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | #include 15 | 16 | #define P2P_NDEF_MAX_NDEF_MESSAGE_SIZE 240 17 | 18 | void P2P_NDEF_Reset(void); 19 | void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 20 | void P2P_NDEF_RegisterPullCallback(void *pCb); 21 | bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb); 22 | //void Sleep (unsigned int ms); 23 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#ifdef RW_SUPPORT 16 | //#ifndef NO_NDEF_SUPPORT 17 | #include "RW_NDEF.h" 18 | #include "RW_NDEF_T1T.h" 19 | #include "RW_NDEF_T2T.h" 20 | #include "RW_NDEF_T3T.h" 21 | #include "RW_NDEF_T4T.h" 22 | #include "RW_NDEF_MIFARE.h" 23 | 24 | /* Allocate buffer for NDEF operations */ 25 | unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE]; 26 | 27 | typedef void RW_NDEF_Fct_t(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 28 | 29 | unsigned char *pRW_NdefMessage; 30 | unsigned short RW_NdefMessage_size; 31 | 32 | RW_NDEF_Callback_t *pRW_NDEF_PullCb; 33 | RW_NDEF_Callback_t *pRW_NDEF_PushCb; 34 | 35 | static RW_NDEF_Fct_t *pReadFct = NULL; 36 | static RW_NDEF_Fct_t *pWriteFct = NULL; 37 | 38 | bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) 39 | { 40 | if (Message_size <= RW_MAX_NDEF_FILE_SIZE) 41 | { 42 | pRW_NdefMessage = pMessage; 43 | RW_NdefMessage_size = Message_size; 44 | pRW_NDEF_PushCb = (RW_NDEF_Callback_t *)pCb; 45 | return true; 46 | } 47 | else 48 | { 49 | RW_NdefMessage_size = 0; 50 | pRW_NDEF_PushCb = NULL; 51 | return false; 52 | } 53 | } 54 | 55 | void RW_NDEF_RegisterPullCallback(void *pCb) 56 | { 57 | pRW_NDEF_PullCb = (RW_NDEF_Callback_t *)pCb; 58 | } 59 | 60 | void RW_NDEF_Reset(unsigned char type) 61 | { 62 | pReadFct = NULL; 63 | pWriteFct = NULL; 64 | 65 | switch (type) 66 | { 67 | case RW_NDEF_TYPE_T1T: 68 | RW_NDEF_T1T_Reset(); 69 | pReadFct = RW_NDEF_T1T_Read_Next; 70 | break; 71 | case RW_NDEF_TYPE_T2T: 72 | RW_NDEF_T2T_Reset(); 73 | pReadFct = RW_NDEF_T2T_Read_Next; 74 | pWriteFct = RW_NDEF_T2T_Write_Next; 75 | break; 76 | case RW_NDEF_TYPE_T3T: 77 | RW_NDEF_T3T_Reset(); 78 | pReadFct = RW_NDEF_T3T_Read_Next; 79 | break; 80 | case RW_NDEF_TYPE_T4T: 81 | RW_NDEF_T4T_Reset(); 82 | pReadFct = RW_NDEF_T4T_Read_Next; 83 | pWriteFct = RW_NDEF_T4T_Write_Next; 84 | break; 85 | case RW_NDEF_TYPE_MIFARE: 86 | RW_NDEF_MIFARE_Reset(); 87 | pReadFct = RW_NDEF_MIFARE_Read_Next; 88 | pWriteFct = RW_NDEF_MIFARE_Write_Next; 89 | break; 90 | default: 91 | break; 92 | } 93 | } 94 | 95 | void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) 96 | { 97 | if (pReadFct != NULL) 98 | pReadFct(pCmd, Cmd_size, Rsp, pRsp_size); 99 | } 100 | 101 | void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size) 102 | { 103 | if (pWriteFct != NULL) 104 | pWriteFct(pCmd, Cmd_size, Rsp, pRsp_size); 105 | } 106 | //#endif 107 | //#endif 108 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | #include 15 | 16 | #define RW_MAX_NDEF_FILE_SIZE 500 17 | 18 | extern unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE]; 19 | 20 | typedef void RW_NDEF_Callback_t (unsigned char*, unsigned short); 21 | 22 | #define RW_NDEF_TYPE_T1T 0x1 23 | #define RW_NDEF_TYPE_T2T 0x2 24 | #define RW_NDEF_TYPE_T3T 0x3 25 | #define RW_NDEF_TYPE_T4T 0x4 26 | #define RW_NDEF_TYPE_MIFARE 0x80 27 | 28 | extern unsigned char *pRW_NdefMessage; 29 | extern unsigned short RW_NdefMessage_size; 30 | 31 | extern RW_NDEF_Callback_t *pRW_NDEF_PullCb; 32 | extern RW_NDEF_Callback_t *pRW_NDEF_PushCb; 33 | 34 | void RW_NDEF_Reset(unsigned char type); 35 | void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 36 | void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 37 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_MIFARE.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void RW_NDEF_MIFARE_Reset(void); 16 | void RW_NDEF_MIFARE_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 17 | void RW_NDEF_MIFARE_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 18 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T1T.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#ifdef RW_SUPPORT 16 | //#ifndef NO_NDEF_SUPPORT 17 | #include "tool.h" 18 | #include "RW_NDEF.h" 19 | 20 | #define T1T_MAGIC_NUMBER 0xE1 21 | #define T1T_NDEF_TLV 0x03 22 | 23 | const unsigned char T1T_RID[] = {0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 24 | const unsigned char T1T_RALL[] = {0x00, 0x00, 0x00}; 25 | const unsigned char T1T_READ8[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 26 | 27 | typedef enum 28 | { 29 | Initial, 30 | Getting_ID, 31 | Reading_CardContent, 32 | Reading_NDEF 33 | } RW_NDEF_T1T_state_t; 34 | 35 | typedef struct 36 | { 37 | unsigned char HR0; 38 | unsigned char HR1; 39 | unsigned char UID[4]; 40 | unsigned char BlkNb; 41 | unsigned short MessagePtr; 42 | unsigned short MessageSize; 43 | unsigned char *pMessage; 44 | } RW_NDEF_T1T_Ndef_t; 45 | 46 | static RW_NDEF_T1T_state_t eRW_NDEF_T1T_State = Initial; 47 | static RW_NDEF_T1T_Ndef_t RW_NDEF_T1T_Ndef; 48 | 49 | void RW_NDEF_T1T_Reset(void) 50 | { 51 | eRW_NDEF_T1T_State = Initial; 52 | RW_NDEF_T1T_Ndef.pMessage = NdefBuffer; 53 | } 54 | 55 | void RW_NDEF_T1T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) 56 | { 57 | /* By default no further command to be sent */ 58 | *pCmd_size = 0; 59 | 60 | switch (eRW_NDEF_T1T_State) 61 | { 62 | case Initial: 63 | /* Send T1T_RID */ 64 | memcpy(pCmd, T1T_RID, sizeof(T1T_RID)); 65 | *pCmd_size = 7; 66 | eRW_NDEF_T1T_State = Getting_ID; 67 | break; 68 | 69 | case Getting_ID: 70 | /* Is CC Read and Is Ndef ?*/ 71 | if ((Rsp_size == 7) && (pRsp[Rsp_size - 1] == 0x00)) 72 | { 73 | /* Fill File structure */ 74 | RW_NDEF_T1T_Ndef.HR0 = pRsp[0]; 75 | RW_NDEF_T1T_Ndef.HR1 = pRsp[1]; 76 | memcpy(RW_NDEF_T1T_Ndef.UID, &pRsp[2], sizeof(RW_NDEF_T1T_Ndef.UID)); 77 | 78 | /* Read full card content */ 79 | memcpy(pCmd, T1T_RALL, sizeof(T1T_RALL)); 80 | memcpy(&pCmd[3], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); 81 | *pCmd_size = sizeof(T1T_RALL) + sizeof(RW_NDEF_T1T_Ndef.UID); 82 | eRW_NDEF_T1T_State = Reading_CardContent; 83 | } 84 | break; 85 | 86 | case Reading_CardContent: 87 | /* Is Read success ?*/ 88 | if ((Rsp_size == 123) && (pRsp[Rsp_size - 1] == 0x00)) 89 | { 90 | /* Check CC */ 91 | if (pRsp[10] == T1T_MAGIC_NUMBER) 92 | { 93 | unsigned char Tmp = 14; 94 | unsigned char data_size; 95 | 96 | /* If not NDEF Type skip TLV */ 97 | while (pRsp[Tmp] != T1T_NDEF_TLV) 98 | { 99 | Tmp += 2 + pRsp[Tmp + 1]; 100 | if (Tmp > Rsp_size) 101 | return; 102 | } 103 | 104 | RW_NDEF_T1T_Ndef.MessageSize = pRsp[Tmp + 1]; 105 | data_size = (Rsp_size - 1) - 16 - Tmp - 2; 106 | 107 | /* If provisioned buffer is not large enough, notify the application and stop reading */ 108 | if (RW_NDEF_T1T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) 109 | { 110 | if (pRW_NDEF_PullCb != NULL) 111 | pRW_NDEF_PullCb(NULL, 0); 112 | break; 113 | } 114 | 115 | /* Is NDEF read already completed ? */ 116 | if (RW_NDEF_T1T_Ndef.MessageSize <= data_size) 117 | { 118 | memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessageSize); 119 | 120 | /* Notify application of the NDEF reception */ 121 | if (pRW_NDEF_PullCb != NULL) 122 | pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); 123 | } 124 | else 125 | { 126 | RW_NDEF_T1T_Ndef.MessagePtr = data_size; 127 | memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T1T_Ndef.MessagePtr); 128 | RW_NDEF_T1T_Ndef.BlkNb = 0x10; 129 | 130 | /* Read NDEF content */ 131 | memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); 132 | pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; 133 | memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); 134 | *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); 135 | 136 | eRW_NDEF_T1T_State = Reading_NDEF; 137 | } 138 | } 139 | } 140 | break; 141 | 142 | case Reading_NDEF: 143 | /* Is Read success ?*/ 144 | if ((Rsp_size == 10) && (pRsp[Rsp_size - 1] == 0x00)) 145 | { 146 | /* Is NDEF read already completed ? */ 147 | if ((RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr) < 8) 148 | { 149 | memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr); 150 | 151 | /* Notify application of the NDEF reception */ 152 | if (pRW_NDEF_PullCb != NULL) 153 | pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize); 154 | } 155 | else 156 | { 157 | memcpy(&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], 8); 158 | RW_NDEF_T1T_Ndef.MessagePtr += 8; 159 | RW_NDEF_T1T_Ndef.BlkNb++; 160 | 161 | /* Read NDEF content */ 162 | memcpy(pCmd, T1T_READ8, sizeof(T1T_READ8)); 163 | pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb; 164 | memcpy(&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID)); 165 | *pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID); 166 | } 167 | } 168 | break; 169 | 170 | default: 171 | break; 172 | } 173 | } 174 | //#endif 175 | //#endif 176 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T1T.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void RW_NDEF_T1T_Reset(void); 16 | void RW_NDEF_T1T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 17 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T2T.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#ifdef RW_SUPPORT 16 | //#ifndef NO_NDEF_SUPPORT 17 | #include "tool.h" 18 | #include "RW_NDEF.h" 19 | 20 | /* TODO: No support for tag larger than 1024 bytes (requiring SECTOR_SELECT command use) */ 21 | 22 | #define T2T_MAGIC_NUMBER 0xE1 23 | #define T2T_NDEF_TLV 0x03 24 | 25 | typedef enum 26 | { 27 | Initial, 28 | Reading_CC, 29 | Reading_Data, 30 | Reading_NDEF, 31 | Writing_Data 32 | } RW_NDEF_T2T_state_t; 33 | 34 | typedef struct 35 | { 36 | unsigned char BlkNb; 37 | unsigned short MessagePtr; 38 | unsigned short MessageSize; 39 | unsigned char *pMessage; 40 | } RW_NDEF_T2T_Ndef_t; 41 | 42 | static RW_NDEF_T2T_state_t eRW_NDEF_T2T_State = Initial; 43 | static RW_NDEF_T2T_Ndef_t RW_NDEF_T2T_Ndef; 44 | 45 | void RW_NDEF_T2T_Reset(void) 46 | { 47 | eRW_NDEF_T2T_State = Initial; 48 | RW_NDEF_T2T_Ndef.pMessage = NdefBuffer; 49 | } 50 | 51 | void RW_NDEF_T2T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) 52 | { 53 | /* By default no further command to be sent */ 54 | *pCmd_size = 0; 55 | 56 | switch (eRW_NDEF_T2T_State) 57 | { 58 | case Initial: 59 | /* Read CC */ 60 | pCmd[0] = 0x30; 61 | pCmd[1] = 0x03; 62 | *pCmd_size = 2; 63 | eRW_NDEF_T2T_State = Reading_CC; 64 | break; 65 | 66 | case Reading_CC: 67 | /* Is CC Read and Is Ndef ?*/ 68 | if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER)) 69 | { 70 | /* Read First data */ 71 | pCmd[0] = 0x30; 72 | pCmd[1] = 0x04; 73 | *pCmd_size = 2; 74 | 75 | eRW_NDEF_T2T_State = Reading_Data; 76 | } 77 | break; 78 | 79 | case Reading_Data: 80 | /* Is Read success ?*/ 81 | if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) 82 | { 83 | unsigned char Tmp = 0; 84 | /* If not NDEF Type skip TLV */ 85 | while (pRsp[Tmp] != T2T_NDEF_TLV) 86 | { 87 | Tmp += 2 + pRsp[Tmp + 1]; 88 | if (Tmp > Rsp_size) 89 | return; 90 | } 91 | 92 | if (pRsp[Tmp + 1] == 0xFF) 93 | { 94 | RW_NDEF_T2T_Ndef.MessageSize = (pRsp[Tmp + 2] << 8) + pRsp[Tmp + 3]; 95 | Tmp += 2; 96 | } 97 | else 98 | RW_NDEF_T2T_Ndef.MessageSize = pRsp[Tmp + 1]; 99 | 100 | /* If provisioned buffer is not large enough or message is empty, notify the application and stop reading */ 101 | if ((RW_NDEF_T2T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T2T_Ndef.MessageSize == 0)) 102 | { 103 | if (pRW_NDEF_PullCb != NULL) 104 | pRW_NDEF_PullCb(NULL, 0); 105 | break; 106 | } 107 | 108 | /* Is NDEF read already completed ? */ 109 | if (RW_NDEF_T2T_Ndef.MessageSize <= ((Rsp_size - 1) - Tmp - 2)) 110 | { 111 | memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessageSize); 112 | 113 | /* Notify application of the NDEF reception */ 114 | if (pRW_NDEF_PullCb != NULL) 115 | pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); 116 | } 117 | else 118 | { 119 | RW_NDEF_T2T_Ndef.MessagePtr = (Rsp_size - 1) - Tmp - 2; 120 | memcpy(RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp + 2], RW_NDEF_T2T_Ndef.MessagePtr); 121 | RW_NDEF_T2T_Ndef.BlkNb = 8; 122 | 123 | /* Read NDEF content */ 124 | pCmd[0] = 0x30; 125 | pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; 126 | *pCmd_size = 2; 127 | eRW_NDEF_T2T_State = Reading_NDEF; 128 | } 129 | } 130 | break; 131 | 132 | case Reading_NDEF: 133 | /* Is Read success ?*/ 134 | if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00)) 135 | { 136 | /* Is NDEF read already completed ? */ 137 | if ((RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr) < 16) 138 | { 139 | memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr); 140 | 141 | /* Notify application of the NDEF reception */ 142 | if (pRW_NDEF_PullCb != NULL) 143 | pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize); 144 | } 145 | else 146 | { 147 | memcpy(&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, 16); 148 | RW_NDEF_T2T_Ndef.MessagePtr += 16; 149 | RW_NDEF_T2T_Ndef.BlkNb += 4; 150 | 151 | /* Read NDEF content */ 152 | pCmd[0] = 0x30; 153 | pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; 154 | *pCmd_size = 2; 155 | } 156 | } 157 | break; 158 | 159 | default: 160 | break; 161 | } 162 | } 163 | 164 | void RW_NDEF_T2T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) 165 | { 166 | /* By default no further command to be sent */ 167 | *pCmd_size = 0; 168 | 169 | switch (eRW_NDEF_T2T_State) 170 | { 171 | case Initial: 172 | /* Read CC */ 173 | pCmd[0] = 0x30; 174 | pCmd[1] = 0x03; 175 | *pCmd_size = 2; 176 | eRW_NDEF_T2T_State = Reading_CC; 177 | break; 178 | 179 | case Reading_CC: 180 | /* Is CC Read, Is Ndef and is R/W ?*/ 181 | if ((Rsp_size == 17) && (pRsp[Rsp_size - 1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER) && (pRsp[3] == 0x00)) 182 | { 183 | /* Is size enough ? */ 184 | if (pRsp[2] * 8 >= RW_NdefMessage_size) 185 | { 186 | /* Write First data */ 187 | pCmd[0] = 0xA2; 188 | pCmd[1] = 0x04; 189 | pCmd[2] = 0x03; 190 | if (RW_NdefMessage_size > 0xFF) 191 | { 192 | pCmd[3] = 0xFF; 193 | pCmd[4] = (RW_NdefMessage_size & 0xFF00) >> 8; 194 | pCmd[5] = RW_NdefMessage_size & 0xFF; 195 | RW_NDEF_T2T_Ndef.MessagePtr = 0; 196 | } 197 | else 198 | { 199 | pCmd[3] = (unsigned char)RW_NdefMessage_size; 200 | memcpy(&pCmd[4], pRW_NdefMessage, 2); 201 | RW_NDEF_T2T_Ndef.MessagePtr = 2; 202 | } 203 | RW_NDEF_T2T_Ndef.BlkNb = 5; 204 | *pCmd_size = 6; 205 | eRW_NDEF_T2T_State = Writing_Data; 206 | } 207 | } 208 | break; 209 | 210 | case Writing_Data: 211 | /* Is Write success ?*/ 212 | if ((Rsp_size == 2) && (pRsp[Rsp_size - 1] == 0x00)) 213 | { 214 | /* Is NDEF write already completed ? */ 215 | if (RW_NdefMessage_size <= RW_NDEF_T2T_Ndef.MessagePtr) 216 | { 217 | /* Notify application of the NDEF send completion */ 218 | if (pRW_NDEF_PushCb != NULL) 219 | pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size); 220 | } 221 | else 222 | { 223 | /* Write NDEF content */ 224 | pCmd[0] = 0xA2; 225 | pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb; 226 | memcpy(&pCmd[2], pRW_NdefMessage + RW_NDEF_T2T_Ndef.MessagePtr, 4); 227 | *pCmd_size = 6; 228 | 229 | RW_NDEF_T2T_Ndef.MessagePtr += 4; 230 | RW_NDEF_T2T_Ndef.BlkNb++; 231 | } 232 | } 233 | break; 234 | 235 | default: 236 | break; 237 | } 238 | } 239 | //#endif 240 | //#endif 241 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T2T.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void RW_NDEF_T2T_Reset(void); 16 | void RW_NDEF_T2T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 17 | void RW_NDEF_T2T_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 18 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T3T.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#ifdef RW_SUPPORT 16 | //#ifndef NO_NDEF_SUPPORT 17 | #include "tool.h" 18 | #include "RW_NDEF.h" 19 | 20 | #define T3T_MAGIC_NUMBER 0xE1 21 | #define T3T_NDEF_TLV 0x03 22 | 23 | unsigned char T3T_Check[] = {0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x1, 0x80, 0x00}; 24 | 25 | typedef enum 26 | { 27 | Initial, 28 | Getting_AttributeInfo, 29 | Reading_CardContent 30 | } RW_NDEF_T3T_state_t; 31 | 32 | typedef struct 33 | { 34 | unsigned char IDm[8]; 35 | unsigned char BlkNb; 36 | unsigned short Ptr; 37 | unsigned short Size; 38 | unsigned char *p; 39 | } RW_NDEF_T3T_Ndef_t; 40 | 41 | static RW_NDEF_T3T_state_t eRW_NDEF_T3T_State = Initial; 42 | static RW_NDEF_T3T_Ndef_t RW_NDEF_T3T_Ndef; 43 | 44 | void RW_NDEF_T3T_Reset(void) 45 | { 46 | eRW_NDEF_T3T_State = Initial; 47 | RW_NDEF_T3T_Ndef.p = NdefBuffer; 48 | } 49 | 50 | void RW_NDEF_T3T_SetIDm(unsigned char *pIDm) 51 | { 52 | memcpy(RW_NDEF_T3T_Ndef.IDm, pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); 53 | memcpy(&T3T_Check[2], pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm)); 54 | } 55 | 56 | void RW_NDEF_T3T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size) 57 | { 58 | /* By default no further command to be sent */ 59 | *pCmd_size = 0; 60 | 61 | switch (eRW_NDEF_T3T_State) 62 | { 63 | case Initial: 64 | /* Get AttributeInfo */ 65 | memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); 66 | *pCmd_size = sizeof(T3T_Check); 67 | eRW_NDEF_T3T_State = Getting_AttributeInfo; 68 | break; 69 | 70 | case Getting_AttributeInfo: 71 | /* Is Check success ?*/ 72 | if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) 73 | { 74 | /* Fill File structure */ 75 | RW_NDEF_T3T_Ndef.Size = (pRsp[24] << 16) + (pRsp[25] << 16) + pRsp[26]; 76 | 77 | /* If provisioned buffer is not large enough or size is null, notify the application and stop reading */ 78 | if ((RW_NDEF_T3T_Ndef.Size > RW_MAX_NDEF_FILE_SIZE) || (RW_NDEF_T3T_Ndef.Size == 0)) 79 | { 80 | if (pRW_NDEF_PullCb != NULL) 81 | pRW_NDEF_PullCb(NULL, 0); 82 | break; 83 | } 84 | 85 | RW_NDEF_T3T_Ndef.Ptr = 0; 86 | RW_NDEF_T3T_Ndef.BlkNb = 1; 87 | 88 | /* Read first NDEF block */ 89 | memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); 90 | pCmd[15] = 0x01; 91 | *pCmd_size = sizeof(T3T_Check); 92 | eRW_NDEF_T3T_State = Reading_CardContent; 93 | } 94 | break; 95 | 96 | case Reading_CardContent: 97 | /* Is Check success ?*/ 98 | if ((pRsp[Rsp_size - 1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00)) 99 | { 100 | /* Is NDEF message read completed ?*/ 101 | if ((RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr) <= 16) 102 | { 103 | memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], (RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr)); 104 | /* Notify application of the NDEF reception */ 105 | if (pRW_NDEF_PullCb != NULL) 106 | pRW_NDEF_PullCb(RW_NDEF_T3T_Ndef.p, RW_NDEF_T3T_Ndef.Size); 107 | } 108 | else 109 | { 110 | memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], 16); 111 | RW_NDEF_T3T_Ndef.Ptr += 16; 112 | RW_NDEF_T3T_Ndef.BlkNb++; 113 | 114 | /* Read next NDEF block */ 115 | memcpy(pCmd, T3T_Check, sizeof(T3T_Check)); 116 | pCmd[15] = RW_NDEF_T3T_Ndef.BlkNb; 117 | *pCmd_size = sizeof(T3T_Check); 118 | } 119 | } 120 | break; 121 | 122 | default: 123 | break; 124 | } 125 | } 126 | //#endif 127 | //#endif 128 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T3T.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void RW_NDEF_T3T_Reset(void); 16 | void RW_NDEF_T3T_SetIDm(unsigned char *pIDm); 17 | void RW_NDEF_T3T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 18 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/RW_NDEF_T4T.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void RW_NDEF_T4T_Reset(void); 16 | void RW_NDEF_T4T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 17 | void RW_NDEF_T4T_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 18 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/T4T_NDEF_emu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#ifdef CARDEMU_SUPPORT 16 | //#ifndef NO_NDEF_SUPPORT 17 | #include "tool.h" 18 | #include "T4T_NDEF_emu.h" 19 | 20 | const unsigned char T4T_NDEF_EMU_APP_Select[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00}; 21 | const unsigned char T4T_NDEF_EMU_CC[] = {0x00, 0x0F, 0x20, 0x00, 0xFF, 0x00, 0xFF, 0x04, 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00}; 22 | const unsigned char T4T_NDEF_EMU_CC_Select[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x03}; 23 | const unsigned char T4T_NDEF_EMU_NDEF_Select[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x04}; 24 | const unsigned char T4T_NDEF_EMU_Read[] = {0x00, 0xB0}; 25 | const unsigned char T4T_NDEF_EMU_Write[] = {0x00, 0xD6}; 26 | const unsigned char T4T_NDEF_EMU_OK[] = {0x90, 0x00}; 27 | const unsigned char T4T_NDEF_EMU_NOK[] = {0x6A, 0x82}; 28 | 29 | unsigned char *pT4T_NdefMessage; 30 | unsigned short T4T_NdefMessage_size = 0; 31 | 32 | unsigned char T4T_NdefMessageWritten[256]; 33 | 34 | typedef enum 35 | { 36 | Ready, 37 | NDEF_Application_Selected, 38 | CC_Selected, 39 | NDEF_Selected, 40 | DESFire_prod 41 | } T4T_NDEF_EMU_state_t; 42 | 43 | typedef void T4T_NDEF_EMU_Callback_t(unsigned char *, unsigned short); 44 | 45 | static T4T_NDEF_EMU_state_t eT4T_NDEF_EMU_State = Ready; 46 | 47 | static T4T_NDEF_EMU_Callback_t *pT4T_NDEF_EMU_PushCb = NULL; 48 | 49 | static void T4T_NDEF_EMU_FillRsp(unsigned char *pRsp, unsigned short offset, unsigned char length) 50 | { 51 | if (offset == 0) 52 | { 53 | pRsp[0] = (T4T_NdefMessage_size & 0xFF00) >> 8; 54 | pRsp[1] = (T4T_NdefMessage_size & 0x00FF); 55 | if (length > 2) 56 | memcpy(&pRsp[2], &pT4T_NdefMessage[0], length - 2); 57 | } 58 | else if (offset == 1) 59 | { 60 | pRsp[0] = (T4T_NdefMessage_size & 0x00FF); 61 | if (length > 1) 62 | memcpy(&pRsp[1], &pT4T_NdefMessage[0], length - 1); 63 | } 64 | else 65 | { 66 | memcpy(pRsp, &pT4T_NdefMessage[offset - 2], length); 67 | } 68 | 69 | /* Did we reached the end of NDEF message ?*/ 70 | if ((offset + length) >= (T4T_NdefMessage_size + 2)) 71 | { 72 | /* Notify application of the NDEF send */ 73 | if (pT4T_NDEF_EMU_PushCb != NULL) 74 | pT4T_NDEF_EMU_PushCb(pT4T_NdefMessage, T4T_NdefMessage_size); 75 | } 76 | } 77 | 78 | bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb) 79 | { 80 | pT4T_NdefMessage = pMessage; 81 | T4T_NdefMessage_size = Message_size; 82 | pT4T_NDEF_EMU_PushCb = (T4T_NDEF_EMU_Callback_t *)pCb; 83 | 84 | return true; 85 | } 86 | 87 | void T4T_NDEF_EMU_Reset(void) 88 | { 89 | eT4T_NDEF_EMU_State = Ready; 90 | } 91 | 92 | void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size) 93 | { 94 | bool eStatus = false; 95 | 96 | if (!memcmp(pCmd, T4T_NDEF_EMU_APP_Select, sizeof(T4T_NDEF_EMU_APP_Select))) 97 | { 98 | *pRsp_size = 0; 99 | eStatus = true; 100 | eT4T_NDEF_EMU_State = NDEF_Application_Selected; 101 | } 102 | else if (!memcmp(pCmd, T4T_NDEF_EMU_CC_Select, sizeof(T4T_NDEF_EMU_CC_Select))) 103 | { 104 | if (eT4T_NDEF_EMU_State == NDEF_Application_Selected) 105 | { 106 | *pRsp_size = 0; 107 | eStatus = true; 108 | eT4T_NDEF_EMU_State = CC_Selected; 109 | } 110 | } 111 | else if (!memcmp(pCmd, T4T_NDEF_EMU_NDEF_Select, sizeof(T4T_NDEF_EMU_NDEF_Select))) 112 | { 113 | *pRsp_size = 0; 114 | eStatus = true; 115 | eT4T_NDEF_EMU_State = NDEF_Selected; 116 | } 117 | else if (!memcmp(pCmd, T4T_NDEF_EMU_Read, sizeof(T4T_NDEF_EMU_Read))) 118 | { 119 | if (eT4T_NDEF_EMU_State == CC_Selected) 120 | { 121 | unsigned short offset = (pCmd[2] << 8) + pCmd[3]; 122 | unsigned char length = pCmd[4]; 123 | 124 | if (length <= (sizeof(T4T_NDEF_EMU_CC) + offset + 2)) 125 | { 126 | memcpy(pRsp, &T4T_NDEF_EMU_CC[offset], length); 127 | *pRsp_size = length; 128 | eStatus = true; 129 | } 130 | } 131 | else if (eT4T_NDEF_EMU_State == NDEF_Selected) 132 | { 133 | unsigned short offset = (pCmd[2] << 8) + pCmd[3]; 134 | unsigned char length = pCmd[4]; 135 | 136 | if (length <= (T4T_NdefMessage_size + offset + 2)) 137 | { 138 | T4T_NDEF_EMU_FillRsp(pRsp, offset, length); 139 | *pRsp_size = length; 140 | eStatus = true; 141 | } 142 | } 143 | } 144 | else if (!memcmp(pCmd, T4T_NDEF_EMU_Write, sizeof(T4T_NDEF_EMU_Write))) 145 | { 146 | if (eT4T_NDEF_EMU_State == NDEF_Selected) 147 | { 148 | 149 | unsigned short offset = (pCmd[2] << 8) + pCmd[3]; 150 | unsigned char length = pCmd[4]; 151 | if (offset + length <= sizeof(T4T_NdefMessageWritten)) 152 | { 153 | memcpy(&T4T_NdefMessageWritten[offset - 2], &pCmd[5], length); 154 | pT4T_NdefMessage = T4T_NdefMessageWritten; 155 | T4T_NdefMessage_size = (pCmd[5] << 8) + pCmd[6]; 156 | *pRsp_size = 0; 157 | eStatus = true; 158 | } 159 | } 160 | } 161 | 162 | if (eStatus == true) 163 | { 164 | memcpy(&pRsp[*pRsp_size], T4T_NDEF_EMU_OK, sizeof(T4T_NDEF_EMU_OK)); 165 | *pRsp_size += sizeof(T4T_NDEF_EMU_OK); 166 | } 167 | else 168 | { 169 | memcpy(pRsp, T4T_NDEF_EMU_NOK, sizeof(T4T_NDEF_EMU_NOK)); 170 | *pRsp_size = sizeof(T4T_NDEF_EMU_NOK); 171 | T4T_NDEF_EMU_Reset(); 172 | } 173 | } 174 | //#endif 175 | //#endif 176 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/T4T_NDEF_emu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | void T4T_NDEF_EMU_Reset(void); 16 | void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size); 17 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/ndef_helper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include "ndef_helper.h" 19 | 20 | const char *ndef_helper_WifiAuth(unsigned char auth) 21 | { 22 | switch (auth) 23 | { 24 | case 0x01: 25 | return "Open"; 26 | case 0x02: 27 | return "WPA-Personal"; 28 | case 0x04: 29 | return "Shared"; 30 | case 0x08: 31 | return "WPA-Enterprise"; 32 | case 0x10: 33 | return "WPA2-Enterprise"; 34 | case 0x20: 35 | return "WPA2-Personal"; 36 | default: 37 | return "unknown"; 38 | } 39 | } 40 | 41 | const char *ndef_helper_WifiEnc(unsigned char enc) 42 | { 43 | switch (enc) 44 | { 45 | case 0x01: 46 | return "None"; 47 | case 0x02: 48 | return "WEP"; 49 | case 0x04: 50 | return "TKIP"; 51 | case 0x08: 52 | return "AES"; 53 | case 0x10: 54 | return "AES/TKIP"; 55 | default: 56 | return "unknown"; 57 | } 58 | } 59 | 60 | const char *ndef_helper_UriHead(unsigned char head) 61 | { 62 | switch (head) 63 | { 64 | case 0: 65 | return (""); 66 | case 1: 67 | return ("http://www."); 68 | case 2: 69 | return ("https://www."); 70 | case 3: 71 | return ("http://"); 72 | case 4: 73 | return ("https://"); 74 | case 5: 75 | return ("tel:"); 76 | case 6: 77 | return ("mailto:"); 78 | default: 79 | return ("!!!unknown!!!"); 80 | } 81 | } 82 | 83 | NdefRecord_t DetectNdefRecordType(unsigned char *pNdefRecord) 84 | { 85 | NdefRecord_t record; 86 | 87 | uint8_t typeField; 88 | 89 | /* Short or normal record ?*/ 90 | if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) 91 | { 92 | record.recordPayloadSize = pNdefRecord[2]; 93 | typeField = 3; 94 | } 95 | else 96 | { 97 | record.recordPayloadSize = (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]; 98 | typeField = 6; 99 | } 100 | 101 | /* ID present ?*/ 102 | if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) 103 | { 104 | record.recordPayload = pNdefRecord + typeField + pNdefRecord[1] + 1 + pNdefRecord[typeField]; 105 | typeField++; 106 | } 107 | else 108 | { 109 | record.recordPayload = pNdefRecord + typeField + pNdefRecord[1]; 110 | } 111 | 112 | /* Well known Record Type ?*/ 113 | if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_WELL_KNOWN) 114 | { 115 | if (pNdefRecord[1] == 0x1) 116 | { 117 | switch (pNdefRecord[typeField]) 118 | { 119 | case 'T': 120 | record.recordType = WELL_KNOWN_SIMPLE_TEXT; 121 | break; 122 | case 'U': 123 | record.recordType = WELL_KNOWN_SIMPLE_URI; 124 | break; 125 | default: 126 | record.recordType = UNSUPPORTED_NDEF_RECORD; 127 | break; 128 | } 129 | } 130 | else if (pNdefRecord[1] == 0x2) 131 | { 132 | if (memcmp(&pNdefRecord[typeField], "Sp", pNdefRecord[1]) == 0x0) 133 | { 134 | record.recordType = WELL_KNOWN_SMART_POSTER; 135 | } 136 | else if (memcmp(&pNdefRecord[typeField], "Hs", pNdefRecord[1]) == 0x0) 137 | { 138 | record.recordType = WELL_KNOWN_HANDOVER_SELECT; 139 | } 140 | else if (memcmp(&pNdefRecord[typeField], "Hr", pNdefRecord[1]) == 0x0) 141 | { 142 | record.recordType = WELL_KNOWN_HANDOVER_REQUEST; 143 | } 144 | else if (memcmp(&pNdefRecord[typeField], "ac", pNdefRecord[1]) == 0x0) 145 | { 146 | record.recordType = WELL_KNOWN_ALTERNATIVE_CARRIER; 147 | } 148 | else if (memcmp(&pNdefRecord[typeField], "cr", pNdefRecord[1]) == 0x0) 149 | { 150 | record.recordType = WELL_KNOWN_COLLISION_RESOLUTION; 151 | } 152 | else 153 | { 154 | record.recordType = UNSUPPORTED_NDEF_RECORD; 155 | } 156 | } 157 | } 158 | /* Media Record Type ?*/ 159 | else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_MEDIA) 160 | { 161 | if ((memcmp(&pNdefRecord[typeField], "text/x-vCard", pNdefRecord[1]) == 0x0) || 162 | (memcmp(&pNdefRecord[typeField], "text/vcard", pNdefRecord[1]) == 0x0)) 163 | { 164 | record.recordType = MEDIA_VCARD; 165 | } 166 | else if (memcmp(&pNdefRecord[typeField], "application/vnd.wfa.wsc", pNdefRecord[1]) == 0x0) 167 | { 168 | record.recordType = MEDIA_HANDOVER_WIFI; 169 | } 170 | else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.ep.oob", pNdefRecord[1]) == 0x0) 171 | { 172 | record.recordType = MEDIA_HANDOVER_BT; 173 | } 174 | else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.le.oob", pNdefRecord[1]) == 0x0) 175 | { 176 | record.recordType = MEDIA_HANDOVER_BLE; 177 | } 178 | else if (memcmp(&pNdefRecord[typeField], "application/vnd.bluetooth.secure.le.oob", pNdefRecord[1]) == 0x0) 179 | { 180 | record.recordType = MEDIA_HANDOVER_BLE_SECURE; 181 | } 182 | else 183 | { 184 | record.recordType = UNSUPPORTED_NDEF_RECORD; 185 | } 186 | } 187 | /* Absolute URI Record Type ?*/ 188 | else if ((pNdefRecord[0] & NDEF_RECORD_TNF_MASK) == NDEF_ABSOLUTE_URI) 189 | { 190 | record.recordType = ABSOLUTE_URI; 191 | } 192 | else 193 | { 194 | record.recordType = UNSUPPORTED_NDEF_RECORD; 195 | } 196 | 197 | return record; 198 | } 199 | 200 | unsigned char *GetNextRecord(unsigned char *pNdefRecord) 201 | { 202 | unsigned char *temp = NULL; 203 | 204 | /* Message End ?*/ 205 | if (!(pNdefRecord[0] & NDEF_RECORD_ME_MASK)) 206 | { 207 | /* Short or normal record ?*/ 208 | if (pNdefRecord[0] & NDEF_RECORD_SR_MASK) 209 | { 210 | /* ID present ?*/ 211 | if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) 212 | temp = (pNdefRecord + 4 + pNdefRecord[1] + pNdefRecord[2] + pNdefRecord[3]); 213 | else 214 | temp = (pNdefRecord + 3 + pNdefRecord[1] + pNdefRecord[2]); 215 | } 216 | else 217 | { 218 | /* ID present ?*/ 219 | if (pNdefRecord[0] & NDEF_RECORD_IL_MASK) 220 | temp = (pNdefRecord + 7 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5] + pNdefRecord[6]); 221 | else 222 | temp = (pNdefRecord + 6 + pNdefRecord[1] + (pNdefRecord[2] << 24) + (pNdefRecord[3] << 16) + (pNdefRecord[4] << 8) + pNdefRecord[5]); 223 | } 224 | } 225 | return temp; 226 | } 227 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/ndef_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | #define NDEF_EMPTY 0x00 16 | #define NDEF_WELL_KNOWN 0x01 17 | #define NDEF_MEDIA 0x02 18 | #define NDEF_ABSOLUTE_URI 0x03 19 | #define NDEF_EXTERNAL 0x04 20 | #define NDEF_UNKNOWN 0x05 21 | #define NDEF_UNCHANGED 0x06 22 | #define NDEF_RESERVED 0x07 23 | 24 | #define NDEF_RECORD_MB_MASK 0x80 25 | #define NDEF_RECORD_ME_MASK 0x40 26 | #define NDEF_RECORD_CF_MASK 0x20 27 | #define NDEF_RECORD_SR_MASK 0x10 28 | #define NDEF_RECORD_IL_MASK 0x08 29 | #define NDEF_RECORD_TNF_MASK 0x07 30 | 31 | typedef enum 32 | { 33 | WELL_KNOWN_SIMPLE_TEXT, 34 | WELL_KNOWN_SIMPLE_URI, 35 | WELL_KNOWN_SMART_POSTER, 36 | WELL_KNOWN_HANDOVER_SELECT, 37 | WELL_KNOWN_HANDOVER_REQUEST, 38 | WELL_KNOWN_ALTERNATIVE_CARRIER, 39 | WELL_KNOWN_COLLISION_RESOLUTION, 40 | MEDIA_VCARD, 41 | MEDIA_HANDOVER_WIFI, 42 | MEDIA_HANDOVER_BT, 43 | MEDIA_HANDOVER_BLE, 44 | MEDIA_HANDOVER_BLE_SECURE, 45 | ABSOLUTE_URI, 46 | UNSUPPORTED_NDEF_RECORD = 0xFF 47 | } NdefRecordType_e; 48 | 49 | typedef struct 50 | { 51 | NdefRecordType_e recordType; 52 | unsigned char *recordPayload; 53 | unsigned int recordPayloadSize; 54 | } NdefRecord_t; 55 | 56 | const char *ndef_helper_WifiAuth(unsigned char auth); 57 | const char *ndef_helper_WifiEnc(unsigned char enc); 58 | const char *ndef_helper_UriHead(unsigned char head); 59 | NdefRecord_t DetectNdefRecordType(unsigned char *pNdefRecord); 60 | unsigned char *GetNextRecord(unsigned char *pNdefRecord); 61 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/tool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#include 16 | 17 | /* LOOP_REF and CLOCK_CALL_TIME must be adapted according to the CPU execution time */ 18 | #define LOOP_REF 6800 19 | #define CLOCK_CALL_TIME 40 20 | 21 | void Sleep(unsigned int ms) 22 | { 23 | int i; 24 | #ifndef DEBUG_SEMIHOSTING 25 | for (i = 0; i < (ms * LOOP_REF); i++) 26 | asm("nop"); 27 | #else 28 | if (ms <= CLOCK_CALL_TIME) 29 | { 30 | for (i = 0; i < (ms * LOOP_REF); i++) 31 | asm("nop"); 32 | } 33 | else 34 | { 35 | clock_t time = clock() + ((ms - CLOCK_CALL_TIME) / 10); 36 | while (clock() <= time) 37 | ; 38 | } 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /Firmware/Arduino/NFC_LIB/src/tool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), NXP Semiconductors Caen / France 3 | * 4 | * (C)NXP Semiconductors 5 | * All rights are reserved. Reproduction in whole or in part is 6 | * prohibited without the written consent of the copyright owner. 7 | * NXP reserves the right to make changes without notice at any time. 8 | * NXP makes no warranty, expressed, implied or statutory, including but 9 | * not limited to any implied warranty of merchantability or fitness for any 10 | *particular purpose, or that the use will not infringe any third party patent, 11 | * copyright or trademark. NXP must not be liable for any loss or damage 12 | * arising from its use. 13 | */ 14 | 15 | //#include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | //#define PRINTF printf 24 | 25 | extern void Sleep (unsigned int ms); 26 | -------------------------------------------------------------------------------- /Firmware/UserGuide.md: -------------------------------------------------------------------------------- 1 | # Chhavi - A Key to Unlock Everything! Setup Guide 2 | 3 | Welcome to the Chhavi NFC and Fingerprint Device! This guide will walk you through the process of using the device and its features. Please follow the steps below: 4 | 5 | ## 1. Initial Setup 6 | 1. Upload the Code: 7 | 1. Open the Arduino IDE on your computer. 8 | 2. Go to File > Open and navigate to the location where you downloaded the Chhavi repository. 9 | 3. Open the Example_Websocket.ino file located in the Firmware -> Arduino -> Example_Websocket folder. 10 | 4. In the Arduino IDE, make sure you have selected the correct board. Go to Tools > Board and choose the ESP32 WROOM module. 11 | 5. Update the WiFi credentials to match your network. Look for the following lines (around line 14) and replace SSID with your WiFi SSID and PWD with your WiFi password: 12 | ```cpp 13 | const char* ssid = "SSID"; 14 | const char* password = "PWD"; 15 | ``` 16 | 6. Click the Upload button to compile and upload the sketch to your Chhavi device. 17 | 18 | ## 2. Connecting to the Device 19 | 1. Power On the Device: 20 | - Make sure your Chhavi device is connected to a power source. 21 | 2. Connect to WiFi: 22 | - Once the device is powered on, it will automatically connect to the WiFi network you specified during setup. 23 | 3. Access the Web Interface: 24 | 1. Open a web browser on any device connected to the same WiFi network. 25 | 2. Enter the IP address of the Chhavi device in the address bar. You can find the IP address from the Arduino IDE's serial monitor after uploading the code. 26 | 27 | ## 3. Using the Web Interface 28 | The Chhavi web interface allows you to interact with the device using a simple interface in your web browser. Here's how to use the available options: 29 | 30 | 1. Enroll Finger: 31 | - Press 'a' to enroll a new fingerprint. 32 | 2. Capture and Identify Finger: 33 | - Press 'b' to capture a fingerprint and identify it against the enrolled templates. 34 | 3. Remove All Templates: 35 | - Press 'c' to remove all enrolled fingerprint templates. 36 | 4. Save Template: 37 | - Press 'd' to save the captured fingerprint as a new template. 38 | 5. Get Version: 39 | - Press 'h' to retrieve the version information of the device. 40 | 6. Wait for Finger: 41 | - Press 'i' to initiate waiting for a finger to be placed on the sensor. 42 | 7. Exit Program: 43 | - Press 'q' to restart the device. 44 | 8. Sending Commands: 45 | - You can also enter any of the above commands directly into the text box on the web page and press 'Enter' to execute them. 46 | 47 | ## Enroll Your Finger: 48 | 1. Press 'a' to enroll a new fingerprint. 49 | 2. Follow these steps to enroll your fingerprint: 50 | 1. Place your finger on the fingerprint sensor. 51 | 2. Wait for the device to capture your fingerprint data. 52 | 3. The web interface will display a success message, indicating that your fingerprint has been enrolled. 53 | 54 | ## Validate Your Fingerprint: 55 | 1. Press 'b' to capture a fingerprint and identify it against the enrolled templates. 56 | 2. Follow these steps to validate your fingerprint: 57 | 1. Place your finger on the fingerprint sensor. 58 | 2. The device will capture your fingerprint and compare it against the enrolled templates. 59 | 3. If the captured fingerprint matches an enrolled template, the web interface will display a message indicating a successful match. 60 | 4. If there is no match, the interface will display a message indicating that the fingerprint was not recognized. 61 | 5. Please note that the device's LEDs and vibration motor may provide feedback during the enrollment and validation processes. 62 | 63 | ## 4. Interacting with Results 64 | As you use different commands, the device will provide feedback through the web interface. 65 | The web page will display responses such as "Match with template ID: X", "No match", "Template saved with ID: X", and so on. 66 | The device LEDs and vibration motor may also provide visual and tactile feedback based on the command executed. 67 | 68 | ## 5. Additional Information 69 | The device is equipped with NFC and fingerprint capabilities, allowing secure access control. 70 | Feel free to explore the code provided in the repository to understand more about the device's functionality and how it communicates with various components. 71 | That's it! You're now ready to enroll and validate fingerprints using your Chhavi NFC and Fingerprint Device. If you have any questions or encounter any issues, refer to the provided resources or contact our support team. 72 | 73 | Enjoy the convenience and security offered by your Chhavi device! 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chhavi - A Key to Unlock Everything! Setup Guide 2 | 3 | ## Welcome to the Chhavi Ecosystem! 4 | 5 | This guide will help you get started with your ESP32-based NFC and fingerprint device. Whether you're a developer, tinkerer, or just curious about this technology, we've got you covered. 6 | 7 | ## Table of Contents 8 | 9 | 1. **Introduction** 10 | 2. **Prerequisites** 11 | 3. **Setting Up** 12 | - Installing Required Libraries 13 | - Uploading the Example Sketch 14 | 4. **Serial Communication** 15 | 5. **Additional Resources** 16 | 6. **Contact and Support** 17 | 18 | ## 1. Introduction 19 | 20 | Chhavi is an open-source project that offers an ESP32-based NFC and fingerprint device. This device has a range of applications, from security systems to access control. Our goal is to provide a seamless and accessible platform for developers and enthusiasts to explore and utilize NFC and fingerprint technologies. 21 | 22 | ## 2. Prerequisites 23 | 24 | Before you dive into the Chhavi project, make sure you have the following: 25 | 26 | - **Chhavi Device:** Ensure you have received the Chhavi device, either through distribution or assembly. 27 | - **Computer:** You'll need a computer to program the device and interact with it. 28 | - **Micro-USB Cable:** Use this to connect the Chhavi device to your computer. 29 | - **Arduino IDE:** Install the Arduino Integrated Development Environment (IDE) from [arduino.cc](https://www.arduino.cc/en/software). 30 | - **CP2102 Driver:** Install the driver to establish serial communication with Chhavi. Download the driver from [Silicon Labs](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads) and choose the Virtual COM Port (VCP) driver. 31 | 32 | ## 3. Setting Up 33 | 34 | ### Installing Required Libraries 35 | 36 | To start with Chhavi, install these Arduino libraries: 37 | 38 | - [Ticker](https://github.com/sstaub/Ticker) 39 | - [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) 40 | - [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) 41 | - [Adafruit_SSD1306](https://github.com/adafruit/Adafruit_SSD1306) and its dependent libraries. 42 | 43 | Install libraries via Arduino Library Manager: 44 | 45 | 1. Open Arduino IDE. 46 | 2. Go to **Sketch > Include Library > Manage Libraries**. 47 | 3. Search for each library and click **Install**. 48 | 49 | ### Running the Example Project 50 | 51 | To begin exploring the capabilities of your Chhavi device, we've provided an example project located in the `Firmware -> Arduino -> Example_Websocket` folder. This example project hosts an HTTP server and WebSocket server, allowing fingerprint sensors to communicate with the device and display live data in a web browser. 52 | 53 | ### Device must need to power up before you see a serial port in computer, there is a side-button near the type-c port which needs to be pressed 4-5 seconds after you plug in the type-c cable in order to see a serial port in device. 54 | 55 | Follow these steps to run the example project: 56 | 57 | 1. Open Arduino IDE. 58 | 2. Go to **File > Open** and navigate to the Chhavi repository. 59 | 3. Inside the repository, navigate to `Firmware -> Arduino -> Example_Websocket` and open the `Example_Websocket.ino` file. 60 | 4. In the Arduino IDE, ensure you have selected the correct board. Go to **Tools > Board** and choose the **ESP32 WROOM** module option. 61 | 5. Update the WiFi credentials to match your network. Look for the following line in the code (usually around line 14): 62 | 63 | ```cpp 64 | const char* ssid = "your_wifi_ssid"; 65 | const char* password = "your_wifi_password"; 66 | 67 | 68 | ## 4. Serial Communication 69 | 70 | To communicate with Chhavi via serial: 71 | 72 | 1. Connect Chhavi to your computer. 73 | 2. Open Arduino IDE. 74 | 3. Go to **Tools > Serial Monitor**. 75 | 4. In Serial Monitor, select the baud rate (usually 115200) from the dropdown at the bottom. 76 | 5. Observe the device's serial output for debugging and monitoring. 77 | 78 | ## 5. Additional Resources 79 | 80 | - For hardware resources, such as design files and schematics, refer to our crowd-supply campaign page once active. 81 | - For firmware resources, explore the code in our repository. 82 | 83 | ## 6. Contact and Support 84 | 85 | For questions, issues, or sharing your Chhavi projects, contact us at [contact@vicharak.in](mailto:contact@vicharak.in). 86 | 87 | Thank you for joining us on this exciting Chhavi journey! 88 | 89 | Remember, Chhavi is not just a device; it's a key to unlock endless possibilities. 90 | 91 | Happy tinkering! 92 | 93 | Discord server! 94 | 95 | https://discord.gg/BWkbF5Sg 96 | --------------------------------------------------------------------------------