pn53x.c

00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library
00003  * 
00004  * Copyright (C) 2009, Roel Verdult, Romuald Conty
00005  * Copyright (C) 2010, Roel Verdult, Romuald Conty, Romain Tartière
00006  * 
00007  * This program is free software: you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation, either version 3 of the License, or (at your
00010  * option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00015  * more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00019  */
00020 
00026 #ifdef HAVE_CONFIG_H
00027 #  include "config.h"
00028 #endif // HAVE_CONFIG_H
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <stdlib.h>
00034 
00035 #include <nfc/nfc.h>
00036 #include <nfc/nfc-messages.h>
00037 
00038 #include "pn53x.h"
00039 #include "../mirror-subr.h"
00040 
00041 #ifdef _WIN32
00042 #  include "../../contrib/windows.h"
00043 #endif
00044 
00045 #include <sys/param.h>
00046 
00047 // PN53X configuration
00048 const byte_t pncmd_get_firmware_version[2] = { 0xD4, 0x02 };
00049 const byte_t pncmd_get_general_status[2] = { 0xD4, 0x04 };
00050 const byte_t pncmd_get_register[4] = { 0xD4, 0x06 };
00051 const byte_t pncmd_set_register[5] = { 0xD4, 0x08 };
00052 const byte_t pncmd_set_parameters[3] = { 0xD4, 0x12 };
00053 const byte_t pncmd_rf_configure[14] = { 0xD4, 0x32 };
00054 
00055 // Reader
00056 const byte_t pncmd_initiator_list_passive[264] = { 0xD4, 0x4A };
00057 const byte_t pncmd_initiator_jump_for_dep[68] = { 0xD4, 0x56 };
00058 const byte_t pncmd_initiator_select[3] = { 0xD4, 0x54 };
00059 const byte_t pncmd_initiator_deselect[3] = { 0xD4, 0x44, 0x00 };
00060 const byte_t pncmd_initiator_release[3] = { 0xD4, 0x52, 0x00 };
00061 const byte_t pncmd_initiator_set_baud_rate[5] = { 0xD4, 0x4E };
00062 const byte_t pncmd_initiator_exchange_data[265] = { 0xD4, 0x40 };
00063 const byte_t pncmd_initiator_exchange_raw_data[266] = { 0xD4, 0x42 };
00064 const byte_t pncmd_initiator_auto_poll[5] = { 0xD4, 0x60 };
00065 
00066 // Target
00067 const byte_t pncmd_target_get_data[2] = { 0xD4, 0x86 };
00068 const byte_t pncmd_target_set_data[264] = { 0xD4, 0x8E };
00069 const byte_t pncmd_target_init[2] = { 0xD4, 0x8C };
00070 //Example of default values for PN532 or PN533:
00071 //const byte_t pncmd_target_init[39] = { 0xD4, 0x8C, 0x00, 0x08, 0x00, 0x12, 0x34, 0x56, 0x40, 0x01, 0xFE, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xFF, 0xFF, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00 };
00072 const byte_t pncmd_target_virtual_card[4] = { 0xD4, 0x14 };
00073 const byte_t pncmd_target_get_initiator_command[2] = { 0xD4, 0x88 };
00074 const byte_t pncmd_target_response_to_initiator[264] = { 0xD4, 0x90 };
00075 const byte_t pncmd_target_get_status[2] = { 0xD4, 0x8A };
00076 
00077 static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
00078 static const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
00079 static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
00080 
00081 /* prototypes */
00082 const nfc_modulation_t pn53x_ptt_to_nm( const pn53x_target_type_t ptt );
00083 const pn53x_modulation_t pn53x_nm_to_pm(const nfc_modulation_t nm);
00084 const pn53x_target_type_t pn53x_nm_to_ptt(const nfc_modulation_t nm);
00085 
00086 bool
00087 pn53x_init(nfc_device_t * pnd)
00088 {
00089   // CRC handling is enabled by default
00090   pnd->bCrc = true;
00091   // Parity handling is enabled by default
00092   pnd->bPar = true;
00093 
00094   // Reset the ending transmission bits register, it is unknown what the last tranmission used there
00095   pnd->ui8TxBits = 0;
00096   if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, 0x00)) {
00097     return false;
00098   }
00099 
00100   // We can't read these parameters, so we set a default config by using the SetParameters wrapper
00101   // Note: pn53x_SetParameters() will save the sent value in pnd->ui8Parameters cache
00102   if(!pn53x_SetParameters(pnd, PARAM_AUTO_ATR_RES | PARAM_AUTO_RATS)) {
00103     return false;
00104   }
00105 
00106   char abtFirmwareText[18];
00107   if (!pn53x_get_firmware_version (pnd, abtFirmwareText)) {
00108     return false;
00109   }
00110 
00111   // Add the firmware revision to the device name
00112   char   *pcName;
00113   pcName = strdup (pnd->acName);
00114   snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - %s", pcName, abtFirmwareText);
00115   free (pcName);
00116   return true;
00117 }
00118 
00119 bool
00120 pn53x_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
00121 {
00122   if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
00123     if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
00124       // DBG ("%s", "PN53x ACKed");
00125       return true;
00126     } else if (0 == memcmp (pbtRxFrame, pn53x_nack_frame, sizeof (pn53x_nack_frame))) {
00127       DBG ("%s", "PN53x NACKed");
00128       // TODO Try to recover when PN53x NACKs !
00129       // A counter could allow the command to be sent again (e.g. max 3 times)
00130       pnd->iLastError = DENACK;
00131       return false;
00132     }
00133   }
00134   pnd->iLastError = DEACKMISMATCH;
00135   ERR ("%s", "Unexpected PN53x reply!");
00136 #if defined(DEBUG)
00137   // coredump so that we can have a backtrace about how this code was reached.
00138   abort ();
00139 #endif
00140   return false;
00141 }
00142 
00143 bool
00144 pn53x_check_error_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
00145 {
00146   if (szRxFrameLen >= sizeof (pn53x_error_frame)) {
00147     if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) {
00148       DBG ("%s", "PN53x sent an error frame");
00149       pnd->iLastError = DEISERRFRAME;
00150       return false;
00151     }
00152   }
00153 
00154   return true;
00155 }
00156 
00157 #define PN53x_REPLY_FRAME_MAX_LEN (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD + sizeof(pn53x_ack_frame))
00158 bool
00159 pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx)
00160 {
00161   byte_t  abtRx[PN53x_REPLY_FRAME_MAX_LEN];
00162   size_t  szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
00163 
00164   // Check if receiving buffers are available, if not, replace them
00165   if (!pszRx || !pbtRx) {
00166     pbtRx = abtRx;
00167     pszRx = &szRx;
00168   }
00169 
00170 #if defined(DEBUG)
00171   if(*pszRx > PN53x_EXTENDED_FRAME_MAX_LEN) {
00172     DBG( "Expected reply bytes count (*pszRx=%zu) is greater than MAX (PN53x_EXTENDED_FRAME_MAX_LEN=%d)", *pszRx, PN53x_EXTENDED_FRAME_MAX_LEN );
00173     *pszRx=MIN(*pszRx, PN53x_EXTENDED_FRAME_MAX_LEN);
00174 //    abort();
00175   }
00176 #endif
00177 
00178   *pszRx += sizeof(pn53x_ack_frame) + PN53x_EXTENDED_FRAME_OVERHEAD;
00179 
00180   // Call the transceive callback function of the current device
00181   if (!pnd->pdc->transceive (pnd, pbtTx, szTx, pbtRx, pszRx))
00182     return false;
00183   // TODO Put all these hex-coded command behind a human-readable #define (1.6.x)
00184   // Should be proceed while we will fix Issue 110 (Rework the way that pn53x commands are built)
00185   switch (pbtTx[1]) {
00186     case 0x16:                   // PowerDown
00187     case 0x40:                   // InDataExchange
00188     case 0x42:                   // InCommunicateThru
00189     case 0x44:                   // InDeselect
00190     case 0x46:                   // InJumpForPSL
00191     case 0x4e:                   // InPSL
00192     case 0x50:                   // InATR
00193     case 0x52:                   // InRelease
00194     case 0x54:                   // InSelect
00195     case 0x56:                   // InJumpForDEP
00196     case 0x86:                   // TgGetData
00197     case 0x88:                   // TgGetInitiatorCommand
00198     case 0x8e:                   // TgSetData
00199     case 0x90:                   // TgResponseToInitiator
00200     case 0x92:                   // TgSetGeneralBytes
00201     case 0x94:                   // TgSetMetaData
00202     pnd->iLastError = pbtRx[0] & 0x3f;
00203     break;
00204   default:
00205     pnd->iLastError = 0;
00206   }
00207   if (pnd->nc == NC_PN533) {
00208     if ((pbtTx[1] == 0x06) // ReadRegister
00209       || (pbtTx[1] == 0x08)) { // WriteRegister
00210       // PN533 prepends its answer by a status byte
00211       pnd->iLastError = pbtRx[0] & 0x3f;
00212     }
00213   }
00214   return (0 == pnd->iLastError);
00215 }
00216 
00217 bool
00218 pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value)
00219 {
00220   byte_t  abtCmd[sizeof (pncmd_get_register)];
00221   memcpy (abtCmd, pncmd_get_register, sizeof (pncmd_get_register));
00222 
00223   abtCmd[2] = ui16Reg >> 8;
00224   abtCmd[3] = ui16Reg & 0xff;
00225 
00226   byte_t  abtRegValue[2];
00227   size_t  szValueLen = 3 + PN53x_NORMAL_FRAME_OVERHEAD;
00228   if (pn53x_transceive (pnd, abtCmd, sizeof (pncmd_get_register), abtRegValue, &szValueLen)) {
00229     if (pnd->nc == NC_PN533) {
00230       // PN533 prepends its answer by a status byte
00231       if (abtRegValue[0] == 0) { // 0x00 
00232         *ui8Value = abtRegValue[1];
00233       } else {
00234         return false;
00235       }
00236     } else {
00237       *ui8Value = abtRegValue[0];
00238     }
00239     return true;
00240   }
00241   return false;
00242 }
00243 
00244 bool
00245 pn53x_set_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SymbolMask, uint8_t ui8Value)
00246 {
00247   uint8_t ui8Current;
00248   byte_t  abtCmd[sizeof (pncmd_set_register)];
00249   memcpy (abtCmd, pncmd_set_register, sizeof (pncmd_set_register));
00250 
00251   abtCmd[2] = ui16Reg >> 8;
00252   abtCmd[3] = ui16Reg & 0xff;
00253   if (ui8SymbolMask != 0xff) {
00254     if (!pn53x_get_reg (pnd, ui16Reg, &ui8Current))
00255       return false;
00256     abtCmd[4] = ui8Value | (ui8Current & (~ui8SymbolMask));
00257     return (abtCmd[4] != ui8Current) ? pn53x_transceive (pnd, abtCmd, sizeof (pncmd_set_register), NULL, NULL) : true;
00258   } else {
00259     abtCmd[4] = ui8Value;
00260     return pn53x_transceive (pnd, abtCmd, sizeof (pncmd_set_register), NULL, NULL);
00261   }
00262 }
00263 
00264 bool
00265 pn53x_set_parameter (nfc_device_t * pnd, const uint8_t ui8Parameter, const bool bEnable)
00266 {
00267   uint8_t ui8Value = (bEnable) ? (pnd->ui8Parameters | ui8Parameter) : (pnd->ui8Parameters & ~(ui8Parameter));
00268   if (ui8Value != pnd->ui8Parameters) {
00269     return pn53x_SetParameters(pnd, ui8Value);
00270   }
00271   return true;
00272 }
00273 
00274 bool
00275 pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value)
00276 {
00277   byte_t  abtCmd[sizeof (pncmd_set_parameters)];
00278   memcpy (abtCmd, pncmd_set_parameters, sizeof (pncmd_set_parameters));
00279 
00280   abtCmd[2] = ui8Value;
00281   if(!pn53x_transceive (pnd, abtCmd, sizeof (pncmd_set_parameters), NULL, NULL)) {
00282     return false;
00283   }
00284   // We save last parameters in register cache
00285   pnd->ui8Parameters = ui8Value;
00286   return true;
00287 }
00288 
00289 bool
00290 pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits)
00291 {
00292   // Test if we need to update the transmission bits register setting
00293   if (pnd->ui8TxBits != ui8Bits) {
00294     // Set the amount of transmission bits in the PN53X chip register
00295     if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, ui8Bits))
00296       return false;
00297 
00298     // Store the new setting
00299     ((nfc_device_t *) pnd)->ui8TxBits = ui8Bits;
00300   }
00301   return true;
00302 }
00303 
00304 bool
00305 pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, 
00306                   byte_t * pbtFrame, size_t * pszFrameBits)
00307 {
00308   byte_t  btFrame;
00309   byte_t  btData;
00310   uint32_t uiBitPos;
00311   uint32_t uiDataPos = 0;
00312   size_t  szBitsLeft = szTxBits;
00313 
00314   // Make sure we should frame at least something
00315   if (szBitsLeft == 0)
00316     return false;
00317 
00318   // Handle a short response (1byte) as a special case
00319   if (szBitsLeft < 9) {
00320     *pbtFrame = *pbtTx;
00321     *pszFrameBits = szTxBits;
00322     return true;
00323   }
00324   // We start by calculating the frame length in bits
00325   *pszFrameBits = szTxBits + (szTxBits / 8);
00326 
00327   // Parse the data bytes and add the parity bits
00328   // This is really a sensitive process, mirror the frame bytes and append parity bits
00329   // buffer = mirror(frame-byte) + parity + mirror(frame-byte) + parity + ...
00330   // split "buffer" up in segments of 8 bits again and mirror them
00331   // air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
00332   while (true) {
00333     // Reset the temporary frame byte;
00334     btFrame = 0;
00335 
00336     for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
00337       // Copy as much data that fits in the frame byte
00338       btData = mirror (pbtTx[uiDataPos]);
00339       btFrame |= (btData >> uiBitPos);
00340       // Save this frame byte
00341       *pbtFrame = mirror (btFrame);
00342       // Set the remaining bits of the date in the new frame byte and append the parity bit
00343       btFrame = (btData << (8 - uiBitPos));
00344       btFrame |= ((pbtTxPar[uiDataPos] & 0x01) << (7 - uiBitPos));
00345       // Backup the frame bits we have so far
00346       pbtFrame++;
00347       *pbtFrame = mirror (btFrame);
00348       // Increase the data (without parity bit) position
00349       uiDataPos++;
00350       // Test if we are done
00351       if (szBitsLeft < 9)
00352         return true;
00353       szBitsLeft -= 8;
00354     }
00355     // Every 8 data bytes we lose one frame byte to the parities
00356     pbtFrame++;
00357   }
00358 }
00359 
00360 bool
00361 pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
00362                     byte_t * pbtRxPar)
00363 {
00364   byte_t  btFrame;
00365   byte_t  btData;
00366   uint8_t uiBitPos;
00367   uint32_t uiDataPos = 0;
00368   byte_t *pbtFramePos = (byte_t *) pbtFrame;
00369   size_t  szBitsLeft = szFrameBits;
00370 
00371   // Make sure we should frame at least something
00372   if (szBitsLeft == 0)
00373     return false;
00374 
00375   // Handle a short response (1byte) as a special case
00376   if (szBitsLeft < 9) {
00377     *pbtRx = *pbtFrame;
00378     *pszRxBits = szFrameBits;
00379     return true;
00380   }
00381   // Calculate the data length in bits
00382   *pszRxBits = szFrameBits - (szFrameBits / 9);
00383 
00384   // Parse the frame bytes, remove the parity bits and store them in the parity array
00385   // This process is the reverse of WrapFrame(), look there for more info
00386   while (true) {
00387     for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
00388       btFrame = mirror (pbtFramePos[uiDataPos]);
00389       btData = (btFrame << uiBitPos);
00390       btFrame = mirror (pbtFramePos[uiDataPos + 1]);
00391       btData |= (btFrame >> (8 - uiBitPos));
00392       pbtRx[uiDataPos] = mirror (btData);
00393       if (pbtRxPar != NULL)
00394         pbtRxPar[uiDataPos] = ((btFrame >> (7 - uiBitPos)) & 0x01);
00395       // Increase the data (without parity bit) position
00396       uiDataPos++;
00397       // Test if we are done
00398       if (szBitsLeft < 9)
00399         return true;
00400       szBitsLeft -= 9;
00401     }
00402     // Every 8 data bytes we lose one frame byte to the parities
00403     pbtFramePos++;
00404   }
00405 }
00406 
00407 bool
00408 pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, nfc_chip_t nc, nfc_modulation_type_t nmt,
00409                           nfc_target_info_t * pnti)
00410 {
00411   uint8_t szAttribRes;
00412 
00413   switch (nmt) {
00414   case NMT_ISO14443A:
00415     // We skip the first byte: its the target number (Tg)
00416     pbtRawData++;
00417 
00418     // Somehow they switched the lower and upper ATQA bytes around for the PN531 chipset
00419     if (nc == NC_PN531) {
00420       pnti->nai.abtAtqa[1] = *(pbtRawData++);
00421       pnti->nai.abtAtqa[0] = *(pbtRawData++);
00422     } else {
00423       pnti->nai.abtAtqa[0] = *(pbtRawData++);
00424       pnti->nai.abtAtqa[1] = *(pbtRawData++);
00425     }
00426     pnti->nai.btSak = *(pbtRawData++);
00427     // Copy the NFCID1
00428     pnti->nai.szUidLen = *(pbtRawData++);
00429     memcpy (pnti->nai.abtUid, pbtRawData, pnti->nai.szUidLen);
00430     pbtRawData += pnti->nai.szUidLen;
00431 
00432     // Did we received an optional ATS (Smardcard ATR)
00433     if (szRawData > (pnti->nai.szUidLen + 5)) {
00434       pnti->nai.szAtsLen = ((*(pbtRawData++)) - 1);     // In pbtRawData, ATS Length byte is counted in ATS Frame.
00435       memcpy (pnti->nai.abtAts, pbtRawData, pnti->nai.szAtsLen);
00436     } else {
00437       pnti->nai.szAtsLen = 0;
00438     }
00439 
00440     // Strip CT (Cascade Tag) to retrieve and store the _real_ UID
00441     // (e.g. 0x8801020304050607 is in fact 0x01020304050607)
00442     if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) {
00443       pnti->nai.szUidLen = 7;
00444       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 7);
00445     } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) {
00446       pnti->nai.szUidLen = 10;
00447       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3);
00448       memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7);
00449     }
00450     break;
00451 
00452   case NMT_ISO14443B:
00453     // We skip the first byte: its the target number (Tg)
00454     pbtRawData++;
00455 
00456     // Now we are in ATQB, we skip the first ATQB byte always equal to 0x50
00457     pbtRawData++;
00458     
00459     // Store the PUPI (Pseudo-Unique PICC Identifier)
00460     memcpy (pnti->nbi.abtPupi, pbtRawData, 4);
00461     pbtRawData += 4;
00462 
00463     // Store the Application Data
00464     memcpy (pnti->nbi.abtApplicationData, pbtRawData, 4);
00465     pbtRawData += 4;
00466 
00467     // Store the Protocol Info
00468     memcpy (pnti->nbi.abtProtocolInfo, pbtRawData, 3);
00469     pbtRawData += 3;
00470 
00471     // We leave the ATQB field, we now enter in Card IDentifier
00472     szAttribRes = *(pbtRawData++);
00473     if (szAttribRes) {
00474       pnti->nbi.ui8CardIdentifier = *(pbtRawData++);
00475     }
00476     break;
00477 
00478   case NMT_FELICA:
00479     // We skip the first byte: its the target number (Tg)
00480     pbtRawData++;
00481 
00482     // Store the mandatory info
00483     pnti->nfi.szLen = *(pbtRawData++);
00484     pnti->nfi.btResCode = *(pbtRawData++);
00485     // Copy the NFCID2t
00486     memcpy (pnti->nfi.abtId, pbtRawData, 8);
00487     pbtRawData += 8;
00488     // Copy the felica padding
00489     memcpy (pnti->nfi.abtPad, pbtRawData, 8);
00490     pbtRawData += 8;
00491     // Test if the System code (SYST_CODE) is available
00492     if (pnti->nfi.szLen > 18) {
00493       memcpy (pnti->nfi.abtSysCode, pbtRawData, 2);
00494     }
00495     break;
00496   case NMT_JEWEL:
00497     // We skip the first byte: its the target number (Tg)
00498     pbtRawData++;
00499 
00500     // Store the mandatory info
00501     memcpy (pnti->nji.btSensRes, pbtRawData, 2);
00502     pbtRawData += 2;
00503     memcpy (pnti->nji.btId, pbtRawData, 4);
00504     break;
00505   default:
00506     return false;
00507     break;
00508   }
00509   return true;
00510 }
00511 
00512 bool
00513 pn53x_initiator_select_passive_target (nfc_device_t * pnd,
00514                                        const nfc_modulation_t nm,
00515                                        const byte_t * pbtInitData, const size_t szInitData,
00516                                        nfc_target_t * pnt)
00517 {
00518   size_t  szTargetsData;
00519   byte_t  abtTargetsData[PN53x_EXTENDED_FRAME_MAX_LEN];
00520 
00521   const pn53x_modulation_t pm = pn53x_nm_to_pm(nm);
00522   if (PM_UNDEFINED == pm) {
00523     pnd->iLastError = DENOTSUP;
00524     return false;
00525   }
00526   if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData))
00527     return false;
00528 
00529   // Make sure one tag has been found, the PN53X returns 0x00 if none was available
00530   if (abtTargetsData[0] == 0)
00531     return false;
00532 
00533   // Is a tag info struct available
00534   if (pnt) {
00535     pnt->nm = nm;
00536     // Fill the tag info struct with the values corresponding to this init modulation
00537     if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, nm.nmt, &(pnt->nti))) {
00538       return false;
00539     }
00540   }
00541   return true;
00542 }
00543 
00544 bool
00545 pn53x_initiator_poll_targets (nfc_device_t * pnd,
00546                               const nfc_modulation_t * pnmModulations, const size_t szModulations,
00547                               const byte_t btPollNr, const byte_t btPeriod,
00548                               nfc_target_t * pntTargets, size_t * pszTargetFound)
00549 {
00550   size_t szTargetTypes = 0;
00551   pn53x_target_type_t apttTargetTypes[32];
00552   for (size_t n=0; n<szModulations; n++) {
00553     const pn53x_target_type_t ptt = pn53x_nm_to_ptt(pnmModulations[n]);
00554     if (PTT_UNDEFINED == ptt) {
00555       pnd->iLastError = DENOTSUP;
00556       return false;
00557     }
00558     apttTargetTypes[szTargetTypes] = ptt;
00559     if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS
00560       apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106;
00561       szTargetTypes++;
00562       apttTargetTypes[szTargetTypes] = PTT_MIFARE;
00563     }
00564     szTargetTypes++;
00565   }
00566 
00567   return pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
00568 }
00569 
00570 
00585 bool
00586 pn53x_InListPassiveTarget (nfc_device_t * pnd,
00587                            const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets,
00588                            const byte_t * pbtInitiatorData, const size_t szInitiatorData,
00589                            byte_t * pbtTargetsData, size_t * pszTargetsData)
00590 {
00591   size_t  szRx;
00592   byte_t  abtCmd[sizeof (pncmd_initiator_list_passive)];
00593   memcpy (abtCmd, pncmd_initiator_list_passive, sizeof (pncmd_initiator_list_passive));
00594 
00595   abtCmd[2] = szMaxTargets;     // MaxTg
00596 
00597   // XXX Is there is a better way to do handle supported modulations ?
00598   switch(pmInitModulation) {
00599     case PM_ISO14443A_106:
00600     case PM_FELICA_212:
00601     case PM_FELICA_424:
00602       // all gone fine.
00603       break;
00604     case PM_ISO14443B_106:
00605       if (!(pnd->btSupportByte & SUPPORT_ISO14443B)) {
00606         // Eg. Some PN532 doesn't support type B!
00607         pnd->iLastError = DENOTSUP;
00608         return false;
00609       }
00610       break;
00611     case PM_JEWEL_106:
00612       if(pnd->nc == NC_PN531) {
00613         // These modulations are not supported by pn531
00614         pnd->iLastError = DENOTSUP;
00615         return false;
00616       }
00617       break;
00618     case PM_ISO14443B_212:
00619     case PM_ISO14443B_424:
00620     case PM_ISO14443B_847:
00621       if((pnd->nc != NC_PN533) || (!(pnd->btSupportByte & SUPPORT_ISO14443B))) {
00622         // These modulations are not supported by pn531 neither pn532
00623         pnd->iLastError = DENOTSUP;
00624         return false;
00625       }
00626       break;
00627     default:
00628       pnd->iLastError = DENOTSUP;
00629       return false;
00630   }
00631   abtCmd[3] = pmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
00632 
00633   // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
00634   if (pbtInitiatorData)
00635     memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorData);
00636 
00637   // Try to find a tag, call the tranceive callback function of the current device
00638   szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
00639   if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorData, pbtTargetsData, &szRx)) {
00640     *pszTargetsData = szRx;
00641     return true;
00642   } else {
00643     return false;
00644   }
00645 }
00646 
00647 bool
00648 pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target)
00649 {
00650   byte_t  abtCmd[sizeof (pncmd_initiator_deselect)];
00651   memcpy (abtCmd, pncmd_initiator_deselect, sizeof (pncmd_initiator_deselect));
00652   abtCmd[2] = ui8Target;
00653 
00654   return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL));
00655 }
00656 
00657 bool
00658 pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target)
00659 {
00660   byte_t  abtCmd[sizeof (pncmd_initiator_release)];
00661   memcpy (abtCmd, pncmd_initiator_release, sizeof (pncmd_initiator_release));
00662   abtCmd[2] = ui8Target;
00663 
00664   return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL));
00665 }
00666 
00667 bool
00668 pn53x_InAutoPoll (nfc_device_t * pnd,
00669                   const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
00670                   const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound)
00671 {
00672   size_t  szTxInAutoPoll,
00673           n;
00674   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
00675   size_t  szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
00676   bool    res;
00677   byte_t *pbtTxInAutoPoll;
00678 
00679   if (pnd->nc != NC_PN532) {
00680     // This function is not supported by pn531 neither pn533
00681     pnd->iLastError = DENOTSUP;
00682     return false;
00683   }
00684   // InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... }
00685   szTxInAutoPoll = 4 + szTargetTypes;
00686   pbtTxInAutoPoll = malloc (szTxInAutoPoll);
00687   pbtTxInAutoPoll[0] = 0xd4;
00688   pbtTxInAutoPoll[1] = 0x60;
00689   pbtTxInAutoPoll[2] = btPollNr;
00690   pbtTxInAutoPoll[3] = btPeriod;
00691   for (n = 0; n < szTargetTypes; n++) {
00692     pbtTxInAutoPoll[4 + n] = ppttTargetTypes[n];
00693   }
00694 
00695   szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
00696   res = pn53x_transceive (pnd, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRx);
00697 
00698   if ((szRx == 0) || (res == false)) {
00699     return false;
00700   } else {
00701     *pszTargetFound = abtRx[0];
00702     if (*pszTargetFound) {
00703       uint8_t ln;
00704       byte_t *pbt = abtRx + 1;
00705       /* 1st target */
00706       // Target type
00707       pn53x_target_type_t ptt = *(pbt++);
00708       pntTargets[0].nm = pn53x_ptt_to_nm(ptt);
00709       // AutoPollTargetData length
00710       ln = *(pbt++);
00711       pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[0].nm.nmt, &(pntTargets[0].nti));
00712       pbt += ln;
00713 
00714       if (abtRx[0] > 1) {
00715         /* 2nd target */
00716         // Target type
00717         ptt = *(pbt++);
00718         pntTargets[1].nm = pn53x_ptt_to_nm(ptt);
00719         // AutoPollTargetData length
00720         ln = *(pbt++);
00721         pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[1].nm.nmt, &(pntTargets[1].nti));
00722       }
00723     }
00724   }
00725   return true;
00726 }
00727 
00728 static struct sErrorMessage {
00729   int     iErrorCode;
00730   const char *pcErrorMsg;
00731 } sErrorMessages[] = {
00732   /* Chip-level errors */
00733   { 0x00, "Success" },
00734   { ETIMEOUT, "Timeout" },      // Time Out, the target has not answered
00735   { ECRC,     "CRC Error" },      // A CRC error has been detected by the CIU
00736   { EPARITY,  "Parity Error" },     // A Parity error has been detected by the CIU
00737   { EBITCOUNT, "Erroneous Bit Count" },   // During an anti-collision/select operation (ISO/IEC14443-3 Type A and ISO/IEC18092 106 kbps passive mode), an erroneous Bit Count has been detected
00738   { EFRAMING, "Framing Error" },    // Framing error during MIFARE operation
00739   { EBITCOLL, "Bit-collision" },    // An abnormal bit-collision has been detected during bit wise anti-collision at 106 kbps
00740   { ESMALLBUF, "Communication Buffer Too Small" },  // Communication buffer size insufficient
00741   { EBUFOVF, "Buffer Overflow" },   // RF Buffer overflow has been detected by the CIU (bit BufferOvfl of the register CIU_Error)
00742   { ERFTIMEOUT, "RF Timeout" },     // In active communication mode, the RF field has not been switched on in time by the counterpart (as defined in NFCIP-1 standard)
00743   { ERFPROTO, "RF Protocol Error" },    // RF Protocol error (see PN53x manual)
00744   { EOVHEAT, "Chip Overheating" },    // Temperature error: the internal temperature sensor has detected overheating, and therefore has automatically switched off the antenna drivers
00745   { EINBUFOVF, "Internal Buffer overflow."},  // Internal buffer overflow
00746   { EINVPARAM, "Invalid Parameter"},    // Invalid parameter (range, format, …)
00747     /* DEP Errors */
00748   { EDEPUNKCMD, "Unknown DEP Command" },
00749     /* MIFARE */
00750   { EMFAUTH, "Mifare Authentication Error" },
00751     /*  */
00752   { EINVRXFRAM, "Invalid Received Frame" }, // DEP Protocol, Mifare or ISO/IEC14443-4: The data format does not match to the specification.
00753   { ENSECNOTSUPP, "NFC Secure not supported" }, // Target or Initiator does not support NFC Secure
00754   { EBCC, "Wrong UID Check Byte (BCC)" }, // ISO/IEC14443-3: UID Check byte is wrong
00755   { EDEPINVSTATE, "Invalid DEP State" },  // DEP Protocol: Invalid device state, the system is in a state which does not allow the operation
00756   { EOPNOTALL, "Operation Not Allowed" }, // Operation not allowed in this configuration (host controller interface)
00757   { ECMD, "Command Not Acceptable" },   // Command is not acceptable due to the current context
00758   { ETGREL, "Target Released" },    // Target have been released by initiator
00759     // FIXME: Errors can be grouped (DEP-related, MIFARE-related, ISO14443B-related, etc.)
00760     // Purposal: Use prefix/suffix to identify them
00761   { ECID, "Card ID Mismatch" },     // ISO14443 type B: Card ID mismatch, meaning that the expected card has been exchanged with another one.
00762   { ECDISCARDED, "Card Discarded" },    // ISO/IEC14443 type B: the card previously activated has disappeared.
00763   { ENFCID3, "NFCID3 Mismatch" },
00764   { EOVCURRENT, "Over Current"  },
00765   { ENAD, "NAD Missing in DEP Frame" },
00766     /* Software level errors */
00767   { ETGUIDNOTSUP, "Target UID not supported" }, // In target mode, PN53x only support 4 bytes UID and the first byte must start with 0x08
00768     /* Driver-level errors */
00769   { DENACK, "Received NACK" },
00770   { DEACKMISMATCH, "Expected ACK/NACK" },
00771   { DEISERRFRAME, "Received an error frame" },
00772     // TODO: Move me in more generic code for libnfc 1.6
00773     // FIXME: Driver-errors and Device-errors have the same prefix (DE*)
00774     // eg. DENACK means Driver Error NACK while DEIO means Device Error I/O
00775   { DEINVAL, "Invalid argument" },
00776   { DEIO, "Input/output error" },
00777   { DETIMEOUT, "Operation timed-out" },
00778   { DENOTSUP, "Operation not supported" }
00779 };
00780 
00781 const char *
00782 pn53x_strerror (const nfc_device_t * pnd)
00783 {
00784   const char *pcRes = "Unknown error";
00785   size_t  i;
00786 
00787   for (i = 0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) {
00788     if (sErrorMessages[i].iErrorCode == pnd->iLastError) {
00789       pcRes = sErrorMessages[i].pcErrorMsg;
00790       break;
00791     }
00792   }
00793 
00794   return pcRes;
00795 }
00796 
00797 bool
00798 pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[18])
00799 {
00800   byte_t  abtFw[4];
00801   size_t  szFwLen = sizeof (abtFw);
00802   if (!pn53x_transceive (pnd, pncmd_get_firmware_version, 2, abtFw, &szFwLen)) {
00803     // Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
00804     pnd->pdc->disconnect (pnd);
00805     return false;
00806   }
00807   // Convert firmware info in text, PN531 gives 2 bytes info, but PN532 and PN533 gives 4
00808   switch (pnd->nc) {
00809   case NC_PN531:
00810     snprintf (abtFirmwareText, 18, "PN531 v%d.%d", abtFw[0], abtFw[1]);
00811     pnd->btSupportByte = SUPPORT_ISO14443A | SUPPORT_ISO18092;
00812     break;
00813   case NC_PN532:
00814     snprintf (abtFirmwareText, 18, "PN532 v%d.%d (0x%02x)", abtFw[1], abtFw[2], abtFw[3]);
00815     pnd->btSupportByte = abtFw[3];
00816     break;
00817   case NC_PN533:
00818     snprintf (abtFirmwareText, 18, "PN533 v%d.%d (0x%02x)", abtFw[1], abtFw[2], abtFw[3]);
00819     pnd->btSupportByte = abtFw[3];
00820     break;
00821   }
00822   // Be sure to have a null end of string
00823   abtFirmwareText[17] = '\0';
00824   return true;
00825 }
00826 
00827 bool
00828 pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
00829 {
00830   byte_t  btValue;
00831   byte_t  abtCmd[sizeof (pncmd_rf_configure)];
00832 
00833   memcpy (abtCmd, pncmd_rf_configure, sizeof (pncmd_rf_configure));
00834 
00835   // Make sure we are dealing with a active device
00836   if (!pnd->bActive)
00837     return false;
00838 
00839   switch (ndo) {
00840   case NDO_HANDLE_CRC:
00841     // Enable or disable automatic receiving/sending of CRC bytes
00842     // TX and RX are both represented by the symbol 0x80
00843     btValue = (bEnable) ? 0x80 : 0x00;
00844     if (!pn53x_set_reg (pnd, REG_CIU_TX_MODE, SYMBOL_TX_CRC_ENABLE, btValue))
00845       return false;
00846     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_CRC_ENABLE, btValue))
00847       return false;
00848     pnd->bCrc = bEnable;
00849     break;
00850 
00851   case NDO_HANDLE_PARITY:
00852     // Handle parity bit by PN53X chip or parse it as data bit
00853     btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE;
00854     if (!pn53x_set_reg (pnd, REG_CIU_MANUAL_RCV, SYMBOL_PARITY_DISABLE, btValue))
00855       return false;
00856     pnd->bPar = bEnable;
00857     break;
00858 
00859   case NDO_EASY_FRAMING:
00860     pnd->bEasyFraming = bEnable;
00861     break;
00862 
00863   case NDO_ACTIVATE_FIELD:
00864     abtCmd[2] = RFCI_FIELD;
00865     abtCmd[3] = (bEnable) ? 1 : 0;
00866     if (!pn53x_transceive (pnd, abtCmd, 4, NULL, NULL))
00867       return false;
00868     break;
00869 
00870   case NDO_ACTIVATE_CRYPTO1:
00871     btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
00872     if (!pn53x_set_reg (pnd, REG_CIU_STATUS2, SYMBOL_MF_CRYPTO1_ON, btValue))
00873       return false;
00874     break;
00875 
00876   case NDO_INFINITE_SELECT:
00877     // TODO Made some research around this point: 
00878     // timings could be tweak better than this, and maybe we can tweak timings
00879     // to "gain" a sort-of hardware polling (ie. like PN532 does)
00880     
00881     // Retry format: 0x00 means only 1 try, 0xff means infinite
00882     abtCmd[2] = RFCI_RETRY_SELECT;
00883     abtCmd[3] = (bEnable) ? 0xff : 0x00;        // MxRtyATR, default: active = 0xff, passive = 0x02
00884     abtCmd[4] = (bEnable) ? 0xff : 0x00;        // MxRtyPSL, default: 0x01
00885     abtCmd[5] = (bEnable) ? 0xff : 0x00;        // MxRtyPassiveActivation, default: 0xff
00886     if (!pn53x_transceive (pnd, abtCmd, 6, NULL, NULL))
00887       return false;
00888     break;
00889 
00890   case NDO_ACCEPT_INVALID_FRAMES:
00891     btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
00892     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_NO_ERROR, btValue))
00893       return false;
00894     break;
00895 
00896   case NDO_ACCEPT_MULTIPLE_FRAMES:
00897     btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
00898     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_MULTIPLE, btValue))
00899       return false;
00900     return true;
00901     break;
00902 
00903   case NDO_AUTO_ISO14443_4:
00904     // TODO Cache activated/disactivated options
00905     pnd->bAutoIso14443_4 = bEnable;
00906     return pn53x_set_parameter(pnd, PARAM_AUTO_RATS, bEnable);
00907     break;
00908 
00909   case NDO_FORCE_ISO14443_A:
00910     if(!bEnable) {
00911       // Nothing to do
00912       return true;
00913     }
00914     // Force pn53x to be in ISO14443-A mode
00915     if (!pn53x_set_reg (pnd, REG_CIU_TX_MODE, SYMBOL_TX_FRAMING, 0x00)) {
00916       return false;
00917     }
00918     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_FRAMING, 0x00)) {
00919       return false;
00920     }
00921     return true;
00922     break;
00923   }
00924 
00925   // When we reach this, the configuration is completed and succesful
00926   return true;
00927 }
00928 
00929 bool
00930 pn53x_initiator_select_dep_target(nfc_device_t * pnd,
00931                                   const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
00932                                   const nfc_dep_info_t * pndiInitiator,
00933                                   nfc_target_t * pnt)
00934 {
00935   const byte_t abtPassiveInitiatorData[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 }; // Only for 212/424 kpbs: First 4 bytes shall be set like this according to NFCIP-1, last byte is TSN (Time Slot Number)
00936   const byte_t * pbtPassiveInitiatorData = NULL;
00937 
00938   switch (nbr) {
00939     case NBR_212:
00940     case NBR_424:
00941       // Only use this predefined bytes array when we are at 212/424kbps
00942       pbtPassiveInitiatorData = abtPassiveInitiatorData;
00943       break;
00944 
00945     default:
00946       // Nothing to do
00947       break;
00948   }
00949 
00950   if (pndiInitiator) {
00951     return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, pndiInitiator->abtNFCID3, pndiInitiator->abtGB, pndiInitiator->szGB, pnt);
00952   } else {
00953     return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, NULL, NULL, 0, pnt);
00954   }
00955 }
00956 
00967 bool
00968 pn53x_InJumpForDEP (nfc_device_t * pnd,
00969                     const nfc_dep_mode_t ndm,
00970                     const nfc_baud_rate_t nbr,
00971                     const byte_t * pbtPassiveInitiatorData,
00972                     const byte_t * pbtNFCID3i,
00973                     const byte_t * pbtGBi, const size_t szGBi,
00974                     nfc_target_t * pnt)
00975 {
00976   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
00977   size_t  szRx;
00978   size_t  offset;
00979   byte_t  abtCmd[sizeof (pncmd_initiator_jump_for_dep)];
00980 
00981   memcpy (abtCmd, pncmd_initiator_jump_for_dep, sizeof (pncmd_initiator_jump_for_dep));
00982 
00983   offset = 5; // 2 bytes for command, 1 byte for DEP mode (Active/Passive), 1 byte for baud rate, 1 byte for following parameters flag
00984   abtCmd[2] = (ndm == NDM_ACTIVE) ? 0x01 : 0x00;
00985 
00986   switch (nbr) {
00987     case NBR_106:
00988       abtCmd[3] = 0x00; // baud rate is 106 kbps
00989     break;
00990     case NBR_212:
00991       abtCmd[3] = 0x01; // baud rate is 212 kbps
00992     break;
00993     case NBR_424:
00994       abtCmd[3] = 0x02; // baud rate is 424 kbps
00995     break;
00996     case NBR_847:
00997     case NBR_UNDEFINED:
00998       // XXX Maybe we should put a "syntax error" or sth like that
00999       pnd->iLastError = DENOTSUP;
01000       return false;
01001     break;
01002   }
01003 
01004   if (pbtPassiveInitiatorData && (ndm == NDM_PASSIVE)) {        /* can't have passive initiator data when using active mode */
01005     switch (nbr) {
01006       case NBR_106:
01007         abtCmd[4] |= 0x01;
01008         memcpy (abtCmd + offset, pbtPassiveInitiatorData, 4);
01009         offset += 4;
01010       break;
01011       case NBR_212:
01012       case NBR_424:
01013         abtCmd[4] |= 0x01;
01014         memcpy (abtCmd + offset, pbtPassiveInitiatorData, 5);
01015         offset += 5;
01016       break;
01017       case NBR_847:
01018       case NBR_UNDEFINED:
01019         // XXX Maybe we should put a "syntax error" or sth like that
01020         pnd->iLastError = DENOTSUP;
01021         return false;
01022       break;
01023     }
01024   }
01025 
01026   if (pbtNFCID3i) {
01027     abtCmd[4] |= 0x02;
01028     memcpy (abtCmd + offset, pbtNFCID3i, 10);
01029     offset += 10;
01030   }
01031 
01032   if (szGBi && pbtGBi) {
01033     abtCmd[4] |= 0x04;
01034     memcpy (abtCmd + offset, pbtGBi, szGBi);
01035     offset += szGBi;
01036   }
01037   // Try to find a target, call the transceive callback function of the current device
01038   if (!pn53x_transceive (pnd, abtCmd, offset, abtRx, &szRx))
01039     return false;
01040 
01041   // Make sure one target has been found, the PN53X returns 0x00 if none was available
01042   if (abtRx[1] != 1)
01043     return false;
01044 
01045   // Is a target struct available
01046   if (pnt) {
01047     pnt->nm.nmt = NMT_DEP;
01048     pnt->nm.nbr = nbr;
01049     memcpy (pnt->nti.ndi.abtNFCID3, abtRx + 2, 10);
01050     pnt->nti.ndi.btDID = abtRx[12];
01051     pnt->nti.ndi.btBS = abtRx[13];
01052     pnt->nti.ndi.btBR = abtRx[14];
01053     pnt->nti.ndi.btTO = abtRx[15];
01054     pnt->nti.ndi.btPP = abtRx[16];
01055     if(szRx > 17) {
01056       pnt->nti.ndi.szGB = szRx - 17;
01057       memcpy (pnt->nti.ndi.abtGB, abtRx + 17, pnt->nti.ndi.szGB);
01058     } else {
01059       pnt->nti.ndi.szGB = 0;
01060     }
01061   }
01062   return true;
01063 }
01064 
01065 bool
01066 pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
01067                                  const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
01068 {
01069   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
01070   size_t  szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
01071   size_t  szFrameBits = 0;
01072   size_t  szFrameBytes = 0;
01073   uint8_t ui8rcc;
01074   uint8_t ui8Bits = 0;
01075   byte_t  abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
01076 
01077   memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
01078 
01079   // Check if we should prepare the parity bits ourself
01080   if (!pnd->bPar) {
01081     // Convert data with parity to a frame
01082     pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
01083   } else {
01084     szFrameBits = szTxBits;
01085   }
01086 
01087   // Retrieve the leading bits
01088   ui8Bits = szFrameBits % 8;
01089 
01090   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
01091   szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
01092 
01093   // When the parity is handled before us, we just copy the data
01094   if (pnd->bPar)
01095     memcpy (abtCmd + 2, pbtTx, szFrameBytes);
01096 
01097   // Set the amount of transmission bits in the PN53X chip register
01098   if (!pn53x_set_tx_bits (pnd, ui8Bits))
01099     return false;
01100 
01101   // Send the frame to the PN53X chip and get the answer
01102   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
01103   if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, abtRx, &szRx))
01104     return false;
01105 
01106   // Get the last bit-count that is stored in the received byte 
01107   if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
01108     return false;
01109   ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
01110 
01111   // Recover the real frame length in bits
01112   szFrameBits = ((szRx - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
01113 
01114   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
01115   // Check if we should recover the parity bits ourself
01116   if (!pnd->bPar) {
01117     // Unwrap the response frame
01118     pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
01119   } else {
01120     // Save the received bits
01121     *pszRxBits = szFrameBits;
01122     // Copy the received bytes
01123     memcpy (pbtRx, abtRx + 1, szRx - 1);
01124   }
01125 
01126   // Everything went successful
01127   return true;
01128 }
01129 
01130 bool
01131 pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx,
01132                                   size_t * pszRx)
01133 {
01134   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
01135   size_t  szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
01136   size_t  szExtraTxLen;
01137   byte_t  abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
01138 
01139   // We can not just send bytes without parity if while the PN53X expects we handled them
01140   if (!pnd->bPar)
01141     return false;
01142 
01143   // Copy the data into the command frame
01144   if (pnd->bEasyFraming) {
01145     memcpy (abtCmd, pncmd_initiator_exchange_data, sizeof (pncmd_initiator_exchange_data));
01146     abtCmd[2] = 1;              /* target number */
01147     memcpy (abtCmd + 3, pbtTx, szTx);
01148     szExtraTxLen = 3;
01149   } else {
01150     memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
01151     memcpy (abtCmd + 2, pbtTx, szTx);
01152     szExtraTxLen = 2;
01153   }
01154 
01155   // To transfer command frames bytes we can not have any leading bits, reset this to zero
01156   if (!pn53x_set_tx_bits (pnd, 0))
01157     return false;
01158 
01159   // Send the frame to the PN53X chip and get the answer
01160   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
01161   if (!pn53x_transceive (pnd, abtCmd, szTx + szExtraTxLen, abtRx, &szRx))
01162     return false;
01163 
01164   // Save the received byte count
01165   *pszRx = szRx - 1;
01166 
01167   // Copy the received bytes
01168   memcpy (pbtRx, abtRx + 1, *pszRx);
01169 
01170   // Everything went successful
01171   return true;
01172 }
01173 
01174 #define SAK_ISO14443_4_COMPLIANT 0x20
01175 bool
01176 pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx)
01177 {
01178   // Save the current configuration settings
01179   bool    bCrc = pnd->bCrc;
01180   bool    bPar = pnd->bPar;
01181 
01182   pn53x_target_mode_t ptm = PTM_NORMAL;
01183   switch (pnt->nm.nmt) {
01184     case NMT_ISO14443A:
01185       ptm = PTM_PASSIVE_ONLY;
01186       if ((pnt->nti.nai.abtUid[0] != 0x08) || (pnt->nti.nai.szUidLen != 4)) {
01187         pnd->iLastError = ETGUIDNOTSUP;
01188         return false;
01189       }
01190       pn53x_set_parameter(pnd, PARAM_AUTO_ATR_RES, false);
01191       if (pnd->nc == NC_PN532) { // We have a PN532
01192         if ((pnt->nti.nai.btSak & SAK_ISO14443_4_COMPLIANT) && (pnd->bAutoIso14443_4)) { 
01193           // We have a ISO14443-4 tag to emulate and NDO_AUTO_14443_4A option is enabled
01194           ptm |= PTM_ISO14443_4_PICC_ONLY; // We add ISO14443-4 restriction
01195           pn53x_set_parameter(pnd, PARAM_14443_4_PICC, true);
01196         } else {
01197           pn53x_set_parameter(pnd, PARAM_14443_4_PICC, false);
01198         }
01199       }
01200     break;
01201     case NMT_FELICA:
01202       ptm = PTM_PASSIVE_ONLY;
01203     break;
01204     case NMT_DEP:
01205       pn53x_set_parameter(pnd, PARAM_AUTO_ATR_RES, true);
01206       ptm = PTM_DEP_ONLY;
01207       if (pnt->nti.ndi.ndm == NDM_PASSIVE) {
01208         ptm |= PTM_PASSIVE_ONLY; // We add passive mode restriction
01209       }
01210     break;
01211     case NMT_ISO14443B:
01212     case NMT_JEWEL:
01213       pnd->iLastError = DENOTSUP;
01214       return false;
01215     break;
01216   }
01217 
01218   // Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
01219   if (!bCrc)
01220     pn53x_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, true);
01221   if (!bPar)
01222     pn53x_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, true);
01223 
01224   // Let the PN53X be activated by the RF level detector from power down mode
01225   if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON, 0x04))
01226     return false;
01227 
01228   byte_t abtMifareParams[6];
01229   byte_t * pbtMifareParams = NULL;
01230   byte_t * pbtTkt = NULL;
01231   size_t szTkt = 0;
01232 
01233   byte_t abtFeliCaParams[18];
01234   byte_t * pbtFeliCaParams = NULL;
01235 
01236   const byte_t * pbtNFCID3t = NULL;
01237   const byte_t * pbtGBt = NULL;
01238   size_t szGBt = 0;
01239 
01240   switch(pnt->nm.nmt) {
01241     case NMT_ISO14443A: {
01242       // Set ATQA (SENS_RES)
01243       abtMifareParams[0] = pnt->nti.nai.abtAtqa[1];
01244       abtMifareParams[1] = pnt->nti.nai.abtAtqa[0];
01245       // Set UID 
01246       // Note: in this mode we can only emulate a single size (4 bytes) UID where the first is hard-wired by PN53x as 0x08
01247       abtMifareParams[2] = pnt->nti.nai.abtUid[1];
01248       abtMifareParams[3] = pnt->nti.nai.abtUid[2];
01249       abtMifareParams[4] = pnt->nti.nai.abtUid[3];
01250       // Set SAK (SEL_RES)
01251       abtMifareParams[5] = pnt->nti.nai.btSak;
01252 
01253       pbtMifareParams = abtMifareParams;
01254 
01255       // Historical Bytes
01256       pbtTkt = iso14443a_locate_historical_bytes (pnt->nti.nai.abtAts, pnt->nti.nai.szAtsLen, &szTkt);
01257     }
01258     break;
01259 
01260     case NMT_FELICA:
01261       // Set NFCID2t 
01262       memcpy(abtFeliCaParams, pnt->nti.nfi.abtId, 8);
01263       // Set PAD
01264       memcpy(abtFeliCaParams+8, pnt->nti.nfi.abtPad, 8);
01265       // Set SystemCode
01266       memcpy(abtFeliCaParams+16, pnt->nti.nfi.abtSysCode, 2);
01267       pbtFeliCaParams = abtFeliCaParams;
01268     break;
01269 
01270     case NMT_DEP:
01271       // Set NFCID3
01272       pbtNFCID3t = pnt->nti.ndi.abtNFCID3;
01273       // Set General Bytes, if relevant
01274       szGBt = pnt->nti.ndi.szGB;
01275       if (szGBt) pbtGBt = pnt->nti.ndi.abtGB;
01276     break;
01277     case NMT_ISO14443B:
01278     case NMT_JEWEL:
01279       pnd->iLastError = DENOTSUP;
01280       return false;
01281     break;
01282   }
01283 
01284   bool targetActivated = false;
01285   while (!targetActivated) {
01286     nfc_modulation_t nm;
01287     nfc_dep_mode_t ndm = NDM_UNDEFINED;
01288     byte_t btActivatedMode;
01289 
01290     nm.nbr = NBR_UNDEFINED;
01291 
01292     if(!pn53x_TgInitAsTarget(pnd, ptm, pbtMifareParams, pbtTkt, szTkt, pbtFeliCaParams, pbtNFCID3t, pbtGBt, szGBt, pbtRx, pszRx, &btActivatedMode)) {
01293       return false;
01294     }
01295 
01296     // Decode activated "mode"
01297     switch(btActivatedMode & 0x70) { // Baud rate
01298       case 0x00: // 106kbps
01299         nm.nbr = NBR_106;
01300       break;
01301       case 0x10: // 212kbps
01302         nm.nbr = NBR_212;
01303       break;
01304       case 0x20: // 424kbps
01305         nm.nbr = NBR_424;
01306       break;
01307     };
01308   
01309     if (btActivatedMode & 0x04) { // D.E.P.
01310       nm.nmt = NMT_DEP;
01311       if ((btActivatedMode & 0x03) == 0x01) { // Active mode
01312         ndm = NDM_ACTIVE;
01313       } else { // Passive mode
01314         ndm = NDM_PASSIVE;
01315       }
01316     } else { // Not D.E.P.
01317       if ((btActivatedMode & 0x03) == 0x00) { // MIFARE
01318         nm.nmt = NMT_ISO14443A;
01319       } else if ((btActivatedMode & 0x03) == 0x02) { // FeliCa
01320         nm.nmt = NMT_FELICA;
01321       }
01322     }
01323 
01324     if(pnt->nm.nmt == nm.nmt) { // Actual activation have the right modulation type
01325       if ((pnt->nm.nbr == NBR_UNDEFINED) || (pnt->nm.nbr == nm.nbr)) { // Have the right baud rate (or undefined)
01326         if ((pnt->nm.nmt != NMT_DEP) || (pnt->nti.ndi.ndm == NDM_UNDEFINED) || (pnt->nti.ndi.ndm == ndm)) { // Have the right DEP mode (or is not a DEP)
01327           targetActivated = true;
01328         }
01329       }
01330     }
01331  
01332     if (targetActivated) {
01333       pnt->nm.nbr = nm.nbr; // Update baud rate
01334       if (pnt->nm.nmt == NMT_DEP) {
01335         pnt->nti.ndi.ndm = ndm; // Update DEP mode
01336       }
01337     }
01338   }
01339 
01340   // Restore the CRC & parity setting to the original value (if needed)
01341   if (!bCrc)
01342     pn53x_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, false);
01343   if (!bPar)
01344     pn53x_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, false);
01345 
01346   return true;
01347 }
01348 
01349 bool
01350 pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm,
01351                       const byte_t * pbtMifareParams,
01352                       const byte_t * pbtTkt, size_t szTkt,
01353                       const byte_t * pbtFeliCaParams,
01354                       const byte_t * pbtNFCID3t, const byte_t * pbtGBt, const size_t szGBt,
01355                       byte_t * pbtRx, size_t * pszRx, byte_t * pbtModeByte)
01356 {
01357   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
01358   size_t  szRx;
01359   byte_t  abtCmd[39 + 47 + 48]; // Worst case: 39-byte base, 47 bytes max. for General Bytes, 48 bytes max. for Historical Bytes
01360   size_t  szOptionalBytes = 0;
01361 
01362   memcpy (abtCmd, pncmd_target_init, sizeof (pncmd_target_init));
01363 
01364   // Clear the target init struct, reset to all zeros
01365   memset (abtCmd + sizeof (pncmd_target_init), 0x00, sizeof (abtCmd) - sizeof (pncmd_target_init));
01366 
01367   // Store the target mode in the initialization params
01368   abtCmd[2] = ptm;
01369 
01370   // MIFARE part
01371   if (pbtMifareParams) {
01372     memcpy (abtCmd+3, pbtMifareParams, 6);
01373   }
01374   // FeliCa part
01375   if (pbtFeliCaParams) {
01376     memcpy (abtCmd+9, pbtFeliCaParams, 18);
01377   }
01378   // DEP part
01379   if (pbtNFCID3t) {
01380     memcpy(abtCmd+27, pbtNFCID3t, 10);
01381   }
01382   // General Bytes (ISO/IEC 18092)
01383   if (pnd->nc == NC_PN531) {
01384     if (szGBt) {
01385       memcpy (abtCmd+37, pbtGBt, szGBt);
01386       szOptionalBytes = szGBt;
01387     }
01388   } else {
01389     abtCmd[37] = (byte_t)(szGBt);
01390     if (szGBt) {
01391       memcpy (abtCmd+38, pbtGBt, szGBt);
01392     }
01393     szOptionalBytes = szGBt + 1;
01394   }
01395   // Historical bytes (ISO/IEC 14443-4)
01396   if (pnd->nc != NC_PN531) { // PN531 does not handle Historical Bytes
01397     abtCmd[37+szOptionalBytes] = (byte_t)(szTkt);
01398     if (szTkt) {
01399       memcpy (abtCmd+38+szOptionalBytes, pbtTkt, szTkt);
01400     }
01401     szOptionalBytes += szTkt + 1;
01402   }
01403 
01404   // Request the initialization as a target
01405   szRx = PN53x_EXTENDED_FRAME_MAX_LEN;
01406 
01407   if (!pn53x_transceive (pnd, abtCmd, 37 + szOptionalBytes, abtRx, &szRx))
01408     return false;
01409 
01410   // Note: the first byte is skip: 
01411   //       its the "mode" byte which contains baudrate, DEP and Framing type (Mifare, active or FeliCa) datas.
01412   if(pbtModeByte) {
01413     *pbtModeByte = abtRx[0];
01414   }
01415 
01416   // Save the received byte count
01417   *pszRx = szRx - 1;
01418   // Copy the received bytes
01419   memcpy (pbtRx, abtRx + 1, *pszRx);
01420 
01421   return true;
01422 }
01423 
01424 bool
01425 pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
01426 {
01427   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
01428   size_t  szRx;
01429   size_t  szFrameBits;
01430   uint8_t ui8rcc;
01431   uint8_t ui8Bits;
01432 
01433   // Try to gather a received frame from the reader
01434   if (!pn53x_transceive (pnd, pncmd_target_get_initiator_command, 2, abtRx, &szRx))
01435     return false;
01436 
01437   // Get the last bit-count that is stored in the received byte 
01438   if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
01439     return false;
01440   ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
01441 
01442   // Recover the real frame length in bits
01443   szFrameBits = ((szRx - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
01444 
01445   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
01446   // Check if we should recover the parity bits ourself
01447   if (!pnd->bPar) {
01448     // Unwrap the response frame
01449     pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
01450   } else {
01451     // Save the received bits
01452     *pszRxBits = szFrameBits;
01453     // Copy the received bytes
01454     memcpy (pbtRx, abtRx + 1, szRx - 1);
01455   }
01456   // Everyting seems ok, return true
01457   return true;
01458 }
01459 
01460 bool
01461 pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx)
01462 {
01463   byte_t const *pbtTx;
01464   byte_t  abtRx[PN53x_EXTENDED_FRAME_MAX_LEN];
01465   size_t  szRx;
01466 
01467   if (pnd->bEasyFraming) {
01468     pbtTx = pncmd_target_get_data;
01469   } else {
01470     pbtTx = pncmd_target_get_initiator_command;
01471   }
01472 
01473   // Try to gather a received frame from the reader
01474   if (!pn53x_transceive (pnd, pbtTx, 2, abtRx, &szRx))
01475     return false;
01476 
01477   // Save the received byte count
01478   *pszRx = szRx - 1;
01479 
01480   // Copy the received bytes
01481   memcpy (pbtRx, abtRx + 1, *pszRx);
01482 
01483   // Everyting seems ok, return true
01484   return true;
01485 }
01486 
01487 bool
01488 pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
01489 {
01490   size_t  szFrameBits = 0;
01491   size_t  szFrameBytes = 0;
01492   uint8_t ui8Bits = 0;
01493   byte_t  abtCmd[sizeof (pncmd_target_response_to_initiator)];
01494 
01495   memcpy (abtCmd, pncmd_target_response_to_initiator, sizeof (pncmd_target_response_to_initiator));
01496 
01497   // Check if we should prepare the parity bits ourself
01498   if (!pnd->bPar) {
01499     // Convert data with parity to a frame
01500     pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
01501   } else {
01502     szFrameBits = szTxBits;
01503   }
01504 
01505   // Retrieve the leading bits
01506   ui8Bits = szFrameBits % 8;
01507 
01508   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
01509   szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
01510 
01511   // When the parity is handled before us, we just copy the data
01512   if (pnd->bPar)
01513     memcpy (abtCmd + 2, pbtTx, szFrameBytes);
01514 
01515   // Set the amount of transmission bits in the PN53X chip register
01516   if (!pn53x_set_tx_bits (pnd, ui8Bits))
01517     return false;
01518 
01519   // Try to send the bits to the reader
01520   if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, NULL, NULL))
01521     return false;
01522 
01523   // Everyting seems ok, return true
01524   return true;
01525 }
01526 
01527 bool
01528 pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx)
01529 {
01530   byte_t  abtCmd[MAX (sizeof (pncmd_target_response_to_initiator), sizeof (pncmd_target_set_data))];
01531 
01532 
01533   // We can not just send bytes without parity if while the PN53X expects we handled them
01534   if (!pnd->bPar)
01535     return false;
01536 
01537   if (pnd->bEasyFraming) {
01538     memcpy (abtCmd, pncmd_target_set_data, sizeof (pncmd_target_set_data));
01539   } else {
01540     memcpy (abtCmd, pncmd_target_response_to_initiator, sizeof (pncmd_target_response_to_initiator));
01541   }
01542 
01543   // Copy the data into the command frame
01544   memcpy (abtCmd + 2, pbtTx, szTx);
01545 
01546   // Try to send the bits to the reader
01547   if (!pn53x_transceive (pnd, abtCmd, szTx + 2, NULL, NULL))
01548     return false;
01549 
01550   // Everyting seems ok, return true
01551   return true;
01552 }
01553 
01554 const pn53x_modulation_t
01555 pn53x_nm_to_pm(const nfc_modulation_t nm)
01556 {
01557   switch(nm.nmt) {
01558     case NMT_ISO14443A:
01559       return PM_ISO14443A_106;
01560     break;
01561 
01562     case NMT_ISO14443B:
01563       switch(nm.nbr) {
01564         case NBR_106:
01565           return PM_ISO14443B_106;
01566         break;
01567         case NBR_212:
01568           return PM_ISO14443B_212;
01569         break;
01570         case NBR_424:
01571           return PM_ISO14443B_424;
01572         break;
01573         case NBR_847:
01574           return PM_ISO14443B_847;
01575         break;
01576         case NBR_UNDEFINED:
01577           // Nothing to do...
01578         break;
01579       }
01580     break;
01581 
01582     case NMT_JEWEL:
01583       return PM_JEWEL_106;
01584     break;
01585 
01586     case NMT_FELICA:
01587       switch(nm.nbr) {
01588         case NBR_212:
01589           return PM_FELICA_212;
01590         break;
01591         case NBR_424:
01592           return PM_FELICA_424;
01593         break;
01594         case NBR_106:
01595         case NBR_847:
01596         case NBR_UNDEFINED:
01597           // Nothing to do...
01598         break;
01599       }
01600     break;
01601     case NMT_DEP:
01602       // Nothing to do...
01603     break;
01604   }
01605   return PM_UNDEFINED;
01606 }
01607 
01608 const nfc_modulation_t
01609 pn53x_ptt_to_nm( const pn53x_target_type_t ptt )
01610 {
01611   switch (ptt) {
01612     case PTT_GENERIC_PASSIVE_106:
01613     case PTT_GENERIC_PASSIVE_212:
01614     case PTT_GENERIC_PASSIVE_424:
01615     case PTT_UNDEFINED:
01616       // XXX This should not happend, how handle it cleanly ?
01617     break;
01618 
01619     case PTT_MIFARE:
01620     case PTT_ISO14443_4A_106:
01621       return (const nfc_modulation_t){ .nmt = NMT_ISO14443A, .nbr = NBR_106 };
01622     break;
01623 
01624     case PTT_ISO14443_4B_106:
01625     case PTT_ISO14443_4B_TCL_106:
01626       return (const nfc_modulation_t){ .nmt = NMT_ISO14443B, .nbr = NBR_106 };
01627     break;
01628 
01629     case PTT_JEWEL_106:
01630       return (const nfc_modulation_t){ .nmt = NMT_JEWEL, .nbr = NBR_106 };
01631     break;
01632 
01633     case PTT_FELICA_212:
01634       return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_212 };
01635     break;
01636     case PTT_FELICA_424:
01637       return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_424 };
01638     break;
01639 
01640     case PTT_DEP_PASSIVE_106:
01641     case PTT_DEP_ACTIVE_106:
01642       return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_106 };
01643     break;
01644     case PTT_DEP_PASSIVE_212:
01645     case PTT_DEP_ACTIVE_212:
01646       return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_212 };
01647     break;
01648     case PTT_DEP_PASSIVE_424:
01649     case PTT_DEP_ACTIVE_424:
01650       return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_424 };
01651     break;
01652   }
01653   // We should never be here, this line silent compilation warning
01654   return (const nfc_modulation_t){ .nmt = NMT_ISO14443A, .nbr = NBR_106 };
01655 }
01656 
01657 const pn53x_target_type_t
01658 pn53x_nm_to_ptt(const nfc_modulation_t nm)
01659 {
01660   switch(nm.nmt) {
01661     case NMT_ISO14443A:
01662       return PTT_MIFARE;
01663       // return PTT_ISO14443_4A_106;
01664     break;
01665 
01666     case NMT_ISO14443B:
01667       switch(nm.nbr) {
01668         case NBR_106:
01669           return PTT_ISO14443_4B_106;
01670         break;
01671         case NBR_UNDEFINED:
01672         case NBR_212:
01673         case NBR_424:
01674         case NBR_847:
01675           // Nothing to do...
01676         break;
01677       }
01678     break;
01679 
01680     case NMT_JEWEL:
01681       return PTT_JEWEL_106;
01682     break;
01683 
01684     case NMT_FELICA:
01685       switch(nm.nbr) {
01686         case NBR_212:
01687           return PTT_FELICA_212;
01688         break;
01689         case NBR_424:
01690           return PTT_FELICA_424;
01691         break;
01692         case NBR_UNDEFINED:
01693         case NBR_106:
01694         case NBR_847:
01695           // Nothing to do...
01696         break;
01697       }
01698     break;
01699 
01700     case NMT_DEP:
01701       // Nothing to do...
01702     break;
01703   }
01704   return PTT_UNDEFINED;
01705 }
01706