libnfc
1.4.2
|
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