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