pn53x.c

00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library
00003  * 
00004  * Copyright (C) 2009, 2010, Roel Verdult, Romuald Conty
00005  * 
00006  * This program is free software: you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation, either version 3 of the License, or (at your
00009  * option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00014  * more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 
00025 #ifdef HAVE_CONFIG_H
00026 #  include "config.h"
00027 #endif // HAVE_CONFIG_H
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <stdlib.h>
00033 
00034 #include <nfc/nfc.h>
00035 // FIXME: WTF are doing debug macros in this file?
00036 #include <nfc/nfc-messages.h>
00037 
00038 #include "pn53x.h"
00039 #include "../mirror-subr.h"
00040 
00041 #ifdef _WIN32
00042 #  include <windows.h>
00043 
00044 #  define strdup _strdup
00045 #  define snprintf sprintf_s
00046 #endif
00047 
00048 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
00049 
00050 // PN53X configuration
00051 const byte_t pncmd_get_firmware_version[2] = { 0xD4, 0x02 };
00052 const byte_t pncmd_get_general_status[2] = { 0xD4, 0x04 };
00053 const byte_t pncmd_get_register[4] = { 0xD4, 0x06 };
00054 const byte_t pncmd_set_register[5] = { 0xD4, 0x08 };
00055 const byte_t pncmd_set_parameters[3] = { 0xD4, 0x12 };
00056 const byte_t pncmd_rf_configure[14] = { 0xD4, 0x32 };
00057 
00058 // Reader
00059 const byte_t pncmd_initiator_list_passive[264] = { 0xD4, 0x4A };
00060 const byte_t pncmd_initiator_jump_for_dep[68] = { 0xD4, 0x56 };
00061 const byte_t pncmd_initiator_select[3] = { 0xD4, 0x54 };
00062 const byte_t pncmd_initiator_deselect[3] = { 0xD4, 0x44, 0x00 };
00063 const byte_t pncmd_initiator_release[3] = { 0xD4, 0x52, 0x00 };
00064 const byte_t pncmd_initiator_set_baud_rate[5] = { 0xD4, 0x4E };
00065 const byte_t pncmd_initiator_exchange_data[265] = { 0xD4, 0x40 };
00066 const byte_t pncmd_initiator_exchange_raw_data[266] = { 0xD4, 0x42 };
00067 const byte_t pncmd_initiator_auto_poll[5] = { 0xD4, 0x60 };
00068 
00069 // Target
00070 const byte_t pncmd_target_get_data[2] = { 0xD4, 0x86 };
00071 const byte_t pncmd_target_set_data[264] = { 0xD4, 0x8E };
00072 const byte_t pncmd_target_init[39] = { 0xD4, 0x8C };
00073 const byte_t pncmd_target_virtual_card[4] = { 0xD4, 0x14 };
00074 const byte_t pncmd_target_receive[2] = { 0xD4, 0x88 };
00075 const byte_t pncmd_target_send[264] = { 0xD4, 0x90 };
00076 const byte_t pncmd_target_get_status[2] = { 0xD4, 0x8A };
00077 
00078 static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
00079 static const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
00080 static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
00081 
00082 // XXX: Is this function correctly named ?
00083 bool
00084 pn53x_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
00085 {
00086   if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
00087     if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
00088       DBG ("%s", "PN53x ACKed");
00089       return true;
00090     } else if (0 == memcmp (pbtRxFrame, pn53x_nack_frame, sizeof (pn53x_nack_frame))) {
00091       DBG ("%s", "PN53x NACKed");
00092       // TODO: Try to recover
00093       // A counter could allow the command to be sent again (e.g. max 3 times)
00094       pnd->iLastError = DENACK;
00095       return false;
00096     }
00097   }
00098   pnd->iLastError = DEACKMISMATCH;
00099   ERR ("%s", "Unexpected PN53x reply!");
00100 #if defined(DEBUG)
00101   // coredump so that we can have a backtrace about how this code was reached.
00102   abort ();
00103 #endif
00104   return false;
00105 }
00106 
00107 bool
00108 pn53x_transceive_check_error_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
00109 {
00110   if (szRxFrameLen >= sizeof (pn53x_error_frame)) {
00111     if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) {
00112       DBG ("%s", "PN53x sent an error frame");
00113       pnd->iLastError = DEISERRFRAME;
00114       return false;
00115     }
00116   }
00117 
00118   return true;
00119 }
00120 
00121 bool
00122 pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen)
00123 {
00124   byte_t  abtRx[MAX_FRAME_LEN];
00125   size_t  szRxLen;
00126 
00127   // Check if receiving buffers are available, if not, replace them
00128   if (!pszRxLen || !pbtRx) {
00129     pbtRx = abtRx;
00130     pszRxLen = &szRxLen;
00131   }
00132 
00133   *pszRxLen = MAX_FRAME_LEN;
00134   // Call the tranceive callback function of the current device
00135   if (!pnd->pdc->transceive (pnd, pbtTx, szTxLen, pbtRx, pszRxLen))
00136     return false;
00137 
00138   switch (pbtTx[1]) {
00139   case 0x16:                   // PowerDown
00140   case 0x40:                   // InDataExchange
00141   case 0x42:                   // InCommunicateThru
00142   case 0x44:                   // InDeselect
00143   case 0x46:                   // InJumpForPSL
00144   case 0x4e:                   // InPSL
00145   case 0x50:                   // InATR
00146   case 0x52:                   // InRelease
00147   case 0x54:                   // InSelect
00148   case 0x56:                   // InJumpForDEP
00149   case 0x86:                   // TgGetData
00150   case 0x88:                   // TgGetInitiatorCommand
00151   case 0x8e:                   // TgSetData
00152   case 0x90:                   // TgResponseToInitiator
00153   case 0x92:                   // TgSetGeneralBytes
00154   case 0x94:                   // TgSetMetaData
00155     pnd->iLastError = pbtRx[0] & 0x3f;
00156     break;
00157   default:
00158     pnd->iLastError = 0;
00159   }
00160 
00161   return (0 == pnd->iLastError);
00162 }
00163 
00164 bool
00165 pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value)
00166 {
00167   size_t  szValueLen = 1;
00168   byte_t  abtCmd[sizeof (pncmd_get_register)];
00169   memcpy (abtCmd, pncmd_get_register, sizeof (pncmd_get_register));
00170 
00171   abtCmd[2] = ui16Reg >> 8;
00172   abtCmd[3] = ui16Reg & 0xff;
00173   return pn53x_transceive (pnd, abtCmd, 4, ui8Value, &szValueLen);
00174 }
00175 
00176 bool
00177 pn53x_set_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
00178 {
00179   uint8_t ui8Current;
00180   byte_t  abtCmd[sizeof (pncmd_set_register)];
00181   memcpy (abtCmd, pncmd_set_register, sizeof (pncmd_set_register));
00182 
00183   abtCmd[2] = ui16Reg >> 8;
00184   abtCmd[3] = ui16Reg & 0xff;
00185   if (!pn53x_get_reg (pnd, ui16Reg, &ui8Current))
00186     return false;
00187 
00188   abtCmd[4] = ui8Value | (ui8Current & (~ui8SybmolMask));
00189   return pn53x_transceive (pnd, abtCmd, 5, NULL, NULL);
00190 }
00191 
00192 bool
00193 pn53x_set_parameters (nfc_device_t * pnd, uint8_t ui8Value)
00194 {
00195   byte_t  abtCmd[sizeof (pncmd_set_parameters)];
00196   memcpy (abtCmd, pncmd_set_parameters, sizeof (pncmd_set_parameters));
00197 
00198   abtCmd[2] = ui8Value;
00199   return pn53x_transceive (pnd, abtCmd, 3, NULL, NULL);
00200 }
00201 
00202 bool
00203 pn53x_set_tx_bits (nfc_device_t * pnd, uint8_t ui8Bits)
00204 {
00205   // Test if we need to update the transmission bits register setting
00206   if (pnd->ui8TxBits != ui8Bits) {
00207     // Set the amount of transmission bits in the PN53X chip register
00208     if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, ui8Bits))
00209       return false;
00210 
00211     // Store the new setting
00212     ((nfc_device_t *) pnd)->ui8TxBits = ui8Bits;
00213   }
00214   return true;
00215 }
00216 
00217 bool
00218 pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtFrame,
00219                   size_t * pszFrameBits)
00220 {
00221   byte_t  btFrame;
00222   byte_t  btData;
00223   uint32_t uiBitPos;
00224   uint32_t uiDataPos = 0;
00225   size_t  szBitsLeft = szTxBits;
00226 
00227   // Make sure we should frame at least something
00228   if (szBitsLeft == 0)
00229     return false;
00230 
00231   // Handle a short response (1byte) as a special case
00232   if (szBitsLeft < 9) {
00233     *pbtFrame = *pbtTx;
00234     *pszFrameBits = szTxBits;
00235     return true;
00236   }
00237   // We start by calculating the frame length in bits
00238   *pszFrameBits = szTxBits + (szTxBits / 8);
00239 
00240   // Parse the data bytes and add the parity bits
00241   // This is really a sensitive process, mirror the frame bytes and append parity bits
00242   // buffer = mirror(frame-byte) + parity + mirror(frame-byte) + parity + ...
00243   // split "buffer" up in segments of 8 bits again and mirror them
00244   // air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
00245   while (true) {
00246     // Reset the temporary frame byte;
00247     btFrame = 0;
00248 
00249     for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
00250       // Copy as much data that fits in the frame byte
00251       btData = mirror (pbtTx[uiDataPos]);
00252       btFrame |= (btData >> uiBitPos);
00253       // Save this frame byte
00254       *pbtFrame = mirror (btFrame);
00255       // Set the remaining bits of the date in the new frame byte and append the parity bit
00256       btFrame = (btData << (8 - uiBitPos));
00257       btFrame |= ((pbtTxPar[uiDataPos] & 0x01) << (7 - uiBitPos));
00258       // Backup the frame bits we have so far
00259       pbtFrame++;
00260       *pbtFrame = mirror (btFrame);
00261       // Increase the data (without parity bit) position
00262       uiDataPos++;
00263       // Test if we are done
00264       if (szBitsLeft < 9)
00265         return true;
00266       szBitsLeft -= 8;
00267     }
00268     // Every 8 data bytes we lose one frame byte to the parities
00269     pbtFrame++;
00270   }
00271 }
00272 
00273 bool
00274 pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
00275                     byte_t * pbtRxPar)
00276 {
00277   byte_t  btFrame;
00278   byte_t  btData;
00279   uint8_t uiBitPos;
00280   uint32_t uiDataPos = 0;
00281   byte_t *pbtFramePos = (byte_t *) pbtFrame;
00282   size_t  szBitsLeft = szFrameBits;
00283 
00284   // Make sure we should frame at least something
00285   if (szBitsLeft == 0)
00286     return false;
00287 
00288   // Handle a short response (1byte) as a special case
00289   if (szBitsLeft < 9) {
00290     *pbtRx = *pbtFrame;
00291     *pszRxBits = szFrameBits;
00292     return true;
00293   }
00294   // Calculate the data length in bits
00295   *pszRxBits = szFrameBits - (szFrameBits / 9);
00296 
00297   // Parse the frame bytes, remove the parity bits and store them in the parity array
00298   // This process is the reverse of WrapFrame(), look there for more info
00299   while (true) {
00300     for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
00301       btFrame = mirror (pbtFramePos[uiDataPos]);
00302       btData = (btFrame << uiBitPos);
00303       btFrame = mirror (pbtFramePos[uiDataPos + 1]);
00304       btData |= (btFrame >> (8 - uiBitPos));
00305       pbtRx[uiDataPos] = mirror (btData);
00306       if (pbtRxPar != NULL)
00307         pbtRxPar[uiDataPos] = ((btFrame >> (7 - uiBitPos)) & 0x01);
00308       // Increase the data (without parity bit) position
00309       uiDataPos++;
00310       // Test if we are done
00311       if (szBitsLeft < 9)
00312         return true;
00313       szBitsLeft -= 9;
00314     }
00315     // Every 8 data bytes we lose one frame byte to the parities
00316     pbtFramePos++;
00317   }
00318 }
00319 
00320 bool
00321 pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt,
00322                           nfc_target_info_t * pnti)
00323 {
00324   uint8_t ui8AttribResLen;
00325   switch (ntt) {
00326   case NTT_MIFARE:
00327   case NTT_GENERIC_PASSIVE_106:
00328     // We skip the first byte: its the target number (Tg)
00329     pbtRawData++;
00330 
00331     // Somehow they switched the lower and upper ATQA bytes around for the PN531 chipset
00332     if (nc == NC_PN531) {
00333       pnti->nai.abtAtqa[1] = *(pbtRawData++);
00334       pnti->nai.abtAtqa[0] = *(pbtRawData++);
00335     } else {
00336       pnti->nai.abtAtqa[0] = *(pbtRawData++);
00337       pnti->nai.abtAtqa[1] = *(pbtRawData++);
00338     }
00339     pnti->nai.btSak = *(pbtRawData++);
00340     // Copy the NFCID1
00341     pnti->nai.szUidLen = *(pbtRawData++);
00342     memcpy (pnti->nai.abtUid, pbtRawData, pnti->nai.szUidLen);
00343     pbtRawData += pnti->nai.szUidLen;
00344 
00345     // Did we received an optional ATS (Smardcard ATR)
00346     if (szDataLen > (pnti->nai.szUidLen + 5)) {
00347       pnti->nai.szAtsLen = ((*(pbtRawData++)) - 1);     // In pbtRawData, ATS Length byte is counted in ATS Frame.
00348       memcpy (pnti->nai.abtAts, pbtRawData, pnti->nai.szAtsLen);
00349     } else {
00350       pnti->nai.szAtsLen = 0;
00351     }
00352 
00353     // Strip CT (Cascade Tag) to retrieve and store the _real_ UID
00354     // (e.g. 0x8801020304050607 is in fact 0x01020304050607)
00355     if ((pnti->nai.szUidLen == 8) && (pnti->nai.abtUid[0] == 0x88)) {
00356       pnti->nai.szUidLen = 7;
00357       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 7);
00358     } else if ((pnti->nai.szUidLen == 12) && (pnti->nai.abtUid[0] == 0x88) && (pnti->nai.abtUid[4] == 0x88)) {
00359       pnti->nai.szUidLen = 10;
00360       memmove (pnti->nai.abtUid, pnti->nai.abtUid + 1, 3);
00361       memmove (pnti->nai.abtUid + 3, pnti->nai.abtUid + 5, 7);
00362     }
00363     break;
00364 
00365   case NTT_ISO14443B_106:
00366     // We skip the first byte: its the target number (Tg)
00367     pbtRawData++;
00368 
00369     // Store the mandatory info
00370     memcpy (pnti->nbi.abtAtqb, pbtRawData, 12);
00371     pbtRawData += 12;
00372 
00373     // Store temporarily the ATTRIB_RES length
00374     ui8AttribResLen = *(pbtRawData++);
00375 
00376     // Store the 4 bytes ID
00377     memcpy (pnti->nbi.abtId, pbtRawData, 4);
00378     pbtRawData += 4;
00379 
00380     pnti->nbi.btParam1 = *(pbtRawData++);
00381     pnti->nbi.btParam2 = *(pbtRawData++);
00382     pnti->nbi.btParam3 = *(pbtRawData++);
00383     pnti->nbi.btParam4 = *(pbtRawData++);
00384 
00385     // Test if the Higher layer (INF) is available
00386     if (ui8AttribResLen > 8) {
00387       pnti->nbi.szInfLen = *(pbtRawData++);
00388       memcpy (pnti->nbi.abtInf, pbtRawData, pnti->nbi.szInfLen);
00389     } else {
00390       pnti->nbi.szInfLen = 0;
00391     }
00392     break;
00393 
00394   case NTT_FELICA_212:
00395   case NTT_FELICA_424:
00396     // We skip the first byte: its the target number (Tg)
00397     pbtRawData++;
00398 
00399     // Store the mandatory info
00400     pnti->nfi.szLen = *(pbtRawData++);
00401     pnti->nfi.btResCode = *(pbtRawData++);
00402     // Copy the NFCID2t
00403     memcpy (pnti->nfi.abtId, pbtRawData, 8);
00404     pbtRawData += 8;
00405     // Copy the felica padding
00406     memcpy (pnti->nfi.abtPad, pbtRawData, 8);
00407     pbtRawData += 8;
00408     // Test if the System code (SYST_CODE) is available
00409     if (pnti->nfi.szLen > 18) {
00410       memcpy (pnti->nfi.abtSysCode, pbtRawData, 2);
00411     }
00412     break;
00413   case NTT_JEWEL_106:
00414     // We skip the first byte: its the target number (Tg)
00415     pbtRawData++;
00416 
00417     // Store the mandatory info
00418     memcpy (pnti->nji.btSensRes, pbtRawData, 2);
00419     pbtRawData += 2;
00420     memcpy (pnti->nji.btId, pbtRawData, 4);
00421     break;
00422   default:
00423     return false;
00424     break;
00425   }
00426   return true;
00427 }
00428 
00443 bool
00444 pn53x_InListPassiveTarget (nfc_device_t * pnd,
00445                            const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets,
00446                            const byte_t * pbtInitiatorData, const size_t szInitiatorDataLen,
00447                            byte_t * pbtTargetsData, size_t * pszTargetsData)
00448 {
00449   size_t  szRxLen;
00450   byte_t  abtCmd[sizeof (pncmd_initiator_list_passive)];
00451   memcpy (abtCmd, pncmd_initiator_list_passive, sizeof (pncmd_initiator_list_passive));
00452 
00453   // FIXME PN531 doesn't support all available modulations
00454   abtCmd[2] = szMaxTargets;     // MaxTg
00455   abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
00456 
00457   // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
00458   if (pbtInitiatorData)
00459     memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorDataLen);
00460 
00461   // Try to find a tag, call the tranceive callback function of the current device
00462   szRxLen = MAX_FRAME_LEN;
00463   if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorDataLen, pbtTargetsData, &szRxLen)) {
00464     *pszTargetsData = szRxLen;
00465     return true;
00466   } else {
00467     return false;
00468   }
00469 }
00470 
00471 bool
00472 pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target)
00473 {
00474   byte_t  abtCmd[sizeof (pncmd_initiator_deselect)];
00475   memcpy (abtCmd, pncmd_initiator_deselect, sizeof (pncmd_initiator_deselect));
00476   abtCmd[2] = ui8Target;
00477 
00478   return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL));
00479 }
00480 
00481 bool
00482 pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target)
00483 {
00484   byte_t  abtCmd[sizeof (pncmd_initiator_release)];
00485   memcpy (abtCmd, pncmd_initiator_release, sizeof (pncmd_initiator_release));
00486   abtCmd[2] = ui8Target;
00487 
00488   return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL));
00489 }
00490 
00491 bool
00492 pn53x_InAutoPoll (nfc_device_t * pnd,
00493                   const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes,
00494                   const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound)
00495 {
00496   size_t  szTxInAutoPoll,
00497           n,
00498           szRxLen;
00499   byte_t  abtRx[MAX_FRAME_LEN];
00500   bool    res;
00501   byte_t *pbtTxInAutoPoll;
00502 
00503   if (pnd->nc != NC_PN532) {
00504     // This function is not supported by pn531 neither pn533
00505     pnd->iLastError = DENOTSUP;
00506     return false;
00507   }
00508   // InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... }
00509   szTxInAutoPoll = 4 + szTargetTypes;
00510   pbtTxInAutoPoll = malloc (szTxInAutoPoll);
00511   pbtTxInAutoPoll[0] = 0xd4;
00512   pbtTxInAutoPoll[1] = 0x60;
00513   pbtTxInAutoPoll[2] = btPollNr;
00514   pbtTxInAutoPoll[3] = btPeriod;
00515   for (n = 0; n < szTargetTypes; n++) {
00516     pbtTxInAutoPoll[4 + n] = pnttTargetTypes[n];
00517   }
00518 
00519   szRxLen = MAX_FRAME_LEN;
00520   res = pnd->pdc->transceive (pnd, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen);
00521 
00522   if ((szRxLen == 0) || (res == false)) {
00523     return false;
00524   } else {
00525     *pszTargetFound = abtRx[0];
00526     if (*pszTargetFound) {
00527       uint8_t ln;
00528       byte_t *pbt = abtRx + 1;
00529       /* 1st target */
00530       // Target type
00531       pntTargets[0].ntt = *(pbt++);
00532       // AutoPollTargetData length
00533       ln = *(pbt++);
00534       pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[0].ntt, &(pntTargets[0].nti));
00535       pbt += ln;
00536 
00537       if (abtRx[0] > 1) {
00538         /* 2nd target */
00539         // Target type
00540         pntTargets[1].ntt = *(pbt++);
00541         // AutoPollTargetData length
00542         ln = *(pbt++);
00543         pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[1].ntt, &(pntTargets[1].nti));
00544       }
00545     }
00546   }
00547   return true;
00548 }
00549 
00550 static struct sErrorMessage {
00551   int     iErrorCode;
00552   const char *pcErrorMsg;
00553 } sErrorMessages[] = {
00554   /* Chip-level errors */
00555   {
00556   0x00, "Success"}, {
00557   0x01, "Timeout"}, {
00558   0x02, "CRC Error"}, {
00559   0x03, "Parity Error"}, {
00560   0x04, "Erroneous Bit Count"}, {
00561   0x05, "Framing Error"}, {
00562   0x06, "Bit-collision"}, {
00563   0x07, "Buffer Too Small"}, {
00564   0x09, "Buffer Overflow"}, {
00565   0x0a, "Timeout"}, {
00566   0x0b, "Protocol Error"}, {
00567   0x0d, "Overheating"}, {
00568   0x0e, "Internal Buffer overflow."}, {
00569   0x10, "Invalid Parameter"},
00570     /* DEP Errors */
00571   {
00572   0x12, "Unknown DEP Command"}, {
00573   0x13, "Invalid Parameter"},
00574     /* MIFARE */
00575   {
00576   0x14, "Authentication Error"},
00577     /*  */
00578   {
00579   0x23, "Wrong ISO/IEC14443-3 Check Byte"}, {
00580   0x25, "Invalid State"}, {
00581   0x26, "Operation Not Allowed"}, {
00582   0x27, "Command Not Acceptable"}, {
00583   0x29, "Target Released"}, {
00584   0x2a, "Card ID Mismatch"}, {
00585   0x2B, "Card Discarded"}, {
00586   0x2C, "NFCID3 Mismatch"}, {
00587   0x2D, "Over Current"}, {
00588   0x2E, "NAD Missing in DEP Frame"},
00589     /* Driver-level error */
00590   {
00591   DENACK, "Received NACK"}, {
00592   DEACKMISMATCH, "Expected ACK/NACK"}, {
00593   DEISERRFRAME, "Received an error frame"},
00594     /* TODO: Move me in more generic code for libnfc 1.6 */
00595   {
00596   DEINVAL, "Invalid argument"}, {
00597   DEIO, "Input/output error"}, {
00598   DETIMEOUT, "Operation timed-out"}, {
00599   DENOTSUP, "Operation not supported"}
00600 };
00601 
00602 const char *
00603 pn53x_strerror (const nfc_device_t * pnd)
00604 {
00605   const char *pcRes = "Unknown error";
00606   size_t  i;
00607 
00608   for (i = 0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) {
00609     if (sErrorMessages[i].iErrorCode == pnd->iLastError) {
00610       pcRes = sErrorMessages[i].pcErrorMsg;
00611       break;
00612     }
00613   }
00614 
00615   return pcRes;
00616 }
00617 
00618 bool
00619 pn53x_get_firmware_version (nfc_device_t * pnd)
00620 {
00621   byte_t  abtFw[4];
00622   size_t  szFwLen = sizeof (abtFw);
00623   char   *pcName;
00624 
00625   if (!pn53x_transceive (pnd, pncmd_get_firmware_version, 2, abtFw, &szFwLen)) {
00626     // Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
00627     DBG ("Failed to get firmware revision for: %s", pnd->acName);
00628     pnd->pdc->disconnect (pnd);
00629     return false;
00630   }
00631   // Add the firmware revision to the device name, PN531 gives 2 bytes info, but PN532 and PN533 gives 4
00632   pcName = strdup (pnd->acName);
00633   switch (pnd->nc) {
00634   case NC_PN531:
00635     snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN531 v%d.%d", pcName, abtFw[0], abtFw[1]);
00636     break;
00637   case NC_PN532:
00638     snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN532 v%d.%d (0x%02x)", pcName, abtFw[1], abtFw[2], abtFw[3]);
00639     break;
00640   case NC_PN533:
00641     snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN533 v%d.%d (0x%02x)", pcName, abtFw[1], abtFw[2], abtFw[3]);
00642     break;
00643   }
00644   free (pcName);
00645   return true;
00646 }
00647 
00648 bool
00649 pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
00650 {
00651   byte_t  btValue;
00652   byte_t  abtCmd[sizeof (pncmd_rf_configure)];
00653 
00654   memcpy (abtCmd, pncmd_rf_configure, sizeof (pncmd_rf_configure));
00655 
00656   // Make sure we are dealing with a active device
00657   if (!pnd->bActive)
00658     return false;
00659 
00660   switch (ndo) {
00661   case NDO_HANDLE_CRC:
00662     // Enable or disable automatic receiving/sending of CRC bytes
00663     // TX and RX are both represented by the symbol 0x80
00664     btValue = (bEnable) ? 0x80 : 0x00;
00665     if (!pn53x_set_reg (pnd, REG_CIU_TX_MODE, SYMBOL_TX_CRC_ENABLE, btValue))
00666       return false;
00667     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_CRC_ENABLE, btValue))
00668       return false;
00669     pnd->bCrc = bEnable;
00670     break;
00671 
00672   case NDO_HANDLE_PARITY:
00673     // Handle parity bit by PN53X chip or parse it as data bit
00674     btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE;
00675     if (!pn53x_set_reg (pnd, REG_CIU_MANUAL_RCV, SYMBOL_PARITY_DISABLE, btValue))
00676       return false;
00677     pnd->bPar = bEnable;
00678     break;
00679 
00680   case NDO_EASY_FRAMING:
00681     pnd->bEasyFraming = bEnable;
00682     break;
00683 
00684   case NDO_ACTIVATE_FIELD:
00685     abtCmd[2] = RFCI_FIELD;
00686     abtCmd[3] = (bEnable) ? 1 : 0;
00687     if (!pn53x_transceive (pnd, abtCmd, 4, NULL, NULL))
00688       return false;
00689     break;
00690 
00691   case NDO_ACTIVATE_CRYPTO1:
00692     btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
00693     if (!pn53x_set_reg (pnd, REG_CIU_STATUS2, SYMBOL_MF_CRYPTO1_ON, btValue))
00694       return false;
00695     break;
00696 
00697   case NDO_INFINITE_SELECT:
00698     // Retry format: 0x00 means only 1 try, 0xff means infinite
00699     abtCmd[2] = RFCI_RETRY_SELECT;
00700     abtCmd[3] = (bEnable) ? 0xff : 0x00;        // MxRtyATR, default: active = 0xff, passive = 0x02
00701     abtCmd[4] = (bEnable) ? 0xff : 0x00;        // MxRtyPSL, default: 0x01
00702     abtCmd[5] = (bEnable) ? 0xff : 0x00;        // MxRtyPassiveActivation, default: 0xff
00703     if (!pn53x_transceive (pnd, abtCmd, 6, NULL, NULL))
00704       return false;
00705     break;
00706 
00707   case NDO_ACCEPT_INVALID_FRAMES:
00708     btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
00709     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_NO_ERROR, btValue))
00710       return false;
00711     break;
00712 
00713   case NDO_ACCEPT_MULTIPLE_FRAMES:
00714     btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
00715     if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_MULTIPLE, btValue))
00716       return false;
00717     return true;
00718     break;
00719 
00720   case NDO_AUTO_ISO14443_4:
00721     // TODO: PN53x parameters could not be read, so we have to buffered current value in order to prevent from configuration overwrite
00722     // ATM, buffered current value is not needed due to a single usage of these parameters
00723     btValue =
00724       (bEnable) ? (SYMBOL_PARAM_fAutomaticRATS | SYMBOL_PARAM_fAutomaticATR_RES) : SYMBOL_PARAM_fAutomaticATR_RES;
00725     if (!pn53x_set_parameters (pnd, btValue))
00726       return false;
00727     return true;
00728     break;
00729   }
00730 
00731   // When we reach this, the configuration is completed and succesful
00732   return true;
00733 }
00734 
00735 bool
00736 pn53x_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
00737                                    const byte_t * pbtPidData, const size_t szPidDataLen, const byte_t * pbtNFCID3i,
00738                                    const size_t szNFCID3iDataLen, const byte_t * pbtGbData, const size_t szGbDataLen,
00739                                    nfc_target_info_t * pnti)
00740 {
00741   byte_t  abtRx[MAX_FRAME_LEN];
00742   size_t  szRxLen;
00743   size_t  offset;
00744   byte_t  abtCmd[sizeof (pncmd_initiator_jump_for_dep)];
00745 
00746   memcpy (abtCmd, pncmd_initiator_jump_for_dep, sizeof (pncmd_initiator_jump_for_dep));
00747 
00748   if (nmInitModulation == NM_ACTIVE_DEP) {
00749     abtCmd[2] = 0x01;           /* active DEP */
00750   }
00751   abtCmd[3] = 0x00;             /* baud rate = 106kbps */
00752 
00753   offset = 5;
00754   if (pbtPidData && nmInitModulation != NM_ACTIVE_DEP) {        /* can't have passive initiator data when using active mode */
00755     abtCmd[4] |= 0x01;
00756     memcpy (abtCmd + offset, pbtPidData, szPidDataLen);
00757     offset += szPidDataLen;
00758   }
00759 
00760   if (pbtNFCID3i) {
00761     abtCmd[4] |= 0x02;
00762     memcpy (abtCmd + offset, pbtNFCID3i, szNFCID3iDataLen);
00763     offset += szNFCID3iDataLen;
00764   }
00765 
00766   if (pbtGbData) {
00767     abtCmd[4] |= 0x04;
00768     memcpy (abtCmd + offset, pbtGbData, szGbDataLen);
00769     offset += szGbDataLen;
00770   }
00771   // Try to find a target, call the transceive callback function of the current device
00772   if (!pn53x_transceive (pnd, abtCmd, 5 + szPidDataLen + szNFCID3iDataLen + szGbDataLen, abtRx, &szRxLen))
00773     return false;
00774 
00775   // Make sure one target has been found, the PN53X returns 0x00 if none was available
00776   if (abtRx[1] != 1)
00777     return false;
00778 
00779   // Is a target info struct available
00780   if (pnti) {
00781     memcpy (pnti->ndi.NFCID3i, abtRx + 2, 10);
00782     pnti->ndi.btDID = abtRx[12];
00783     pnti->ndi.btBSt = abtRx[13];
00784     pnti->ndi.btBRt = abtRx[14];
00785   }
00786   return true;
00787 }
00788 
00789 bool
00790 pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
00791                                  const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
00792 {
00793   byte_t  abtRx[MAX_FRAME_LEN];
00794   size_t  szRxLen;
00795   size_t  szFrameBits = 0;
00796   size_t  szFrameBytes = 0;
00797   uint8_t ui8rcc;
00798   uint8_t ui8Bits = 0;
00799   byte_t  abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
00800 
00801   memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
00802 
00803   // Check if we should prepare the parity bits ourself
00804   if (!pnd->bPar) {
00805     // Convert data with parity to a frame
00806     pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
00807   } else {
00808     szFrameBits = szTxBits;
00809   }
00810 
00811   // Retrieve the leading bits
00812   ui8Bits = szFrameBits % 8;
00813 
00814   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
00815   szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
00816 
00817   // When the parity is handled before us, we just copy the data
00818   if (pnd->bPar)
00819     memcpy (abtCmd + 2, pbtTx, szFrameBytes);
00820 
00821   // Set the amount of transmission bits in the PN53X chip register
00822   if (!pn53x_set_tx_bits (pnd, ui8Bits))
00823     return false;
00824 
00825   // Send the frame to the PN53X chip and get the answer
00826   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
00827   if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, abtRx, &szRxLen))
00828     return false;
00829 
00830   // Get the last bit-count that is stored in the received byte 
00831   if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
00832     return false;
00833   ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
00834 
00835   // Recover the real frame length in bits
00836   szFrameBits = ((szRxLen - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
00837 
00838   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
00839   // Check if we should recover the parity bits ourself
00840   if (!pnd->bPar) {
00841     // Unwrap the response frame
00842     pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
00843   } else {
00844     // Save the received bits
00845     *pszRxBits = szFrameBits;
00846     // Copy the received bytes
00847     memcpy (pbtRx, abtRx + 1, szRxLen - 1);
00848   }
00849 
00850   // Everything went successful
00851   return true;
00852 }
00853 
00854 bool
00855 pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
00856                                   size_t * pszRxLen)
00857 {
00858   byte_t  abtRx[MAX_FRAME_LEN];
00859   size_t  szExtraTxLen,
00860           szRxLen;
00861   byte_t  abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
00862 
00863   // We can not just send bytes without parity if while the PN53X expects we handled them
00864   if (!pnd->bPar)
00865     return false;
00866 
00867   // Copy the data into the command frame
00868   if (pnd->bEasyFraming) {
00869     memcpy (abtCmd, pncmd_initiator_exchange_data, sizeof (pncmd_initiator_exchange_data));
00870     abtCmd[2] = 1;              /* target number */
00871     memcpy (abtCmd + 3, pbtTx, szTxLen);
00872     szExtraTxLen = 3;
00873   } else {
00874     memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
00875     memcpy (abtCmd + 2, pbtTx, szTxLen);
00876     szExtraTxLen = 2;
00877   }
00878 
00879   // To transfer command frames bytes we can not have any leading bits, reset this to zero
00880   if (!pn53x_set_tx_bits (pnd, 0))
00881     return false;
00882 
00883   // Send the frame to the PN53X chip and get the answer
00884   // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
00885   if (!pn53x_transceive (pnd, abtCmd, szTxLen + szExtraTxLen, abtRx, &szRxLen))
00886     return false;
00887 
00888   // Save the received byte count
00889   *pszRxLen = szRxLen - 1;
00890 
00891   // Copy the received bytes
00892   memcpy (pbtRx, abtRx + 1, *pszRxLen);
00893 
00894   // Everything went successful
00895   return true;
00896 }
00897 
00898 bool
00899 pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
00900 {
00901   byte_t  abtRx[MAX_FRAME_LEN];
00902   size_t  szRxLen;
00903   uint8_t ui8rcc;
00904   uint8_t ui8Bits;
00905   // Save the current configuration settings
00906   bool    bCrc = pnd->bCrc;
00907   bool    bPar = pnd->bPar;
00908   byte_t  abtCmd[sizeof (pncmd_target_init)];
00909 
00910   memcpy (abtCmd, pncmd_target_init, sizeof (pncmd_target_init));
00911 
00912   // Clear the target init struct, reset to all zeros
00913   memset (abtCmd + 2, 0x00, 37);
00914 
00915   // Set ATQA (SENS_RES)
00916   abtCmd[3] = 0x04;
00917   abtCmd[4] = 0x00;
00918 
00919   // Set SAK (SEL_RES)
00920   abtCmd[8] = 0x20;
00921 
00922   // Set UID
00923   abtCmd[5] = 0x00;
00924   abtCmd[6] = 0xb0;
00925   abtCmd[7] = 0x0b;
00926 
00927   // Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
00928   if (!bCrc)
00929     nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, true);
00930   if (!bPar)
00931     nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, true);
00932 
00933   // Let the PN53X be activated by the RF level detector from power down mode
00934   if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON, 0x04))
00935     return false;
00936 
00937   // Request the initialization as a target
00938   szRxLen = MAX_FRAME_LEN;
00939   if (!pn53x_transceive (pnd, abtCmd, 39, abtRx, &szRxLen))
00940     return false;
00941 
00942   // Get the last bit-count that is stored in the received byte 
00943   if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
00944     return false;
00945   ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
00946 
00947   // We are sure the parity is handled by the PN53X chip, so we handle it this way
00948   *pszRxBits = ((szRxLen - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
00949   // Copy the received bytes
00950   memcpy (pbtRx, abtRx + 1, szRxLen - 1);
00951 
00952   // Restore the CRC & parity setting to the original value (if needed)
00953   if (!bCrc)
00954     nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, false);
00955   if (!bPar)
00956     nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, false);
00957 
00958   return true;
00959 }
00960 
00961 bool
00962 pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
00963 {
00964   byte_t  abtRx[MAX_FRAME_LEN];
00965   size_t  szRxLen;
00966   size_t  szFrameBits;
00967   uint8_t ui8rcc;
00968   uint8_t ui8Bits;
00969 
00970   // Try to gather a received frame from the reader
00971   if (!pn53x_transceive (pnd, pncmd_target_receive, 2, abtRx, &szRxLen))
00972     return false;
00973 
00974   // Get the last bit-count that is stored in the received byte 
00975   if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
00976     return false;
00977   ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
00978 
00979   // Recover the real frame length in bits
00980   szFrameBits = ((szRxLen - 1 - ((ui8Bits == 0) ? 0 : 1)) * 8) + ui8Bits;
00981 
00982   // Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
00983   // Check if we should recover the parity bits ourself
00984   if (!pnd->bPar) {
00985     // Unwrap the response frame
00986     pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
00987   } else {
00988     // Save the received bits
00989     *pszRxBits = szFrameBits;
00990     // Copy the received bytes
00991     memcpy (pbtRx, abtRx + 1, szRxLen - 1);
00992   }
00993   // Everyting seems ok, return true
00994   return true;
00995 }
00996 
00997 bool
00998 pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen)
00999 {
01000   byte_t const *pbtTx;
01001   byte_t  abtRx[MAX_FRAME_LEN];
01002   size_t  szRxLen;
01003 
01004   if (pnd->bEasyFraming) {
01005     pbtTx = pncmd_target_get_data;
01006   } else {
01007     pbtTx = pncmd_target_receive;
01008   }
01009 
01010   // Try to gather a received frame from the reader
01011   if (!pn53x_transceive (pnd, pbtTx, 2, abtRx, &szRxLen))
01012     return false;
01013 
01014   // Save the received byte count
01015   *pszRxLen = szRxLen - 1;
01016 
01017   // Copy the received bytes
01018   memcpy (pbtRx, abtRx + 1, *pszRxLen);
01019 
01020   // Everyting seems ok, return true
01021   return true;
01022 }
01023 
01024 bool
01025 pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
01026 {
01027   size_t  szFrameBits = 0;
01028   size_t  szFrameBytes = 0;
01029   uint8_t ui8Bits = 0;
01030   byte_t  abtCmd[sizeof (pncmd_target_send)];
01031 
01032   memcpy (abtCmd, pncmd_target_send, sizeof (pncmd_target_send));
01033 
01034   // Check if we should prepare the parity bits ourself
01035   if (!pnd->bPar) {
01036     // Convert data with parity to a frame
01037     pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
01038   } else {
01039     szFrameBits = szTxBits;
01040   }
01041 
01042   // Retrieve the leading bits
01043   ui8Bits = szFrameBits % 8;
01044 
01045   // Get the amount of frame bytes + optional (1 byte if there are leading bits) 
01046   szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
01047 
01048   // When the parity is handled before us, we just copy the data
01049   if (pnd->bPar)
01050     memcpy (abtCmd + 2, pbtTx, szFrameBytes);
01051 
01052   // Set the amount of transmission bits in the PN53X chip register
01053   if (!pn53x_set_tx_bits (pnd, ui8Bits))
01054     return false;
01055 
01056   // Try to send the bits to the reader
01057   if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, NULL, NULL))
01058     return false;
01059 
01060   // Everyting seems ok, return true
01061   return true;
01062 }
01063 
01064 bool
01065 pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen)
01066 {
01067   byte_t  abtCmd[MAX (sizeof (pncmd_target_send), sizeof (pncmd_target_set_data))];
01068 
01069 
01070   // We can not just send bytes without parity if while the PN53X expects we handled them
01071   if (!pnd->bPar)
01072     return false;
01073 
01074   if (pnd->bEasyFraming) {
01075     memcpy (abtCmd, pncmd_target_set_data, sizeof (pncmd_target_set_data));
01076   } else {
01077     memcpy (abtCmd, pncmd_target_send, sizeof (pncmd_target_send));
01078   }
01079 
01080   // Copy the data into the command frame
01081   memcpy (abtCmd + 2, pbtTx, szTxLen);
01082 
01083   // Try to send the bits to the reader
01084   if (!pn53x_transceive (pnd, abtCmd, szTxLen + 2, NULL, NULL))
01085     return false;
01086 
01087   // Everyting seems ok, return true
01088   return true;
01089 }