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