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_ndef_raw.c
19
20 * Project: NFC FRI 1.1
21 *
22 * $Date: Mon Dec 13 14:14:15 2010 $
23 * $Author: ing02260 $
24 * $Revision: 1.74 $
25 * $Aliases:  $
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_ndef_raw.h>
39#include <phLibNfc_initiator.h>
40#include <phLibNfc_discovery.h>
41#include <phFriNfc_NdefReg.h>
42#include <phFriNfc_MifareStdMap.h>
43
44/*
45*************************** Macro's  ****************************************
46*/
47
48#ifndef STATIC_DISABLE
49#define STATIC static
50#else
51//#undef STATIC
52#define STATIC
53#endif
54
55#define     TOPAZ_NDEF_BITMASK             0x10U
56#define     TOPAZ_LEN_BITMASK              0x02U
57#define     TOPAZ_DYNAMIC_LEN               460U
58#define     TOPAZ_STATIC_CARD_LEN           128U
59#define     MIFARE_STD_BLOCK_SIZE          0x10U
60/*
61*************************** Global Variables **********************************
62*/
63phLibNfc_Ndef_Info_t NdefInfo;
64phFriNfc_NdefRecord_t *pNdefRecord=NULL;
65/*
66*************************** Static Function Declaration ***********************
67*/
68
69/* Response callback for Check Ndef */
70STATIC
71void phLibNfc_Ndef_CheckNdef_Cb(void *pContext, NFCSTATUS status);
72
73/* Response callback for Ndef Write */
74STATIC
75void phLibNfc_Ndef_Write_Cb(void* Context,NFCSTATUS status);
76
77/* Response callback for Ndef Read*/
78STATIC
79void phLibNfc_Ndef_Read_Cb(void* Context,NFCSTATUS status);
80
81/* Response callback forNdef Format*/
82STATIC
83void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS status);
84
85#ifdef LIBNFC_READONLY_NDEF
86STATIC
87void
88phLibNfc_Ndef_ReadOnly_Cb (
89    void        *p_context,
90    NFCSTATUS   status);
91#endif /* #ifdef LIBNFC_READONLY_NDEF */
92
93/* Response callback for Search Ndef Content */
94STATIC
95void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status);
96
97/* Response callback for Ndef Record Type Discovery */
98STATIC
99void phLibNfc_Ndef_Rtd_Cb( void *CallBackParam);
100
101/* Response callback for Check Ndef timer callback */
102STATIC void CheckNdef_timer_cb(uint32_t timer_id, void *pContext);
103
104/*Callback for Presence check call from Chk Ndef*/
105STATIC void phLibNfc_Ndef_ChkNdef_Pchk_Cb(void   *pContext,
106                                NFCSTATUS  status
107                                );
108/*
109*************************** Function Definitions ******************************
110*/
111
112/**
113* This function reads an NDEF message from  already connected tag.
114* the NDEF message  is read starting after the position of the
115* last read operation of the same tag during current session.
116*/
117
118NFCSTATUS phLibNfc_Ndef_Read( phLibNfc_Handle                   hRemoteDevice,
119                            phNfc_sData_t                      *psRd,
120                            phLibNfc_Ndef_EOffset_t             Offset,
121                            pphLibNfc_RspCb_t                   pNdefRead_RspCb,
122                            void*                               pContext
123                            )
124{
125    NFCSTATUS RetVal = NFCSTATUS_FAILED;
126
127    if((NULL == gpphLibContext)||
128        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
129    {
130        RetVal = NFCSTATUS_NOT_INITIALISED;
131    }
132    else if((NULL == psRd) || (NULL == pNdefRead_RspCb)
133        || (NULL == psRd->buffer)
134        || (0 == psRd->length)
135        || (NULL == pContext)
136        || (0 == hRemoteDevice))
137    {
138        RetVal= NFCSTATUS_INVALID_PARAMETER;
139    }
140    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
141    {
142        RetVal = NFCSTATUS_SHUTDOWN;
143    }
144    else if(0 == gpphLibContext->Connected_handle)
145    {   /*presently no target or tag is connected*/
146        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
147    }
148    else if(hRemoteDevice != gpphLibContext->Connected_handle)
149    {   /*This handle of the device sent by application is not connected */
150        RetVal=NFCSTATUS_INVALID_HANDLE;
151    }
152    else if((TRUE == gpphLibContext->status.GenCb_pending_status)
153            ||(NULL!=gpphLibContext->CBInfo.pClientRdNdefCb)
154            ||(CHK_NDEF_NOT_DONE == gpphLibContext->ndef_cntx.is_ndef))
155    {
156        /*Previous callback is pending*/
157        RetVal = NFCSTATUS_REJECTED;
158    }
159    else if(gpphLibContext->ndef_cntx.is_ndef == FALSE)
160    {
161        /*no Ndef Support in tag*/
162         RetVal = NFCSTATUS_NON_NDEF_COMPLIANT;
163    }
164    else if((gpphLibContext->ndef_cntx.is_ndef == TRUE)
165        &&(0 == gpphLibContext->ndef_cntx.NdefActualSize))
166    {
167        /*Card is empty- So Returning length as zero*/
168        psRd->length = 0;
169        RetVal = NFCSTATUS_SUCCESS;
170    }
171#ifdef LLCP_TRANSACT_CHANGES
172    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
173            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
174    {
175        RetVal= NFCSTATUS_BUSY;
176    }
177#endif /* #ifdef LLCP_TRANSACT_CHANGES */
178    else
179    {
180        gpphLibContext->psRemoteDevList->psRemoteDevInfo->SessionOpened = SESSION_OPEN;
181        gpphLibContext->ndef_cntx.eLast_Call = NdefRd;
182        if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
183            phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
184            hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
185            ((NULL == gpphLibContext->psBufferedAuth)
186            ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd))
187            )
188        {
189            if(NULL != gpphLibContext->psBufferedAuth)
190            {
191                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
192                {
193                    phOsalNfc_FreeMemory(
194                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
195                }
196                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
197                {
198                    phOsalNfc_FreeMemory(
199                        gpphLibContext->psBufferedAuth->sSendData.buffer);
200                }
201                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
202            }
203            gpphLibContext->psBufferedAuth
204                =(phLibNfc_sTransceiveInfo_t *)
205                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
206            gpphLibContext->psBufferedAuth->addr =
207             (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
208             ->StdMifareContainer.currentBlock;
209            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
210            gpphLibContext->psBufferedAuth->sSendData.length
211                = 0;
212            gpphLibContext->psBufferedAuth->sRecvData.length
213                = MIFARE_STD_BLOCK_SIZE;
214            gpphLibContext->psBufferedAuth->sRecvData.buffer
215                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
216            gpphLibContext->psBufferedAuth->sSendData.buffer
217             = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
218        }
219        if(eLibNfcHalStatePresenceChk !=
220                gpphLibContext->LibNfcState.next_state)
221        {
222            uint8_t     cr_index = 0;
223            gpphLibContext->ndef_cntx.psUpperNdefMsg = psRd;
224            for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
225            {
226                RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
227                                    gpphLibContext->ndef_cntx.psNdefMap,
228                                    cr_index,
229                                    phLibNfc_Ndef_Read_Cb,
230                                    (void *)gpphLibContext);
231
232            }
233            gpphLibContext->ndef_cntx.NdefContinueRead =(uint8_t) ((phLibNfc_Ndef_EBegin==Offset) ?
234                                                    PH_FRINFC_NDEFMAP_SEEK_BEGIN :
235                                                    PH_FRINFC_NDEFMAP_SEEK_CUR);
236            /* call below layer Ndef Read*/
237            RetVal = phFriNfc_NdefMap_RdNdef(gpphLibContext->ndef_cntx.psNdefMap,
238                            gpphLibContext->ndef_cntx.psUpperNdefMsg->buffer,
239                            (uint32_t*)&gpphLibContext->ndef_cntx.psUpperNdefMsg->length,
240                            gpphLibContext->ndef_cntx.NdefContinueRead);
241
242            RetVal = PHNFCSTATUS(RetVal);
243            if(NFCSTATUS_INSUFFICIENT_STORAGE == RetVal)
244            {
245                gpphLibContext->ndef_cntx.psUpperNdefMsg->length = 0;
246                RetVal = NFCSTATUS_SUCCESS;
247            }
248        }
249        else
250        {
251             gpphLibContext->CBInfo.pClientRdNdefCb= NULL;
252             RetVal = NFCSTATUS_PENDING;
253        }
254        if(NFCSTATUS_PENDING == RetVal)
255        {
256            gpphLibContext->CBInfo.pClientRdNdefCb = pNdefRead_RspCb;
257            gpphLibContext->CBInfo.pClientRdNdefCntx = pContext;
258            gpphLibContext->status.GenCb_pending_status=TRUE;
259			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
260
261        }
262        else if (NFCSTATUS_SUCCESS == RetVal)
263        {
264            RetVal= NFCSTATUS_SUCCESS;
265        }
266        else
267        {
268            /*Ndef read failed*/
269            RetVal = NFCSTATUS_FAILED;
270        }
271    }
272    return RetVal;
273}
274/* Response callback for phLibNfc_Ndef_Read */
275STATIC
276void phLibNfc_Ndef_Read_Cb(void* Context,NFCSTATUS status)
277{
278    NFCSTATUS               RetStatus = NFCSTATUS_SUCCESS;
279    pphLibNfc_RspCb_t       pClientCb=NULL;
280    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
281    void                    *pUpperLayerContext=NULL;
282    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
283
284    if(pLibNfc_Ctxt != gpphLibContext)
285    {
286        /*wrong context returned*/
287        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
288    }
289    else
290    {
291        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
292        {   /*shutdown called before completion of Ndef read allow
293              shutdown to happen */
294            phLibNfc_Pending_Shutdown();
295            RetStatus = NFCSTATUS_SHUTDOWN;
296        }
297        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
298        {
299            RetStatus = NFCSTATUS_ABORTED;
300        }
301        else
302        {
303            gpphLibContext->status.GenCb_pending_status = FALSE;
304            if (gpphLibContext->psBufferedAuth != NULL && gpphLibContext->ndef_cntx.psNdefMap != NULL) {
305                   gpphLibContext->psBufferedAuth->addr = (uint8_t)
306                   gpphLibContext->ndef_cntx.psNdefMap->StdMifareContainer.currentBlock;
307            }
308
309            if(NFCSTATUS_FAILED == status )
310            {
311                /*During Ndef read operation tag was not present in RF
312                field of reader*/
313                RetStatus = NFCSTATUS_FAILED;
314                gpphLibContext->LastTrancvSuccess = FALSE;
315                gpphLibContext->ndef_cntx.is_ndef = FALSE;
316                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
317                                    gpphLibContext->Connected_handle;
318                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) &&
319                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)) ||
320                    (0x01 == ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak))
321                {
322
323                    /* card type is mifare 1k/4k, then reconnect */
324                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,
325                                ps_rem_dev_info,
326                                (pphHal4Nfc_ConnectCallback_t)
327                                phLibNfc_Reconnect_Mifare_Cb,
328                                (void *)gpphLibContext);
329                }
330
331            }
332            else if(status == NFCSTATUS_SUCCESS)
333            {
334                gpphLibContext->LastTrancvSuccess = TRUE;
335                RetStatus = NFCSTATUS_SUCCESS;
336            }
337		    else
338		    {
339                gpphLibContext->LastTrancvSuccess = FALSE;
340				RetStatus = NFCSTATUS_FAILED;
341			}
342        }
343        /*update the current state as connected*/
344        phLibNfc_UpdateCurState(status,gpphLibContext);
345
346        pClientCb = gpphLibContext->CBInfo.pClientRdNdefCb;
347        pUpperLayerContext = gpphLibContext->CBInfo.pClientRdNdefCntx;
348
349        gpphLibContext->CBInfo.pClientRdNdefCb = NULL;
350        gpphLibContext->CBInfo.pClientRdNdefCntx = NULL;
351        if(NFCSTATUS_PENDING != RetStatus)
352        {
353            if (NULL != pClientCb)
354            {
355                /*Notify to upper layer status and read bytes*/
356                pClientCb(pUpperLayerContext,RetStatus);
357            }
358        }
359    }
360    return;
361}
362
363/**
364* Write NDEF to a tag.
365*
366* This function allows the user to write a NDEF data to already connected NFC
367* tag.Function writes   a complete NDEF message to a tag. If a NDEF message
368* already exists in the tag, it will be overwritten. When the transaction is
369* complete,a notification callback is notified.
370*/
371NFCSTATUS phLibNfc_Ndef_Write(
372                            phLibNfc_Handle          hRemoteDevice,
373                            phNfc_sData_t           *psWr,
374                            pphLibNfc_RspCb_t        pNdefWrite_RspCb,
375                            void*                    pContext
376                            )
377{
378    NFCSTATUS RetVal = NFCSTATUS_FAILED;
379    uint8_t             NdefWriteType=0xFF;
380    /*LibNfc is initilized or not */
381    if((NULL == gpphLibContext)||
382        (gpphLibContext->LibNfcState.cur_state
383                            == eLibNfcHalStateShutdown))
384    {
385        RetVal = NFCSTATUS_NOT_INITIALISED;
386    }/*Check for application has sent the valid parameters*/
387    else if((NULL == psWr) || (NULL == pNdefWrite_RspCb)
388        || (NULL == psWr->buffer)
389        || (NULL == pContext)
390        || (0 ==hRemoteDevice))
391    {
392        RetVal= NFCSTATUS_INVALID_PARAMETER;
393    }
394    else if(gpphLibContext->LibNfcState.next_state
395                            == eLibNfcHalStateShutdown)
396    {   /* Lib Nfc Shutdown*/
397        RetVal= NFCSTATUS_SHUTDOWN;
398    }
399    else if(0 == gpphLibContext->Connected_handle)
400    {
401        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
402    }
403    else if(hRemoteDevice != gpphLibContext->Connected_handle)
404    {
405        RetVal=NFCSTATUS_INVALID_HANDLE;
406    }
407    else if((TRUE == gpphLibContext->status.GenCb_pending_status)||
408           (gpphLibContext->ndef_cntx.is_ndef == CHK_NDEF_NOT_DONE))
409    {
410         /* Previous callback is pending or Tag is not NDEF tag*/
411        RetVal = NFCSTATUS_REJECTED;
412        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
413    }
414    else if(FALSE == gpphLibContext->ndef_cntx.is_ndef)
415    {
416        RetVal = NFCSTATUS_NON_NDEF_COMPLIANT;
417    }
418    else if(psWr->length > gpphLibContext->ndef_cntx.NdefLength)
419    {
420        RetVal = NFCSTATUS_NOT_ENOUGH_MEMORY;
421    }
422#ifdef LLCP_TRANSACT_CHANGES
423    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
424            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
425    {
426        RetVal= NFCSTATUS_BUSY;
427    }
428#endif /* #ifdef LLCP_TRANSACT_CHANGES */
429    else
430    {
431        uint8_t         cr_index = 0;
432        gpphLibContext->ndef_cntx.psUpperNdefMsg = psWr;
433        gpphLibContext->ndef_cntx.AppWrLength= psWr->length;
434        gpphLibContext->ndef_cntx.eLast_Call = NdefWr;
435        gpphLibContext->psRemoteDevList->psRemoteDevInfo->SessionOpened
436            = SESSION_OPEN;
437        if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
438               phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
439               hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
440               ((NULL == gpphLibContext->psBufferedAuth)
441                ||(phHal_eMifareAuthentA ==
442                   gpphLibContext->psBufferedAuth->cmd.MfCmd))
443               )
444        {
445            if(NULL != gpphLibContext->psBufferedAuth)
446            {
447                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
448                {
449                    phOsalNfc_FreeMemory(
450                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
451                }
452                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
453                {
454                    phOsalNfc_FreeMemory(
455                        gpphLibContext->psBufferedAuth->sSendData.buffer);
456                }
457                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
458            }
459            gpphLibContext->psBufferedAuth
460                =(phLibNfc_sTransceiveInfo_t *)
461                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
462            gpphLibContext->psBufferedAuth->addr =
463             (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
464             ->StdMifareContainer.currentBlock;
465            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
466            gpphLibContext->psBufferedAuth->sSendData.length
467                = 0;
468            gpphLibContext->psBufferedAuth->sRecvData.length
469                = MIFARE_STD_BLOCK_SIZE;
470            gpphLibContext->psBufferedAuth->sRecvData.buffer
471                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
472             gpphLibContext->psBufferedAuth->sSendData.buffer
473                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
474        }
475        if(eLibNfcHalStatePresenceChk ==
476                gpphLibContext->LibNfcState.next_state)
477        {
478            gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
479            RetVal = NFCSTATUS_PENDING;
480        }
481        else
482        {
483            for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
484            {
485                /* Registering the Completion Routine.*/
486                RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
487                                    gpphLibContext->ndef_cntx.psNdefMap,
488                                    cr_index,
489                                    phLibNfc_Ndef_Write_Cb,
490                                    (void *)gpphLibContext);
491
492            }
493            if(0 == psWr->length)
494            {
495                 /* Length of bytes to be written Zero- Erase the Tag  */
496                RetVal = phFriNfc_NdefMap_EraseNdef(gpphLibContext->ndef_cntx.psNdefMap);
497            }
498            else
499            {
500                /*Write from beginning or current location*/
501                NdefWriteType = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
502                /*Call FRI Ndef Write*/
503                RetVal=phFriNfc_NdefMap_WrNdef(gpphLibContext->ndef_cntx.psNdefMap,
504                            gpphLibContext->ndef_cntx.psUpperNdefMsg->buffer,
505                            (uint32_t*)&gpphLibContext->ndef_cntx.psUpperNdefMsg->length,
506                            NdefWriteType);
507            }
508            if(NFCSTATUS_PENDING == RetVal)
509            {
510                gpphLibContext->CBInfo.pClientWrNdefCb = pNdefWrite_RspCb;
511                gpphLibContext->CBInfo.pClientWrNdefCntx = pContext;
512                gpphLibContext->status.GenCb_pending_status=TRUE;
513                gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
514            }
515            else
516            {
517                RetVal = NFCSTATUS_FAILED;
518            }
519        }
520    }
521    return RetVal;
522}
523
524/* Response callback for phLibNfc_Ndef_Write */
525STATIC
526void phLibNfc_Ndef_Write_Cb(void* Context,NFCSTATUS status)
527{
528
529    pphLibNfc_RspCb_t       pClientCb=NULL;
530    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
531    void                    *pUpperLayerContext=NULL;
532    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
533
534    if(pLibNfc_Ctxt != gpphLibContext)
535    {   /*wrong context returned*/
536        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
537    }
538    else
539    {
540        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
541        {   /*shutdown called before completion of Ndef write allow
542              shutdown to happen */
543            phLibNfc_Pending_Shutdown();
544            status = NFCSTATUS_SHUTDOWN;
545        }
546        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
547        {
548            status = NFCSTATUS_ABORTED;
549        }
550        else
551        {
552            gpphLibContext->status.GenCb_pending_status = FALSE;
553            if (gpphLibContext->psBufferedAuth != NULL && gpphLibContext->ndef_cntx.psNdefMap != NULL) {
554                gpphLibContext->psBufferedAuth->addr = (uint8_t)
555                    gpphLibContext->ndef_cntx.psNdefMap->TLVStruct.NdefTLVBlock;
556            }
557            if(status == NFCSTATUS_FAILED )
558            {
559				status = NFCSTATUS_FAILED;
560                gpphLibContext->LastTrancvSuccess = FALSE;
561                /*During Ndef write operation tag was not present in RF
562                field of reader*/
563                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
564                                    gpphLibContext->Connected_handle;
565               if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) &&
566                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
567                {
568
569
570                    /* card type is mifare 1k/4k, then reconnect */
571                    status = phHal4Nfc_Connect(gpphLibContext->psHwReference,
572                                ps_rem_dev_info,
573                                (pphHal4Nfc_ConnectCallback_t)
574                                phLibNfc_Reconnect_Mifare_Cb,
575                                (void *)gpphLibContext);
576                }
577            }
578            else if( status== NFCSTATUS_SUCCESS)
579            {
580                gpphLibContext->LastTrancvSuccess = TRUE;
581                status = NFCSTATUS_SUCCESS;
582                if(gpphLibContext->ndef_cntx.AppWrLength >
583                                 gpphLibContext->ndef_cntx.NdefLength)
584                {
585                    status = NFCSTATUS_NOT_ENOUGH_MEMORY;
586                }
587                else
588                {
589                    pLibNfc_Ctxt->ndef_cntx.NdefActualSize =
590                                    pLibNfc_Ctxt->ndef_cntx.psUpperNdefMsg->length;
591                }
592            }
593            else
594            {
595                gpphLibContext->LastTrancvSuccess = FALSE;
596				status = NFCSTATUS_FAILED;;
597			}
598        }
599        phLibNfc_UpdateCurState(status,gpphLibContext);
600
601        pClientCb = gpphLibContext->CBInfo.pClientWrNdefCb;
602        pUpperLayerContext = gpphLibContext->CBInfo.pClientWrNdefCntx;
603
604        gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
605        gpphLibContext->CBInfo.pClientWrNdefCntx = NULL;
606        if(NFCSTATUS_PENDING !=status)
607        {
608            if (NULL != pClientCb)
609            {
610                /*Notify to upper layer status and No. of bytes
611                actually written */
612                pClientCb(pUpperLayerContext, status);
613            }
614        }
615    }
616    return;
617}
618
619
620/**
621* Initialize structures needed for the Ndef
622* related operation such as Check Ndef, read, write
623* and Ndef foramt.only once allocation
624*/
625void phLibNfc_Ndef_Init(void)
626{
627    if(gpphLibContext->psTransInfo==NULL)
628    {
629        /*Allocate memory for Transceiveinformation Structure*/
630        gpphLibContext->psTransInfo = (phLibNfc_sTransceiveInfo_t *)
631            phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
632    }
633    if(gpphLibContext->psTransInfo==NULL)
634    {
635        /*exception: Not enough memory*/
636        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
637
638    }
639    if(NULL == gpphLibContext->ndef_cntx.psNdefMap)
640    {
641        /*Allocate memory for NDEF Mapping Component Context Structure*/
642        gpphLibContext->ndef_cntx.psNdefMap = (phFriNfc_NdefMap_t *)
643                    phOsalNfc_GetMemory(sizeof(phFriNfc_NdefMap_t));
644    }
645    if(NULL != gpphLibContext->ndef_cntx.psNdefMap)
646    {
647        /*Allocation successful*/
648        (void)memset(gpphLibContext->ndef_cntx.psNdefMap,0,sizeof(phFriNfc_NdefMap_t));
649        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
650        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf =
651                (uint8_t*) phOsalNfc_GetMemory(gpphLibContext->
652                ndef_cntx.NdefSendRecvLen);
653
654        if(NULL != gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf)
655        {
656            (void)memset(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
657                0,
658                gpphLibContext->ndef_cntx.NdefSendRecvLen);
659
660            gpphLibContext->psOverHalCtxt =(phFriNfc_OvrHal_t *)
661                phOsalNfc_GetMemory(sizeof(phFriNfc_OvrHal_t));
662        }
663    }
664    if(NULL == gpphLibContext->psOverHalCtxt)
665    {   /*exception: Not enough memory*/
666        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
667    }
668    else
669    {
670
671        (void)memset(gpphLibContext->psOverHalCtxt,0,
672            sizeof(phFriNfc_OvrHal_t));
673
674        /* Initialize the Overlapped hal structure*/
675        gpphLibContext->psOverHalCtxt->psHwReference =
676             gpphLibContext->psHwReference;
677        if(NULL == gpphLibContext->psDevInputParam )
678        {
679            gpphLibContext->psDevInputParam = (phHal_sDevInputParam_t *)
680                phOsalNfc_GetMemory(sizeof(phHal_sDevInputParam_t));
681        }
682        gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
683    }
684    if(NULL == gpphLibContext->ndef_cntx.ndef_fmt)
685    {
686        /*Allocate memory for Ndef format structure*/
687        gpphLibContext->ndef_cntx.ndef_fmt = (phFriNfc_sNdefSmtCrdFmt_t *)
688                phOsalNfc_GetMemory(sizeof(phFriNfc_sNdefSmtCrdFmt_t));
689    }
690    if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
691    {
692        (void)memset(gpphLibContext->ndef_cntx.ndef_fmt,
693                        0,
694                        sizeof(phFriNfc_sNdefSmtCrdFmt_t));
695    }
696    else
697    {
698        /*exception: Not enough memory*/
699        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
700    }
701    return;
702}
703/**
704* Free the allocated memory used for Ndef operations
705*/
706void phLibNfc_Ndef_DeInit(void)
707{
708    /* If only allocated then only free the memory*/
709    if(gpphLibContext->ndef_cntx.psNdefMap !=NULL)
710    {
711        if(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf !=NULL)
712        {
713            phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf);
714            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf=NULL;
715        }
716        phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap);
717        gpphLibContext->ndef_cntx.psNdefMap =NULL;
718    }
719
720    if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
721    {
722        phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.ndef_fmt);
723        gpphLibContext->ndef_cntx.ndef_fmt = NULL;
724    }
725
726    if(gpphLibContext->psOverHalCtxt !=NULL)
727    {
728        phOsalNfc_FreeMemory(gpphLibContext->psOverHalCtxt);
729        gpphLibContext->psOverHalCtxt =NULL;
730    }
731    if(gpphLibContext->psDevInputParam !=NULL)
732    {
733        phOsalNfc_FreeMemory(gpphLibContext->psDevInputParam);
734        gpphLibContext->psDevInputParam = NULL;
735    }
736    if(gpphLibContext->psTransInfo!=NULL)
737    {
738        phOsalNfc_FreeMemory(gpphLibContext->psTransInfo);
739        gpphLibContext->psTransInfo= NULL;
740    }
741}
742
743
744/**
745* This function allows  the user to check whether a particular Remote Device
746* is NDEF compliant or not
747*/
748NFCSTATUS phLibNfc_Ndef_CheckNdef(phLibNfc_Handle       hRemoteDevice,
749                        pphLibNfc_ChkNdefRspCb_t        pCheckNdef_RspCb,
750                        void*                           pContext)
751{
752    NFCSTATUS RetVal = NFCSTATUS_FAILED;
753
754
755    if((NULL == gpphLibContext)||
756        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
757    {
758        /*Lib Nfc not initialized*/
759        RetVal = NFCSTATUS_NOT_INITIALISED;
760    }
761    else if((NULL == pCheckNdef_RspCb)||
762        (NULL==pContext)||
763        (hRemoteDevice == 0))
764    {
765        /*parameter sent by upper layer are not valid */
766        RetVal= NFCSTATUS_INVALID_PARAMETER;
767    }
768    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
769    {
770        RetVal = NFCSTATUS_SHUTDOWN;
771    }
772    else if(0 == gpphLibContext->Connected_handle)
773    {
774        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
775    }
776    else if(hRemoteDevice != gpphLibContext->Connected_handle)
777    {
778        RetVal=NFCSTATUS_INVALID_HANDLE;
779    }
780#ifdef LLCP_TRANSACT_CHANGES
781    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
782            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
783    {
784        RetVal= NFCSTATUS_BUSY;
785    }
786#endif /* #ifdef LLCP_TRANSACT_CHANGES */
787    else
788    {
789        uint8_t     cr_index = 0;
790        static uint16_t     data_cnt = 0;
791        /* Allocate memory for the ndef related structure */
792        gpphLibContext->ndef_cntx.NdefSendRecvLen=300;
793        gpphLibContext->ndef_cntx.eLast_Call = ChkNdef;
794
795        /* Resets the component instance */
796        RetVal = phFriNfc_NdefMap_Reset( gpphLibContext->ndef_cntx.psNdefMap,
797                            gpphLibContext->psOverHalCtxt,
798                            (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
799                            gpphLibContext->psDevInputParam,
800                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
801                            gpphLibContext->ndef_cntx.NdefSendRecvLen,
802                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
803                            &(gpphLibContext->ndef_cntx.NdefSendRecvLen),
804                            &(data_cnt));
805
806
807        for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
808        {
809            /* Register the callback for the check ndef */
810            RetVal = phFriNfc_NdefMap_SetCompletionRoutine(
811                                gpphLibContext->ndef_cntx.psNdefMap,
812                                cr_index,
813                                phLibNfc_Ndef_CheckNdef_Cb,
814                                (void *)gpphLibContext);
815        }
816        /*call below layer check Ndef function*/
817        RetVal = phFriNfc_NdefMap_ChkNdef(gpphLibContext->ndef_cntx.psNdefMap);
818        RetVal =PHNFCSTATUS(RetVal);
819
820        if(RetVal== NFCSTATUS_PENDING)
821        {
822            RetVal = NFCSTATUS_PENDING;
823        }
824        else if((RetVal == NFCSTATUS_FAILED) || (RetVal ==(PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
825                    NFCSTATUS_INVALID_REMOTE_DEVICE))))
826        {
827			      RetVal= NFCSTATUS_FAILED;
828        }
829        else
830        {
831            if((0x00 == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id)||
832              (PH_OSALNFC_INVALID_TIMER_ID == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id))
833	          {
834		            gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id =
835			          phOsalNfc_Timer_Create();
836	          }
837	          if((0x00 == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id)||
838              (PH_OSALNFC_INVALID_TIMER_ID == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id))
839	          {
840		            RetVal = NFCSTATUS_FAILED;
841	          }
842	          else
843	          {
844	              phOsalNfc_Timer_Start(gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id,
845			          CHK_NDEF_TIMER_TIMEOUT,CheckNdef_timer_cb,NULL);
846                RetVal = NFCSTATUS_PENDING;
847	          }
848        }
849        if(RetVal== NFCSTATUS_PENDING)
850        {
851            gpphLibContext->CBInfo.pClientCkNdefCb = pCheckNdef_RspCb;
852            gpphLibContext->CBInfo.pClientCkNdefCntx = pContext;
853            gpphLibContext->status.GenCb_pending_status=TRUE;
854            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
855        }
856
857    }
858    return RetVal;
859}
860
861/* Response callback for phLibNfc_Ndef_CheckNdef */
862STATIC
863void phLibNfc_Ndef_CheckNdef_Cb(void *pContext,NFCSTATUS status)
864{
865    phLibNfc_ChkNdef_Info_t    Ndef_Info;
866    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
867    pphLibNfc_ChkNdefRspCb_t       pClientCb=NULL;
868    phLibNfc_LibContext_t           *pLibNfc_Ctxt =
869                                    (phLibNfc_LibContext_t *)pContext;
870    void                    *pUpperLayerContext=NULL;
871    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
872
873    Ndef_Info.ActualNdefMsgLength = 0;
874    Ndef_Info.MaxNdefMsgLength = 0;
875    Ndef_Info.NdefCardState = PHLIBNFC_NDEF_CARD_INVALID;
876    if(pLibNfc_Ctxt != gpphLibContext)
877    {    /*wrong context returned from below layer*/
878        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
879    }
880    else
881    {
882        ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
883                                    gpphLibContext->Connected_handle;
884        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
885        {   /*shutdown called before completion of check Ndef, allow
886              shutdown to happen */
887            phLibNfc_Pending_Shutdown();
888            RetStatus = NFCSTATUS_SHUTDOWN;
889        }
890        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
891        {
892            RetStatus = NFCSTATUS_ABORTED;
893        }
894        else
895        {
896            if(status == NFCSTATUS_SUCCESS)
897            {
898                /*Tag is Ndef tag*/
899                gpphLibContext->ndef_cntx.is_ndef = TRUE;
900                (void)phFriNfc_NdefMap_GetContainerSize(
901                                pLibNfc_Ctxt->ndef_cntx.psNdefMap,
902                                &(pLibNfc_Ctxt->ndef_cntx.NdefLength),
903                                &(pLibNfc_Ctxt->ndef_cntx.NdefActualSize));
904                /*Get the data size support by particular ndef card */
905                Ndef_Info.ActualNdefMsgLength = pLibNfc_Ctxt->ndef_cntx.NdefActualSize;
906                Ndef_Info.MaxNdefMsgLength = pLibNfc_Ctxt->ndef_cntx.NdefLength;
907                gpphLibContext->LastTrancvSuccess = TRUE;
908                RetStatus =NFCSTATUS_SUCCESS;
909            }
910            else if (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION )
911            {
912                /*Ndef check Failed.Issue a PresenceChk to ascertain if tag is
913                  still in the field*/
914                RetStatus = phHal4Nfc_PresenceCheck(
915                                    gpphLibContext->psHwReference,
916                                    phLibNfc_Ndef_ChkNdef_Pchk_Cb,
917                                    (void *)gpphLibContext
918                                    );
919            }
920            else
921            {
922				RetStatus = NFCSTATUS_FAILED;
923                gpphLibContext->LastTrancvSuccess = FALSE;
924                gpphLibContext->ndef_cntx.is_ndef = FALSE;
925
926                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) &&
927                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
928                {
929
930                    /* card type is mifare 1k/4k, then reconnect */
931                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,
932                                ps_rem_dev_info,
933                                (pphHal4Nfc_ConnectCallback_t)
934                                phLibNfc_Reconnect_Mifare_Cb,
935                                (void *)gpphLibContext);
936                }
937                else
938                {
939                   if((phHal_eJewel_PICC == ps_rem_dev_info->RemDevType)
940                       &&(TOPAZ_NDEF_BITMASK &
941                          ps_rem_dev_info->RemoteDevInfo.Jewel_Info.HeaderRom0))
942                    {
943                        gpphLibContext->ndef_cntx.is_ndef = TRUE;
944                        RetStatus = phFriNfc_NdefMap_GetContainerSize(
945                                        pLibNfc_Ctxt->ndef_cntx.psNdefMap,
946                                        &(pLibNfc_Ctxt->ndef_cntx.NdefLength),
947                                        &(pLibNfc_Ctxt->ndef_cntx.NdefActualSize));
948                        /*Get the data size support by particular ndef card */
949                        Ndef_Info.ActualNdefMsgLength =
950                            pLibNfc_Ctxt->ndef_cntx.NdefActualSize;
951                        Ndef_Info.MaxNdefMsgLength
952                            = pLibNfc_Ctxt->ndef_cntx.NdefLength
953                            = (TOPAZ_LEN_BITMASK &
954                            ps_rem_dev_info->RemoteDevInfo.Jewel_Info.HeaderRom0?
955                            TOPAZ_DYNAMIC_LEN:TOPAZ_STATIC_CARD_LEN);
956                        RetStatus = NFCSTATUS_SUCCESS;
957                    }
958                }
959            }
960            gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect;
961        }
962        gpphLibContext->status.GenCb_pending_status = FALSE;
963        /* Update the current state */
964        phLibNfc_UpdateCurState(RetStatus,gpphLibContext);
965        if(NFCSTATUS_PENDING != RetStatus)
966        {
967            if(((ps_rem_dev_info->RemDevType == phHal_eMifare_PICC)
968                && (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
969               ((NULL == gpphLibContext->psBufferedAuth)
970                ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd)))
971               )
972            {
973                if(NULL != gpphLibContext->psBufferedAuth)
974                {
975                    if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
976                    {
977                        phOsalNfc_FreeMemory(
978                            gpphLibContext->psBufferedAuth->sRecvData.buffer);
979                    }
980                    if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
981                    {
982                        phOsalNfc_FreeMemory(
983                            gpphLibContext->psBufferedAuth->sSendData.buffer);
984                    }
985                    phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
986                }
987                gpphLibContext->psBufferedAuth
988                    =(phLibNfc_sTransceiveInfo_t *)
989                    phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
990                gpphLibContext->psBufferedAuth->addr =
991                (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
992                ->StdMifareContainer.currentBlock;
993                gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
994                gpphLibContext->psBufferedAuth->sSendData.length
995                    = 0;
996                gpphLibContext->psBufferedAuth->sRecvData.length
997                    = MIFARE_STD_BLOCK_SIZE;
998                gpphLibContext->psBufferedAuth->sRecvData.buffer
999                    = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
1000                gpphLibContext->psBufferedAuth->sSendData.buffer
1001                    = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
1002            }
1003            pClientCb = gpphLibContext->CBInfo.pClientCkNdefCb;
1004            pUpperLayerContext = gpphLibContext->CBInfo.pClientCkNdefCntx;
1005            gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
1006            gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
1007            if(NULL != pClientCb)
1008            {
1009                if (!RetStatus)
1010                {
1011                    switch (pLibNfc_Ctxt->ndef_cntx.psNdefMap->CardState)
1012                    {
1013                        case PH_NDEFMAP_CARD_STATE_INITIALIZED:
1014                        {
1015                            Ndef_Info.NdefCardState =
1016                                            PHLIBNFC_NDEF_CARD_INITIALISED;
1017                            break;
1018                        }
1019
1020                        case PH_NDEFMAP_CARD_STATE_READ_ONLY:
1021                        {
1022                            Ndef_Info.NdefCardState =
1023                                            PHLIBNFC_NDEF_CARD_READ_ONLY;
1024                            break;
1025                        }
1026
1027                        case PH_NDEFMAP_CARD_STATE_READ_WRITE:
1028                        {
1029                            Ndef_Info.NdefCardState =
1030                                            PHLIBNFC_NDEF_CARD_READ_WRITE;
1031                            break;
1032                        }
1033
1034                        default:
1035                        {
1036                            Ndef_Info.NdefCardState =
1037                                            PHLIBNFC_NDEF_CARD_INVALID;
1038                            break;
1039                        }
1040                    }
1041                }
1042                /* call the upper check ndef callback */
1043                pClientCb(pUpperLayerContext,Ndef_Info,RetStatus);
1044            }
1045        }
1046    }
1047    return;
1048}
1049
1050/*Callback for Presence check call from Chk Ndef*/
1051STATIC void phLibNfc_Ndef_ChkNdef_Pchk_Cb(void   *pContext,
1052                                NFCSTATUS  status
1053                                )
1054{
1055    phLibNfc_ChkNdef_Info_t    Ndef_Info = {0,0,0};
1056    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
1057    pphLibNfc_ChkNdefRspCb_t       pClientCb=NULL;
1058    phLibNfc_LibContext_t           *pLibNfc_Ctxt =
1059                                    (phLibNfc_LibContext_t *)pContext;
1060    void                    *pUpperLayerContext=NULL;
1061    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
1062    if(NFCSTATUS_SUCCESS == status)
1063    {
1064        RetStatus = NFCSTATUS_FAILED;
1065        gpphLibContext->ndef_cntx.is_ndef = FALSE;
1066    }
1067    else
1068    {
1069        RetStatus = NFCSTATUS_TARGET_LOST;
1070    }
1071    if(pLibNfc_Ctxt != gpphLibContext)
1072    {    /*wrong context returned from below layer*/
1073        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1074    }
1075    else
1076    {
1077        ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
1078                                    gpphLibContext->Connected_handle;
1079        if(((ps_rem_dev_info->RemDevType == phHal_eMifare_PICC)
1080            && (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
1081            ((NULL == gpphLibContext->psBufferedAuth)
1082            ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd)))
1083            )
1084        {
1085            if(NULL != gpphLibContext->psBufferedAuth)
1086            {
1087                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
1088                {
1089                    phOsalNfc_FreeMemory(
1090                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
1091                }
1092                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
1093                {
1094                    phOsalNfc_FreeMemory(
1095                        gpphLibContext->psBufferedAuth->sSendData.buffer);
1096                }
1097                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
1098            }
1099            gpphLibContext->psBufferedAuth
1100                =(phLibNfc_sTransceiveInfo_t *)
1101                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
1102            gpphLibContext->psBufferedAuth->addr =
1103            (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
1104            ->StdMifareContainer.currentBlock;
1105            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
1106            gpphLibContext->psBufferedAuth->sSendData.length
1107                = 0;
1108            gpphLibContext->psBufferedAuth->sRecvData.length
1109                = MIFARE_STD_BLOCK_SIZE;
1110            gpphLibContext->psBufferedAuth->sRecvData.buffer
1111                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
1112            gpphLibContext->psBufferedAuth->sSendData.buffer
1113                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
1114        }
1115        pClientCb = gpphLibContext->CBInfo.pClientCkNdefCb;
1116        pUpperLayerContext = gpphLibContext->CBInfo.pClientCkNdefCntx;
1117        gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
1118        gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
1119        if(NULL != pClientCb)
1120        {
1121            Ndef_Info.NdefCardState = PHLIBNFC_NDEF_CARD_INVALID;
1122            /* call the upper check ndef callback */
1123            pClientCb(pUpperLayerContext,Ndef_Info,RetStatus);
1124        }
1125    }
1126    return;
1127}
1128/* Check Ndef Timer Callback*/
1129STATIC void CheckNdef_timer_cb(uint32_t timer_id, void *pContext)
1130{
1131	PHNFC_UNUSED_VARIABLE(pContext);
1132   phOsalNfc_Timer_Stop(timer_id);
1133	phOsalNfc_Timer_Delete(gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id);
1134	gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id = 0x00;
1135	phLibNfc_Ndef_CheckNdef_Cb((void *)gpphLibContext,NFCSTATUS_MORE_INFORMATION);
1136}
1137
1138void phLibNfc_Reconnect_Mifare_Cb (
1139                    void                            *pContext,
1140                    phHal_sRemoteDevInformation_t   *psRemoteDevInfo,
1141                    NFCSTATUS                       status)
1142{
1143    phLibNfc_ChkNdef_Info_t     Ndef_Info;
1144    phLibNfc_LibContext_t       *pLibNfc_Ctxt =
1145                                (phLibNfc_LibContext_t *)pContext;
1146    void                        *pUpperLayerContext = NULL;
1147    switch(gpphLibContext->ndef_cntx.eLast_Call)
1148    {
1149        case ChkNdef:
1150        {
1151            pphLibNfc_ChkNdefRspCb_t    pClientCb=NULL;
1152            pClientCb = pLibNfc_Ctxt->CBInfo.pClientCkNdefCb;
1153            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientCkNdefCntx;
1154            pLibNfc_Ctxt->CBInfo.pClientCkNdefCb = NULL;
1155            pLibNfc_Ctxt->CBInfo.pClientCkNdefCntx = NULL;
1156            if (NULL != pClientCb)
1157            {
1158                status = (NFCSTATUS_SUCCESS == status?
1159                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
1160                Ndef_Info.ActualNdefMsgLength = 0;
1161                Ndef_Info.MaxNdefMsgLength = 0;
1162                /* call the upper check ndef callback */
1163                pClientCb(pUpperLayerContext,Ndef_Info,status);
1164            }
1165        }
1166        break;
1167        case NdefRd:
1168        {
1169            pphLibNfc_RspCb_t       pClientCb = pLibNfc_Ctxt->CBInfo.pClientRdNdefCb;
1170            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientRdNdefCntx;
1171            pLibNfc_Ctxt->CBInfo.pClientRdNdefCb = NULL;
1172            pLibNfc_Ctxt->CBInfo.pClientRdNdefCntx = NULL;
1173            if (NULL != pClientCb)
1174            {
1175                status = (NFCSTATUS_SUCCESS == status?
1176                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
1177                /* call the upper ndef read callback */
1178                pClientCb(pUpperLayerContext,status);
1179            }
1180        }
1181        break;
1182        case NdefWr:
1183        {
1184            pphLibNfc_RspCb_t       pClientCb =  pLibNfc_Ctxt->CBInfo.pClientWrNdefCb;
1185            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientWrNdefCntx;
1186            pLibNfc_Ctxt->CBInfo.pClientWrNdefCb = NULL;
1187            pLibNfc_Ctxt->CBInfo.pClientWrNdefCntx = NULL;
1188            if (NULL != pClientCb)
1189            {
1190                status = (NFCSTATUS_SUCCESS == status?
1191                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
1192                /* call the upper ndef write callback */
1193                pClientCb(pUpperLayerContext,status);
1194            }
1195        }
1196        break;
1197        case NdefFmt:
1198#ifdef LIBNFC_READONLY_NDEF
1199        case NdefReadOnly:
1200#endif /* #ifdef LIBNFC_READONLY_NDEF */
1201        {
1202            pphLibNfc_RspCb_t       pClientCb =
1203                           pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCb;
1204            pUpperLayerContext= pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCntx;
1205            pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCb = NULL;
1206            pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCntx = NULL;
1207            if (NULL != pClientCb)
1208            {
1209                status = (NFCSTATUS_SUCCESS == status?
1210                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
1211                /* call the upper ndef format callback */
1212                pClientCb(pUpperLayerContext,status);
1213            }
1214        }
1215        break;
1216        case RawTrans:
1217        {
1218            phNfc_sData_t trans_resp;
1219            pphLibNfc_TransceiveCallback_t pClientCb =
1220                           pLibNfc_Ctxt->CBInfo.pClientTransceiveCb;
1221            trans_resp.length = 0;
1222            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientTranseCntx;
1223            pLibNfc_Ctxt->CBInfo.pClientTranseCntx= NULL;
1224            pLibNfc_Ctxt->CBInfo.pClientTransceiveCb= NULL;
1225            if (NULL != pClientCb)
1226            {
1227                status = (NFCSTATUS_SUCCESS == status?
1228                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
1229                /* call the upper transceive callback */
1230                pClientCb(pUpperLayerContext,
1231                        (uint32_t)psRemoteDevInfo,
1232                        & trans_resp,
1233                        status);
1234            }
1235        }
1236        break;
1237        default:
1238        {
1239        }
1240        break;
1241    }
1242
1243}
1244/**
1245* Target format to make it NDEF compliant
1246*/
1247NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle         hRemoteDevice,
1248                                        phNfc_sData_t*          pScrtKey,
1249                                        pphLibNfc_RspCb_t       pNdefformat_RspCb,
1250                                        void*                   pContext
1251                                        )
1252{
1253    NFCSTATUS RetVal = NFCSTATUS_FAILED;
1254
1255    static uint8_t       mif_std_key[6] ={0},
1256                         Index = 0;
1257    if((NULL == gpphLibContext)
1258        ||(gpphLibContext->LibNfcState.cur_state
1259                            == eLibNfcHalStateShutdown))
1260    {
1261        /*Lib Nfc not initialized*/
1262        RetVal = NFCSTATUS_NOT_INITIALISED;
1263    }
1264    else if((NULL == pContext)
1265        || (NULL == pNdefformat_RspCb)
1266        ||(NULL == pScrtKey)
1267        ||(0 == hRemoteDevice))
1268    {
1269        RetVal= NFCSTATUS_INVALID_PARAMETER;
1270    }
1271    else if(gpphLibContext->LibNfcState.next_state
1272                            == eLibNfcHalStateShutdown)
1273    {
1274        RetVal= NFCSTATUS_SHUTDOWN;
1275    }
1276    else if(0 == gpphLibContext->Connected_handle)
1277    {
1278        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
1279    }
1280    else if(hRemoteDevice != gpphLibContext->Connected_handle)
1281    {
1282        RetVal=NFCSTATUS_INVALID_HANDLE;
1283    }
1284    else if((TRUE == gpphLibContext->status.GenCb_pending_status)||
1285        (NULL != gpphLibContext->ndef_cntx.pClientNdefFmtCb)
1286        ||(gpphLibContext->ndef_cntx.is_ndef == TRUE))
1287    {
1288        /*Previous Callback is Pending*/
1289        RetVal = NFCSTATUS_REJECTED;
1290        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
1291    }
1292#ifdef LLCP_TRANSACT_CHANGES
1293    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
1294            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
1295    {
1296        RetVal= NFCSTATUS_BUSY;
1297    }
1298#endif /* #ifdef LLCP_TRANSACT_CHANGES */
1299    else
1300    {
1301        uint8_t   fun_id;
1302        gpphLibContext->ndef_cntx.eLast_Call = NdefFmt;
1303        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
1304
1305        /* Call ndef format reset, this will initialize the ndef
1306        format structure, and appropriate values are filled */
1307        RetVal = phFriNfc_NdefSmtCrd_Reset(gpphLibContext->ndef_cntx.ndef_fmt,
1308                            gpphLibContext->psOverHalCtxt,
1309                            (phHal_sRemoteDevInformation_t*)hRemoteDevice,
1310                            gpphLibContext->psDevInputParam,
1311                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
1312                            &(gpphLibContext->ndef_cntx.NdefSendRecvLen));
1313        for(fun_id = 0; fun_id < PH_FRINFC_SMTCRDFMT_CR; fun_id++)
1314        {
1315            /* Register for all the callbacks */
1316            RetVal = phFriNfc_NdefSmtCrd_SetCR(gpphLibContext->ndef_cntx.ndef_fmt,
1317                        fun_id,
1318                        phLibNfc_Ndef_format_Cb,
1319                        gpphLibContext);
1320        }
1321        /* mif_std_key is required to format the mifare 1k/4k card */
1322        for (Index =0 ;Index < (pScrtKey->length); Index++ )
1323        {
1324            mif_std_key[Index] = *(pScrtKey->buffer++);
1325        }
1326        /* Start smart card formatting function   */
1327        RetVal = phFriNfc_NdefSmtCrd_Format(gpphLibContext->ndef_cntx.ndef_fmt,
1328                                        mif_std_key);
1329		RetVal = PHNFCSTATUS(RetVal);
1330        if(RetVal== NFCSTATUS_PENDING)
1331        {
1332            gpphLibContext->ndef_cntx.pClientNdefFmtCb = pNdefformat_RspCb;
1333            gpphLibContext->ndef_cntx.pClientNdefFmtCntx = pContext;
1334            gpphLibContext->status.GenCb_pending_status=TRUE;
1335            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
1336        }
1337        else
1338        {
1339            RetVal = NFCSTATUS_FAILED;
1340        }
1341    }
1342    return RetVal;
1343}
1344
1345#ifdef LIBNFC_READONLY_NDEF
1346
1347NFCSTATUS
1348phLibNfc_ConvertToReadOnlyNdef (
1349    phLibNfc_Handle         hRemoteDevice,
1350    phNfc_sData_t*          pScrtKey,
1351    pphLibNfc_RspCb_t       pNdefReadOnly_RspCb,
1352    void*                   pContext
1353    )
1354{
1355    NFCSTATUS           ret_val = NFCSTATUS_FAILED;
1356    static uint8_t      mif_std_key[6] ={0},
1357                        Index = 0;
1358
1359    if ((NULL == gpphLibContext)
1360        || (gpphLibContext->LibNfcState.cur_state
1361                            == eLibNfcHalStateShutdown))
1362    {
1363        /* LibNfc not initialized */
1364        ret_val = NFCSTATUS_NOT_INITIALISED;
1365    }
1366    else if ((NULL == pContext)
1367        || (NULL == pNdefReadOnly_RspCb)
1368        || (0 == hRemoteDevice))
1369    {
1370        ret_val = NFCSTATUS_INVALID_PARAMETER;
1371    }
1372    else if (gpphLibContext->LibNfcState.next_state
1373            == eLibNfcHalStateShutdown)
1374    {
1375        ret_val = NFCSTATUS_SHUTDOWN;
1376    }
1377    else if (0 == gpphLibContext->Connected_handle)
1378    {
1379        ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
1380    }
1381    else if (hRemoteDevice != gpphLibContext->Connected_handle)
1382    {
1383        ret_val = NFCSTATUS_INVALID_HANDLE;
1384    }
1385    else if ((TRUE == gpphLibContext->status.GenCb_pending_status)
1386        || (NULL != gpphLibContext->ndef_cntx.pClientNdefFmtCb)
1387        || (FALSE == gpphLibContext->ndef_cntx.is_ndef))
1388    {
1389        /* Previous Callback is Pending */
1390        ret_val = NFCSTATUS_REJECTED;
1391        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
1392    }
1393    else
1394    {
1395        gpphLibContext->ndef_cntx.eLast_Call = NdefReadOnly;
1396
1397        if(eLibNfcHalStatePresenceChk != gpphLibContext->LibNfcState.next_state)
1398        {
1399            phHal_sRemoteDevInformation_t           *ps_rem_dev_info =
1400                                                (phHal_sRemoteDevInformation_t *)hRemoteDevice;
1401            uint8_t                                 fun_id;
1402
1403            switch (ps_rem_dev_info->RemDevType)
1404            {
1405                case phHal_eMifare_PICC:
1406                case phHal_eISO14443_A_PICC:
1407                {
1408                    if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType)
1409                        && (0x00 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak))
1410                    {
1411                        for (fun_id = 0; fun_id < PH_FRINFC_NDEFMAP_CR; fun_id++)
1412                        {
1413                            /* Register the callback for the check ndef */
1414                            ret_val = phFriNfc_NdefMap_SetCompletionRoutine (
1415                                      gpphLibContext->ndef_cntx.psNdefMap,
1416                                      fun_id, phLibNfc_Ndef_ReadOnly_Cb,
1417                                      (void *)gpphLibContext);
1418                        }
1419
1420                        /* Start mifare NFC read only function   */
1421                        /* mif_std_key is required to format the mifare 1k/4k card */
1422                        if(pScrtKey != NULL && pScrtKey->length == MIFARE_STD_KEY_LEN)
1423                        {
1424                            for (Index =0 ;Index < (pScrtKey->length); Index++ )
1425                            {
1426                                mif_std_key[Index] = *(pScrtKey->buffer++);
1427                            }
1428
1429                            ret_val = phFriNfc_MifareStdMap_ConvertToReadOnly (
1430                                      gpphLibContext->ndef_cntx.psNdefMap, mif_std_key);
1431                            ret_val = PHNFCSTATUS(ret_val);
1432                        }
1433                    }
1434                    else
1435                    {
1436                        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
1437
1438                        /* Call ndef format reset, this will initialize the ndef
1439                        format structure, and appropriate values are filled */
1440                        ret_val = phFriNfc_NdefSmtCrd_Reset (gpphLibContext->ndef_cntx.ndef_fmt,
1441                                                gpphLibContext->psOverHalCtxt,
1442                                                (phHal_sRemoteDevInformation_t*)hRemoteDevice,
1443                                                gpphLibContext->psDevInputParam,
1444                                                gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
1445                                                &(gpphLibContext->ndef_cntx.NdefSendRecvLen));
1446
1447                        for(fun_id = 0; fun_id < PH_FRINFC_SMTCRDFMT_CR; fun_id++)
1448                        {
1449                            /* Register for all the callbacks */
1450                            ret_val = phFriNfc_NdefSmtCrd_SetCR (gpphLibContext->ndef_cntx.ndef_fmt,
1451                                                                fun_id, phLibNfc_Ndef_ReadOnly_Cb,
1452                                                                gpphLibContext);
1453                        }
1454
1455                        /* Start smart card formatting function   */
1456                        ret_val = phFriNfc_NdefSmtCrd_ConvertToReadOnly (
1457                                                        gpphLibContext->ndef_cntx.ndef_fmt);
1458                        ret_val = PHNFCSTATUS(ret_val);
1459                    }
1460                    break;
1461                }
1462
1463                case phHal_eJewel_PICC:
1464                case phHal_eISO15693_PICC:
1465                {
1466// MC: Got the feedback this was #if 0'd because it was resetting the lock bits
1467// read in check NDEF, and these should not be reset here already.
1468#if 0
1469                    static uint16_t     data_cnt = 0;
1470
1471                    /* Resets the component instance */
1472                    ret_val = phFriNfc_NdefMap_Reset (gpphLibContext->ndef_cntx.psNdefMap,
1473                                        gpphLibContext->psOverHalCtxt,
1474                                        (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
1475                                        gpphLibContext->psDevInputParam,
1476                                        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
1477                                        gpphLibContext->ndef_cntx.NdefSendRecvLen,
1478                                        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
1479                                        &(gpphLibContext->ndef_cntx.NdefSendRecvLen),
1480                                        &(data_cnt));
1481#endif /* #if 0 */
1482
1483
1484                    for (fun_id = 0; fun_id < PH_FRINFC_NDEFMAP_CR; fun_id++)
1485                    {
1486                        /* Register the callback for the check ndef */
1487                        ret_val = phFriNfc_NdefMap_SetCompletionRoutine (
1488                                            gpphLibContext->ndef_cntx.psNdefMap,
1489                                            fun_id, phLibNfc_Ndef_ReadOnly_Cb,
1490                                            (void *)gpphLibContext);
1491                    }
1492
1493                    /* call below layer check Ndef function */
1494                    ret_val = phFriNfc_NdefMap_ConvertToReadOnly (
1495                                            gpphLibContext->ndef_cntx.psNdefMap);
1496                    ret_val = PHNFCSTATUS(ret_val);
1497                    break;
1498                }
1499
1500                default:
1501                {
1502                    /* Tag not supported */
1503                    ret_val = NFCSTATUS_REJECTED;
1504                    break;
1505                }
1506            }
1507        }
1508        else
1509        {
1510             gpphLibContext->ndef_cntx.pClientNdefFmtCb= NULL;
1511             ret_val = NFCSTATUS_PENDING;
1512        }
1513
1514        if (NFCSTATUS_PENDING == ret_val)
1515        {
1516            gpphLibContext->ndef_cntx.pClientNdefFmtCb = pNdefReadOnly_RspCb;
1517            gpphLibContext->ndef_cntx.pClientNdefFmtCntx = pContext;
1518
1519            gpphLibContext->status.GenCb_pending_status = TRUE;
1520            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
1521        }
1522        else
1523        {
1524            ret_val = NFCSTATUS_FAILED;
1525        }
1526    }
1527    return ret_val;
1528}
1529
1530#endif /* #ifdef LIBNFC_READONLY_NDEF */
1531
1532/**
1533* Response callback for NDEF format.
1534*/
1535STATIC
1536void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS  status)
1537{
1538    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
1539    pphLibNfc_RspCb_t       pClientCb=NULL;
1540    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
1541    void                    *pUpperLayerContext=NULL;
1542    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
1543    if(pLibNfc_Ctxt != gpphLibContext)
1544    {   /*wrong context returned*/
1545        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1546    }
1547    else
1548    {
1549        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
1550        {
1551            /*shutdown is pending so issue shutdown*/
1552            phLibNfc_Pending_Shutdown();
1553            RetStatus = NFCSTATUS_SHUTDOWN;
1554        }
1555        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
1556        {
1557            RetStatus = NFCSTATUS_ABORTED;
1558        }
1559        else
1560        {
1561            gpphLibContext->status.GenCb_pending_status = FALSE;
1562            if(NFCSTATUS_SUCCESS == status)
1563            {
1564                RetStatus = NFCSTATUS_SUCCESS;
1565            }
1566            else if(PHNFCSTATUS(status)==NFCSTATUS_FAILED)
1567            {
1568                RetStatus = NFCSTATUS_FAILED;
1569                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
1570                                    gpphLibContext->Connected_handle;
1571                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) &&
1572                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
1573                {
1574
1575                    /* card type is mifare 1k/4k, then reconnect */
1576                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,
1577                                (phHal_sRemoteDevInformation_t *)
1578                                gpphLibContext->Connected_handle,
1579                                (pphHal4Nfc_ConnectCallback_t)
1580                                phLibNfc_Reconnect_Mifare_Cb,
1581                                (void *)gpphLibContext);
1582                }
1583            }
1584			else
1585            {
1586                /*Target was removed during transaction*/
1587                RetStatus = NFCSTATUS_FAILED;
1588            }
1589            gpphLibContext->LibNfcState.cur_state =eLibNfcHalStateConnect;
1590        }
1591        phLibNfc_UpdateCurState(status,gpphLibContext);
1592
1593        pClientCb = gpphLibContext->ndef_cntx.pClientNdefFmtCb;
1594        pUpperLayerContext= gpphLibContext->ndef_cntx.pClientNdefFmtCntx;
1595        gpphLibContext->ndef_cntx.pClientNdefFmtCb = NULL;
1596        gpphLibContext->ndef_cntx.pClientNdefFmtCntx = NULL;
1597        if(NFCSTATUS_PENDING != RetStatus)
1598        {
1599            if (NULL != pClientCb)
1600            {
1601                /* Call the tag format upper layer callback */
1602                pClientCb(pUpperLayerContext,RetStatus);
1603            }
1604        }
1605    }
1606    return;
1607}
1608
1609#ifdef LIBNFC_READONLY_NDEF
1610STATIC
1611void
1612phLibNfc_Ndef_ReadOnly_Cb (
1613    void        *p_context,
1614    NFCSTATUS   status)
1615{
1616    NFCSTATUS                       ret_status = NFCSTATUS_SUCCESS;
1617    pphLibNfc_RspCb_t               p_client_cb = NULL;
1618    phLibNfc_LibContext_t           *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)p_context;
1619    void                            *p_upper_layer_ctxt = NULL;
1620
1621    if(pLibNfc_Ctxt != gpphLibContext)
1622    {
1623        /*wrong context returned*/
1624        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1625    }
1626    else
1627    {
1628        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
1629        {
1630            /*shutdown is pending so issue shutdown*/
1631            phLibNfc_Pending_Shutdown();
1632            ret_status = NFCSTATUS_SHUTDOWN;
1633        }
1634        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
1635        {
1636            ret_status = NFCSTATUS_ABORTED;
1637        }
1638        else
1639        {
1640            gpphLibContext->status.GenCb_pending_status = FALSE;
1641            if(NFCSTATUS_SUCCESS == status)
1642            {
1643                gpphLibContext->ndef_cntx.psNdefMap->CardState =
1644                                                PH_NDEFMAP_CARD_STATE_READ_ONLY;
1645                ret_status = NFCSTATUS_SUCCESS;
1646            }
1647            else
1648            {
1649                ret_status = NFCSTATUS_FAILED;
1650            }
1651            gpphLibContext->LibNfcState.cur_state =eLibNfcHalStateConnect;
1652        }
1653
1654        phLibNfc_UpdateCurState(status, gpphLibContext);
1655
1656        p_client_cb = gpphLibContext->ndef_cntx.pClientNdefFmtCb;
1657        p_upper_layer_ctxt = gpphLibContext->ndef_cntx.pClientNdefFmtCntx;
1658        gpphLibContext->ndef_cntx.pClientNdefFmtCb = NULL;
1659        gpphLibContext->ndef_cntx.pClientNdefFmtCntx = NULL;
1660        if(NFCSTATUS_PENDING != ret_status)
1661        {
1662            if (NULL != p_client_cb)
1663            {
1664                /* Call the tag format upper layer callback */
1665                p_client_cb (p_upper_layer_ctxt, ret_status);
1666            }
1667        }
1668    }
1669}
1670#endif /* #ifdef LIBNFC_READONLY_NDEF */
1671
1672STATIC
1673void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status)
1674{
1675    static NFCSTATUS RegPrSt=FALSE;
1676    uint8_t RegStatus=0;
1677    NFCSTATUS RetVal = NFCSTATUS_SUCCESS ;
1678    uint32_t Index=0;
1679
1680
1681	  PHNFC_UNUSED_VARIABLE(context);
1682    if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
1683    {   /*shutdown called before completion of Ndef read allow
1684              shutdown to happen */
1685        phLibNfc_Pending_Shutdown();
1686        RetVal = NFCSTATUS_SHUTDOWN;
1687    }
1688    else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
1689    {
1690        RetVal = NFCSTATUS_ABORTED;
1691    }
1692    else if(NFCSTATUS_SUCCESS != status)
1693    {
1694        RetVal = status;
1695    }
1696    else
1697    {
1698     /* This conditional branch is for QMORE fix */
1699    }
1700    gpphLibContext->status.GenCb_pending_status = FALSE;
1701
1702    phLibNfc_UpdateCurState(status,gpphLibContext);
1703    /* Read is not success send failed to upperlayer Call back*/
1704    if( RetVal!= NFCSTATUS_SUCCESS )
1705    {
1706        if((RetVal!=NFCSTATUS_SHUTDOWN)&& (RetVal!=NFCSTATUS_ABORTED))
1707        {
1708            RetVal= NFCSTATUS_FAILED;
1709        }
1710        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
1711                            gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
1712                            NULL,
1713                            gpphLibContext->Connected_handle,
1714                            RetVal);
1715        gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
1716        gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
1717        return;
1718    }
1719
1720    /*Get the Number of records ( If Raw record parameter is null then API gives number of Records*/
1721    RetVal = phFriNfc_NdefRecord_GetRecords(
1722                            gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
1723                            gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
1724                            NULL,
1725                            gpphLibContext->phLib_NdefRecCntx.IsChunked,
1726                            &(gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords));
1727
1728    NdefInfo.pNdefMessage = gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer;
1729    NdefInfo.NdefMessageLengthActual = gpphLibContext->ndef_cntx.NdefActualSize;
1730    NdefInfo.NdefMessageLengthMaximum = gpphLibContext->ndef_cntx.NdefLength;
1731    NdefInfo.NdefRecordCount =0;
1732
1733    /*Allocate memory to hold the records Read*/
1734    NdefInfo.pNdefRecord = phOsalNfc_GetMemory
1735        (sizeof(phFriNfc_NdefRecord_t)* gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords );
1736    if(NULL==NdefInfo.pNdefRecord)
1737    {
1738        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
1739                            gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
1740                            NULL,
1741                            gpphLibContext->Connected_handle,
1742                            NFCSTATUS_FAILED);
1743        gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
1744        gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
1745        return;
1746    }
1747
1748    pNdefRecord=NdefInfo.pNdefRecord;
1749    /*If phLibNfc_Ndef_SearchNdefContent Reg type is NULL return all the Records*/
1750    if(gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type==NULL)
1751    {
1752        RetVal = phFriNfc_NdefRecord_GetRecords(
1753                        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
1754                        gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
1755                        gpphLibContext->phLib_NdefRecCntx.RawRecords,
1756                        gpphLibContext->phLib_NdefRecCntx.IsChunked,
1757                        &(gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords));
1758
1759        for (Index = 0; Index < gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords; Index++)
1760        {
1761            RetVal = phFriNfc_NdefRecord_Parse(
1762                        pNdefRecord,
1763                        gpphLibContext->phLib_NdefRecCntx.RawRecords[Index]);
1764            pNdefRecord++;
1765            NdefInfo.NdefRecordCount++;
1766        }
1767    }
1768    else
1769    {
1770
1771        /* Look for registerd TNF */
1772        RetVal = phFriNfc_NdefReg_DispatchPacket(
1773                    &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
1774                    gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
1775                    (uint16_t)gpphLibContext->phLib_NdefRecCntx.ndef_message.length);
1776        if(NFCSTATUS_SUCCESS != RetVal)
1777        {
1778            /*phFriNfc_NdefReg_DispatchPacket is failed call upper layer*/
1779            gpphLibContext->CBInfo.pClientNdefNtfRespCb(gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
1780                                                    NULL,gpphLibContext->Connected_handle,NFCSTATUS_FAILED);
1781            gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
1782            gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
1783            return;
1784        }
1785
1786        while(1 != RegStatus)
1787        {
1788            /* Process the NDEF records, If match FOUND we will get Call back*/
1789            RegStatus = phFriNfc_NdefReg_Process(   &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
1790                                                &RegPrSt);
1791            if(RegPrSt == TRUE)
1792            {
1793                /*  Processing Done */
1794                break;
1795            }
1796            /*If match found the CbParam will be updated by lower layer, copy the record info*/
1797            for(Index=0;Index<gpphLibContext->phLib_NdefRecCntx.CbParam.Count;Index++)
1798            {
1799                pNdefRecord->Tnf  = gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Tnf;
1800                pNdefRecord->TypeLength  =
1801                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].TypeLength;
1802                pNdefRecord->PayloadLength  =
1803                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].PayloadLength;
1804                pNdefRecord->IdLength  =
1805                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].IdLength;
1806                pNdefRecord->Flags =
1807                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Flags;
1808
1809                pNdefRecord->Id = phOsalNfc_GetMemory(pNdefRecord->IdLength);
1810                pNdefRecord->Type = phOsalNfc_GetMemory(pNdefRecord->TypeLength);
1811                pNdefRecord->PayloadData = phOsalNfc_GetMemory(pNdefRecord->PayloadLength);
1812
1813                (void)memcpy(pNdefRecord->Id,
1814                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Id,
1815                    pNdefRecord->IdLength);
1816                (void)memcpy(pNdefRecord->PayloadData,
1817                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].PayloadData,
1818                    pNdefRecord->PayloadLength);
1819                (void)memcpy(pNdefRecord->Type,
1820                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Type,
1821                    pNdefRecord->TypeLength);
1822
1823                pNdefRecord++;
1824                NdefInfo.NdefRecordCount++;
1825            }
1826        }
1827    }
1828    /* If no record found call upper layer with failed status*/
1829    if(pNdefRecord == NdefInfo.pNdefRecord)
1830    {
1831        NdefInfo.NdefRecordCount =0;
1832        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
1833                    gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
1834                    &NdefInfo,gpphLibContext->Connected_handle,
1835                    NFCSTATUS_SUCCESS);
1836
1837    }
1838    else
1839    {
1840        /*Call upperlayer Call back with match records*/
1841
1842        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
1843                    gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
1844                    &NdefInfo,gpphLibContext->Connected_handle,
1845                    NFCSTATUS_SUCCESS);
1846        /*Remove entry from FRI*/
1847        RetVal = phFriNfc_NdefReg_RmCb(
1848                    &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
1849                    gpphLibContext->phLib_NdefRecCntx.NdefCb );
1850        /*Free the memory*/
1851        if(gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type!=NULL)
1852        {
1853            pNdefRecord=NdefInfo.pNdefRecord;
1854            for(Index=0;Index<gpphLibContext->phLib_NdefRecCntx.CbParam.Count;Index++)
1855            {
1856                phOsalNfc_FreeMemory(pNdefRecord->Id);
1857                phOsalNfc_FreeMemory(pNdefRecord->PayloadData);
1858                phOsalNfc_FreeMemory(pNdefRecord->Type);
1859                pNdefRecord++;
1860            }
1861        }
1862    }
1863
1864    gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
1865    gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
1866
1867}
1868
1869STATIC
1870void phLibNfc_Ndef_Rtd_Cb( void *CallBackParam)
1871{
1872    /*There will be single call back given to all match
1873      It's processed in phLibNfc_Ndef_SrchNdefCnt_Cb*/
1874    PHNFC_UNUSED_VARIABLE(CallBackParam);
1875}
1876
1877NFCSTATUS phLibNfc_Ndef_SearchNdefContent(
1878                                phLibNfc_Handle                 hRemoteDevice,
1879                                phLibNfc_Ndef_SrchType_t*       psSrchTypeList,
1880                                uint8_t                         uNoSrchRecords,
1881                                pphLibNfc_Ndef_Search_RspCb_t   pNdefNtfRspCb,
1882                                void *                          pContext
1883                                )
1884{
1885
1886     NFCSTATUS  RetVal =NFCSTATUS_SUCCESS;
1887     uint32_t Index=0;
1888     uint8_t     cr_index = 0;
1889
1890
1891      if((NULL == gpphLibContext) ||
1892        (gpphLibContext->LibNfcState.cur_state
1893                            == eLibNfcHalStateShutdown))
1894      {
1895         RetVal = NFCSTATUS_NOT_INITIALISED;
1896      }
1897     /* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/
1898      else if(gpphLibContext->LibNfcState.next_state
1899                            == eLibNfcHalStateShutdown)
1900     {
1901        RetVal= NFCSTATUS_SHUTDOWN;
1902     }
1903     else if( (NULL == pNdefNtfRspCb) ||
1904        (NULL == pContext ) ||
1905        (0 == hRemoteDevice))
1906     {
1907        RetVal= NFCSTATUS_INVALID_PARAMETER;
1908     }
1909     else if( (NULL != psSrchTypeList) && (0==uNoSrchRecords))
1910     {
1911        RetVal= NFCSTATUS_INVALID_PARAMETER;
1912     }
1913     else if(0 == gpphLibContext->Connected_handle)
1914     {   /*presently no target or tag is connected*/
1915        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
1916     }
1917     else if(hRemoteDevice != gpphLibContext->Connected_handle)
1918     {   /*This handle of the device sent by application is not connected */
1919        RetVal=NFCSTATUS_INVALID_HANDLE;
1920     }
1921     else if((TRUE == gpphLibContext->status.GenCb_pending_status)
1922        ||(NULL!=gpphLibContext->CBInfo.pClientNdefNtfRespCb))
1923     {
1924        /*Previous callback is pending*/
1925        RetVal = NFCSTATUS_REJECTED;
1926     }
1927     else
1928     {
1929        gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type = psSrchTypeList;
1930
1931        if(psSrchTypeList!=NULL)
1932        {
1933            /*Maximum records supported*/
1934            gpphLibContext->phLib_NdefRecCntx.NumberOfRecords = 255;
1935            /*Reset the FRI component to add the Reg type*/
1936            RetVal = phFriNfc_NdefReg_Reset(
1937                            &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
1938                            gpphLibContext->phLib_NdefRecCntx.NdefTypes_array,
1939                            &(gpphLibContext->phLib_NdefRecCntx.RecordsExtracted),
1940                            &(gpphLibContext->phLib_NdefRecCntx.CbParam),
1941                            gpphLibContext->phLib_NdefRecCntx.ChunkedRecordsarray,
1942                            gpphLibContext->phLib_NdefRecCntx.NumberOfRecords);
1943
1944            gpphLibContext->phLib_NdefRecCntx.NdefCb = phOsalNfc_GetMemory(sizeof(phFriNfc_NdefReg_Cb_t));
1945            if(gpphLibContext->phLib_NdefRecCntx.NdefCb==NULL)
1946            {
1947                /*exception: Not enough memory*/
1948                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
1949            }
1950            gpphLibContext->phLib_NdefRecCntx.NdefCb->NdefCallback = phLibNfc_Ndef_Rtd_Cb;
1951            /*Copy the TNF types to search in global structure*/
1952            gpphLibContext->phLib_NdefRecCntx.NdefCb->NumberOfRTDs = uNoSrchRecords;
1953            for(Index=0;Index<uNoSrchRecords;Index++)
1954            {
1955                gpphLibContext->phLib_NdefRecCntx.NdefCb->NdefType[Index] = psSrchTypeList->Type;
1956                gpphLibContext->phLib_NdefRecCntx.NdefCb->Tnf[Index] = psSrchTypeList->Tnf ;
1957                gpphLibContext->phLib_NdefRecCntx.NdefCb->NdeftypeLength[Index] = psSrchTypeList->TypeLength;
1958                psSrchTypeList++;
1959            }
1960            /* Add the TNF type to FRI component*/
1961
1962            RetVal = phFriNfc_NdefReg_AddCb(&(gpphLibContext->phLib_NdefRecCntx.NdefReg),
1963                                                gpphLibContext->phLib_NdefRecCntx.NdefCb );
1964
1965        }
1966        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer =
1967            phOsalNfc_GetMemory(gpphLibContext->ndef_cntx.NdefActualSize);
1968        gpphLibContext->phLib_NdefRecCntx.ndef_message.length =
1969            gpphLibContext->ndef_cntx.NdefActualSize;
1970        /*Set Complete routine for NDEF Read*/
1971        for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
1972        {
1973            RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
1974                                gpphLibContext->ndef_cntx.psNdefMap,
1975                                cr_index,
1976                                phLibNfc_Ndef_SrchNdefCnt_Cb,
1977                                (void *)gpphLibContext);
1978
1979        }
1980        gpphLibContext->ndef_cntx.NdefContinueRead = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
1981        /* call below layer Ndef Read*/
1982        RetVal = phFriNfc_NdefMap_RdNdef(gpphLibContext->ndef_cntx.psNdefMap,
1983                        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
1984                        (uint32_t*)&gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
1985                        PH_FRINFC_NDEFMAP_SEEK_BEGIN);
1986
1987        if(NFCSTATUS_PENDING == RetVal)
1988        {
1989            gpphLibContext->CBInfo.pClientNdefNtfRespCb = pNdefNtfRspCb;
1990            gpphLibContext->CBInfo.pClientNdefNtfRespCntx = pContext;
1991            gpphLibContext->status.GenCb_pending_status=TRUE;
1992            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
1993        }
1994        else if (NFCSTATUS_SUCCESS == RetVal)
1995        {
1996            RetVal= NFCSTATUS_SUCCESS;
1997        }
1998        else
1999        {
2000            /*Ndef read failed*/
2001            RetVal = NFCSTATUS_FAILED;
2002        }
2003    }
2004    return RetVal;
2005
2006}
2007
2008