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