nfc-emulate.c

Go to the documentation of this file.
00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library
00003  * 
00004  * Copyright (C) 2009, Roel Verdult
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 <stddef.h>
00032 #include <stdint.h>
00033 #include <string.h>
00034 
00035 #include <nfc/nfc.h>
00036 
00037 #include <nfc/nfc-messages.h>
00038 #include "bitutils.h"
00039 
00040 #define MAX_FRAME_LEN 264
00041 
00042 static byte_t abtRecv[MAX_FRAME_LEN];
00043 static size_t szRecvBits;
00044 static nfc_device_t* pnd;
00045 
00046 // ISO14443A Anti-Collision response
00047 byte_t abtAtqa      [2] = { 0x04,0x00 };
00048 byte_t abtUidBcc    [5] = { 0xDE,0xAD,0xBE,0xAF,0x62 };
00049 byte_t abtSak       [9] = { 0x08,0xb6,0xdd };
00050 
00051 void print_usage(char* argv[])
00052 {
00053   printf("Usage: %s [OPTIONS] [UID]\n", argv[0]);
00054   printf("Options:\n");
00055   printf("\t-h\tHelp. Print this message.\n");
00056   printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
00057   printf("\n");
00058   printf("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n");
00059 }
00060 
00061 int main(int argc, char *argv[])
00062 {
00063   byte_t* pbtTx = NULL;
00064   size_t szTxBits;
00065   bool quiet_output = false;
00066 
00067   int arg, i;
00068 
00069   // Get commandline options
00070   for (arg=1;arg<argc;arg++) {
00071     if (0 == strcmp(argv[arg], "-h")) {
00072       print_usage(argv);
00073       return 0;
00074     } else if (0 == strcmp(argv[arg], "-q")) {
00075       INFO("%s", "Quiet mode.");
00076       quiet_output = true;
00077     } else if((arg == argc-1) && (strlen(argv[arg]) == 8)) { // See if UID was specified as HEX string
00078       byte_t abtTmp[3] = { 0x00,0x00,0x00 };
00079       printf("[+] Using UID: %s\n",argv[arg]);
00080       abtUidBcc[4]= 0x00;
00081       for(i= 0; i < 4; ++i)
00082       {
00083         memcpy(abtTmp,argv[arg]+i*2,2);
00084         abtUidBcc[i]= (byte_t) strtol((char*)abtTmp,NULL,16);
00085         abtUidBcc[4] ^= abtUidBcc[i];
00086       }
00087     } else {
00088       ERR("%s is not supported option.", argv[arg]);
00089       print_usage(argv);
00090       return -1;
00091     }
00092   }
00093 
00094   // Try to open the NFC reader
00095   pnd = nfc_connect(NULL);
00096 
00097   if (pnd == NULL)
00098   {
00099     printf("Error connecting NFC reader\n");
00100     return 1;
00101   }
00102 
00103   printf("\n");
00104   printf("[+] Connected to NFC reader: %s\n",pnd->acName);
00105   printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
00106   printf("[+] To do this, please send any command after the anti-collision\n");
00107   printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
00108   if (!nfc_target_init(pnd,abtRecv,&szRecvBits))
00109   {
00110     printf("Error: Could not come out of auto-emulation, no command was received\n");
00111     return 1;
00112   }
00113   printf("[+] Received initiator command: ");
00114   print_hex_bits(abtRecv,szRecvBits);
00115   printf("[+] Configuring communication\n");
00116   nfc_configure(pnd,NDO_HANDLE_CRC,false);
00117   nfc_configure(pnd,NDO_HANDLE_PARITY,true);
00118   printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n",abtUidBcc[0],abtUidBcc[1],abtUidBcc[2],abtUidBcc[3]);
00119 
00120   while(true)
00121   {
00122     // Test if we received a frame
00123     if (nfc_target_receive_bits(pnd,abtRecv,&szRecvBits,NULL))
00124     {
00125       // Prepare the command to send back for the anti-collision request
00126       switch(szRecvBits)
00127       {
00128         case 7: // Request or Wakeup
00129           pbtTx = abtAtqa;
00130           szTxBits = 16;
00131           // New anti-collsion session started
00132           if (!quiet_output) printf("\n"); 
00133         break;
00134 
00135         case 16: // Select All
00136           pbtTx = abtUidBcc;
00137           szTxBits = 40;
00138         break;
00139 
00140         case 72: // Select Tag
00141           pbtTx = abtSak;
00142           szTxBits = 24;
00143         break;
00144 
00145         default: // unknown length?
00146           szTxBits = 0;
00147         break;
00148       }
00149 
00150       if(!quiet_output)
00151       {
00152         printf("R: ");
00153         print_hex_bits(abtRecv,szRecvBits);
00154       }
00155 
00156       // Test if we know how to respond
00157       if(szTxBits)
00158       {
00159         // Send and print the command to the screen
00160         nfc_target_send_bits(pnd,pbtTx,szTxBits,NULL);
00161         if(!quiet_output)
00162         {
00163           printf("T: ");
00164           print_hex_bits(pbtTx,szTxBits);
00165         }
00166       }
00167     }
00168   }
00169 
00170   nfc_disconnect(pnd);
00171 }
00172 

Generated on 8 May 2010 for libnfc by  doxygen 1.6.1