Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*!
     18  * \file phLibNfc_initiator.c
     19 
     20  * Project: NFC FRI 1.1
     21  *
     22  * $Date: Fri Apr 23 14:34:08 2010 $
     23  * $Author: ing07385 $
     24  * $Revision: 1.53 $
     25  * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
     26  *
     27  */
     28 
     29 /*
     30 ************************* Header Files ****************************************
     31 */
     32 
     33 #include <phLibNfcStatus.h>
     34 #include <phLibNfc.h>
     35 #include <phHal4Nfc.h>
     36 #include <phOsalNfc.h>
     37 #include <phLibNfc_Internal.h>
     38 #include <phLibNfc_SE.h>
     39 #include <phLibNfc_ndef_raw.h>
     40 #include <phLibNfc_initiator.h>
     41 #include <phLibNfc_discovery.h>
     42 
     43 
     44 /*
     45 *************************** Macro's  ****************************************
     46 */
     47 
     48 #ifndef STATIC_DISABLE
     49 #define STATIC static
     50 #else
     51 #define STATIC
     52 #endif
     53 
     54 /*
     55 *************************** Global Variables **********************************
     56 */
     57 
     58 #define PN544_IO_TIMEOUT_RESPONSE 0x89
     59 
     60 /*
     61 *************************** Static Function Declaration ***********************
     62 */
     63 
     64 /* Target discvovery notification callback */
     65 STATIC void phLibNfc_NotificationRegister_Resp_Cb (
     66                                 void                             *context,
     67                                 phHal_eNotificationType_t        type,
     68                                 phHal4Nfc_NotificationInfo_t     info,
     69                                 NFCSTATUS                        status
     70                                 );
     71 
     72 /*Remote device connect response callback*/
     73 STATIC void phLibNfc_RemoteDev_Connect_Cb(
     74                            void        *pContext,
     75                            phHal_sRemoteDevInformation_t *pRmtdev_info,
     76                            NFCSTATUS    status
     77                            );
     78 
     79 #ifdef RECONNECT_SUPPORT
     80 STATIC
     81 void
     82 phLibNfc_config_discovery_con_failure_cb (
     83     void                *context,
     84     NFCSTATUS           status);
     85 #endif /* #ifdef RECONNECT_SUPPORT */
     86 
     87 /*Remote device disconnect response callback*/
     88 STATIC void phLibNfc_RemoteDev_Disconnect_cb(
     89                                 void                          *context,
     90                                 phHal_sRemoteDevInformation_t *reg_handle,
     91                                 NFCSTATUS                      status
     92                                 );
     93 /*Remote device Transceive response callback*/
     94 STATIC void phLibNfc_RemoteDev_Transceive_Cb(void *context,
     95                                 phHal_sRemoteDevInformation_t *pRmtdev_info,
     96                                 phNfc_sData_t *response,
     97                                 NFCSTATUS status
     98                                 );
     99 /*Set P2P config paramater response callback*/
    100 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(
    101                                 void                             *context,
    102                                 NFCSTATUS                        status
    103                                 );
    104 
    105 
    106 /*
    107 *************************** Function Definitions ******************************
    108 */
    109 
    110 /**
    111 * Response to target discovery.
    112 */
    113 STATIC
    114 void phLibNfc_NotificationRegister_Resp_Cb (
    115                                 void                            *context,
    116                                 phHal_eNotificationType_t       type,
    117                                 phHal4Nfc_NotificationInfo_t    info,
    118                                 NFCSTATUS                       status
    119                                 )
    120 {
    121     NFCSTATUS RetVal = NFCSTATUS_SUCCESS,
    122               Status = NFCSTATUS_SUCCESS;
    123     uint16_t DeviceIndx, DeviceIndx1;
    124     uint8_t sak_byte=0;
    125     uint8_t tag_disc_flg = 0;
    126     phLibNfc_NtfRegister_RspCb_t pClientCb=NULL;
    127     pClientCb =gpphLibContext->CBInfo.pClientNtfRegRespCB;
    128 	PHNFC_UNUSED_VARIABLE(context);
    129 
    130 
    131     if(( type != NFC_DISCOVERY_NOTIFICATION )
    132         &&(PHNFCSTATUS(status)!=NFCSTATUS_DESELECTED))
    133     {
    134         Status = NFCSTATUS_FAILED;
    135     }
    136     else if (PHNFCSTATUS(status) == NFCSTATUS_DESELECTED)
    137     {
    138         return;
    139     }
    140 	else
    141 	{
    142 		DeviceIndx=0;DeviceIndx1=0;
    143 		while(DeviceIndx < info.psDiscoveryInfo->NumberOfDevices)
    144 		{
    145 			switch(info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]->RemDevType)
    146 			{
    147 				case  phHal_eMifare_PICC:
    148 				{
    149 					/*Mifare Tag discovered*/
    150 					sak_byte =  info.psDiscoveryInfo->
    151 								ppRemoteDevInfo[DeviceIndx]->RemoteDevInfo.Iso14443A_Info.Sak;
    152 					if((TRUE == gpphLibContext->RegNtfType.MifareUL)&& (sak_byte==0x00))
    153 					{
    154 						/*Copy the tag related info*/
    155 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    156 							info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    157 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    158 							(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    159 						gpphLibContext->Discov_handle[DeviceIndx1] =
    160 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    161 						DeviceIndx1++;
    162 						tag_disc_flg++;
    163 					}
    164 
    165 					if((TRUE == gpphLibContext->RegNtfType.MifareStd)&&
    166 						(((sak_byte & 0x18)==0x08)||((sak_byte & 0x18)==0x18) ||
    167                                                 (sak_byte == 0x01)))
    168 					{
    169 						/*Copy the tag related info*/
    170 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    171 							info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    172 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    173 							(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    174 						gpphLibContext->Discov_handle[DeviceIndx1]=
    175 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    176 						DeviceIndx1++;
    177 						tag_disc_flg++;
    178 					}
    179 
    180 				}break;
    181 				case  phHal_eISO14443_A_PICC:
    182 				{
    183 					/*ISO 14443-A type tag discovered*/
    184 					if(TRUE == gpphLibContext->RegNtfType.ISO14443_4A)
    185 					{
    186 						/*Copy the ISO type A tag info*/
    187 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    188 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    189 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    190 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    191 						gpphLibContext->Discov_handle[DeviceIndx1] =
    192 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    193 						DeviceIndx1++;
    194 						tag_disc_flg++;
    195 					}
    196 				}break;
    197 				case  phHal_eISO14443_3A_PICC:
    198 				{
    199 					/*ISO 14443-A type tag discovered*/
    200 					if(TRUE == gpphLibContext->RegNtfType.MifareUL)
    201 					{
    202 						/*Copy the ISO type A tag info*/
    203 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    204 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    205 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    206 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    207 						gpphLibContext->Discov_handle[DeviceIndx1] =
    208 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    209 						DeviceIndx1++;
    210 						tag_disc_flg++;
    211 					}
    212 				}break;
    213 				case  phHal_eISO14443_B_PICC:
    214 				{
    215 					/*ISO 14443-B type tag Discovered */
    216 					if(TRUE == gpphLibContext->RegNtfType.ISO14443_4B)
    217 					{
    218 						/*Copy the Type B tag info */
    219 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    220 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    221 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    222 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    223 						gpphLibContext->Discov_handle[DeviceIndx1] =
    224 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    225 						DeviceIndx1++;
    226 						tag_disc_flg++;
    227 					}
    228 				}break;
    229 				case  phHal_eFelica_PICC:
    230 				{
    231 					/*Felica Type Tag Discovered */
    232 					if(TRUE == gpphLibContext->RegNtfType.Felica)
    233 					{
    234 						/*Copy the Felica tag info */
    235 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    236 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    237 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    238 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    239 						gpphLibContext->Discov_handle[DeviceIndx1] =
    240 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    241 						DeviceIndx1++;
    242 						tag_disc_flg++;
    243 					}
    244 				}break;
    245 				case  phHal_eJewel_PICC:
    246 				{
    247 					/*Jewel Type Tag Discovered */
    248 					if(TRUE == gpphLibContext->RegNtfType.Jewel)
    249 					{
    250 						/*Copy the Felica tag info */
    251 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    252 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    253 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    254 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    255 						gpphLibContext->Discov_handle[DeviceIndx1] =
    256 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    257 						DeviceIndx1++;
    258 						tag_disc_flg++;
    259 					}
    260 				}
    261 				break;
    262 				case  phHal_eISO15693_PICC:
    263 				{
    264 					/*Jewel Type Tag Discovered */
    265 					if(TRUE == gpphLibContext->RegNtfType.ISO15693)
    266 					{
    267 						/*Copy the Felica tag info */
    268 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    269 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    270 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    271 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    272 						gpphLibContext->Discov_handle[DeviceIndx1] =
    273 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    274 						DeviceIndx1++;
    275 						tag_disc_flg++;
    276 					}
    277 				}
    278 				break;
    279 				case  phHal_eNfcIP1_Target:
    280 				{
    281 					if(TRUE == gpphLibContext->RegNtfType.NFC)
    282 					{
    283 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    284 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    285 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    286 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
    287 						gpphLibContext->Discov_handle[DeviceIndx1] =
    288 							gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    289 						DeviceIndx1++;
    290 						tag_disc_flg++;
    291 					}
    292 				}
    293 				break;
    294 				case  phHal_eNfcIP1_Initiator:
    295 				{
    296 					if(TRUE == gpphLibContext->RegNtfType.NFC)
    297 					{
    298 						gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect;
    299 						gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
    300 								info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
    301 						gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
    302 								(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo;
    303 						gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle=
    304 								gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
    305 						DeviceIndx1++;
    306 						tag_disc_flg++;
    307 					}
    308 				}
    309 				break;
    310 				default :
    311 				{
    312 					break;
    313 				}
    314 			}
    315 			DeviceIndx++;
    316 		}
    317 	}
    318 
    319     if((tag_disc_flg >0 )&&(status != NFCSTATUS_FAILED))
    320     {
    321         gpphLibContext->dev_cnt = tag_disc_flg;
    322         /* Check for if the discovered tags are multiple or
    323          Multiple protocol tag */
    324         if((gpphLibContext->dev_cnt > 1)&&(
    325             (status ==NFCSTATUS_MULTIPLE_PROTOCOLS) ||
    326             (status ==NFCSTATUS_MULTIPLE_TAGS)) )
    327         {
    328             status = status;
    329         }
    330         else
    331         {
    332             status =NFCSTATUS_SUCCESS;
    333         }
    334         /*Notify to upper layer the no of tag discovered and
    335           the protocol */
    336         if (NULL != pClientCb)
    337         {
    338             pClientCb(
    339 					(void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
    340                     gpphLibContext->psRemoteDevList,
    341                     gpphLibContext->dev_cnt,
    342 					status
    343                     );
    344         }
    345 
    346     }
    347     else if(PHNFCSTATUS(status)==NFCSTATUS_DESELECTED)
    348     {
    349         info.psDiscoveryInfo->NumberOfDevices = 0;
    350         if (NULL != pClientCb)
    351         {
    352             gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateRelease;
    353             pClientCb((void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
    354                     NULL,
    355                     0,
    356                     status);
    357         }
    358 
    359     }
    360     else /*Reconfigure the discovery wheel*/
    361     {
    362         RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference,
    363                                             NFC_DISCOVERY_RESUME,
    364                                             &(gpphLibContext->sADDconfig),
    365                                             phLibNfc_config_discovery_cb,
    366                                             gpphLibContext);
    367 
    368         if((RetVal!=NFCSTATUS_SUCCESS) &&(RetVal!=NFCSTATUS_PENDING))
    369         {
    370             Status = NFCSTATUS_FAILED;
    371         }
    372 
    373     }
    374     if(Status == NFCSTATUS_FAILED)
    375     {
    376         if (NULL != pClientCb)
    377         {
    378             pClientCb(gpphLibContext->CBInfo.pClientNtfRegRespCntx,
    379                 NULL,
    380                 0,
    381                 Status);
    382         }
    383     }
    384     return;
    385 }
    386 
    387 /**
    388 * This interface registers notification handler for target discovery.
    389 */
    390 NFCSTATUS
    391 phLibNfc_RemoteDev_NtfRegister(
    392                         phLibNfc_Registry_Info_t*       pRegistryInfo,
    393                         phLibNfc_NtfRegister_RspCb_t    pNotificationHandler,
    394                         void                            *pContext
    395                         )
    396 {
    397     NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
    398 
    399 
    400     /*Check for valid parameters*/
    401     if((NULL == pNotificationHandler)
    402         || (NULL == pContext)
    403         ||(NULL== pRegistryInfo))
    404     {
    405         RetVal= NFCSTATUS_INVALID_PARAMETER;
    406     }
    407     else if((NULL == gpphLibContext) ||
    408         (gpphLibContext->LibNfcState.cur_state
    409                             == eLibNfcHalStateShutdown))
    410     {
    411         RetVal = NFCSTATUS_NOT_INITIALISED;
    412     }
    413     else if(gpphLibContext->LibNfcState.next_state
    414                             == eLibNfcHalStateShutdown)
    415     {
    416         /*Next state is shutdown*/
    417         RetVal= NFCSTATUS_SHUTDOWN;
    418     }
    419     else
    420     {
    421 
    422         PHDBG_INFO("LibNfc:Registering Notification Handler");
    423 
    424 
    425         (void) memcpy(&(gpphLibContext->RegNtfType),pRegistryInfo,
    426                         sizeof(phLibNfc_Registry_Info_t));
    427         /* Register Discovery Notification Handler*/
    428 
    429 		/*Register for NFCIP1 target type*/
    430 		RetVal = phHal4Nfc_RegisterNotification(
    431                                 gpphLibContext->psHwReference,
    432                                 eRegisterP2PDiscovery,
    433                                 phLibNfc_NotificationRegister_Resp_Cb,
    434                                 (void*)gpphLibContext
    435                                 );
    436         /*Register for Tag discovery*/
    437 		RetVal = phHal4Nfc_RegisterNotification(
    438                             gpphLibContext->psHwReference,
    439                             eRegisterTagDiscovery,
    440                             phLibNfc_NotificationRegister_Resp_Cb,
    441                             (void*)gpphLibContext
    442                             );
    443         gpphLibContext->CBInfo.pClientNtfRegRespCB = pNotificationHandler;
    444         gpphLibContext->CBInfo.pClientNtfRegRespCntx = pContext;
    445         /*Register notification handler with below layer*/
    446 
    447     }
    448     return RetVal;
    449 }
    450 /**
    451 * This interface unregisters notification handler for target discovery.
    452 */
    453 NFCSTATUS phLibNfc_RemoteDev_NtfUnregister(void)
    454 {
    455     NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
    456     if((NULL == gpphLibContext) ||
    457        (gpphLibContext->LibNfcState.cur_state
    458                             == eLibNfcHalStateShutdown))
    459     {
    460         /*Lib Nfc not Initialized*/
    461         RetVal = NFCSTATUS_NOT_INITIALISED;
    462     }
    463     else if(gpphLibContext->LibNfcState.next_state
    464                             == eLibNfcHalStateShutdown)
    465     {
    466         /*Lib Nfc Shutdown*/
    467         RetVal= NFCSTATUS_SHUTDOWN;
    468     }
    469     else
    470     {
    471         /*Unregister notification handler with lower layer */
    472         RetVal = phHal4Nfc_UnregisterNotification(
    473                                     gpphLibContext->psHwReference,
    474                                     eRegisterP2PDiscovery,
    475                                     gpphLibContext);
    476 
    477 		RetVal = phHal4Nfc_UnregisterNotification(
    478                                     gpphLibContext->psHwReference,
    479                                     eRegisterTagDiscovery,
    480                                     gpphLibContext);
    481 
    482         gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL;
    483         gpphLibContext->CBInfo.pClientNtfRegRespCntx =NULL;
    484         PHDBG_INFO("LibNfc:Unregister Notification Handler");
    485     }
    486     return RetVal;
    487 }
    488 
    489 #ifdef RECONNECT_SUPPORT
    490 
    491 NFCSTATUS
    492 phLibNfc_RemoteDev_ReConnect (
    493     phLibNfc_Handle                 hRemoteDevice,
    494     pphLibNfc_ConnectCallback_t     pNotifyReConnect_RspCb,
    495     void                            *pContext)
    496 {
    497 
    498     NFCSTATUS                           ret_val = NFCSTATUS_FAILED;
    499     phLibNfc_sRemoteDevInformation_t    *psRemoteDevInfo = NULL;
    500 
    501     if ((NULL == gpphLibContext)
    502       || (eLibNfcHalStateShutdown ==
    503         gpphLibContext->LibNfcState.cur_state))
    504     {
    505          ret_val = NFCSTATUS_NOT_INITIALISED;
    506     }
    507     else if ((NULL == pContext)
    508         || (NULL == pNotifyReConnect_RspCb)
    509         || (NULL == (void *)hRemoteDevice))
    510     {
    511         /* Check valid parameters */
    512         ret_val = NFCSTATUS_INVALID_PARAMETER;
    513     }
    514     /* Check valid lib nfc State */
    515     else if (gpphLibContext->LibNfcState.next_state
    516              == eLibNfcHalStateShutdown)
    517     {
    518         ret_val = NFCSTATUS_SHUTDOWN;
    519     }
    520     else if (0 == gpphLibContext->Connected_handle)
    521     {
    522         ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
    523     }
    524     else if ((gpphLibContext->Discov_handle[0] != hRemoteDevice)
    525 		&& (gpphLibContext->Discov_handle[1] != hRemoteDevice)
    526 		&& (gpphLibContext->Discov_handle[2] != hRemoteDevice)
    527 		&& (gpphLibContext->Discov_handle[3] != hRemoteDevice)
    528 		&& (gpphLibContext->Discov_handle[4] != hRemoteDevice)
    529 		&& (gpphLibContext->Discov_handle[5] != hRemoteDevice)
    530 		&& (gpphLibContext->Discov_handle[6] != hRemoteDevice)
    531 		&& (gpphLibContext->Discov_handle[7] != hRemoteDevice)
    532 		&& (gpphLibContext->Discov_handle[8] != hRemoteDevice)
    533 		&& (gpphLibContext->Discov_handle[9] != hRemoteDevice))
    534     {
    535         ret_val = NFCSTATUS_INVALID_HANDLE;
    536     }
    537     else
    538     {
    539         psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *)hRemoteDevice;
    540 
    541         /* Call the HAL connect*/
    542         ret_val = phHal4Nfc_Connect (gpphLibContext->psHwReference,
    543                                psRemoteDevInfo,
    544                                phLibNfc_RemoteDev_Connect_Cb,
    545                                (void *)gpphLibContext);
    546 
    547         if (NFCSTATUS_PENDING == ret_val)
    548         {
    549             /* If HAL Connect is pending update the LibNFC state machine
    550                 and store the CB pointer and Context,
    551                 mark the General CB pending status is TRUE */
    552             gpphLibContext->CBInfo.pClientConnectCb = pNotifyReConnect_RspCb;
    553             gpphLibContext->CBInfo.pClientConCntx = pContext;
    554             gpphLibContext->status.GenCb_pending_status = TRUE;
    555 			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
    556 
    557             gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
    558 
    559 			gpphLibContext->Connected_handle = hRemoteDevice;
    560          }
    561          else if (NFCSTATUS_INVALID_REMOTE_DEVICE == PHNFCSTATUS(ret_val))
    562          {
    563            /* The Handle given for connect is invalid*/
    564             ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
    565          }
    566          else
    567          {
    568             /* Lower layer returns internal error code return NFCSTATUS_FAILED*/
    569             ret_val = NFCSTATUS_FAILED;
    570          }
    571     }
    572 
    573     return ret_val;
    574 }
    575 #endif /* #ifdef RECONNECT_SUPPORT */
    576 
    577 
    578 /**
    579 * Connect to a single Remote Device
    580 */
    581 NFCSTATUS phLibNfc_RemoteDev_Connect(
    582                     phLibNfc_Handle             hRemoteDevice,
    583                     pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,
    584                     void                        *pContext
    585                     )
    586 {
    587 
    588     NFCSTATUS RetVal = NFCSTATUS_FAILED;
    589     phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo;
    590 
    591     if((NULL == gpphLibContext) ||
    592       (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
    593     {
    594          RetVal = NFCSTATUS_NOT_INITIALISED;
    595     }/* Check valid parameters*/
    596     else if((NULL == pContext)
    597         || (NULL == pNotifyConnect_RspCb)
    598         || (NULL == (void*)hRemoteDevice))
    599     {
    600        RetVal= NFCSTATUS_INVALID_PARAMETER;
    601     }
    602     /* Check valid lib nfc State*/
    603     else if(gpphLibContext->LibNfcState.next_state
    604                             == eLibNfcHalStateShutdown)
    605     {
    606         RetVal= NFCSTATUS_SHUTDOWN;
    607     }
    608     else if((gpphLibContext->Discov_handle[0] != hRemoteDevice)&&
    609 		(gpphLibContext->Discov_handle[1] != hRemoteDevice)&&
    610 		(gpphLibContext->Discov_handle[2] != hRemoteDevice)&&
    611 		(gpphLibContext->Discov_handle[3] != hRemoteDevice)&&
    612 		(gpphLibContext->Discov_handle[4] != hRemoteDevice)&&
    613 		(gpphLibContext->Discov_handle[5] != hRemoteDevice)&&
    614 		(gpphLibContext->Discov_handle[6] != hRemoteDevice)&&
    615 		(gpphLibContext->Discov_handle[7] != hRemoteDevice)&&
    616 		(gpphLibContext->Discov_handle[8] != hRemoteDevice)&&
    617 		(gpphLibContext->Discov_handle[9] != hRemoteDevice))
    618     {
    619         RetVal= NFCSTATUS_INVALID_HANDLE;
    620     }
    621     else if ((hRemoteDevice != gpphLibContext->Connected_handle)
    622         && (0 != gpphLibContext->Connected_handle))
    623     {
    624         RetVal = NFCSTATUS_FAILED;
    625     }
    626     else
    627     {
    628         psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
    629 
    630         /* Call the HAL connect*/
    631         RetVal = phHal4Nfc_Connect(gpphLibContext->psHwReference,
    632                                psRemoteDevInfo,
    633                                phLibNfc_RemoteDev_Connect_Cb,
    634                                (void* )gpphLibContext);
    635         if(RetVal== NFCSTATUS_PENDING)
    636         {
    637             /* If HAL Connect is pending update the LibNFC state machine
    638                 and store the CB pointer and Context,
    639                 mark the General CB pending status is TRUE*/
    640             gpphLibContext->CBInfo.pClientConnectCb = pNotifyConnect_RspCb;
    641             gpphLibContext->CBInfo.pClientConCntx = pContext;
    642             gpphLibContext->status.GenCb_pending_status=TRUE;
    643 			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
    644             gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
    645 			gpphLibContext->Connected_handle = hRemoteDevice;
    646          }
    647          else if(PHNFCSTATUS(RetVal) == NFCSTATUS_INVALID_REMOTE_DEVICE)
    648          {
    649            /* The Handle given for connect is invalid*/
    650             RetVal= NFCSTATUS_TARGET_NOT_CONNECTED;
    651          }
    652          else
    653          {
    654             /* Lower layer returns internal error code return NFCSTATUS_FAILED*/
    655             RetVal = NFCSTATUS_FAILED;
    656          }
    657     }
    658     return RetVal;
    659 }
    660 
    661 #ifdef RECONNECT_SUPPORT
    662 STATIC
    663 void
    664 phLibNfc_config_discovery_con_failure_cb (
    665     void                *context,
    666     NFCSTATUS           status)
    667 {
    668     if((phLibNfc_LibContext_t *)context == gpphLibContext)
    669     {   /*check for same context*/
    670         pphLibNfc_ConnectCallback_t    ps_client_con_cb =
    671                                     gpphLibContext->CBInfo.pClientConnectCb;
    672 
    673         if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
    674         {
    675             /*If shutdown called in between allow shutdown to happen*/
    676             phLibNfc_Pending_Shutdown();
    677             status = NFCSTATUS_SHUTDOWN;
    678         }
    679         else
    680         {
    681             gpphLibContext->status.GenCb_pending_status = FALSE;
    682             gpphLibContext->status.DiscEnbl_status = FALSE;
    683             status = NFCSTATUS_TARGET_LOST;
    684 
    685             phLibNfc_UpdateCurState (status,gpphLibContext);
    686 #ifdef RESTART_CFG
    687             if(gpphLibContext->status.Discovery_pending_status == TRUE)
    688             {
    689                 NFCSTATUS RetStatus = NFCSTATUS_FAILED;
    690                 /* Application has called discovery before receiving this callback,
    691                 so NO notification to the upper layer, instead lower layer
    692                 discovery is called */
    693                 gpphLibContext->status.Discovery_pending_status = FALSE;
    694                 RetStatus =  phHal4Nfc_ConfigureDiscovery(
    695                         gpphLibContext->psHwReference,
    696                         gpphLibContext->eLibNfcCfgMode,
    697                         &gpphLibContext->sADDconfig,
    698                         (pphLibNfc_RspCb_t)
    699                         phLibNfc_config_discovery_cb,
    700                         (void *)gpphLibContext);
    701                 if (NFCSTATUS_PENDING == RetStatus)
    702                 {
    703                     (void)phLibNfc_UpdateNextState(gpphLibContext,
    704                                             eLibNfcHalStateConfigReady);
    705                     gpphLibContext->status.GenCb_pending_status = TRUE;
    706                     gpphLibContext->status.DiscEnbl_status = TRUE;
    707                 }
    708             }
    709 
    710 #endif /* #ifdef RESTART_CFG */
    711         }
    712 
    713         if (NULL != ps_client_con_cb)
    714         {
    715             gpphLibContext->CBInfo.pClientConnectCb = NULL;
    716             /* Call the upper layer callback*/
    717             ps_client_con_cb (gpphLibContext->CBInfo.pClientConCntx,
    718                             0, NULL, status);
    719         }
    720     } /*End of if-context check*/
    721     else
    722     {   /*exception: wrong context pointer returned*/
    723         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    724         status = NFCSTATUS_FAILED;
    725     }
    726 
    727 
    728 }
    729 #endif /* #ifdef RECONNECT_SUPPORT */
    730 /**
    731 * Response callback for remote device connect
    732 */
    733 STATIC void phLibNfc_RemoteDev_Connect_Cb(
    734                            void        *pContext,
    735                            phHal_sRemoteDevInformation_t *pRmtdev_info,
    736                            NFCSTATUS    status
    737                            )
    738 {
    739     NFCSTATUS             Connect_status = NFCSTATUS_SUCCESS;
    740     /*Check valid lib nfc context is returned from lower layer*/
    741     if((phLibNfc_LibContext_t *)pContext == gpphLibContext)
    742     {
    743         gpphLibContext->LastTrancvSuccess = FALSE;
    744 
    745         /* Mark General Callback pending status as false*/
    746         gpphLibContext->status.GenCb_pending_status = FALSE;
    747 
    748         /* Check the shutdown is called during the lower layer Connect in process,
    749            If yes call shutdown call and return NFCSTATUS_SHUTDOWN */
    750         if((eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state))
    751         {
    752             phLibNfc_Pending_Shutdown();
    753             Connect_status = NFCSTATUS_SHUTDOWN;
    754 
    755         }
    756         else if(PHNFCSTATUS(status)==NFCSTATUS_SUCCESS)
    757         {
    758             /* Copy the Remote device address as connected handle*/
    759             gpphLibContext->Connected_handle =(uint32_t) pRmtdev_info;
    760             /* Update the state to connected and return status as SUCCESS*/
    761             gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
    762             Connect_status = NFCSTATUS_SUCCESS;
    763         }
    764         else
    765         {  /* if(PHNFCSTATUS(status)==NFCSTATUS_INVALID_REMOTE_DEVICE) */
    766             /* If remote device is invalid return as TARGET LOST to upper layer*/
    767             /* If error code is other than SUCCESS return NFCSTATUS_TARGET_LOST */
    768             Connect_status = NFCSTATUS_TARGET_LOST;
    769             gpphLibContext->Connected_handle = gpphLibContext->Prev_Connected_handle ;
    770         }
    771         gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
    772         /* Update the Current Sate*/
    773         phLibNfc_UpdateCurState(Connect_status,(phLibNfc_LibContext_t *)pContext);
    774         /* Call the upper layer callback*/
    775         gpphLibContext->CBInfo.pClientConnectCb(
    776                     gpphLibContext->CBInfo.pClientConCntx,
    777                     (uint32_t)pRmtdev_info,
    778                     (phLibNfc_sRemoteDevInformation_t*)pRmtdev_info,
    779                     Connect_status);
    780     }
    781     else
    782     {   /*exception: wrong context pointer returned*/
    783         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    784     }
    785     return;
    786 }
    787 
    788 /**
    789 * Allows to disconnect from already connected target.
    790 */
    791 NFCSTATUS phLibNfc_RemoteDev_Disconnect( phLibNfc_Handle                 hRemoteDevice,
    792                                         phLibNfc_eReleaseType_t          ReleaseType,
    793                                         pphLibNfc_DisconnectCallback_t   pDscntCallback,
    794                                         void*                            pContext
    795                                         )
    796 {
    797     NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
    798     phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo=NULL;
    799 
    800     /*Check for valid parameter*/
    801     if((NULL == gpphLibContext) ||
    802         (gpphLibContext->LibNfcState.cur_state
    803                             == eLibNfcHalStateShutdown))
    804     {
    805         RetVal = NFCSTATUS_NOT_INITIALISED;
    806     }
    807     else if((NULL == pContext) ||
    808         (NULL == pDscntCallback)||(hRemoteDevice == 0))
    809     {
    810         RetVal= NFCSTATUS_INVALID_PARAMETER;
    811     }
    812     /* Check for valid state,If De initialize is called then
    813     return NFCSTATUS_SHUTDOWN */
    814     else if(gpphLibContext->LibNfcState.next_state
    815                             == eLibNfcHalStateShutdown)
    816     {
    817         RetVal= NFCSTATUS_SHUTDOWN;
    818     }
    819     else if(gpphLibContext->Connected_handle==0)
    820     {
    821         RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
    822     }
    823     /* The given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE*/
    824     else if(hRemoteDevice != gpphLibContext->Connected_handle )
    825     {
    826         RetVal=NFCSTATUS_INVALID_HANDLE;
    827     }
    828     else
    829     {
    830         if((eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
    831             ||((gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)&&
    832                     (ReleaseType != NFC_SMARTMX_RELEASE))
    833                     ||((gpphLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)&&
    834                             (ReleaseType == NFC_SMARTMX_RELEASE)))
    835         {   /* Previous disconnect callback is pending */
    836             RetVal = NFCSTATUS_REJECTED;
    837         }
    838 #ifndef LLCP_CHANGES
    839         else if(eLibNfcHalStateTransaction == gpphLibContext->LibNfcState.next_state)
    840         {   /* Previous  Transaction is Pending*/
    841             RetVal = NFCSTATUS_BUSY;
    842             PHDBG_INFO("LibNfc:Transaction is Pending");
    843         }
    844 #endif /* #ifdef LLCP_CHANGES */
    845         else
    846         {
    847             gpphLibContext->ReleaseType = ReleaseType;
    848             psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
    849             RetVal = phHal4Nfc_Disconnect(gpphLibContext->psHwReference,
    850                                 (phHal_sRemoteDevInformation_t*)psRemoteDevInfo,
    851                                 gpphLibContext->ReleaseType,
    852                                 (pphHal4Nfc_DiscntCallback_t)
    853                                 phLibNfc_RemoteDev_Disconnect_cb,
    854                                 (void *)gpphLibContext);
    855             if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal))
    856             {
    857                 /*Copy the upper layer Callback pointer and context*/
    858                 gpphLibContext->CBInfo.pClientDisConnectCb = pDscntCallback;
    859                 gpphLibContext->CBInfo.pClientDConCntx = pContext;
    860                 /* Mark general callback pending status as TRUE and update the state*/
    861                 gpphLibContext->status.GenCb_pending_status=TRUE;
    862 				gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
    863 
    864             }
    865             else
    866             {
    867                 /*If lower layer returns other than pending
    868                 (internal error codes) return NFCSTATUS_FAILED */
    869                 RetVal = NFCSTATUS_FAILED;
    870             }
    871         }
    872     }
    873     return RetVal;
    874 }
    875 /**
    876 * Response callback for Remote device Disconnect.
    877 */
    878 STATIC void phLibNfc_RemoteDev_Disconnect_cb(
    879                                 void                          *context,
    880                                 phHal_sRemoteDevInformation_t *reg_handle,
    881                                 NFCSTATUS                      status
    882                                 )
    883 {
    884     NFCSTATUS             DisCnct_status = NFCSTATUS_SUCCESS;
    885     pphLibNfc_DisconnectCallback_t pUpper_NtfCb = NULL;
    886         void  *pUpper_Context = NULL;
    887 
    888     /* Copy the upper layer Callback and context*/
    889     pUpper_NtfCb = gpphLibContext->CBInfo.pClientDisConnectCb;
    890     pUpper_Context = gpphLibContext->CBInfo.pClientDConCntx;
    891 
    892     /* Check valid context is returned or not */
    893     if((phLibNfc_LibContext_t *)context != gpphLibContext)
    894     {
    895         /*exception: wrong context pointer returned*/
    896         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    897     }
    898     else
    899     {
    900         /* Mark the General callback pending status FALSE   */
    901         gpphLibContext->status.GenCb_pending_status = FALSE;
    902         gpphLibContext->CBInfo.pClientDisConnectCb = NULL;
    903         gpphLibContext->CBInfo.pClientDConCntx = NULL;
    904 
    905         gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
    906         gpphLibContext->LastTrancvSuccess = FALSE;
    907         /*Reset Connected handle */
    908         gpphLibContext->Connected_handle=0x0000;
    909         /*Reset previous Connected handle */
    910         gpphLibContext->Prev_Connected_handle = 0x0000;
    911 
    912         if(gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)
    913         {
    914           gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
    915         }
    916         if(NULL != gpphLibContext->psBufferedAuth)
    917         {
    918             if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
    919             {
    920                 phOsalNfc_FreeMemory(
    921                     gpphLibContext->psBufferedAuth->sRecvData.buffer);
    922             }
    923             if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
    924             {
    925                 phOsalNfc_FreeMemory(
    926                     gpphLibContext->psBufferedAuth->sSendData.buffer);
    927             }
    928             phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
    929             gpphLibContext->psBufferedAuth = NULL;
    930         }
    931     }
    932     /* Check DeInit is called or not */
    933     if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
    934     {
    935         /*call shutdown and return  status as NFCSTATUS_SHUTDOWN */
    936         phLibNfc_Pending_Shutdown();
    937         DisCnct_status = NFCSTATUS_SHUTDOWN;
    938     }
    939     else if(NFCSTATUS_SUCCESS == status)
    940     {
    941         DisCnct_status = NFCSTATUS_SUCCESS;
    942 		gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
    943     }
    944     else
    945     {
    946         DisCnct_status = NFCSTATUS_FAILED;
    947         phLibNfc_UpdateCurState(DisCnct_status,(phLibNfc_LibContext_t *)context);
    948     }
    949     /* Call the upper layer Callback */
    950     (*pUpper_NtfCb)(pUpper_Context,
    951                     (uint32_t)reg_handle,
    952                     DisCnct_status);
    953     return;
    954 }
    955 
    956 /**
    957 * This interface allows to perform Read/write operation on remote device.
    958 */
    959 NFCSTATUS
    960 phLibNfc_RemoteDev_Transceive(phLibNfc_Handle                   hRemoteDevice,
    961                               phLibNfc_sTransceiveInfo_t*       psTransceiveInfo,
    962                               pphLibNfc_TransceiveCallback_t    pTransceive_RspCb,
    963                               void*                             pContext
    964                               )
    965 {
    966     NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
    967 
    968     /*Check for valid parameter */
    969 
    970     if((NULL == gpphLibContext) ||
    971         (gpphLibContext->LibNfcState.cur_state
    972                             == eLibNfcHalStateShutdown))
    973     {
    974         RetVal = NFCSTATUS_NOT_INITIALISED;
    975     }
    976     else if((NULL == psTransceiveInfo)
    977         || (NULL == pTransceive_RspCb)
    978         || (NULL == (void *)hRemoteDevice)
    979         || (NULL == psTransceiveInfo->sRecvData.buffer)
    980         || (NULL == psTransceiveInfo->sSendData.buffer)
    981         || (NULL == pContext))
    982     {
    983         RetVal= NFCSTATUS_INVALID_PARAMETER;
    984     }
    985     /* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/
    986     else if(gpphLibContext->LibNfcState.next_state
    987                             == eLibNfcHalStateShutdown)
    988     {
    989         RetVal= NFCSTATUS_SHUTDOWN;
    990     }/* If there is no handle connected return NFCSTATUS_TARGET_NOT_CONNECTED*/
    991     else if(gpphLibContext->Connected_handle==0)
    992     {
    993         RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
    994     }/* If the given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE */
    995 	else if(gpphLibContext->Connected_handle!= hRemoteDevice )
    996     {
    997         RetVal=NFCSTATUS_INVALID_HANDLE;
    998     } /*If the transceive is called before finishing the previous transceive function
    999       return NFCSTATUS_REJECTED  */
   1000     else if((eLibNfcHalStateTransaction ==
   1001         gpphLibContext->LibNfcState.next_state)
   1002         ||(phHal_eNfcIP1_Initiator==
   1003         ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType))
   1004     {
   1005         RetVal = NFCSTATUS_REJECTED;
   1006     }
   1007 #ifdef LLCP_TRANSACT_CHANGES
   1008     else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
   1009             && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
   1010     {
   1011         RetVal= NFCSTATUS_BUSY;
   1012     }
   1013 #endif /* #ifdef LLCP_TRANSACT_CHANGES */
   1014     else
   1015     {
   1016         gpphLibContext->ndef_cntx.eLast_Call = RawTrans;
   1017         (void)memcpy((void *)(gpphLibContext->psTransInfo),
   1018                     (void *)psTransceiveInfo,
   1019                     sizeof(phLibNfc_sTransceiveInfo_t));
   1020         /* Check the given Mifare command is supported or not ,
   1021                             If not return NFCSTATUS_COMMAND_NOT_SUPPORTED */
   1022         if( (((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
   1023                phHal_eMifare_PICC)&&
   1024             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRaw ) &&
   1025             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentA ) &&
   1026             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentB ) &&
   1027             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead16 ) &&
   1028             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead ) &&
   1029             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite16 ) &&
   1030             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite4 ) &&
   1031             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareDec ) &&
   1032             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareTransfer ) &&
   1033             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRestore ) &&
   1034             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareReadSector ) &&
   1035             ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWriteSector ))
   1036         {
   1037             RetVal = NFCSTATUS_COMMAND_NOT_SUPPORTED;
   1038         }
   1039         if(eLibNfcHalStatePresenceChk !=
   1040                      gpphLibContext->LibNfcState.next_state)
   1041         {
   1042             PHDBG_INFO("LibNfc:Transceive In Progress");
   1043             if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
   1044                phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
   1045                hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
   1046                (phHal_eMifareAuthentA == gpphLibContext->psTransInfo->cmd.MfCmd))
   1047             {
   1048                 if(NULL != gpphLibContext->psBufferedAuth)
   1049                 {
   1050                     if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
   1051                     {
   1052                         phOsalNfc_FreeMemory(
   1053                             gpphLibContext->psBufferedAuth->sRecvData.buffer);
   1054                     }
   1055                     if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
   1056                     {
   1057                         phOsalNfc_FreeMemory(
   1058                             gpphLibContext->psBufferedAuth->sSendData.buffer);
   1059                     }
   1060                     phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
   1061                 }
   1062                 gpphLibContext->psBufferedAuth
   1063                     =(phLibNfc_sTransceiveInfo_t *)
   1064                     phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
   1065                 gpphLibContext->psBufferedAuth->addr = psTransceiveInfo->addr;
   1066                 gpphLibContext->psBufferedAuth->cmd = psTransceiveInfo->cmd;
   1067                 gpphLibContext->psBufferedAuth->sSendData.length
   1068                     = psTransceiveInfo->sSendData.length;
   1069                 gpphLibContext->psBufferedAuth->sRecvData.length
   1070                     = psTransceiveInfo->sRecvData.length;
   1071                 gpphLibContext->psBufferedAuth->sSendData.buffer
   1072                   = (uint8_t *)
   1073                       phOsalNfc_GetMemory(
   1074                       gpphLibContext->psTransInfo->sSendData.length);
   1075 
   1076                 (void)memcpy((void *)
   1077                         (gpphLibContext->psBufferedAuth->sSendData.buffer),
   1078                         (void *)psTransceiveInfo->sSendData.buffer,
   1079                         psTransceiveInfo->sSendData.length);
   1080 
   1081                 gpphLibContext->psBufferedAuth->sRecvData.buffer
   1082                   = (uint8_t *)
   1083                       phOsalNfc_GetMemory(
   1084                         gpphLibContext->psTransInfo->sRecvData.length);
   1085             }
   1086             /*Call the lower layer Transceive function */
   1087             RetVal = phHal4Nfc_Transceive( gpphLibContext->psHwReference,
   1088                                         (phHal_sTransceiveInfo_t*)gpphLibContext->psTransInfo,
   1089                                         (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
   1090                                         (pphHal4Nfc_TransceiveCallback_t)
   1091                                         phLibNfc_RemoteDev_Transceive_Cb,
   1092                                         (void* )gpphLibContext);
   1093             if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING)
   1094             {
   1095                 /* Copy the upper layer callback pointer and context */
   1096                 gpphLibContext->CBInfo.pClientTransceiveCb = pTransceive_RspCb;
   1097                 gpphLibContext->CBInfo.pClientTranseCntx = pContext;
   1098                 /* Mark the General callback pending status is TRUE */
   1099                 gpphLibContext->status.GenCb_pending_status = TRUE;
   1100                 /*Transceive is in Progress-Used in Release API*/
   1101 
   1102                 /*Update the state machine*/
   1103                 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
   1104             }
   1105         }
   1106         else
   1107         {
   1108             gpphLibContext->status.GenCb_pending_status = FALSE;
   1109             RetVal = NFCSTATUS_FAILED;
   1110         }
   1111     }
   1112     return RetVal;
   1113 }
   1114 /**
   1115 * Response for Remote device transceive.
   1116 */
   1117 STATIC
   1118 void phLibNfc_RemoteDev_Transceive_Cb(void *context,
   1119                                     phHal_sRemoteDevInformation_t *pRmtdev_info,
   1120                                     phNfc_sData_t *response,
   1121                                     NFCSTATUS status
   1122                                     )
   1123 {
   1124     NFCSTATUS             trans_status = NFCSTATUS_SUCCESS;
   1125     phNfc_sData_t         *trans_resp= NULL;
   1126     void                  *pUpper_Context = NULL;
   1127     pphLibNfc_TransceiveCallback_t pUpper_TagNtfCb =
   1128                             gpphLibContext->CBInfo.pClientTransceiveCb;
   1129 
   1130     /*Check valid context is returned or not */
   1131     if((phLibNfc_LibContext_t *)context == gpphLibContext)
   1132     {
   1133         trans_resp = &gpphLibContext->psTransInfo->sRecvData;
   1134 
   1135         pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
   1136         gpphLibContext->status.GenCb_pending_status = FALSE;
   1137 
   1138         /*If DeInit is called during the transceive,
   1139            call the shutdown and return NFCSTATUS_SHUTDOWN*/
   1140         if(gpphLibContext->LibNfcState.next_state
   1141                             == eLibNfcHalStateShutdown)
   1142         {
   1143             phLibNfc_Pending_Shutdown();
   1144             trans_status = NFCSTATUS_SHUTDOWN;
   1145         }
   1146          /* If Disconnect is called return NFCSTATUS_ABORTED */
   1147         else if(eLibNfcHalStateRelease ==
   1148                 gpphLibContext->LibNfcState.next_state)
   1149         {
   1150             trans_status = NFCSTATUS_ABORTED;
   1151         }
   1152         /* If the received lower layer status is not SUCCESS return NFCSTATUS_FAILED */
   1153         else if( NFCSTATUS_SUCCESS == status)
   1154         {
   1155             trans_status = NFCSTATUS_SUCCESS;
   1156         }
   1157         else if((PHNFCSTATUS(status) != NFCSTATUS_SUCCESS) &&
   1158                 (phHal_eMifare_PICC == pRmtdev_info->RemDevType) &&
   1159                 (0x00 != pRmtdev_info->RemoteDevInfo.Iso14443A_Info.Sak))
   1160         {
   1161             gpphLibContext->LastTrancvSuccess = FALSE;
   1162             trans_status = NFCSTATUS_FAILED;
   1163             /* card type is mifare 1k/4k, then reconnect */
   1164             trans_status = phHal4Nfc_Connect(gpphLibContext->psHwReference,
   1165                         pRmtdev_info,
   1166                         (pphHal4Nfc_ConnectCallback_t)
   1167                         phLibNfc_Reconnect_Mifare_Cb,
   1168                         (void *)gpphLibContext);
   1169         }
   1170         else if ((PHNFCSTATUS(status) == PN544_IO_TIMEOUT_RESPONSE) ||
   1171                  (PHNFCSTATUS(status) == NFCSTATUS_RF_TIMEOUT))
   1172         {
   1173             // 0x89, 0x09 HCI response values from PN544 indicate timeout
   1174             trans_status = NFCSTATUS_TARGET_LOST;
   1175         }
   1176         else
   1177         {
   1178             // PN544 did get some reply from tag, just not valid
   1179             trans_status = NFCSTATUS_FAILED;
   1180         }
   1181         /*Update the state machine */
   1182         phLibNfc_UpdateCurState(status,gpphLibContext);
   1183         gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
   1184         if(NFCSTATUS_PENDING != trans_status)
   1185         {
   1186             /* Tranceive over */
   1187             PHDBG_INFO("LibNfc:TXRX Callback-Update the Transceive responce");
   1188             if (NULL != pUpper_TagNtfCb)
   1189             {
   1190                 if(trans_status == NFCSTATUS_SUCCESS)
   1191                 {
   1192                     gpphLibContext->LastTrancvSuccess = TRUE;
   1193                     pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
   1194                     trans_resp->buffer = response->buffer;
   1195                     trans_resp->length = response->length;
   1196                             /* Notify the upper layer */
   1197                     PHDBG_INFO("LibNfc:Transceive Complete");
   1198                     /* Notify the Transceive Completion to upper layer */
   1199                     gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
   1200                                 (uint32_t)pRmtdev_info,
   1201                                 trans_resp,
   1202                                 trans_status);
   1203                 }
   1204                 else
   1205                 {
   1206                     gpphLibContext->LastTrancvSuccess = FALSE;
   1207                     pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
   1208                     trans_resp->length = 0;
   1209                             /* Notify the upper layer */
   1210                     PHDBG_INFO("LibNfc:Transceive Complete");
   1211                     /* Notify the Transceive Completion to upper layer */
   1212                     gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
   1213                                 (uint32_t)pRmtdev_info,
   1214                                 trans_resp,
   1215                                 trans_status);
   1216                 }
   1217             }
   1218        }
   1219 
   1220     }
   1221     else
   1222     {    /*exception: wrong context pointer returned*/
   1223         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
   1224     }
   1225 
   1226     return;
   1227 }
   1228 /**
   1229 * Interface to configure P2P configurations.
   1230 */
   1231 NFCSTATUS
   1232 phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t*		pConfigInfo,
   1233                                 pphLibNfc_RspCb_t			pConfigRspCb,
   1234                                 void*						pContext
   1235                                 )
   1236 {
   1237     NFCSTATUS RetVal = NFCSTATUS_FAILED;
   1238     /* LibNfc Initialized or not */
   1239     if((NULL == gpphLibContext)||
   1240         (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
   1241     {
   1242         RetVal = NFCSTATUS_NOT_INITIALISED;
   1243     }/* Check for valid parameters */
   1244     else if((NULL == pConfigInfo) || (NULL == pConfigRspCb)
   1245         || (NULL == pContext))
   1246     {
   1247         RetVal= NFCSTATUS_INVALID_PARAMETER;
   1248     }
   1249     else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
   1250     {
   1251         RetVal = NFCSTATUS_SHUTDOWN;
   1252     }
   1253     else if(TRUE == gpphLibContext->status.GenCb_pending_status)
   1254     { /*Previous callback is pending */
   1255         RetVal = NFCSTATUS_BUSY;
   1256     }
   1257     else
   1258     {
   1259         if(eLibNfcHalStatePresenceChk !=
   1260                 gpphLibContext->LibNfcState.next_state)
   1261         {
   1262             phHal_uConfig_t uConfig;
   1263             /* copy General bytes of Max length = 48 bytes */
   1264             (void)memcpy((void *)&(uConfig.nfcIPConfig.generalBytes),
   1265                     (void *)pConfigInfo->generalBytes,
   1266                     pConfigInfo->generalBytesLength);
   1267             /* also copy the General Bytes length*/
   1268             uConfig.nfcIPConfig.generalBytesLength = pConfigInfo->generalBytesLength;
   1269 
   1270             RetVal = phHal4Nfc_ConfigParameters(
   1271                                 gpphLibContext->psHwReference,
   1272                                 NFC_P2P_CONFIG,
   1273                                 &uConfig,
   1274                                 phLibNfc_Mgt_SetP2P_ConfigParams_Cb,
   1275                                 (void *)gpphLibContext
   1276                                 );
   1277         }
   1278         else
   1279         {
   1280              gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb= NULL;
   1281              RetVal = NFCSTATUS_PENDING;
   1282         }
   1283         if(NFCSTATUS_PENDING == RetVal)
   1284         {
   1285             /* save the context and callback for later use */
   1286             gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = pConfigRspCb;
   1287             gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = pContext;
   1288             gpphLibContext->status.GenCb_pending_status=TRUE;
   1289             /* Next state is configured */
   1290             gpphLibContext->LibNfcState.next_state =eLibNfcHalStateConfigReady;
   1291         }
   1292         else
   1293         {
   1294             RetVal = NFCSTATUS_FAILED;
   1295         }
   1296     }
   1297     return RetVal;
   1298 }
   1299 /**
   1300 * Response callback for P2P configurations.
   1301 */
   1302 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void     *context,
   1303                                         NFCSTATUS status)
   1304 {
   1305         pphLibNfc_RspCb_t       pClientCb=NULL;
   1306     void                    *pUpperLayerContext=NULL;
   1307      /* Check for the context returned by below layer */
   1308     if((phLibNfc_LibContext_t *)context != gpphLibContext)
   1309     {   /*wrong context returned*/
   1310         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
   1311     }
   1312     else
   1313     {
   1314         if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
   1315         {   /*shutdown called before completion of this api allow
   1316             shutdown to happen */
   1317             phLibNfc_Pending_Shutdown();
   1318             status = NFCSTATUS_SHUTDOWN;
   1319         }
   1320         else
   1321         {
   1322             gpphLibContext->status.GenCb_pending_status = FALSE;
   1323             if(NFCSTATUS_SUCCESS != status)
   1324             {
   1325                 status = NFCSTATUS_FAILED;
   1326             }
   1327             else
   1328             {
   1329                 status = NFCSTATUS_SUCCESS;
   1330             }
   1331         }
   1332         /*update the current state */
   1333         phLibNfc_UpdateCurState(status,gpphLibContext);
   1334 
   1335         pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb;
   1336         pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx;
   1337 
   1338         gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL;
   1339         gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL;
   1340         if (NULL != pClientCb)
   1341         {
   1342             /* Notify to upper layer status of configure operation */
   1343             pClientCb(pUpperLayerContext, status);
   1344         }
   1345     }
   1346     return;
   1347 }
   1348 
   1349 
   1350 
   1351 
   1352 
   1353 
   1354 
   1355 
   1356 
   1357 
   1358