libnfc 1.4.2
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library examples 00003 * 00004 * Copyright (C) 2009, Roel Verdult 00005 * Copyright (C) 2010, Romuald Conty 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 1) Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2 )Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 * Note that this license only applies on the examples, NFC library itself is under LGPL 00028 * 00029 */ 00030 00036 #ifdef HAVE_CONFIG_H 00037 # include "config.h" 00038 #endif /* HAVE_CONFIG_H */ 00039 00040 #include <stdio.h> 00041 #include <stdlib.h> 00042 #include <stdint.h> 00043 #include <string.h> 00044 #include <signal.h> 00045 00046 #include <nfc/nfc.h> 00047 00048 #include <nfc/nfc-messages.h> 00049 #include "nfc-utils.h" 00050 00051 #define MAX_FRAME_LEN 264 00052 #define MAX_DEVICE_COUNT 2 00053 00054 static byte_t abtReaderRx[MAX_FRAME_LEN]; 00055 static byte_t abtReaderRxPar[MAX_FRAME_LEN]; 00056 static size_t szReaderRxBits; 00057 static byte_t abtTagRx[MAX_FRAME_LEN]; 00058 static byte_t abtTagRxPar[MAX_FRAME_LEN]; 00059 static size_t szTagRxBits; 00060 static nfc_device_t *pndReader; 00061 static nfc_device_t *pndTag; 00062 static bool quitting = false; 00063 00064 void 00065 intr_hdlr (void) 00066 { 00067 printf ("\nQuitting...\n"); 00068 quitting = true; 00069 return; 00070 } 00071 00072 void 00073 print_usage (char *argv[]) 00074 { 00075 printf ("Usage: %s [OPTIONS]\n", argv[0]); 00076 printf ("Options:\n"); 00077 printf ("\t-h\tHelp. Print this message.\n"); 00078 printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n"); 00079 } 00080 00081 int 00082 main (int argc, char *argv[]) 00083 { 00084 int arg; 00085 bool quiet_output = false; 00086 size_t szFound; 00087 nfc_device_desc_t *pnddDevices; 00088 const char *acLibnfcVersion = nfc_version (); 00089 00090 // Get commandline options 00091 for (arg = 1; arg < argc; arg++) { 00092 if (0 == strcmp (argv[arg], "-h")) { 00093 print_usage (argv); 00094 return EXIT_SUCCESS; 00095 } else if (0 == strcmp (argv[arg], "-q")) { 00096 quiet_output = true; 00097 } else { 00098 ERR ("%s is not supported option.", argv[arg]); 00099 print_usage (argv); 00100 return EXIT_FAILURE; 00101 } 00102 } 00103 00104 // Display libnfc version 00105 printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); 00106 00107 #ifdef WIN32 00108 signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr); 00109 #else 00110 signal (SIGINT, (void (*)()) intr_hdlr); 00111 #endif 00112 00113 // Allocate memory to put the result of available devices listing 00114 if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { 00115 fprintf (stderr, "malloc() failed\n"); 00116 return EXIT_FAILURE; 00117 } 00118 // List available devices 00119 nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); 00120 00121 if (szFound < 2) { 00122 ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound); 00123 return EXIT_FAILURE; 00124 } 00125 // Try to open the NFC emulator device 00126 pndTag = nfc_connect (&(pnddDevices[0])); 00127 if (pndTag == NULL) { 00128 printf ("Error connecting NFC emulator device\n"); 00129 return EXIT_FAILURE; 00130 } 00131 00132 printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n"); 00133 00134 printf ("Connected to the NFC emulator device: %s\n", pndTag->acName); 00135 printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n"); 00136 printf ("[+] To do this, please send any command after the anti-collision\n"); 00137 printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); 00138 00139 nfc_target_t nt = { 00140 .nm.nmt = NMT_ISO14443A, 00141 .nm.nbr = NBR_UNDEFINED, 00142 .nti.nai.abtAtqa = { 0x04, 0x00 }, 00143 .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xef }, 00144 .nti.nai.btSak = 0x20, 00145 .nti.nai.szUidLen = 4, 00146 .nti.nai.szAtsLen = 0, 00147 }; 00148 00149 if (!nfc_target_init (pndTag, &nt, abtReaderRx, &szReaderRxBits)) { 00150 ERR ("%s", "Initialization of NFC emulator failed"); 00151 nfc_disconnect (pndTag); 00152 return EXIT_FAILURE; 00153 } 00154 printf ("%s", "Configuring emulator settings..."); 00155 if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) || 00156 !nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) { 00157 nfc_perror (pndTag, "nfc_configure"); 00158 exit (EXIT_FAILURE); 00159 } 00160 printf ("%s", "Done, emulated tag is initialized"); 00161 00162 // Try to open the NFC reader 00163 pndReader = nfc_connect (&(pnddDevices[1])); 00164 00165 printf ("Connected to the NFC reader device: %s", pndReader->acName); 00166 printf ("%s", "Configuring NFC reader settings..."); 00167 nfc_initiator_init (pndReader); 00168 if (!nfc_configure (pndReader, NDO_HANDLE_CRC, false) || 00169 !nfc_configure (pndReader, NDO_HANDLE_PARITY, false) || 00170 !nfc_configure (pndReader, NDO_ACCEPT_INVALID_FRAMES, true)) { 00171 nfc_perror (pndReader, "nfc_configure"); 00172 exit (EXIT_FAILURE); 00173 } 00174 printf ("%s", "Done, relaying frames now!"); 00175 00176 while (!quitting) { 00177 // Test if we received a frame from the reader 00178 if (nfc_target_receive_bits (pndTag, abtReaderRx, &szReaderRxBits, abtReaderRxPar)) { 00179 // Drop down the field before sending a REQA command and start a new session 00180 if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) { 00181 // Drop down field for a very short time (original tag will reboot) 00182 if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) { 00183 nfc_perror (pndReader, "nfc_configure"); 00184 exit (EXIT_FAILURE); 00185 } 00186 if (!quiet_output) 00187 printf ("\n"); 00188 if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, true)) { 00189 nfc_perror (pndReader, "nfc_configure"); 00190 exit (EXIT_FAILURE); 00191 } 00192 } 00193 // Print the reader frame to the screen 00194 if (!quiet_output) { 00195 printf ("R: "); 00196 print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar); 00197 } 00198 // Forward the frame to the original tag 00199 if (nfc_initiator_transceive_bits 00200 (pndReader, abtReaderRx, szReaderRxBits, abtReaderRxPar, abtTagRx, &szTagRxBits, abtTagRxPar)) { 00201 // Redirect the answer back to the reader 00202 if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) { 00203 nfc_perror (pndTag, "nfc_target_send_bits"); 00204 exit (EXIT_FAILURE); 00205 } 00206 // Print the tag frame to the screen 00207 if (!quiet_output) { 00208 printf ("T: "); 00209 print_hex_par (abtTagRx, szTagRxBits, abtTagRxPar); 00210 } 00211 } 00212 } 00213 } 00214 00215 nfc_disconnect (pndTag); 00216 nfc_disconnect (pndReader); 00217 exit (EXIT_SUCCESS); 00218 }