/*- * Public platform independent Near Field Communication (NFC) library * * Copyright (C) 2009, 2010, Roel Verdult, Romuald Conty * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ /** * @file nfc-relay.c * @brief Relay example using two devices. */ #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 #define MAX_DEVICE_COUNT 2 static byte_t abtReaderRx[MAX_FRAME_LEN]; static byte_t abtReaderRxPar[MAX_FRAME_LEN]; static size_t szReaderRxBits; static byte_t abtTagRx[MAX_FRAME_LEN]; static byte_t abtTagRxPar[MAX_FRAME_LEN]; static size_t szTagRxBits; static nfc_device_t* pndReader; static nfc_device_t* pndTag; static bool quitting=false; void intr_hdlr(void) { printf("\nQuitting...\n"); quitting=true; return; } void print_usage(char* argv[]) { printf("Usage: %s [OPTIONS]\n", argv[0]); printf("Options:\n"); printf("\t-h\tHelp. Print this message.\n"); printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n"); } int main(int argc,char* argv[]) { int arg; bool quiet_output = false; size_t szFound; nfc_device_desc_t *pnddDevices; const char* acLibnfcVersion = nfc_version(); // Get commandline options for (arg=1;arg emulator (relay) <---> reader (relay) <---> original reader\n\n"); printf("Connected to the NFC emulator device: %s\n", pndTag->acName); printf("[+] Try to break out the auto-emulation, this requires a second reader!\n"); printf("[+] To do this, please send any command after the anti-collision\n"); printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); if (!nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits)) { ERR("%s", "Initialization of NFC emulator failed"); nfc_disconnect(pndTag); return EXIT_FAILURE; } printf("%s", "Configuring emulator settings..."); nfc_configure(pndTag,NDO_HANDLE_CRC,false); nfc_configure(pndTag,NDO_HANDLE_PARITY,false); nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true); printf("%s", "Done, emulated tag is initialized"); // Try to open the NFC reader pndReader = nfc_connect(&(pnddDevices[1])); printf("Connected to the NFC reader device: %s", pndReader->acName); printf("%s", "Configuring NFC reader settings..."); nfc_initiator_init(pndReader); nfc_configure(pndReader,NDO_HANDLE_CRC,false); nfc_configure(pndReader,NDO_HANDLE_PARITY,false); nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true); printf("%s", "Done, relaying frames now!"); while(!quitting) { // Test if we received a frame from the reader if (nfc_target_receive_bits(pndTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar)) { // Drop down the field before sending a REQA command and start a new session if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) { // Drop down field for a very short time (original tag will reboot) nfc_configure(pndReader,NDO_ACTIVATE_FIELD,false); if(!quiet_output) printf("\n"); nfc_configure(pndReader,NDO_ACTIVATE_FIELD,true); } // Print the reader frame to the screen if(!quiet_output) { printf("R: "); print_hex_par(abtReaderRx,szReaderRxBits,abtReaderRxPar); } // Forward the frame to the original tag if (nfc_initiator_transceive_bits(pndReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar)) { // Redirect the answer back to the reader nfc_target_send_bits(pndTag,abtTagRx,szTagRxBits,abtTagRxPar); // Print the tag frame to the screen if(!quiet_output) { printf("T: "); print_hex_par(abtTagRx,szTagRxBits,abtTagRxPar); } } } } nfc_disconnect(pndTag); nfc_disconnect(pndReader); exit(EXIT_SUCCESS); }