ST Expansion SW Team / RFAL

Dependents:   mbed-os-nfc05a1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rfal_nfcf.cpp Source File

rfal_nfcf.cpp

00001 
00002 /******************************************************************************
00003   * @attention
00004   *
00005   * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
00006   *
00007   * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
00008   * You may not use this file except in compliance with the License.
00009   * You may obtain a copy of the License at:
00010   *
00011   *        http://www.st.com/myliberty
00012   *
00013   * Unless required by applicable law or agreed to in writing, software 
00014   * distributed under the License is distributed on an "AS IS" BASIS, 
00015   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
00016   * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
00017   * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00018   * See the License for the specific language governing permissions and
00019   * limitations under the License.
00020   *
00021 ******************************************************************************/
00022 
00023 /*
00024  *      PROJECT:   ST25R391x firmware
00025  *      $Revision: $
00026  *      LANGUAGE:  ISO C99
00027  */
00028 
00029 /*! \file rfal_nfcf.c
00030  *
00031  *  \author Gustavo Patricio
00032  *
00033  *  \brief Implementation of NFC-F Poller (FeliCa PCD) device
00034  *
00035  *  The definitions and helpers methods provided by this module are 
00036  *  aligned with NFC-F (FeliCa - JIS X6319-4)
00037  *
00038  */
00039 
00040 /*
00041  ******************************************************************************
00042  * INCLUDES
00043  ******************************************************************************
00044  */
00045 #include <platform1.h>
00046 #include "rfal_nfcf.h"
00047 #include "utils.h"
00048 
00049 /*
00050  ******************************************************************************
00051  * ENABLE SWITCH
00052  ******************************************************************************
00053  */
00054 
00055 #ifndef RFAL_FEATURE_NFCF
00056     #error " RFAL: Module configuration missing. Please enable/disable NFC-F module by setting: RFAL_FEATURE_NFCF "
00057 #endif
00058 
00059 #if RFAL_FEATURE_NFCF
00060 
00061 /*
00062  ******************************************************************************
00063  * GLOBAL DEFINES
00064  ******************************************************************************
00065  */
00066 #define RFAL_NFCF_SENSF_REQ_LEN_MIN                5     /*!< SENSF_RES minimum length                   */
00067 
00068 #define RFAL_NFCF_READ_WO_ENCRYPTION_MIN_LEN       15    /*!< Minimum length for a Check Command   -  T3T  5.4.1 */
00069 #define RFAL_NFCF_WRITE_WO_ENCRYPTION_MIN_LEN      31    /*!< Minimum length for an Update Command -  T3T  5.5.1 */
00070 
00071 
00072 /*
00073  ******************************************************************************
00074  * GLOBAL MACROS
00075  ******************************************************************************
00076  */
00077 #define rfalNfcfSlots2CardNum( s )                 (s+1) /*!< Converts Time Slot Number (TSN) into num of slots  */
00078 
00079 /*
00080 ******************************************************************************
00081 * GLOBAL TYPES
00082 ******************************************************************************
00083 */
00084 
00085 /*! Structure/Buffer to hold the SENSF_RES with LEN byte prepended                                 */
00086 typedef struct{
00087     uint8_t           LEN;                                /*!< NFC-F LEN byte                      */
00088     rfalNfcfSensfRes   SENSF_RES;                          /*!< SENSF_RES                           */
00089 } rfalNfcfSensfResBuf;
00090 
00091 
00092 /*! Greedy collection for NFCF GRE_POLL_F  Activity 1.0 Table 10                                   */
00093 typedef struct{
00094     uint8_t              pollFound;                       /*!< Number of devices found by the Poll */
00095     uint8_t              pollCollision;                   /*!< Number of collisions detected       */
00096     rfalFeliCaPollRes     POLL_F[RFAL_NFCF_POLL_MAXCARDS]; /*!< GRE_POLL_F   Activity 1.0 Table 10  */
00097 } rfalNfcfGreedyF;
00098 
00099 
00100 /*! NFC-F SENSF_REQ format  Digital 1.1  8.6.1                     */
00101 typedef struct
00102 {
00103     uint8_t  CMD;                          /*!< Command code: 00h  */
00104     uint8_t  SC[RFAL_NFCF_SENSF_SC_LEN];   /*!< System Code        */
00105     uint8_t  RC;                           /*!< Request Code       */
00106     uint8_t  TSN;                          /*!< Time Slot Number   */
00107 } rfalNfcfSensfReq;
00108 
00109 
00110 /*
00111 ******************************************************************************
00112 * LOCAL VARIABLES
00113 ******************************************************************************
00114 */
00115 static rfalNfcfGreedyF gRfalNfcfGreedyF;   /*!< Activity's NFCF Greedy collection */
00116 
00117 
00118 /*
00119 ******************************************************************************
00120 * LOCAL FUNCTION PROTOTYPES
00121 ******************************************************************************
00122 */
00123 static void rfalNfcfComputeValidSENF( rfalNfcfListenDevice  *outDevInfo, uint8_t *curDevIdx, uint8_t devLimit, bool overwrite, bool *nfcDepFound );
00124 
00125 
00126 /*
00127 ******************************************************************************
00128 * LOCAL VARIABLES
00129 ******************************************************************************
00130 */
00131 
00132 /*******************************************************************************/
00133 static void rfalNfcfComputeValidSENF( rfalNfcfListenDevice  *outDevInfo, uint8_t *curDevIdx, uint8_t devLimit, bool overwrite, bool *nfcDepFound )
00134 {
00135     uint8_t             tmpIdx;
00136     bool                duplicate;    
00137     rfalNfcfSensfResBuf *sensfBuf;
00138     
00139     
00140     /*******************************************************************************/
00141     /* Go through all responses check if valid and duplicates                      */
00142     /*******************************************************************************/
00143     while( (gRfalNfcfGreedyF.pollFound > 0) && ((*curDevIdx) < devLimit) )
00144     {
00145         duplicate = false;
00146         gRfalNfcfGreedyF.pollFound--;
00147         
00148         /* Point to received SENSF_RES */
00149         sensfBuf = (rfalNfcfSensfResBuf*) &gRfalNfcfGreedyF.POLL_F[gRfalNfcfGreedyF.pollFound];
00150         
00151         
00152         /* Check for devices that are already in device list */
00153         for( tmpIdx = 0; tmpIdx < (*curDevIdx); tmpIdx++ )
00154         {
00155             if( !ST_BYTECMP( sensfBuf->SENSF_RES.NFCID2, outDevInfo[tmpIdx].sensfRes .NFCID2 , RFAL_NFCF_NFCID2_LEN ) )
00156             {
00157                 duplicate = true;
00158                 break;
00159             }
00160         }
00161         
00162         /* If is a duplicate skip this (and not to overwrite)*/        
00163         if(duplicate && !overwrite)
00164         {
00165             continue;
00166         }
00167         
00168         /* Check if response length is OK */
00169         if( (( sensfBuf->LEN - RFAL_NFCF_HEADER_LEN) < RFAL_NFCF_SENSF_RES_LEN_MIN) || ((sensfBuf->LEN - RFAL_NFCF_HEADER_LEN) > RFAL_NFCF_SENSF_RES_LEN_MAX) )
00170         {
00171             continue;
00172         }
00173         
00174         /* Check if the response is a SENSF_RES / Polling response */
00175         if( sensfBuf->SENSF_RES.CMD != RFAL_NFCF_CMD_POLLING_RES  )
00176         {
00177             continue;
00178         }
00179         
00180         /* Check if is an overwrite request or new device*/
00181         if(duplicate && overwrite)
00182         {
00183             /* overwrite deviceInfo/GRE_SENSF_RES with SENSF_RES */
00184             outDevInfo[tmpIdx].sensfResLen  = (sensfBuf->LEN - RFAL_NFCF_LENGTH_LEN);
00185             ST_MEMCPY( &outDevInfo[tmpIdx].sensfRes, &sensfBuf->SENSF_RES.CMD, outDevInfo[tmpIdx].sensfResLen  );
00186             continue;
00187         }
00188         else
00189         {
00190             /* fill deviceInfo/GRE_SENSF_RES with new SENSF_RES */
00191             outDevInfo[(*curDevIdx)].sensfResLen  = (sensfBuf->LEN - RFAL_NFCF_LENGTH_LEN);
00192             ST_MEMCPY( &outDevInfo[(*curDevIdx)].sensfRes, &sensfBuf->SENSF_RES.CMD, outDevInfo[(*curDevIdx)].sensfResLen  );            
00193         }
00194         
00195         /* Check if this device supports NFC-DEP and signal it (ACTIVITY 1.1   9.3.6.63) */        
00196         *nfcDepFound = rfalNfcfIsNfcDepSupported( &outDevInfo[(*curDevIdx)] );
00197                 
00198         (*curDevIdx)++;
00199     }
00200 }
00201 
00202 /*
00203 ******************************************************************************
00204 * GLOBAL FUNCTIONS
00205 ******************************************************************************
00206 */
00207 
00208 /*******************************************************************************/
00209 ReturnCode rfalNfcfPollerInitialize( rfalBitRate  bitRate,SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00210 {
00211     ReturnCode ret;
00212     
00213     if( (bitRate != RFAL_BR_212 ) && (bitRate != RFAL_BR_424 ) )
00214     {
00215         return ERR_PARAM;
00216     }
00217     
00218     EXIT_ON_ERR( ret, rfalSetMode( RFAL_MODE_POLL_NFCF , bitRate, bitRate, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )  );
00219     rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC  );
00220     
00221     rfalSetGT( RFAL_GT_NFCF  );
00222     rfalSetFDTListen( RFAL_FDT_LISTEN_NFCF_POLLER  );
00223     rfalSetFDTPoll( RFAL_FDT_POLL_NFCF_POLLER  );
00224     
00225     return ERR_NONE;
00226 }
00227 
00228 
00229 
00230 /*******************************************************************************/
00231 ReturnCode rfalNfcfPollerPoll( rfalFeliCaPollSlots  slots, uint16_t sysCode, uint8_t reqCode, rfalFeliCaPollRes  *cardList, uint8_t *devCnt, uint8_t *collisions, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00232 {
00233     return rfalFeliCaPoll( slots, sysCode, reqCode, cardList, rfalNfcfSlots2CardNum(slots), devCnt, collisions, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00234 }
00235 
00236 /*******************************************************************************/
00237 ReturnCode rfalNfcfPollerCheckPresence( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00238 {
00239     gRfalNfcfGreedyF.pollFound     = 0;
00240     gRfalNfcfGreedyF.pollCollision = 0;
00241         
00242     /* ACTIVITY 1.0 & 1.1 - 9.2.3.17 SENSF_REQ  must be with number of slots equal to 4
00243      *                                SC must be 0xFFFF
00244      *                                RC must be 0x00 (No system code info required) */
00245     return rfalFeliCaPoll( RFAL_FELICA_4_SLOTS , RFAL_NFCF_SYSTEMCODE, RFAL_FELICA_POLL_RC_NO_REQUEST , gRfalNfcfGreedyF.POLL_F, rfalNfcfSlots2CardNum(RFAL_FELICA_4_SLOTS ), &gRfalNfcfGreedyF.pollFound, &gRfalNfcfGreedyF.pollCollision, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00246 }
00247 
00248 
00249 /*******************************************************************************/
00250 ReturnCode rfalNfcfPollerCollisionResolution( rfalComplianceMode  compMode, uint8_t devLimit, rfalNfcfListenDevice  *nfcfDevList, uint8_t *devCnt, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00251 {
00252     ReturnCode  ret;
00253     bool        nfcDepFound;
00254     
00255     if( nfcfDevList == NULL || devCnt == NULL )
00256     {
00257         return ERR_PARAM;
00258     }
00259             
00260     *devCnt      = 0;
00261     nfcDepFound  = false;
00262     
00263     
00264     /*******************************************************************************************/
00265     /* ACTIVITY 1.0 - 9.3.6.3 Copy valid SENSF_RES in GRE_POLL_F into GRE_SENSF_RES            */
00266     /* ACTIVITY 1.0 - 9.3.6.6 The NFC Forum Device MUST remove all entries from GRE_SENSF_RES[]*/
00267     /* ACTIVITY 1.1 - 9.3.63.59 Populate GRE_SENSF_RES with data from GRE_POLL_F               */
00268     /*                                                                                         */
00269     /* CON_DEVICES_LIMIT = 0 Just check if devices from Tech Detection exceeds -> always true  */
00270     /* Allow the number of slots open on Technology Detection                                  */
00271     /*******************************************************************************************/
00272     rfalNfcfComputeValidSENF( nfcfDevList, devCnt, (devLimit == 0 ? rfalNfcfSlots2CardNum( RFAL_FELICA_4_SLOTS  ) : devLimit), false, &nfcDepFound );
00273 
00274     
00275     /*******************************************************************************/
00276     /* ACTIVITY 1.0 - 9.3.6.4                                                      */
00277     /* ACTIVITY 1.1 - 9.3.63.60 Check if devices found are lower than the limit    */
00278     /* and send a SENSF_REQ if so                                                  */
00279     /*******************************************************************************/
00280     if( *devCnt < devLimit )
00281     {
00282         /* ACTIVITY 1.0 - 9.3.6.5  Copy valid SENSF_RES and then to remove it
00283          * ACTIVITY 1.1 - 9.3.6.65 Copy and filter duplicates                                           
00284          * For now, due to some devices keep generating different nfcid2, we use 1.0  
00285          * Phones detected: Samsung Galaxy Nexus,Samsung Galaxy S3,Samsung Nexus S */
00286         *devCnt = 0;
00287         
00288         ret = rfalNfcfPollerPoll( RFAL_FELICA_16_SLOTS , RFAL_NFCF_SYSTEMCODE, RFAL_FELICA_POLL_RC_NO_REQUEST , gRfalNfcfGreedyF.POLL_F, &gRfalNfcfGreedyF.pollFound, &gRfalNfcfGreedyF.pollCollision, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00289         if( ret == ERR_NONE )
00290         {
00291             rfalNfcfComputeValidSENF( nfcfDevList, devCnt, devLimit, false, &nfcDepFound );
00292         }
00293       
00294       /*******************************************************************************/
00295       /* ACTIVITY 1.1 -  9.3.6.63 Check if any device supports NFC DEP               */
00296       /*******************************************************************************/
00297       if( nfcDepFound && (compMode == RFAL_COMPLIANCE_MODE_NFC ) )
00298       {
00299           ret = rfalNfcfPollerPoll( RFAL_FELICA_16_SLOTS , RFAL_NFCF_SYSTEMCODE, RFAL_FELICA_POLL_RC_SYSTEM_CODE , gRfalNfcfGreedyF.POLL_F, &gRfalNfcfGreedyF.pollFound, &gRfalNfcfGreedyF.pollCollision, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00300           if( ret == ERR_NONE )
00301           {
00302               rfalNfcfComputeValidSENF( nfcfDevList, devCnt, devLimit, true, &nfcDepFound );
00303           }
00304       }
00305     }
00306     
00307     return ERR_NONE;
00308 }
00309 
00310 
00311 /*******************************************************************************/
00312 bool rfalNfcfListenerIsT3TReq( uint8_t* buf, uint16_t bufLen, uint8_t* nfcid2 )
00313 {
00314     /* Check cmd byte */
00315     switch( *buf )
00316     {
00317         case RFAL_NFCF_CMD_READ_WITHOUT_ENCRYPTION :
00318             if( bufLen < RFAL_NFCF_READ_WO_ENCRYPTION_MIN_LEN )
00319             {
00320                 return false;
00321             }
00322             break;
00323             
00324         case RFAL_NFCF_CMD_WRITE_WITHOUT_ENCRYPTION :
00325             if( bufLen < RFAL_NFCF_WRITE_WO_ENCRYPTION_MIN_LEN )
00326             {
00327                 return false;
00328             }
00329             break;
00330             
00331         default:
00332             return false;       
00333     }
00334     
00335     /* Output NFID2 if requested */
00336     if( nfcid2 != NULL )
00337     {
00338         ST_MEMCPY( nfcid2, (uint8_t*)(buf + RFAL_NFCF_CMD_LEN), RFAL_NFCF_NFCID2_LEN );
00339     }
00340     
00341     return true;
00342 }
00343 
00344 #endif /* RFAL_FEATURE_NFCF */