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
phLibNfc_NotificationRegister_Resp_Cb(void * context,phHal_eNotificationType_t type,phHal4Nfc_NotificationInfo_t info,NFCSTATUS status)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 							(phLibNfc_Handle)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 							(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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 								(phLibNfc_Handle)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
phLibNfc_RemoteDev_NtfRegister(phLibNfc_Registry_Info_t * pRegistryInfo,phLibNfc_NtfRegister_RspCb_t pNotificationHandler,void * pContext)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 */
phLibNfc_RemoteDev_NtfUnregister(void)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
phLibNfc_RemoteDev_ReConnect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb,void * pContext)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 */
phLibNfc_RemoteDev_Connect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,void * pContext)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
phLibNfc_config_discovery_con_failure_cb(void * context,NFCSTATUS status)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 */
phLibNfc_RemoteDev_Connect_Cb(void * pContext,phHal_sRemoteDevInformation_t * pRmtdev_info,NFCSTATUS status)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 = (uintptr_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                     (phLibNfc_Handle)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 */
phLibNfc_RemoteDev_Disconnect(phLibNfc_Handle hRemoteDevice,phLibNfc_eReleaseType_t ReleaseType,pphLibNfc_DisconnectCallback_t pDscntCallback,void * pContext)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 */
phLibNfc_RemoteDev_Disconnect_cb(void * context,phHal_sRemoteDevInformation_t * reg_handle,NFCSTATUS status)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                     (phLibNfc_Handle)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
phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice,phLibNfc_sTransceiveInfo_t * psTransceiveInfo,pphLibNfc_TransceiveCallback_t pTransceive_RspCb,void * pContext)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
phLibNfc_RemoteDev_Transceive_Cb(void * context,phHal_sRemoteDevInformation_t * pRmtdev_info,phNfc_sData_t * response,NFCSTATUS status)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                                 (phLibNfc_Handle)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                                 (phLibNfc_Handle)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
phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t * pConfigInfo,pphLibNfc_RspCb_t pConfigRspCb,void * pContext)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 */
phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void * context,NFCSTATUS status)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