libnfc
1.4.2
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library examples 00003 * 00004 * Copyright (C) 2010, Romuald Conty 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 1) Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 2 )Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00015 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00016 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00017 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00018 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00019 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00020 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00021 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00022 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00023 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00024 * POSSIBILITY OF SUCH DAMAGE. 00025 * 00026 * Note that this license only applies on the examples, NFC library itself is under LGPL 00027 * 00028 */ 00029 00035 // Note that depending on the device (initiator) you'll use against, this 00036 // emulator it might work or not. Some readers are very strict on responses 00037 // timings, e.g. a Nokia NFC and will drop communication too soon for us. 00038 00039 #ifdef HAVE_CONFIG_H 00040 # include "config.h" 00041 #endif // HAVE_CONFIG_H 00042 00043 #include <stdio.h> 00044 #include <stdlib.h> 00045 #include <stddef.h> 00046 #include <stdint.h> 00047 #include <string.h> 00048 #include <signal.h> 00049 00050 #include <nfc/nfc.h> 00051 00052 #include <nfc/nfc-messages.h> 00053 #include "nfc-utils.h" 00054 00055 #define MAX_FRAME_LEN (264) 00056 #define SAK_ISO14443_4_COMPLIANT 0x20 00057 00058 static byte_t abtRx[MAX_FRAME_LEN]; 00059 static size_t szRx; 00060 static nfc_device_t *pnd; 00061 static bool quiet_output = false; 00062 static bool init_mfc_auth = false; 00063 00064 void 00065 intr_hdlr (void) 00066 { 00067 printf ("\nQuitting...\n"); 00068 if (pnd != NULL) { 00069 nfc_disconnect(pnd); 00070 } 00071 exit (EXIT_FAILURE); 00072 } 00073 00074 bool 00075 target_io( nfc_target_t * pnt, const byte_t * pbtInput, const size_t szInput, byte_t * pbtOutput, size_t *pszOutput ) 00076 { 00077 bool loop = true; 00078 *pszOutput = 0; 00079 00080 // Show transmitted command 00081 if (!quiet_output) { 00082 printf (" In: "); 00083 print_hex (pbtInput, szInput); 00084 } 00085 if(szInput) { 00086 switch(pbtInput[0]) { 00087 case 0x30: // Mifare read 00088 // block address is in pbtInput[1] 00089 *pszOutput = 15; 00090 strcpy((char*)pbtOutput, "You read block "); 00091 pbtOutput[15] = pbtInput[1]; 00092 break; 00093 case 0x50: // Deselect / HALT 00094 if (!quiet_output) { 00095 printf("Target halted me. Bye!\n"); 00096 } 00097 loop = false; 00098 break; 00099 case 0x60: // Mifare authA 00100 case 0x61: // Mifare authB 00101 // Let's give back a very random nonce... 00102 *pszOutput = 2; 00103 pbtOutput[0] = 0x12; 00104 pbtOutput[1] = 0x34; 00105 // Next commands will be without CRC 00106 init_mfc_auth = true; 00107 break; 00108 case 0xe0: // RATS 00109 // Send ATS 00110 *pszOutput = pnt->nti.nai.szAtsLen + 1; 00111 pbtOutput[0] = pnt->nti.nai.szAtsLen + 1; // ISO14443-4 says that ATS contains ATS_Lenght as first byte 00112 if(pnt->nti.nai.szAtsLen) { 00113 memcpy(pbtOutput+1, pnt->nti.nai.abtAts, pnt->nti.nai.szAtsLen); 00114 } 00115 break; 00116 case 0xc2: // S-block DESELECT 00117 if (!quiet_output) { 00118 printf("Target released me. Bye!\n"); 00119 } 00120 loop = false; 00121 break; 00122 default: // Unknown 00123 if (!quiet_output) { 00124 printf("Unknown frame, emulated target abort.\n"); 00125 } 00126 loop = false; 00127 } 00128 } 00129 // Show transmitted command 00130 if ((!quiet_output) && *pszOutput) { 00131 printf (" Out: "); 00132 print_hex (pbtOutput, *pszOutput); 00133 } 00134 return loop; 00135 } 00136 00137 bool 00138 nfc_target_emulate_tag(nfc_device_t* pnd, nfc_target_t * pnt) 00139 { 00140 size_t szTx; 00141 byte_t abtTx[MAX_FRAME_LEN]; 00142 bool loop = true; 00143 00144 if (!nfc_target_init (pnd, pnt, abtRx, &szRx)) { 00145 nfc_perror (pnd, "nfc_target_init"); 00146 return false; 00147 } 00148 00149 while ( loop ) { 00150 loop = target_io( pnt, abtRx, szRx, abtTx, &szTx ); 00151 if (szTx) { 00152 if (!nfc_target_send_bytes(pnd, abtTx, szTx)) { 00153 nfc_perror (pnd, "nfc_target_send_bytes"); 00154 return false; 00155 } 00156 } 00157 if ( loop ) { 00158 if ( init_mfc_auth ) { 00159 nfc_configure (pnd, NDO_HANDLE_CRC, false); 00160 init_mfc_auth = false; 00161 } 00162 if (!nfc_target_receive_bytes(pnd, abtRx, &szRx)) { 00163 nfc_perror (pnd, "nfc_target_receive_bytes"); 00164 return false; 00165 } 00166 } 00167 } 00168 return true; 00169 } 00170 00171 int 00172 main (int argc, char *argv[]) 00173 { 00174 const char *acLibnfcVersion; 00175 00176 #ifdef WIN32 00177 signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr); 00178 #else 00179 signal (SIGINT, (void (*)()) intr_hdlr); 00180 #endif 00181 00182 // Try to open the NFC reader 00183 pnd = nfc_connect (NULL); 00184 00185 // Display libnfc version 00186 acLibnfcVersion = nfc_version (); 00187 printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); 00188 00189 if (pnd == NULL) { 00190 ERR("Unable to connect to NFC device"); 00191 return EXIT_FAILURE; 00192 } 00193 00194 printf ("Connected to NFC device: %s\n", pnd->acName); 00195 00196 // Notes for ISO14443-A emulated tags: 00197 // * Only short UIDs are supported 00198 // If your UID is longer it will be truncated 00199 // Therefore e.g. an UltraLight can only have short UID, which is 00200 // typically badly handled by readers who still try to send their "0x95" 00201 // * First byte of UID will be masked by 0x08 by the PN53x firmware 00202 // as security countermeasure against real UID emulation 00203 00204 // Example of a Mifare Classic Mini 00205 // Note that crypto1 is not implemented in this example 00206 nfc_target_t nt = { 00207 .nm.nmt = NMT_ISO14443A, 00208 .nm.nbr = NBR_UNDEFINED, 00209 .nti.nai.abtAtqa = { 0x00, 0x04 }, 00210 .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, 00211 .nti.nai.btSak = 0x09, 00212 .nti.nai.szUidLen = 4, 00213 .nti.nai.szAtsLen = 0, 00214 }; 00215 /* 00216 // Example of a FeliCa 00217 nfc_target_t nt = { 00218 .nm.nmt = NMT_FELICA, 00219 .nm.nbr = NBR_UNDEFINED, 00220 .nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF }, 00221 .nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF }, 00222 .nti.nfi.abtSysCode = { 0xFF, 0xFF }, 00223 }; 00224 */ 00225 /* 00226 // Example of a ISO14443-4 (DESfire) 00227 nfc_target_t nt = { 00228 .nm.nmt = NMT_ISO14443A, 00229 .nm.nbr = NBR_UNDEFINED, 00230 .nti.nai.abtAtqa = { 0x03, 0x44 }, 00231 .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, 00232 .nti.nai.btSak = 0x20, 00233 .nti.nai.szUidLen = 4, 00234 .nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 }, 00235 .nti.nai.szAtsLen = 5, 00236 }; 00237 */ 00238 00239 printf ("%s will emulate this ISO14443-A tag:\n", argv[0]); 00240 print_nfc_iso14443a_info (nt.nti.nai, true); 00241 00242 // Switch off NDO_EASY_FRAMING if target is not ISO14443-4 00243 nfc_configure (pnd, NDO_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT)); 00244 printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n"); 00245 if (!nfc_target_emulate_tag (pnd, &nt)) { 00246 nfc_perror (pnd, "nfc_target_emulate_tag"); 00247 return EXIT_FAILURE; 00248 } 00249 00250 nfc_disconnect(pnd); 00251 exit (EXIT_SUCCESS); 00252 } 00253