00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 #ifdef HAVE_CONFIG_H
00036 # include "config.h"
00037 #endif // HAVE_CONFIG_H
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <stddef.h>
00042 #include <stdint.h>
00043 #include <stdbool.h>
00044 #include <string.h>
00045
00046 #include <nfc/nfc.h>
00047
00048 #include <nfc/nfc-messages.h>
00049 #include "nfc-utils.h"
00050
00051 #define SAK_FLAG_ATS_SUPPORTED 0x20
00052
00053 #define MAX_FRAME_LEN 264
00054
00055 static byte_t abtRx[MAX_FRAME_LEN];
00056 static size_t szRxBits;
00057 static size_t szRx;
00058 static byte_t abtRawUid[12];
00059 static byte_t abtAtqa[2];
00060 static byte_t abtSak;
00061 static size_t szCL = 1;
00062 static nfc_device_t *pnd;
00063
00064 bool quiet_output = false;
00065
00066
00067 byte_t abtReqa[1] = { 0x26 };
00068 byte_t abtSelectAll[2] = { 0x93, 0x20 };
00069 byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00070 byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
00071 byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
00072 #define CASCADE_BIT 0x04
00073
00074 static bool
00075 transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
00076 {
00077
00078 if (!quiet_output) {
00079 printf ("Sent bits: ");
00080 print_hex_bits (pbtTx, szTxBits);
00081 }
00082
00083 if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
00084 return false;
00085
00086
00087 if (!quiet_output) {
00088 printf ("Received bits: ");
00089 print_hex_bits (abtRx, szRxBits);
00090 }
00091
00092 return true;
00093 }
00094
00095
00096 static bool
00097 transmit_bytes (const byte_t * pbtTx, const size_t szTx)
00098 {
00099
00100 if (!quiet_output) {
00101 printf ("Sent bits: ");
00102 print_hex (pbtTx, szTx);
00103 }
00104
00105 if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx))
00106 return false;
00107
00108
00109 if (!quiet_output) {
00110 printf ("Received bits: ");
00111 print_hex (abtRx, szRx);
00112 }
00113
00114 return true;
00115 }
00116
00117 static void
00118 print_usage (char *argv[])
00119 {
00120 printf ("Usage: %s [OPTIONS]\n", argv[0]);
00121 printf ("Options:\n");
00122 printf ("\t-h\tHelp. Print this message.\n");
00123 printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
00124 }
00125
00126 int
00127 main (int argc, char *argv[])
00128 {
00129 int arg;
00130
00131
00132 for (arg = 1; arg < argc; arg++) {
00133 if (0 == strcmp (argv[arg], "-h")) {
00134 print_usage (argv);
00135 exit(EXIT_SUCCESS);
00136 } else if (0 == strcmp (argv[arg], "-q")) {
00137 quiet_output = true;
00138 } else {
00139 ERR ("%s is not supported option.", argv[arg]);
00140 print_usage (argv);
00141 exit(EXIT_FAILURE);
00142 }
00143 }
00144
00145
00146 pnd = nfc_connect (NULL);
00147
00148 if (!pnd) {
00149 printf ("Error connecting NFC reader\n");
00150 exit(EXIT_FAILURE);
00151 }
00152
00153
00154 nfc_initiator_init (pnd);
00155
00156
00157 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
00158 nfc_perror (pnd, "nfc_configure");
00159 exit (EXIT_FAILURE);
00160 }
00161
00162
00163 if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
00164 nfc_perror (pnd, "nfc_configure");
00165 exit (EXIT_FAILURE);
00166 }
00167
00168 if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
00169 nfc_perror (pnd, "nfc_configure");
00170 exit (EXIT_FAILURE);
00171 }
00172
00173 if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
00174 nfc_perror (pnd, "nfc_configure");
00175 exit (EXIT_FAILURE);
00176 }
00177
00178 if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
00179 nfc_perror (pnd, "nfc_configure");
00180 exit (EXIT_FAILURE);
00181 }
00182
00183 if (!nfc_configure (pnd, NDO_FORCE_ISO14443_A, true)) {
00184 nfc_perror (pnd, "nfc_configure");
00185 exit (EXIT_FAILURE);
00186 }
00187
00188
00189 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
00190 nfc_perror (pnd, "nfc_configure");
00191 exit (EXIT_FAILURE);
00192 }
00193
00194 printf ("Connected to NFC reader: %s\n\n", pnd->acName);
00195
00196
00197 if (!transmit_bits (abtReqa, 7)) {
00198 printf ("Error: No tag available\n");
00199 nfc_disconnect (pnd);
00200 return 1;
00201 }
00202 memcpy (abtAtqa, abtRx, 2);
00203
00204
00205 transmit_bytes (abtSelectAll, 2);
00206
00207
00208 if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
00209 printf("WARNING: BCC check failed!\n");
00210 }
00211
00212
00213 memcpy (abtRawUid, abtRx, 4);
00214
00215
00216 memcpy (abtSelectTag + 2, abtRx, 5);
00217 iso14443a_crc_append (abtSelectTag, 7);
00218 transmit_bytes (abtSelectTag, 9);
00219 abtSak = abtRx[0];
00220
00221
00222 if (abtSak & CASCADE_BIT) {
00223 szCL = 2;
00224
00225 if (abtRawUid[0] != 0x88) {
00226 printf("WARNING: Cascade bit set but CT != 0x88!\n");
00227 }
00228 }
00229
00230 if(szCL == 2) {
00231
00232
00233
00234 abtSelectAll[0] = 0x95;
00235
00236
00237 transmit_bytes (abtSelectAll, 2);
00238
00239
00240 if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
00241 printf("WARNING: BCC check failed!\n");
00242 }
00243
00244
00245 memcpy (abtRawUid + 4, abtRx, 4);
00246
00247
00248 abtSelectTag[0] = 0x95;
00249 memcpy (abtSelectTag + 2, abtRx, 5);
00250 iso14443a_crc_append (abtSelectTag, 7);
00251 transmit_bytes (abtSelectTag, 9);
00252 abtSak = abtRx[0];
00253
00254
00255 if (abtSak & CASCADE_BIT) {
00256 szCL = 3;
00257
00258 if (abtRawUid[0] != 0x88) {
00259 printf("WARNING: Cascade bit set but CT != 0x88!\n");
00260 }
00261 }
00262
00263 if ( szCL == 3) {
00264
00265
00266
00267 abtSelectAll[0] = 0x97;
00268 transmit_bytes (abtSelectAll, 2);
00269
00270
00271 if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
00272 printf("WARNING: BCC check failed!\n");
00273 }
00274
00275
00276 memcpy (abtRawUid + 8, abtRx, 4);
00277
00278
00279 abtSelectTag[0] = 0x97;
00280 memcpy (abtSelectTag + 2, abtRx, 5);
00281 iso14443a_crc_append (abtSelectTag, 7);
00282 transmit_bytes (abtSelectTag, 9);
00283 abtSak = abtRx[0];
00284 }
00285 }
00286
00287
00288 if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) {
00289 iso14443a_crc_append(abtRats, 2);
00290 transmit_bytes (abtRats, 4);
00291 }
00292
00293
00294 iso14443a_crc_append(abtHalt, 2);
00295 transmit_bytes (abtHalt, 4);
00296
00297 printf ("\nFound tag with\n UID: ");
00298 switch (szCL) {
00299 case 1:
00300 printf ("%02x%02x%02x%02x", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]);
00301 break;
00302 case 2:
00303 printf ("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
00304 printf ("%02x%02x%02x%02x", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]);
00305 break;
00306 case 3:
00307 printf ("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
00308 printf ("%02x%02x%02x", abtRawUid[5], abtRawUid[6], abtRawUid[7]);
00309 printf ("%02x%02x%02x%02x", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]);
00310 break;
00311 }
00312 printf("\n");
00313 printf("ATQA: %02x%02x\n SAK: %02x\n", abtAtqa[1], abtAtqa[0], abtSak);
00314
00315 nfc_disconnect (pnd);
00316 return 0;
00317 }