libnfc 1.3.9
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library 00003 * 00004 * Copyright (C) 2009, 2010, Roel Verdult, Romuald Conty 00005 * 00006 * This program is free software: you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by the 00008 * Free Software Foundation, either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00014 * more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 00025 #ifdef HAVE_CONFIG_H 00026 # include "config.h" 00027 #endif /* HAVE_CONFIG_H */ 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <stdint.h> 00032 #include <string.h> 00033 #include <signal.h> 00034 00035 #include <nfc/nfc.h> 00036 00037 #include <nfc/nfc-messages.h> 00038 #include "nfc-utils.h" 00039 00040 #define MAX_FRAME_LEN 264 00041 #define MAX_DEVICE_COUNT 2 00042 00043 static byte_t abtReaderRx[MAX_FRAME_LEN]; 00044 static byte_t abtReaderRxPar[MAX_FRAME_LEN]; 00045 static size_t szReaderRxBits; 00046 static byte_t abtTagRx[MAX_FRAME_LEN]; 00047 static byte_t abtTagRxPar[MAX_FRAME_LEN]; 00048 static size_t szTagRxBits; 00049 static nfc_device_t *pndReader; 00050 static nfc_device_t *pndTag; 00051 static bool quitting = false; 00052 00053 void 00054 intr_hdlr (void) 00055 { 00056 printf ("\nQuitting...\n"); 00057 quitting = true; 00058 return; 00059 } 00060 00061 void 00062 print_usage (char *argv[]) 00063 { 00064 printf ("Usage: %s [OPTIONS]\n", argv[0]); 00065 printf ("Options:\n"); 00066 printf ("\t-h\tHelp. Print this message.\n"); 00067 printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n"); 00068 } 00069 00070 int 00071 main (int argc, char *argv[]) 00072 { 00073 int arg; 00074 bool quiet_output = false; 00075 size_t szFound; 00076 nfc_device_desc_t *pnddDevices; 00077 const char *acLibnfcVersion = nfc_version (); 00078 00079 // Get commandline options 00080 for (arg = 1; arg < argc; arg++) { 00081 if (0 == strcmp (argv[arg], "-h")) { 00082 print_usage (argv); 00083 return EXIT_SUCCESS; 00084 } else if (0 == strcmp (argv[arg], "-q")) { 00085 INFO ("%s", "Quiet mode."); 00086 quiet_output = true; 00087 } else { 00088 ERR ("%s is not supported option.", argv[arg]); 00089 print_usage (argv); 00090 return EXIT_FAILURE; 00091 } 00092 } 00093 00094 // Display libnfc version 00095 printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); 00096 00097 #ifdef WIN32 00098 signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr); 00099 #else 00100 signal (SIGINT, (void (*)()) intr_hdlr); 00101 #endif 00102 00103 // Allocate memory to put the result of available devices listing 00104 if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { 00105 fprintf (stderr, "malloc() failed\n"); 00106 return EXIT_FAILURE; 00107 } 00108 // List available devices 00109 nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); 00110 00111 if (szFound < 2) { 00112 ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound); 00113 return EXIT_FAILURE; 00114 } 00115 // Try to open the NFC emulator device 00116 pndTag = nfc_connect (&(pnddDevices[0])); 00117 if (pndTag == NULL) { 00118 printf ("Error connecting NFC emulator device\n"); 00119 return EXIT_FAILURE; 00120 } 00121 00122 printf ("Hint: tag <---> emulator (relay) <---> reader (relay) <---> original reader\n\n"); 00123 00124 printf ("Connected to the NFC emulator device: %s\n", pndTag->acName); 00125 printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n"); 00126 printf ("[+] To do this, please send any command after the anti-collision\n"); 00127 printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); 00128 if (!nfc_target_init (pndTag, abtReaderRx, &szReaderRxBits)) { 00129 ERR ("%s", "Initialization of NFC emulator failed"); 00130 nfc_disconnect (pndTag); 00131 return EXIT_FAILURE; 00132 } 00133 printf ("%s", "Configuring emulator settings..."); 00134 if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) || 00135 !nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) { 00136 nfc_perror (pndTag, "nfc_configure"); 00137 exit (EXIT_FAILURE); 00138 } 00139 printf ("%s", "Done, emulated tag is initialized"); 00140 00141 // Try to open the NFC reader 00142 pndReader = nfc_connect (&(pnddDevices[1])); 00143 00144 printf ("Connected to the NFC reader device: %s", pndReader->acName); 00145 printf ("%s", "Configuring NFC reader settings..."); 00146 nfc_initiator_init (pndReader); 00147 if (!nfc_configure (pndReader, NDO_HANDLE_CRC, false) || 00148 !nfc_configure (pndReader, NDO_HANDLE_PARITY, false) || 00149 !nfc_configure (pndReader, NDO_ACCEPT_INVALID_FRAMES, true)) { 00150 nfc_perror (pndReader, "nfc_configure"); 00151 exit (EXIT_FAILURE); 00152 } 00153 printf ("%s", "Done, relaying frames now!"); 00154 00155 while (!quitting) { 00156 // Test if we received a frame from the reader 00157 if (nfc_target_receive_bits (pndTag, abtReaderRx, &szReaderRxBits, abtReaderRxPar)) { 00158 // Drop down the field before sending a REQA command and start a new session 00159 if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) { 00160 // Drop down field for a very short time (original tag will reboot) 00161 if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) { 00162 nfc_perror (pndReader, "nfc_configure"); 00163 exit (EXIT_FAILURE); 00164 } 00165 if (!quiet_output) 00166 printf ("\n"); 00167 if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, true)) { 00168 nfc_perror (pndReader, "nfc_configure"); 00169 exit (EXIT_FAILURE); 00170 } 00171 } 00172 // Print the reader frame to the screen 00173 if (!quiet_output) { 00174 printf ("R: "); 00175 print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar); 00176 } 00177 // Forward the frame to the original tag 00178 if (nfc_initiator_transceive_bits 00179 (pndReader, abtReaderRx, szReaderRxBits, abtReaderRxPar, abtTagRx, &szTagRxBits, abtTagRxPar)) { 00180 // Redirect the answer back to the reader 00181 if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) { 00182 nfc_perror (pndTag, "nfc_target_send_bits"); 00183 exit (EXIT_FAILURE); 00184 } 00185 // Print the tag frame to the screen 00186 if (!quiet_output) { 00187 printf ("T: "); 00188 print_hex_par (abtTagRx, szTagRxBits, abtTagRxPar); 00189 } 00190 } 00191 } 00192 } 00193 00194 nfc_disconnect (pndTag); 00195 nfc_disconnect (pndReader); 00196 exit (EXIT_SUCCESS); 00197 }