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