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