• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 							(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
phLibNfc_RemoteDev_NtfRegister(phLibNfc_Registry_Info_t * pRegistryInfo,phLibNfc_NtfRegister_RspCb_t pNotificationHandler,void * pContext)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 */
phLibNfc_RemoteDev_NtfUnregister(void)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
phLibNfc_RemoteDev_ReConnect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb,void * pContext)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 */
phLibNfc_RemoteDev_Connect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,void * pContext)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
phLibNfc_config_discovery_con_failure_cb(void * context,NFCSTATUS status)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 */
phLibNfc_RemoteDev_Connect_Cb(void * pContext,phHal_sRemoteDevInformation_t * pRmtdev_info,NFCSTATUS status)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 */
phLibNfc_RemoteDev_Disconnect(phLibNfc_Handle hRemoteDevice,phLibNfc_eReleaseType_t ReleaseType,pphLibNfc_DisconnectCallback_t pDscntCallback,void * pContext)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 */
phLibNfc_RemoteDev_Disconnect_cb(void * context,phHal_sRemoteDevInformation_t * reg_handle,NFCSTATUS status)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
phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice,phLibNfc_sTransceiveInfo_t * psTransceiveInfo,pphLibNfc_TransceiveCallback_t pTransceive_RspCb,void * pContext)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
phLibNfc_RemoteDev_Transceive_Cb(void * context,phHal_sRemoteDevInformation_t * pRmtdev_info,phNfc_sData_t * response,NFCSTATUS status)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
phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t * pConfigInfo,pphLibNfc_RspCb_t pConfigRspCb,void * pContext)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 */
phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void * context,NFCSTATUS status)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