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 */
65STATIC 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*/
73STATIC void phLibNfc_RemoteDev_Connect_Cb(
74                           void        *pContext,
75                           phHal_sRemoteDevInformation_t *pRmtdev_info,
76                           NFCSTATUS    status
77                           );
78
79#ifdef RECONNECT_SUPPORT
80STATIC
81void
82phLibNfc_config_discovery_con_failure_cb (
83    void                *context,
84    NFCSTATUS           status);
85#endif /* #ifdef RECONNECT_SUPPORT */
86
87/*Remote device disconnect response callback*/
88STATIC void phLibNfc_RemoteDev_Disconnect_cb(
89                                void                          *context,
90                                phHal_sRemoteDevInformation_t *reg_handle,
91                                NFCSTATUS                      status
92                                );
93/*Remote device Transceive response callback*/
94STATIC 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*/
100STATIC 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*/
113STATIC
114void 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*/
389NFCSTATUS
390phLibNfc_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*/
452NFCSTATUS 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
490NFCSTATUS
491phLibNfc_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*/
580NFCSTATUS 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
661STATIC
662void
663phLibNfc_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*/
732STATIC 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*/
790NFCSTATUS 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*/
877STATIC 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*/
958NFCSTATUS
959phLibNfc_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*/
1116STATIC
1117void 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*/
1230NFCSTATUS
1231phLibNfc_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*/
1301STATIC 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