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