/*- * Public platform independent Near Field Communication (NFC) library examples * * Copyright (C) 2010, Roel Verdult, Romuald Conty * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1) Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2 )Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Note that this license only applies on the examples, NFC library itself is under LGPL * */ /** * @file nfc-emulate-forum-tag4.c * @brief Emulates a NFC Forum Tag Type 4 with a NDEF message */ // Notes & differences with nfc-emulate-tag: // - This example only works with PN532 because it relies on // its internal handling of ISO14443-4 specificities. // - Thanks to this internal handling & injection of WTX frames, // this example works on readers very strict on timing // - This example expects a hardcoded list of commands and // more precisely the commands sent by a Nokia NFC when // discovering a NFC-Forum tag type4: // * Anticoll & RATS // * App Select by name "e103e103e103" // * App Select by name "e103e103e103" // * App Select by name "D2760000850100" // * Select CC // * ReadBinary CC // * Select NDEF // * Read first 2 NDEF bytes // * Read remaining of NDEF file #ifdef HAVE_CONFIG_H # include "config.h" #endif // HAVE_CONFIG_H #include #include #include #include #include #include #include #include "nfc-utils.h" #define MAX_FRAME_LEN 264 static byte_t abtRx[MAX_FRAME_LEN]; static size_t szRx = sizeof(abtRx); static nfc_device_t *pnd; static bool quiet_output = false; #define SYMBOL_PARAM_fISO14443_4_PICC 0x20 void stop_emulation (int sig) { (void) sig; if (pnd) nfc_abort_command (pnd); else exit (EXIT_FAILURE); } bool send_bytes (const byte_t * pbtTx, const size_t szTx) { // Show transmitted command if (!quiet_output) { printf ("Sent data: "); print_hex (pbtTx, szTx); } // Transmit the command bytes if (!nfc_target_send_bytes(pnd, pbtTx, szTx)) { nfc_perror (pnd, "nfc_target_send_bytes"); exit(EXIT_FAILURE); } // Succesful transfer return true; } bool receive_bytes (void) { if (!nfc_target_receive_bytes(pnd,abtRx,&szRx)) { nfc_perror (pnd, "nfc_target_receive_bytes"); exit(EXIT_FAILURE); } // Show received answer if (!quiet_output) { printf ("Received data: "); print_hex (abtRx, szRx); } // Succesful transfer return true; } int main (void) { // Try to open the NFC reader pnd = nfc_connect (NULL); if (pnd == NULL) { ERR("Unable to connect to NFC device"); return EXIT_FAILURE; } signal (SIGINT, stop_emulation); printf ("Connected to NFC device: %s\n", pnd->acName); printf ("Emulating NDEF tag now, please touch it with a second NFC device\n"); nfc_target_t nt = { .nm = { .nmt = NMT_ISO14443A, .nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init() }, .nti = { .nai = { .abtAtqa = { 0x00, 0x04 }, .abtUid = { 0x08, 0x00, 0xb0, 0x0b }, .szUidLen = 4, .btSak = 0x20, .abtAts = { 0x75, 0x33, 0x92, 0x03 }, /* Not used by PN532 */ .szAtsLen = 4, }, }, }; print_nfc_iso14443a_info (nt.nti.nai, true); if (!nfc_target_init (pnd, &nt, abtRx, &szRx)) { if (pnd->iLastError == DEABORT) { errx (EXIT_SUCCESS, "Operation canceld by keystroke."); } nfc_perror (pnd, "nfc_target_init"); ERR("Could not come out of auto-emulation, no command was received"); return EXIT_FAILURE; } if (!quiet_output) { printf ("Received data: "); print_hex (abtRx, szRx); } //Receiving data: e0 40 //= RATS, FSD=48 //Actually PN532 already sent back the ATS so nothing to send now receive_bytes(); //Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03 //= App Select by name "e103e103e103" send_bytes((const byte_t*)"\x6a\x87",2); receive_bytes(); //Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03 //= App Select by name "e103e103e103" send_bytes((const byte_t*)"\x6a\x87",2); receive_bytes(); //Receiving data: 00 a4 04 00 07 d2 76 00 00 85 01 00 //= App Select by name "D2760000850100" send_bytes((const byte_t*)"\x90\x00",2); receive_bytes(); //Receiving data: 00 a4 00 00 02 e1 03 //= Select CC send_bytes((const byte_t*)"\x90\x00",2); receive_bytes(); //Receiving data: 00 b0 00 00 0f //= ReadBinary CC //We send CC + OK send_bytes((const byte_t*)"\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",17); receive_bytes(); //Receiving data: 00 a4 00 00 02 e1 04 //= Select NDEF send_bytes((const byte_t*)"\x90\x00",2); receive_bytes(); //Receiving data: 00 b0 00 00 02 //= Read first 2 NDEF bytes //Sent NDEF Length=0x21 send_bytes((const byte_t*)"\x00\x21\x90\x00",4); receive_bytes(); //Receiving data: 00 b0 00 02 21 //= Read remaining of NDEF file send_bytes((const byte_t*)"\xd1\x02\x1c\x53\x70\x91\x01\x09\x54\x02\x65\x6e\x4c\x69\x62\x6e\x66\x63\x51\x01\x0b\x55\x03\x6c\x69\x62\x6e\x66\x63\x2e\x6f\x72\x67\x90\x00",35); nfc_disconnect(pnd); exit (EXIT_SUCCESS); }