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