libnfc 1.3.9
|
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 <time.h> 00032 00033 #ifndef _WIN32 00034 // Needed by sleep() under Unix 00035 # include <unistd.h> 00036 # define sleep sleep 00037 # define SUSP_TIME 1 // secs. 00038 #else 00039 // Needed by Sleep() under Windows 00040 # include <winbase.h> 00041 # define sleep Sleep 00042 # define SUSP_TIME 1000 // msecs. 00043 #endif 00044 00045 #include <nfc/nfc.h> 00046 #include <nfc/nfc-messages.h> 00047 #include "nfc-utils.h" 00048 // FIXME: Remove me 00049 #include "chips/pn53x.h" 00050 00051 #define MAX_FRAME_LEN 264 00052 #define TIMEOUT 60 // secs. 00053 00054 #define NORMAL_MODE 1 00055 #define VIRTUAL_CARD_MODE 2 00056 #define WIRED_CARD_MODE 3 00057 #define DUAL_CARD_MODE 4 00058 00059 bool 00060 sam_connection (nfc_device_t * pnd, int mode) 00061 { 00062 byte_t pncmd_sam_config[] = { 0xD4, 0x14, 0x00, 0x00 }; 00063 size_t szCmd = 0; 00064 00065 byte_t abtRx[MAX_FRAME_LEN]; 00066 size_t szRxLen; 00067 00068 pncmd_sam_config[2] = mode; 00069 00070 switch (mode) { 00071 case VIRTUAL_CARD_MODE: 00072 { 00073 // Only the VIRTUAL_CARD_MODE requires 4 bytes. 00074 szCmd = sizeof (pncmd_sam_config); 00075 } 00076 break; 00077 00078 default: 00079 { 00080 szCmd = sizeof (pncmd_sam_config) - 1; 00081 } 00082 break; 00083 } 00084 00085 // FIXME: Direct call 00086 if (!pn53x_transceive (pnd, pncmd_sam_config, szCmd, abtRx, &szRxLen)) { 00087 ERR ("%s %d", "Unable to execute SAMConfiguration command with mode byte:", mode); 00088 return false; 00089 } 00090 00091 return true; 00092 } 00093 00094 void 00095 wait_one_minute () 00096 { 00097 int secs = 0; 00098 00099 printf ("|"); 00100 fflush (stdout); 00101 00102 while (secs < TIMEOUT) { 00103 sleep (SUSP_TIME); 00104 secs++; 00105 printf ("."); 00106 fflush (stdout); 00107 } 00108 00109 printf ("|\n"); 00110 } 00111 00112 int 00113 main (int argc, const char *argv[]) 00114 { 00115 nfc_device_t *pnd; 00116 00117 (void) argc; 00118 (void) argv; 00119 00120 // Display libnfc version 00121 const char *acLibnfcVersion = nfc_version (); 00122 printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); 00123 00124 // Connect using the first available NFC device 00125 pnd = nfc_connect (NULL); 00126 00127 if (pnd == NULL) { 00128 ERR ("%s", "Unable to connect to NFC device."); 00129 return EXIT_FAILURE; 00130 } 00131 00132 printf ("Connected to NFC reader: %s\n", pnd->acName); 00133 00134 // Print the example's menu 00135 printf ("\nSelect the comunication mode:\n"); 00136 printf ("[1] Virtual card mode.\n"); 00137 printf ("[2] Wired card mode.\n"); 00138 printf ("[3] Dual card mode.\n"); 00139 printf (">> "); 00140 00141 // Take user's choice 00142 char input = getchar (); 00143 int mode = input - '0' + 1; 00144 printf ("\n"); 00145 if (mode < VIRTUAL_CARD_MODE || mode > DUAL_CARD_MODE) { 00146 ERR ("%s", "Invalid selection."); 00147 return EXIT_FAILURE; 00148 } 00149 // Connect with the SAM 00150 sam_connection (pnd, mode); 00151 00152 switch (mode) { 00153 case VIRTUAL_CARD_MODE: 00154 { 00155 // FIXME: after the loop the reader doesn't respond to host commands... 00156 printf ("Now the SAM is readable for 1 minute from an external reader.\n"); 00157 wait_one_minute (); 00158 } 00159 break; 00160 00161 case WIRED_CARD_MODE: 00162 { 00163 nfc_target_info_t nti; 00164 00165 // Set connected NFC device to initiator mode 00166 nfc_initiator_init (pnd); 00167 00168 // Drop the field for a while 00169 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) { 00170 nfc_perror (pnd, "nfc_configure"); 00171 exit (EXIT_FAILURE); 00172 } 00173 // Let the reader only try once to find a tag 00174 if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) { 00175 nfc_perror (pnd, "nfc_configure"); 00176 exit (EXIT_FAILURE); 00177 } 00178 // Configure the CRC and Parity settings 00179 if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) { 00180 nfc_perror (pnd, "nfc_configure"); 00181 exit (EXIT_FAILURE); 00182 } 00183 if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) { 00184 nfc_perror (pnd, "nfc_configure"); 00185 exit (EXIT_FAILURE); 00186 } 00187 // Enable field so more power consuming cards can power themselves up 00188 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) { 00189 nfc_perror (pnd, "nfc_configure"); 00190 exit (EXIT_FAILURE); 00191 } 00192 // Read the SAM's info 00193 if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { 00194 ERR ("%s", "Reading of SAM info failed."); 00195 return EXIT_FAILURE; 00196 } 00197 00198 printf ("The following ISO14443A tag (SAM) was found:\n\n"); 00199 print_nfc_iso14443a_info (nti.nai); 00200 } 00201 break; 00202 00203 case DUAL_CARD_MODE: 00204 { 00205 byte_t abtRx[MAX_FRAME_LEN]; 00206 size_t szRxLen; 00207 00208 // FIXME: it does not work as expected...Probably the issue is in "nfc_target_init" 00209 // which doesn't provide a way to set custom data for SENS_RES, NFCID1, SEL_RES, etc. 00210 if (!nfc_target_init (pnd, abtRx, &szRxLen)) 00211 return EXIT_FAILURE; 00212 00213 printf ("Now both the NFC reader and SAM are readable for 1 minute from an external reader.\n"); 00214 wait_one_minute (); 00215 } 00216 break; 00217 } 00218 00219 // Disconnect from the SAM 00220 sam_connection (pnd, NORMAL_MODE); 00221 00222 // Disconnect from NFC device 00223 nfc_disconnect (pnd); 00224 00225 return EXIT_SUCCESS; 00226 }