nfc-utils.c

00001 #include <nfc/nfc.h>
00002 
00003 #include "nfc-utils.h"
00004 
00005 static const byte_t OddParity[256] = {
00006   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00007   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00008   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00009   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00010   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00011   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00012   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00013   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00014   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00015   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00016   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00017   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00018   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00019   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00020   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00021   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
00022 };
00023 
00024 byte_t
00025 oddparity (const byte_t bt)
00026 {
00027   return OddParity[bt];
00028 }
00029 
00030 void
00031 oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
00032 {
00033   size_t  szByteNr;
00034   // Calculate the parity bits for the command
00035   for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
00036     pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
00037   }
00038 }
00039 
00040 void
00041 print_hex (const byte_t * pbtData, const size_t szBytes)
00042 {
00043   size_t  szPos;
00044 
00045   for (szPos = 0; szPos < szBytes; szPos++) {
00046     printf ("%02x  ", pbtData[szPos]);
00047   }
00048   printf ("\n");
00049 }
00050 
00051 void
00052 print_hex_bits (const byte_t * pbtData, const size_t szBits)
00053 {
00054   uint8_t uRemainder;
00055   size_t  szPos;
00056   size_t  szBytes = szBits / 8;
00057 
00058   for (szPos = 0; szPos < szBytes; szPos++) {
00059     printf ("%02x  ", pbtData[szPos]);
00060   }
00061 
00062   uRemainder = szBits % 8;
00063   // Print the rest bits
00064   if (uRemainder != 0) {
00065     if (uRemainder < 5)
00066       printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
00067     else
00068       printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
00069   }
00070   printf ("\n");
00071 }
00072 
00073 void
00074 print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar)
00075 {
00076   uint8_t uRemainder;
00077   size_t  szPos;
00078   size_t  szBytes = szBits / 8;
00079 
00080   for (szPos = 0; szPos < szBytes; szPos++) {
00081     printf ("%02x", pbtData[szPos]);
00082     if (OddParity[pbtData[szPos]] != pbtDataPar[szPos]) {
00083       printf ("! ");
00084     } else {
00085       printf ("  ");
00086     }
00087   }
00088 
00089   uRemainder = szBits % 8;
00090   // Print the rest bits, these cannot have parity bit
00091   if (uRemainder != 0) {
00092     if (uRemainder < 5)
00093       printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
00094     else
00095       printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
00096   }
00097   printf ("\n");
00098 }
00099 
00100 #define SAK_ISO14443_4_COMPLIANT 0x20
00101 #define SAK_ISO18092_COMPLIANT   0x40
00102 
00103 void
00104 print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai)
00105 {
00106   printf ("    ATQA (SENS_RES): ");
00107   print_hex (nai.abtAtqa, 2);
00108   printf ("       UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
00109   print_hex (nai.abtUid, nai.szUidLen);
00110   printf ("      SAK (SEL_RES): ");
00111   print_hex (&nai.btSak, 1);
00112   if (nai.szAtsLen) {
00113     printf ("          ATS (ATR): ");
00114     print_hex (nai.abtAts, nai.szAtsLen);
00115   }
00116   if ((nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT)) {
00117     printf ("     Compliant with: ");
00118     if (nai.btSak & SAK_ISO14443_4_COMPLIANT)
00119       printf ("ISO/IEC 14443-4 ");
00120     if (nai.btSak & SAK_ISO18092_COMPLIANT)
00121       printf ("ISO/IEC 18092");
00122     printf ("\n");
00123   }
00124 }
00125 
00126 void
00127 print_nfc_felica_info (const nfc_felica_info_t nfi)
00128 {
00129   printf ("        ID (NFCID2): ");
00130   print_hex (nfi.abtId, 8);
00131   printf ("    Parameter (PAD): ");
00132   print_hex (nfi.abtPad, 8);
00133 }
00134 
00135 void
00136 print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi)
00137 {
00138   printf ("               ATQB: ");
00139   print_hex (nbi.abtAtqb, 12);
00140   printf ("                 ID: ");
00141   print_hex (nbi.abtId, 4);
00142   printf ("                CID: %02x\n", nbi.btCid);
00143   if (nbi.szInfLen > 0) {
00144     printf ("                INF: ");
00145     print_hex (nbi.abtInf, nbi.szInfLen);
00146   }
00147   printf ("             PARAMS: %02x %02x %02x %02x\n", nbi.btParam1, nbi.btParam2, nbi.btParam3, nbi.btParam4);
00148 }
00149 
00154 nfc_device_desc_t *
00155 parse_device_desc (int argc, const char *argv[], size_t * szFound)
00156 {
00157   nfc_device_desc_t *pndd = 0;
00158   int     arg;
00159   *szFound = 0;
00160 
00161   // Get commandline options
00162   for (arg = 1; arg < argc; arg++) {
00163 
00164     if (0 == strcmp (argv[arg], "--device")) {
00165 
00166       if (argc > arg + 1) {
00167         char    buffer[256];
00168 
00169         pndd = malloc (sizeof (nfc_device_desc_t));
00170 
00171         strncpy (buffer, argv[++arg], 256);
00172 
00173         // Driver.
00174         pndd->pcDriver = (char *) malloc (256);
00175         strcpy (pndd->pcDriver, strtok (buffer, ":"));
00176 
00177         // Port.
00178         pndd->pcPort = (char *) malloc (256);
00179         strcpy (pndd->pcPort, strtok (NULL, ":"));
00180 
00181         // Speed.
00182         sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
00183 
00184         *szFound = 1;
00185       }
00186       break;
00187     }
00188   }
00189 
00190   return pndd;
00191 }