nfc.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 <string.h>
00033 
00034 #include <nfc/nfc.h>
00035 
00036 #include "chips.h"
00037 #include "drivers.h"
00038 
00039 #include <nfc/nfc-messages.h>
00040 
00041 nfc_device_desc_t * nfc_pick_device (void);
00042 
00043 // PN53X configuration
00044 extern const byte_t pncmd_get_firmware_version       [  2];
00045 extern const byte_t pncmd_get_general_status         [  2];
00046 extern const byte_t pncmd_get_register               [  4];
00047 extern const byte_t pncmd_set_register               [  5];
00048 extern const byte_t pncmd_set_parameters             [  3];
00049 extern const byte_t pncmd_rf_configure               [ 14];
00050 
00051 // Reader
00052 extern const byte_t pncmd_initiator_list_passive        [264];
00053 extern const byte_t pncmd_initiator_jump_for_dep        [ 68];
00054 extern const byte_t pncmd_initiator_select              [  3];
00055 extern const byte_t pncmd_initiator_deselect            [  3];
00056 extern const byte_t pncmd_initiator_release             [  3];
00057 extern const byte_t pncmd_initiator_set_baud_rate       [  5];
00058 extern const byte_t pncmd_initiator_exchange_data       [265];
00059 extern const byte_t pncmd_initiator_exchange_raw_data   [266];
00060 extern const byte_t pncmd_initiator_auto_poll           [  5];
00061 
00062 // Target
00063 extern const byte_t pncmd_target_get_data            [  2];
00064 extern const byte_t pncmd_target_set_data            [264];
00065 extern const byte_t pncmd_target_init                [ 39];
00066 extern const byte_t pncmd_target_virtual_card        [  4];
00067 extern const byte_t pncmd_target_receive             [  2];
00068 extern const byte_t pncmd_target_send                [264];
00069 extern const byte_t pncmd_target_get_status          [  2];
00070 
00071 nfc_device_desc_t *
00072 nfc_pick_device (void)
00073 {
00074   uint32_t uiDriver;
00075   nfc_device_desc_t *nddRes;
00076 
00077   for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
00078   {
00079     if (drivers_callbacks_list[uiDriver].pick_device != NULL)
00080     {
00081       nddRes = drivers_callbacks_list[uiDriver].pick_device ();
00082       if (nddRes != NULL) return nddRes;
00083     }
00084   }
00085 
00086   return NULL;
00087 }
00088 
00095 void
00096 nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
00097 {
00098   uint32_t uiDriver;
00099   size_t szN;
00100 
00101   *pszDeviceFound = 0;
00102 
00103   for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
00104   {
00105     if (drivers_callbacks_list[uiDriver].list_devices != NULL)
00106     {
00107       DBG("List avaible device using %s driver",drivers_callbacks_list[uiDriver].acDriver);
00108       szN = 0;
00109       if (drivers_callbacks_list[uiDriver].list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN))
00110       {
00111         *pszDeviceFound += szN;
00112       }
00113     }
00114     else
00115     {
00116       DBG("No listing function avaible for %s driver",drivers_callbacks_list[uiDriver].acDriver);
00117     }
00118   }
00119 }
00120 
00134 nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
00135 {
00136   nfc_device_t* pnd = NULL;
00137   uint32_t uiDriver;
00138   byte_t abtFw[4];
00139   size_t szFwLen = sizeof(abtFw);
00140 
00141   // Search through the device list for an available device
00142   for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
00143   {
00144     if(pndd == NULL) {
00145       // No device description specified: try to automatically claim a device
00146       if(drivers_callbacks_list[uiDriver].pick_device != NULL) {
00147         DBG("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver);
00148         pndd = drivers_callbacks_list[uiDriver].pick_device ();
00149 
00150         if(pndd != NULL) {
00151           DBG("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver); 
00152           pnd = drivers_callbacks_list[uiDriver].connect(pndd);
00153           if(pnd == NULL) {
00154             DBG("No device available using %s driver",drivers_callbacks_list[uiDriver].acDriver);
00155             pndd = NULL;
00156           }
00157 
00158           free(pndd);
00159         }
00160       }
00161     } else {
00162       // Specific device is requested: using device description pndd
00163       if( 0 != strcmp(drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver ) )
00164       {
00165         DBG("Looking for %s, found %s... Skip it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
00166         continue;
00167       } else {
00168         DBG("Looking for %s, found %s... Use it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
00169         pnd = drivers_callbacks_list[uiDriver].connect(pndd);
00170       }
00171     }
00172 
00173     // Test if the connection was successful
00174     if (pnd != NULL)
00175     {
00176       DBG("[%s] has been claimed.", pnd->acName);
00177       // Great we have claimed a device
00178       pnd->pdc = &(drivers_callbacks_list[uiDriver]);
00179 
00180       // Try to retrieve PN53x chip revision
00181       // We can not use pn53x_transceive() because abtRx[0] gives no status info
00182       if (!pnd->pdc->transceive(pnd->nds,pncmd_get_firmware_version,2,abtFw,&szFwLen))
00183       {
00184         // Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
00185         DBG("Failed to get firmware revision for: %s", pnd->acName);
00186         pnd->pdc->disconnect(pnd);
00187         return NULL;
00188       }
00189 
00190       // Add the firmware revision to the device name, PN531 gives 2 bytes info, but PN532 gives 4
00191       switch(pnd->nc)
00192       {
00193         case NC_PN531: sprintf(pnd->acName,"%s - PN531 v%d.%d",pnd->acName,abtFw[0],abtFw[1]); break;
00194         case NC_PN532: sprintf(pnd->acName,"%s - PN532 v%d.%d (0x%02x)",pnd->acName,abtFw[1],abtFw[2],abtFw[3]); break;
00195         case NC_PN533: sprintf(pnd->acName,"%s - PN533 v%d.%d (0x%02x)",pnd->acName,abtFw[1],abtFw[2],abtFw[3]); break;
00196       }
00197 
00198       // Reset the ending transmission bits register, it is unknown what the last tranmission used there
00199       if (!pn53x_set_reg(pnd,REG_CIU_BIT_FRAMING,SYMBOL_TX_LAST_BITS,0x00)) return NULL;
00200 
00201       // Make sure we reset the CRC and parity to chip handling.
00202       if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) return NULL;
00203       if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) return NULL;
00204 
00205       // Deactivate the CRYPTO1 chiper, it may could cause problems when still active
00206       if (!nfc_configure(pnd,NDO_ACTIVATE_CRYPTO1,false)) return NULL;
00207 
00208       return pnd;
00209     } else {
00210       DBG("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
00211     }
00212   }
00213   // Too bad, no reader is ready to be claimed
00214   return NULL;
00215 }
00216 
00223 void nfc_disconnect(nfc_device_t* pnd)
00224 {
00225   // Release and deselect all active communications
00226   nfc_initiator_deselect_tag(pnd);
00227   // Disable RF field to avoid heating
00228   nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
00229   // Disconnect, clean up and release the device 
00230   pnd->pdc->disconnect(pnd);
00231 }
00232 
00244 bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable)
00245 {
00246   byte_t btValue;
00247   byte_t abtCmd[sizeof(pncmd_rf_configure)];
00248   memcpy(abtCmd,pncmd_rf_configure,sizeof(pncmd_rf_configure));
00249 
00250   // Make sure we are dealing with a active device
00251   if (!pnd->bActive) return false;
00252 
00253   switch(ndo)
00254   {
00255     case NDO_HANDLE_CRC:
00256       // Enable or disable automatic receiving/sending of CRC bytes
00257       // TX and RX are both represented by the symbol 0x80
00258       btValue = (bEnable) ? 0x80 : 0x00;
00259       if (!pn53x_set_reg(pnd,REG_CIU_TX_MODE,SYMBOL_TX_CRC_ENABLE,btValue)) return false;
00260       if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_CRC_ENABLE,btValue)) return false;
00261       pnd->bCrc = bEnable;
00262     break;
00263 
00264     case NDO_HANDLE_PARITY:
00265       // Handle parity bit by PN53X chip or parse it as data bit
00266       btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE;
00267       if (!pn53x_set_reg(pnd,REG_CIU_MANUAL_RCV,SYMBOL_PARITY_DISABLE,btValue)) return false;
00268       pnd->bPar = bEnable;
00269     break;
00270 
00271     case NDO_ACTIVATE_FIELD:
00272       abtCmd[2] = RFCI_FIELD;
00273       abtCmd[3] = (bEnable) ? 1 : 0;
00274       // We can not use pn53x_transceive() because abtRx[0] gives no status info
00275       if (!pnd->pdc->transceive(pnd->nds,abtCmd,4,NULL,NULL)) return false;
00276     break;
00277 
00278     case NDO_ACTIVATE_CRYPTO1:
00279       btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
00280       if (!pn53x_set_reg(pnd,REG_CIU_STATUS2,SYMBOL_MF_CRYPTO1_ON,btValue)) return false;
00281     break;
00282 
00283     case NDO_INFINITE_SELECT:
00284       // Retry format: 0x00 means only 1 try, 0xff means infinite
00285       abtCmd[2] = RFCI_RETRY_SELECT;
00286       abtCmd[3] = (bEnable) ? 0xff : 0x00; // MxRtyATR, default: active = 0xff, passive = 0x02
00287       abtCmd[4] = (bEnable) ? 0xff : 0x00; // MxRtyPSL, default: 0x01
00288       abtCmd[5] = (bEnable) ? 0xff : 0x00; // MxRtyPassiveActivation, default: 0xff
00289       // We can not use pn53x_transceive() because abtRx[0] gives no status info
00290       if (!pnd->pdc->transceive(pnd->nds,abtCmd,6,NULL,NULL)) return false;
00291     break;
00292 
00293     case NDO_ACCEPT_INVALID_FRAMES:
00294       btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
00295       if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_NO_ERROR,btValue)) return false;
00296     break;
00297 
00298     case NDO_ACCEPT_MULTIPLE_FRAMES:
00299       btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
00300       if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_MULTIPLE,btValue)) return false;
00301     return true;
00302 
00303     break;
00304   }
00305 
00306   // When we reach this, the configuration is completed and succesful
00307   return true;
00308 }
00309 
00310 
00318 bool nfc_initiator_init(const nfc_device_t* pnd)
00319 {
00320   // Make sure we are dealing with a active device
00321   if (!pnd->bActive) return false;
00322 
00323   // Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
00324   if (!pn53x_set_reg(pnd,REG_CIU_TX_AUTO,SYMBOL_FORCE_100_ASK,0x40)) return false;
00325 
00326   // Configure the PN53X to be an Initiator or Reader/Writer
00327   if (!pn53x_set_reg(pnd,REG_CIU_CONTROL,SYMBOL_INITIATOR,0x10)) return false;
00328 
00329   return true;
00330 }
00331 
00344 bool nfc_initiator_select_dep_target(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pnti)
00345 {
00346   byte_t abtRx[MAX_FRAME_LEN];
00347   size_t szRxLen;
00348   size_t offset;
00349   byte_t abtCmd[sizeof(pncmd_initiator_jump_for_dep)];
00350   memcpy(abtCmd,pncmd_initiator_jump_for_dep,sizeof(pncmd_initiator_jump_for_dep));
00351 
00352   if(nmInitModulation == NM_ACTIVE_DEP) {
00353     abtCmd[2] = 0x01; /* active DEP */
00354   }
00355   abtCmd[3] = 0x00; /* baud rate = 106kbps */
00356 
00357   offset = 5;
00358   if(pbtPidData && nmInitModulation != NM_ACTIVE_DEP) { /* can't have passive initiator data when using active mode */
00359     abtCmd[4] |= 0x01;
00360     memcpy(abtCmd+offset,pbtPidData,szPidDataLen);
00361     offset+= szPidDataLen;
00362   }
00363 
00364   if(pbtNFCID3i) {
00365     abtCmd[4] |= 0x02;
00366     memcpy(abtCmd+offset,pbtNFCID3i,szNFCID3iDataLen);
00367     offset+= szNFCID3iDataLen;
00368   }
00369 
00370   if(pbtGbData) {
00371     abtCmd[4] |= 0x04;
00372     memcpy(abtCmd+offset,pbtGbData,szGbDataLen);
00373     offset+= szGbDataLen;
00374   }
00375 
00376   // Try to find a target, call the transceive callback function of the current device
00377   if (!pn53x_transceive(pnd,abtCmd,5+szPidDataLen+szNFCID3iDataLen+szGbDataLen,abtRx,&szRxLen)) return false;
00378 
00379   // Make sure one target has been found, the PN53X returns 0x00 if none was available
00380   if (abtRx[1] != 1) return false;
00381 
00382   // Is a target info struct available
00383   if (pnti)
00384   {
00385     memcpy(pnti->ndi.NFCID3i,abtRx+2,10);
00386     pnti->ndi.btDID = abtRx[12];
00387     pnti->ndi.btBSt = abtRx[13];
00388     pnti->ndi.btBRt = abtRx[14];
00389   }
00390   return true;
00391 }
00392 
00405 bool nfc_initiator_select_tag(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtInitData, const size_t szInitDataLen, nfc_target_info_t* pnti)
00406 {
00407   byte_t abtInit[MAX_FRAME_LEN];
00408   size_t szInitLen;
00409   byte_t abtRx[MAX_FRAME_LEN];
00410   size_t szRxLen;
00411   byte_t abtCmd[sizeof(pncmd_initiator_list_passive)];
00412   memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive));
00413 
00414   // Make sure we are dealing with a active device
00415   if (!pnd->bActive) return false;
00416 
00417   abtCmd[2] = 1;  // MaxTg, we only want to select 1 tag at the time
00418   abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
00419 
00420   switch(nmInitModulation)
00421   {
00422     case NM_ISO14443A_106:
00423       switch (szInitDataLen)
00424       {
00425         case 7:
00426           abtInit[0] = 0x88;
00427           memcpy(abtInit+1,pbtInitData,7);
00428           szInitLen = 8;
00429         break;
00430 
00431         case 10:
00432           abtInit[0] = 0x88;
00433           memcpy(abtInit+1,pbtInitData,3);
00434           abtInit[4] = 0x88;
00435           memcpy(abtInit+5,pbtInitData+3,7);
00436           szInitLen = 12;
00437         break;
00438 
00439         case 4:
00440         default:
00441           memcpy(abtInit,pbtInitData,szInitDataLen);
00442           szInitLen = szInitDataLen;
00443         break;
00444       }
00445     break;
00446 
00447     default:
00448       memcpy(abtInit,pbtInitData,szInitDataLen);
00449       szInitLen = szInitDataLen;
00450     break;
00451   }
00452 
00453   // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
00454   if (pbtInitData) memcpy(abtCmd+4,abtInit,szInitLen);
00455 
00456   // Try to find a tag, call the tranceive callback function of the current device
00457   szRxLen = MAX_FRAME_LEN;
00458   // We can not use pn53x_transceive() because abtRx[0] gives no status info
00459   if (!pnd->pdc->transceive(pnd->nds,abtCmd,4+szInitLen,abtRx,&szRxLen)) return false;
00460 
00461   // Make sure one tag has been found, the PN53X returns 0x00 if none was available
00462   if (abtRx[0] != 1) return false;
00463 
00464   // Is a tag info struct available
00465   if (pnti)
00466   {
00467     // Fill the tag info struct with the values corresponding to this init modulation
00468     switch(nmInitModulation)
00469     {
00470       case NM_ISO14443A_106:
00471         // Somehow they switched the lower and upper ATQA bytes around for the PN531 chipset
00472         if (pnd->nc == NC_PN531)
00473         {
00474           pnti->nai.abtAtqa[0] = abtRx[3];
00475           pnti->nai.abtAtqa[1] = abtRx[2];
00476         } else {
00477           memcpy(pnti->nai.abtAtqa,abtRx+2,2);
00478         }
00479         pnti->nai.btSak = abtRx[4];
00480         // Copy the NFCID1
00481         pnti->nai.szUidLen = abtRx[5];
00482         memcpy(pnti->nai.abtUid,abtRx+6,pnti->nai.szUidLen);
00483         // Did we received an optional ATS (Smardcard ATR)
00484         if (szRxLen > pnti->nai.szUidLen+6)
00485         {
00486           pnti->nai.szAtsLen = abtRx[pnti->nai.szUidLen+6];
00487           memcpy(pnti->nai.abtAts,abtRx+pnti->nai.szUidLen+6,pnti->nai.szAtsLen);
00488         } else {
00489           pnti->nai.szAtsLen = 0;
00490         }
00491 
00492   // Strip CT (Cascade Tag) to retrieve and store the _real_ UID
00493   // (e.g. 0x8801020304050607 is in fact 0x01020304050607)
00494   if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) {
00495       pnti->nai.szUidLen = 7;
00496       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 7);
00497   } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) {
00498       pnti->nai.szUidLen = 10;
00499       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3);
00500       memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7);
00501   }
00502       break;
00503 
00504       case NM_FELICA_212:
00505       case NM_FELICA_424:
00506         // Store the mandatory info
00507         pnti->nfi.szLen = abtRx[2];
00508         pnti->nfi.btResCode = abtRx[3];
00509         // Copy the NFCID2t
00510         memcpy(pnti->nfi.abtId,abtRx+4,8);
00511         // Copy the felica padding
00512         memcpy(pnti->nfi.abtPad,abtRx+12,8);
00513         // Test if the System code (SYST_CODE) is available
00514         if (szRxLen > 20)
00515         {
00516           memcpy(pnti->nfi.abtSysCode,abtRx+20,2);  
00517         }
00518       break;
00519 
00520       case NM_ISO14443B_106:
00521         // Store the mandatory info
00522         memcpy(pnti->nbi.abtAtqb,abtRx+2,12);
00523         // Ignore the 0x1D byte, and just store the 4 byte id
00524         memcpy(pnti->nbi.abtId,abtRx+15,4);
00525         pnti->nbi.btParam1 = abtRx[19];
00526         pnti->nbi.btParam2 = abtRx[20];
00527         pnti->nbi.btParam3 = abtRx[21];
00528         pnti->nbi.btParam4 = abtRx[22];
00529         // Test if the Higher layer (INF) is available
00530         if (szRxLen > 22)
00531         {
00532           pnti->nbi.szInfLen = abtRx[23];
00533           memcpy(pnti->nbi.abtInf,abtRx+24,pnti->nbi.szInfLen);
00534         } else {
00535           pnti->nbi.szInfLen = 0;
00536         }
00537       break;
00538 
00539       case NM_JEWEL_106:
00540         // Store the mandatory info
00541         memcpy(pnti->nji.btSensRes,abtRx+2,2);
00542         memcpy(pnti->nji.btId,abtRx+4,4);
00543       break;
00544 
00545       default:
00546         // Should not be possible, so whatever...
00547       break;
00548     }
00549   }
00550   return true;
00551 }
00552 
00561 bool nfc_initiator_deselect_tag(const nfc_device_t* pnd)
00562 {
00563   return (pn53x_transceive(pnd,pncmd_initiator_deselect,3,NULL,NULL));
00564 }
00565 
00579 bool nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
00580 {
00581   byte_t abtRx[MAX_FRAME_LEN];
00582   size_t szRxLen;
00583   size_t szFrameBits = 0;
00584   size_t szFrameBytes = 0;
00585   uint8_t ui8Bits = 0;
00586   byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
00587   memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
00588 
00589   // Check if we should prepare the parity bits ourself
00590   if (!pnd->bPar)
00591   {
00592     // Convert data with parity to a frame
00593     pn53x_wrap_frame(pbtTx,szTxBits,pbtTxPar,abtCmd+2,&szFrameBits);
00594   } else {
00595     szFrameBits = szTxBits;
00596   }
00597 
00598   // Retrieve the leading bits
00599   ui8Bits = szFrameBits%8;
00600 
00601   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
00602   szFrameBytes = (szFrameBits/8)+((ui8Bits==0)?0:1);
00603 
00604   // When the parity is handled before us, we just copy the data
00605   if (pnd->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
00606 
00607   // Set the amount of transmission bits in the PN53X chip register
00608   if (!pn53x_set_tx_bits(pnd,ui8Bits)) return false;
00609 
00610   // Send the frame to the PN53X chip and get the answer
00611   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
00612   if (!pn53x_transceive(pnd,abtCmd,szFrameBytes+2,abtRx,&szRxLen)) return false;
00613 
00614   // Get the last bit-count that is stored in the received byte 
00615   ui8Bits = pn53x_get_reg(pnd,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
00616 
00617   // Recover the real frame length in bits
00618   szFrameBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
00619 
00620   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
00621   // Check if we should recover the parity bits ourself
00622   if (!pnd->bPar)
00623   {
00624     // Unwrap the response frame
00625     pn53x_unwrap_frame(abtRx+1,szFrameBits,pbtRx,pszRxBits,pbtRxPar);
00626   } else {
00627     // Save the received bits
00628     *pszRxBits = szFrameBits;
00629     // Copy the received bytes
00630     memcpy(pbtRx,abtRx+1,szRxLen-1);
00631   }
00632 
00633   // Everything went successful
00634   return true;
00635 }
00636 
00643 bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
00644 {
00645   byte_t abtRx[MAX_FRAME_LEN];
00646   size_t szRxLen;
00647   byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
00648   memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
00649 
00650   // We can not just send bytes without parity if while the PN53X expects we handled them
00651   if (!pnd->bPar) return false;
00652 
00653   // Copy the data into the command frame
00654   abtCmd[2] = 1; /* target number */
00655   memcpy(abtCmd+3,pbtTx,szTxLen);
00656 
00657   // To transfer command frames bytes we can not have any leading bits, reset this to zero
00658   if (!pn53x_set_tx_bits(pnd,0)) return false;
00659 
00660   // Send the frame to the PN53X chip and get the answer
00661   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
00662   if (!pn53x_transceive(pnd,abtCmd,szTxLen+3,abtRx,&szRxLen)) return false;
00663 
00664   // Save the received byte count
00665   *pszRxLen = szRxLen-1;
00666 
00667   // Copy the received bytes
00668   memcpy(pbtRx,abtRx+1,*pszRxLen);
00669 
00670   // Everything went successful
00671   return true;
00672 }
00673 
00681 bool nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
00682 {
00683   byte_t abtRx[MAX_FRAME_LEN];
00684   size_t szRxLen;
00685   byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
00686   memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
00687 
00688   // We can not just send bytes without parity if while the PN53X expects we handled them
00689   if (!pnd->bPar) return false;
00690 
00691   // Copy the data into the command frame
00692   memcpy(abtCmd+2,pbtTx,szTxLen);
00693 
00694   // To transfer command frames bytes we can not have any leading bits, reset this to zero
00695   if (!pn53x_set_tx_bits(pnd,0)) return false;
00696 
00697   // Send the frame to the PN53X chip and get the answer
00698   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
00699   if (!pn53x_transceive(pnd,abtCmd,szTxLen+2,abtRx,&szRxLen)) return false;
00700 
00701   // Save the received byte count
00702   *pszRxLen = szRxLen-1;
00703 
00704   // Copy the received bytes
00705   memcpy(pbtRx,abtRx+1,*pszRxLen);
00706 
00707   // Everything went successful
00708   return true;
00709 }
00710 
00721 bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
00722 {
00723   byte_t abtRx[MAX_FRAME_LEN];
00724   size_t szRxLen;
00725   size_t szParamLen;
00726   byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
00727   memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
00728 
00729   // Make sure we are dealing with a active device
00730   if (!pnd->bActive) return false;
00731 
00732   abtCmd[2] = 0x01;     // Use first target/card
00733   abtCmd[3] = mc;       // The MIFARE Classic command
00734   abtCmd[4] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
00735 
00736   switch (mc)
00737   {
00738     // Read and store command have no parameter
00739     case MC_READ:
00740     case MC_STORE:
00741       szParamLen = 0;
00742     break;
00743 
00744     // Authenticate command
00745     case MC_AUTH_A:
00746     case MC_AUTH_B:
00747       szParamLen = sizeof(mifare_param_auth);
00748     break;
00749 
00750     // Data command
00751     case MC_WRITE:
00752       szParamLen = sizeof(mifare_param_data);
00753     break;
00754 
00755     // Value command
00756     case MC_DECREMENT:
00757     case MC_INCREMENT:
00758     case MC_TRANSFER:
00759       szParamLen = sizeof(mifare_param_value);
00760     break;
00761 
00762     // Please fix your code, you never should reach this statement
00763     default:
00764       return false;
00765     break;
00766   }
00767 
00768   // When available, copy the parameter bytes
00769   if (szParamLen) memcpy(abtCmd+5,(byte_t*)pmp,szParamLen);
00770 
00771   // Fire the mifare command
00772   if (!pn53x_transceive(pnd,abtCmd,5+szParamLen,abtRx,&szRxLen)) return false;
00773 
00774   // When we have executed a read command, copy the received bytes into the param
00775   if (mc == MC_READ && szRxLen == 17) memcpy(pmp->mpd.abtData,abtRx+1,16);
00776 
00777   // Command succesfully executed
00778   return true;
00779 }
00780 
00789 bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
00790 {
00791   byte_t abtRx[MAX_FRAME_LEN];
00792   size_t szRxLen;
00793   uint8_t ui8Bits;
00794   // Save the current configuration settings
00795   bool bCrc = pnd->bCrc;
00796   bool bPar = pnd->bPar;
00797   byte_t abtCmd[sizeof(pncmd_target_init)];
00798   memcpy(abtCmd,pncmd_target_init,sizeof(pncmd_target_init));
00799 
00800   // Clear the target init struct, reset to all zeros
00801   memset(abtCmd+2,0x00,37);
00802 
00803   // Set ATQA (SENS_RES)
00804   abtCmd[3] = 0x04;
00805   abtCmd[4] = 0x00;
00806 
00807   // Set SAK (SEL_RES)
00808   abtCmd[8] = 0x20;
00809 
00810   // Set UID
00811   abtCmd[5] = 0x00;
00812   abtCmd[6] = 0xb0;
00813   abtCmd[7] = 0x0b;
00814 
00815   // Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
00816   if (!bCrc) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_CRC,true);
00817   if (!bPar) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_PARITY,true);
00818 
00819   // Let the PN53X be activated by the RF level detector from power down mode
00820   if (!pn53x_set_reg(pnd,REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON,0x04)) return false;
00821 
00822   // Request the initialization as a target, we can not use pn53x_transceive() because
00823   // abtRx[0] contains the emulation mode (baudrate, 14443-4?, DEP and framing type)
00824   szRxLen = MAX_FRAME_LEN;
00825   if (!pnd->pdc->transceive(pnd->nds,abtCmd,39,abtRx,&szRxLen)) return false;
00826 
00827   // Get the last bit-count that is stored in the received byte 
00828   ui8Bits = pn53x_get_reg(pnd,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
00829 
00830   // We are sure the parity is handled by the PN53X chip, so we handle it this way
00831   *pszRxBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
00832   // Copy the received bytes
00833   memcpy(pbtRx,abtRx+1,szRxLen-1);
00834 
00835   // Restore the CRC & parity setting to the original value (if needed)
00836   if (!bCrc) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_CRC,false);
00837   if (!bPar) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_PARITY,false);
00838 
00839   return true;
00840 }
00841 
00848 bool nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
00849 {
00850   byte_t abtRx[MAX_FRAME_LEN];
00851   size_t szRxLen;
00852   size_t szFrameBits;
00853   uint8_t ui8Bits;
00854 
00855   // Try to gather a received frame from the reader
00856   if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
00857 
00858   // Get the last bit-count that is stored in the received byte 
00859   ui8Bits = pn53x_get_reg(pnd,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
00860 
00861   // Recover the real frame length in bits
00862   szFrameBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
00863 
00864   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
00865   // Check if we should recover the parity bits ourself
00866   if (!pnd->bPar)
00867   {
00868     // Unwrap the response frame
00869     pn53x_unwrap_frame(abtRx+1,szFrameBits,pbtRx,pszRxBits,pbtRxPar);
00870   } else {
00871     // Save the received bits
00872     *pszRxBits = szFrameBits;
00873     // Copy the received bytes
00874     memcpy(pbtRx,abtRx+1,szRxLen-1);
00875   }
00876   // Everyting seems ok, return true
00877   return true;
00878 }
00879 
00886 bool nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
00887 {
00888   byte_t abtRx[MAX_FRAME_LEN];
00889   size_t szRxLen;
00890 
00891   // Try to gather a received frame from the reader
00892   if (!pn53x_transceive(pnd,pncmd_target_get_data,2,abtRx,&szRxLen)) return false;
00893 
00894   // Save the received byte count
00895   *pszRxLen = szRxLen-1;
00896 
00897   // Copy the received bytes
00898   memcpy(pbtRx,abtRx+1,*pszRxLen);
00899 
00900   // Everyting seems ok, return true
00901   return true;
00902 }
00903 
00910 bool nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
00911 {
00912   byte_t abtRx[MAX_FRAME_LEN];
00913   size_t szRxLen;
00914 
00915   // Try to gather a received frame from the reader
00916   if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
00917 
00918   // Save the received byte count
00919   *pszRxLen = szRxLen-1;
00920 
00921   // Copy the received bytes
00922   memcpy(pbtRx,abtRx+1,*pszRxLen);
00923 
00924   // Everyting seems ok, return true
00925   return true;
00926 }
00927 
00934 bool nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
00935 {
00936   size_t szFrameBits = 0;
00937   size_t szFrameBytes = 0;
00938   uint8_t ui8Bits = 0;
00939   byte_t abtCmd[sizeof(pncmd_target_send)];
00940   memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
00941 
00942   // Check if we should prepare the parity bits ourself
00943   if (!pnd->bPar)
00944   {
00945     // Convert data with parity to a frame
00946     pn53x_wrap_frame(pbtTx,szTxBits,pbtTxPar,abtCmd+2,&szFrameBits);
00947   } else {
00948     szFrameBits = szTxBits;
00949   }
00950 
00951   // Retrieve the leading bits
00952   ui8Bits = szFrameBits%8;
00953 
00954   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
00955   szFrameBytes = (szFrameBits/8)+((ui8Bits==0)?0:1);
00956 
00957   // When the parity is handled before us, we just copy the data
00958   if (pnd->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
00959 
00960   // Set the amount of transmission bits in the PN53X chip register
00961   if (!pn53x_set_tx_bits(pnd,ui8Bits)) return false;
00962 
00963   // Try to send the bits to the reader
00964   if (!pn53x_transceive(pnd,abtCmd,szFrameBytes+2,NULL,NULL)) return false;
00965 
00966   // Everyting seems ok, return true
00967   return true;
00968 }
00969 
00970 
00977 bool nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
00978 {
00979   byte_t abtCmd[sizeof(pncmd_target_send)];
00980   memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
00981 
00982   // We can not just send bytes without parity if while the PN53X expects we handled them
00983   if (!pnd->bPar) return false;
00984 
00985   // Copy the data into the command frame
00986   memcpy(abtCmd+2,pbtTx,szTxLen);
00987 
00988   // Try to send the bits to the reader
00989   if (!pn53x_transceive(pnd,abtCmd,szTxLen+2,NULL,NULL)) return false;
00990 
00991   // Everyting seems ok, return true
00992   return true;
00993 }
00994 
01001 bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
01002 {
01003   byte_t abtCmd[sizeof(pncmd_target_set_data)];
01004   memcpy(abtCmd,pncmd_target_set_data,sizeof(pncmd_target_set_data));
01005 
01006   // We can not just send bytes without parity if while the PN53X expects we handled them
01007   if (!pnd->bPar) return false;
01008 
01009   // Copy the data into the command frame
01010   memcpy(abtCmd+2,pbtTx,szTxLen);
01011 
01012   // Try to send the bits to the reader
01013   if (!pn53x_transceive(pnd,abtCmd,szTxLen+2,NULL,NULL)) return false;
01014 
01015   // Everyting seems ok, return true
01016   return true;
01017 }
01018 
01019 /* Special data accessors */
01020 
01025 const char* nfc_device_name(nfc_device_t* pnd)
01026 {
01027   return pnd->acName;
01028 }
01029 
01030 /* Misc. functions */
01031 
01036 const char* nfc_version(void)
01037 {
01038   #ifdef SVN_REVISION
01039   return PACKAGE_VERSION" (r"SVN_REVISION")";
01040   #else
01041   return PACKAGE_VERSION;
01042   #endif // SVN_REVISION
01043 }
01044 

Generated on 8 May 2010 for libnfc by  doxygen 1.6.1