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  phFriNfc_NdefReg.c
19  * \Contains Registry and module functions.
20  *
21  * Project: NDEFT
22  *
23  * $Date: Mon May 25 13:59:32 2009 $
24  * $Author: ing08150 $
25  * $Revision: 1.4 $
26  * $Aliases: NFC_FRI1.1_WK920_R25_1,NFC_FRI1.1_WK922_PREP1,NFC_FRI1.1_WK922_R26_1,NFC_FRI1.1_WK924_PREP1,NFC_FRI1.1_WK924_R27_1,NFC_FRI1.1_WK926_R28_1,NFC_FRI1.1_WK928_R29_1,NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
27  *
28  */
29 
30 
31 #include "phNfcTypes.h"
32 #include "phNfcStatus.h"
33 #include "phNfcCompId.h"
34 #include "phNfcHalTypes.h"
35 #include "phFriNfc.h"
36 #include "phFriNfc_NdefReg.h"
37 #include "phFriNfc_NdefRecord.h"
38 
39 /* Harsha: To Fix: 0000358: phFriNfc_NdefRecord.h: includes should be moved */
40 #include <string.h>
41 static int16_t phFriNfc_NdefReg_Strncmp (const int8_t *s1, const int8_t *s2, uint32_t count);
42 
43 /*********  String functions *********/
44 
phFriNfc_NdefReg_Strncmp(const int8_t * s1,const int8_t * s2,uint32_t count)45 static int16_t phFriNfc_NdefReg_Strncmp (const int8_t *s1, const int8_t *s2, uint32_t count)
46 {
47     return (int16_t)strncmp((const char*)s1,(const char*)s2, count);
48 }
phFriNfc_NdefReg_Strnicmp(const int8_t * s1,const int8_t * s2,uint32_t count)49 int16_t  phFriNfc_NdefReg_Strnicmp(const int8_t *s1, const int8_t *s2, uint32_t count)
50 {
51     int8_t c1, c2;
52     int16_t returnvalue;
53     do
54     {
55         c1 = *s1;
56         s1++;
57         if (c1 >=97)
58             c1 = (c1 - 32);
59         c2 = *s2;
60         s2++;
61         if (c2 >=97)
62             c2 = (c2 - 32);
63         --count;
64     }
65     while ( (c1 == c2) && (c1 != '\0') && (c2 != '\0') && (count > 0) );
66 
67     if ( (count == 0) || (c1 == c2) )
68         returnvalue = 0;
69 
70     else if ( (c1 > c2) )
71         returnvalue = 1;
72     else
73         returnvalue = -1;
74 
75     return(returnvalue);
76 }
77 
78 /*********  REGISTRY AND LISTENER MODULE *********/
79 
phFriNfc_NdefReg_Reset(phFriNfc_NdefReg_t * NdefReg,uint8_t ** NdefTypesarray,phFriNfc_NdefRecord_t * RecordsExtracted,phFriNfc_NdefReg_CbParam_t * CbParam,uint8_t * ChunkedRecordsarray,uint32_t NumberOfRecords)80 NFCSTATUS phFriNfc_NdefReg_Reset(phFriNfc_NdefReg_t         *NdefReg,
81                                  uint8_t                    **NdefTypesarray,
82                                  phFriNfc_NdefRecord_t      *RecordsExtracted,
83                                  phFriNfc_NdefReg_CbParam_t *CbParam,
84                                  uint8_t                    *ChunkedRecordsarray,
85                                  uint32_t                   NumberOfRecords)
86 {
87     NFCSTATUS status = NFCSTATUS_SUCCESS;
88 
89     /* Reset/Initialise the values of the Context structure */
90     /* Store the required pointers in the context structure */
91     if(NdefReg == NULL || NdefTypesarray == NULL || RecordsExtracted == NULL || CbParam == NULL)
92     {
93         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_PARAMETER);
94     }
95     else
96     {
97         NdefReg->State=PH_FRINFC_NDEFREG_STATE_INIT;
98         NdefReg->NdefData=NULL;
99         NdefReg->NdefDataLength=0;
100         NdefReg->NdefTypeList=NULL;
101         NdefReg->NdefTypes = NdefTypesarray ;
102         NdefReg->RecordsExtracted = RecordsExtracted;
103         NdefReg->CbParam = CbParam;
104         NdefReg->validPreviousTnf = 0xff;
105         NdefReg->IsChunked = ChunkedRecordsarray;
106         NdefReg->NumberOfRecords = NumberOfRecords;
107         NdefReg->newRecordextracted = 0;
108         NdefReg->MainTnfFound = 0;
109     }
110     return(status);
111 }
112 
113 /* Adds a NDEF type listener to the internal list of listeners*/
114 /*Libraray does no allocation of the memory*/
phFriNfc_NdefReg_AddCb(phFriNfc_NdefReg_t * NdefReg,phFriNfc_NdefReg_Cb_t * NdefCb)115 NFCSTATUS phFriNfc_NdefReg_AddCb(phFriNfc_NdefReg_t     *NdefReg,
116                                  phFriNfc_NdefReg_Cb_t  *NdefCb)
117 {
118     NFCSTATUS status = NFCSTATUS_SUCCESS;
119 
120     if(  NdefReg == NULL || NdefCb ==NULL)
121     {
122         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_PARAMETER);
123     }
124     else
125     {
126         /*  Check whether we can accomodate all these records in a single node */
127         if(NdefCb->NumberOfRTDs <= PH_FRINFC_NDEFREG_MAX_RTD_REGISTERED)
128         {
129             /*  Yes, all these Records can be accomodated in a single node */
130             /* No existing node. This will be the first Node    */
131             if(NdefReg->NdefTypeList==NULL)
132             {
133                 NdefCb->Previous =NULL;
134                 NdefCb->Next =NULL;
135                 NdefReg->NdefTypeList = NdefCb;
136             }
137             else
138             {
139                 /*  Some nodes are existing. Add the new CB node at the front
140                     of the List and update pointers */
141                 NdefCb->Next = NdefReg->NdefTypeList;
142                 NdefCb->Previous = NULL;
143                 NdefReg->NdefTypeList->Previous = NdefCb;
144                 NdefReg->NdefTypeList = NdefReg->NdefTypeList->Previous;
145             }
146         }
147         else
148         {
149             /*  We cannot accomodate more records than PH_FRINFC_NDEFREG_MAX_RTD_REGISTERED
150                 in this node.
151                 So return warning NFCSTATUS_INVALID_PARAMETER. */
152             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY,
153                                 NFCSTATUS_INVALID_PARAMETER);
154         }
155     }
156 
157     return(status);
158 }
159 
160 /*Removes a specific listener from the list. The element to remove is specified by its address.*/
161 /*Libraray does no deallocation of the memory*/
phFriNfc_NdefReg_RmCb(phFriNfc_NdefReg_t * NdefReg,phFriNfc_NdefReg_Cb_t * NdefCb)162 NFCSTATUS phFriNfc_NdefReg_RmCb(phFriNfc_NdefReg_t    *NdefReg,
163                                 phFriNfc_NdefReg_Cb_t *NdefCb)
164 {
165     NFCSTATUS               status = NFCSTATUS_SUCCESS;
166     phFriNfc_NdefReg_Cb_t   *tempNode;
167     uint8_t                 found=0;/* to check for the node present or not */
168 
169     if(  NdefReg==NULL || NdefCb ==NULL)
170     {
171         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_PARAMETER);
172     }
173     else
174     {
175         tempNode = NdefReg->NdefTypeList;
176         /* if the list is empty */
177         if(NdefReg->NdefTypeList == NULL)
178         {
179             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_NOT_REGISTERED);
180         }
181         else
182         {
183             while(tempNode!=NULL)
184             {
185                 if(NdefCb == tempNode)
186                 {
187                     found=1;/* if the node is present */
188 
189                     /* node is present in the front of the list so
190                     update the NdefReg->NdefTypeList pointer */
191                     if(tempNode->Previous==NULL && tempNode->Next!=NULL)
192                     {
193                         NdefReg->NdefTypeList =NdefReg->NdefTypeList->Next;
194                         NdefReg->NdefTypeList->Previous = NULL;
195                         break;
196                     }
197                     /* only one node in the list so update the head node */
198                     if(tempNode->Next==NULL && tempNode->Previous==NULL)
199                     {
200                           NdefReg->NdefTypeList=NULL;
201                           break;
202                     }
203                     if (tempNode->Previous != NULL)
204                     {
205                         tempNode->Previous->Next = tempNode->Next;
206                     }
207                     if (tempNode->Next != NULL)
208                     {
209                         tempNode->Next->Previous = tempNode->Previous;
210                     }
211                     break;
212                 }
213                 /* move to the next node */
214                 tempNode = tempNode->Next;
215             }
216         }
217         if(!found )
218         {
219             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_NOT_REGISTERED);
220         }
221     }
222     return(status);
223 }
224 
225 /* Copy the relevant pointers to the context structure, change the
226 FSM state, so as to trigger the process and return pending. This function is non-blocking,
227 it returns once the operation is initiated or an error occurs */
228 
phFriNfc_NdefReg_DispatchPacket(phFriNfc_NdefReg_t * NdefReg,uint8_t * PacketData,uint16_t PacketDataLength)229 NFCSTATUS phFriNfc_NdefReg_DispatchPacket(phFriNfc_NdefReg_t   *NdefReg,
230                                           uint8_t              *PacketData,
231                                           uint16_t              PacketDataLength)
232 {
233     NFCSTATUS status = NFCSTATUS_SUCCESS;
234 
235     if(NdefReg==NULL ||PacketData==NULL || PacketDataLength==0)
236     {
237         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_PARAMETER);
238     }
239     else
240     {
241         NdefReg->NdefData = PacketData;
242         NdefReg->NdefDataLength = PacketDataLength;
243         NdefReg->State = PH_FRINFC_NDEFREG_STATE_DIS_PKT;
244         NdefReg->NumberOfNdefTypes = 0;
245         NdefReg->RecordIndex = 0;
246         NdefReg->RtdIndex = 0;
247         status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
248     }
249     return(status);
250 }
251 
252 /* Copy the relevant pointers to the context structure, change the
253 FSM state, so as to trigger the process and return pending */
phFriNfc_NdefReg_DispatchRecord(phFriNfc_NdefReg_t * NdefReg,phFriNfc_NdefRecord_t * RecordsExtracted)254 NFCSTATUS phFriNfc_NdefReg_DispatchRecord(phFriNfc_NdefReg_t     *NdefReg,
255                                           phFriNfc_NdefRecord_t  *RecordsExtracted)
256 {
257     NFCSTATUS status = NFCSTATUS_SUCCESS;
258     if(NdefReg==NULL || RecordsExtracted==NULL)
259     {
260         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_PARAMETER);
261     }
262     else
263     {
264         NdefReg->RecordsExtracted = RecordsExtracted;
265         NdefReg->State = PH_FRINFC_NDEFREG_STATE_DIS_RCD;
266 
267         status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
268     }
269     return(status);
270 }
271 
phFriNfc_NdefReg_Process(phFriNfc_NdefReg_t * NdefReg,NFCSTATUS * Status)272 uint8_t phFriNfc_NdefReg_Process(phFriNfc_NdefReg_t  *NdefReg,
273                                  NFCSTATUS           *Status)
274 {
275     uint8_t     count = 0,
276                 ret_val=0,
277                 TnfMatchFound = 0,
278                 index = 0,
279                 matchFound = 0;
280 
281 
282 
283     if(NdefReg->NdefTypeList == NULL)
284     {
285         /*  No Nodes added. Return error  */
286         *Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_NOT_REGISTERED);
287         return(1);
288     }
289 
290     *Status = NFCSTATUS_SUCCESS;
291     switch(NdefReg->State)
292     {
293         case PH_FRINFC_NDEFREG_STATE_DIS_RCD:
294 
295         /* for START ( each node in the list NdefReg->NdefTypeList), do the following */
296         for(index=0;index<NdefReg->NdefTypeList->NumberOfRTDs;index++)
297         {
298             /* First, Match should be done with The TNF*/
299             if( (NdefReg->NdefTypeList->Tnf[index] & PH_FRINFC_NDEFRECORD_TNF_MASK ) ==
300                 (NdefReg->RecordsExtracted->Tnf & PH_FRINFC_NDEFRECORD_TNF_MASK ) )
301             {
302                 /* Second, Match should be done with The Typelength*/
303                 if( NdefReg->NdefTypeList->NdeftypeLength[index] == \
304                     NdefReg->RecordsExtracted->TypeLength )
305                 {
306                     /* Third, Match should be done with The Type*/
307                     matchFound = 0;
308                     switch(NdefReg->NdefTypeList->Tnf[index])
309                     {
310                         case 1:
311                             /*  TNF = 0X01 NFC Forum well-known type : Case sensitive  */
312                             /*  comparison is to be made. */
313                             if( !phFriNfc_NdefReg_Strncmp( (const int8_t *)NdefReg->NdefTypeList->NdefType[index] ,
314                                 (const int8_t *)(NdefReg->RecordsExtracted->Type),
315                                 NdefReg->RecordsExtracted->TypeLength))
316                             {
317                                 matchFound = 1;
318                             }
319                         break;
320 
321                         case 2:
322                         case 4:
323                             /*  For TNF = 0X02 Media-type as defined in RFC 2046
324                                 From iana.org, it has never been found any registered media type
325                                 with non-ascii character ==> Comparison to be used for *types* in
326                                 *registry*: case INSENSITIVE comparison.
327 
328                                 For TNF = 0X04 NFC Forum external type : ==> Comparison to be used
329                                 for *types* in *registry* : case INSENSITIVE comparison */
330                             if( !phFriNfc_NdefReg_Strnicmp( (int8_t *)NdefReg->NdefTypeList->NdefType[index] ,
331                                 (int8_t *)(NdefReg->RecordsExtracted->Type),
332                                 NdefReg->RecordsExtracted->TypeLength))
333                             {
334                                 matchFound = 1;
335                             }
336                         break;
337 
338                         case 3:
339                             /*  TNF = 0X03 Absolute URI as defined in RFC 3986 [RFC 3986]
340                                 Big issue concerning the Encoding, which is actually determined
341                                 by the application.Conclusion is that: Comparison to be used for
342                                 *types* in *registry*: NONE. only TNF ; type should be ignored,
343                                 and its comparison shall be done by the application. */
344                             matchFound = 1;
345                         break;
346                         default:
347                             break;
348                     }
349                     if(matchFound)
350                     {
351                         /*  Copy the chunked flag info to the callback parameter */
352                         NdefReg->CbParam->Chunked[count] = (NdefReg->RecordsExtracted->Flags & \
353                                                             PH_FRINFC_NDEFRECORD_FLAGS_CF );
354 
355                         /*  NOTE: Raw record and the raw record size cannot be
356                             copied as this itself is an extracted record ! */
357 
358                         /*  Copy the record in the format phFriNfc_NdefRecord_t
359                             to the callback parameter */
360                             (void) memcpy( &NdefReg->CbParam->Records[count],
361                                                     NdefReg->RecordsExtracted,
362                                                     sizeof(phFriNfc_NdefRecord_t));
363                             count++;
364                     }
365                 }
366             }
367         }
368 
369         /*  now, we have all the matching entries for the RTDs present
370             in this particular node NdefReg->NdefTypeList.
371             call the callback */
372         if(count>0)
373         {
374             NdefReg->CbParam->Count = count;
375             NdefReg->CbParam->CbContext = NdefReg->NdefTypeList->CbContext;
376             NdefReg->NdefTypeList->NdefCallback (NdefReg->CbParam);
377         }
378         else
379         {
380             NdefReg->CbParam->Count = 0;
381         }
382 
383         /* for END ( each node in the list NdefReg->NdefTypeList), do the following */
384         if(NdefReg->NdefTypeList->Next==NULL)
385         {
386             NdefReg->State = PH_FRINFC_NDEFREG_STATE_INIT;
387             while(NdefReg->NdefTypeList->Previous!=NULL)
388             {
389                 NdefReg->NdefTypeList = NdefReg->NdefTypeList->Previous;
390             }
391             /* No further node present in the list. End of process function call */
392             ret_val=1;
393         }
394         else
395         {
396             /* Move the linked list by one node.*/
397             NdefReg->NdefTypeList = NdefReg->NdefTypeList->Next;
398             /* list is not empty so come again */
399             ret_val=0;
400         }
401         break;
402 
403         case PH_FRINFC_NDEFREG_STATE_DIS_PKT:
404 
405         if(NdefReg->NumberOfNdefTypes == 0)
406         {
407             /*  First, Get all the records present in the data packet NdefReg->NdefData
408                 using NDEF tool library */
409             /*  and, get the NumberOfNdefTypes from NdefData */
410             *Status = phFriNfc_NdefRecord_GetRecords(   NdefReg->NdefData,
411                                                         NdefReg->NdefDataLength,
412                                                         NULL,
413                                                         NdefReg->IsChunked,
414                                                         &NdefReg->NumberOfNdefTypes);
415             if((*Status)!= NFCSTATUS_SUCCESS)
416             {
417                 /* Error in the Packet. Exit from the process */
418                 ret_val = 1;
419                 NdefReg->NumberOfNdefTypes = 0;
420                 break;
421             }
422 
423             if(NdefReg->NumberOfNdefTypes > NdefReg->NumberOfRecords)
424             {
425                 /*  There is not enough space in the arrays NdefReg->NdefTypes
426                     and NdefReg->IsChunked, to write NdefReg->NumberOfRecords
427                     number of records. Return error. */
428                 *Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_BUFFER_TOO_SMALL);
429                 ret_val = 1;
430                 NdefReg->NumberOfNdefTypes = 0;
431                 break;
432             }
433 
434             /* Now, get the NdefTypes */
435             *Status = phFriNfc_NdefRecord_GetRecords(   NdefReg->NdefData,
436                                                         NdefReg->NdefDataLength,
437                                                         NdefReg->NdefTypes,
438                                                         NdefReg->IsChunked,
439                                                         &NdefReg->NumberOfNdefTypes);
440             if((*Status)!= NFCSTATUS_SUCCESS)
441             {
442                 /* Error in the Packet. Exit from the process */
443                 ret_val = 1;
444                 NdefReg->NumberOfNdefTypes = 0;
445                 break;
446             }
447         }
448 
449         /*  For each record, in the arry NdefReg->NdefTypes, check
450             whether it matches with any of the registered RTD in the
451             present node. If it matches, copy this to the Callback
452             parameter array and increment count.
453             If count is 8, call the callback function.
454             Remember the record index that we last processed, before
455             calling the callback.   */
456 
457         /*  for each record in the Message  */
458         while(NdefReg->RecordIndex < NdefReg->NumberOfNdefTypes)
459         {
460             /*  Extract a record from the Message */
461             *Status = phFriNfc_NdefRecord_Parse(NdefReg->RecordsExtracted,
462                                                 NdefReg->NdefTypes[NdefReg->RecordIndex]);
463             if((*Status)!= NFCSTATUS_SUCCESS)
464             {
465                 /* Error in the Record. Exit from the process */
466                 NdefReg->NumberOfNdefTypes = 0;
467                 return 1;
468             }
469 
470             NdefReg->newRecordextracted = 1;
471 
472             /*  for each RTD in the present node */
473             while(NdefReg->RtdIndex < NdefReg->NdefTypeList->NumberOfRTDs)
474             {
475                 /*  Harsha: Fix for 0000243: [JF] phFriNfc_NdefReg_Process
476                     won't parse correctly chunked records   */
477 
478                 /*  Check whether the TNF = 0x06
479                     PH_FRINFC_NDEFRECORD_TNF_UNCHANGED */
480 
481                 if((NdefReg->RecordsExtracted->Tnf & PH_FRINFC_NDEFRECORD_TNF_MASK ) ==
482                     PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
483                 {
484                     if(NdefReg->MainTnfFound == 1)
485                     {
486                         /*  Matching RTD is there  */
487                         TnfMatchFound = 1;
488                     }
489                 }
490                 else
491                 {
492                     if(NdefReg->newRecordextracted)
493                     {
494                         NdefReg->MainTnfFound  = 0;
495                     }
496                     /*  This is a tnf other than 0x06.
497                         that means, this is a valid tnf */
498                     NdefReg->validPreviousTnf = NdefReg->RecordsExtracted->Tnf;
499 
500                     /* First, Match should be done with The TNF*/
501                     /* Second, Match should be done with The Typelength*/
502                         /* Third, Match should be done with The Type*/
503                     if((NdefReg->NdefTypeList->Tnf[NdefReg->RtdIndex] &
504                         PH_FRINFC_NDEFRECORD_TNF_MASK ) ==
505                         (NdefReg->RecordsExtracted->Tnf & PH_FRINFC_NDEFRECORD_TNF_MASK ) &&
506                         (NdefReg->NdefTypeList->NdeftypeLength[NdefReg->RtdIndex] ==
507                         NdefReg->RecordsExtracted->TypeLength))
508                     {
509                         matchFound = 0;
510                         switch(NdefReg->NdefTypeList->Tnf[NdefReg->RtdIndex])
511                         {
512                             case 1:
513                                 /*  TNF = 0X01 NFC Forum well-known type : Case sensitive
514                                     comparison is to be made. */
515                                 if(!phFriNfc_NdefReg_Strncmp((const int8_t *)NdefReg->NdefTypeList->NdefType[NdefReg->RtdIndex],
516                                             (const int8_t *)(NdefReg->RecordsExtracted->Type),
517                                             NdefReg->RecordsExtracted->TypeLength))
518                                 {
519                                     matchFound = 1;
520                                 }
521                             break;
522 
523                             case 2:
524                             case 4:
525                                 /*  For TNF = 0X02 Media-type as defined in RFC 2046
526                                     From iana.org, it has never been found any registered media type
527                                     with non-ascii character ==> Comparison to be used for *types* in
528                                     *registry*: case INSENSITIVE comparison. */
529 
530                                 /*  For TNF = 0X04 NFC Forum external type : ==> Comparison to be used
531                                     for *types* in *registry* : case INSENSITIVE comparison */
532                                 if( !phFriNfc_NdefReg_Strnicmp(  (int8_t *)NdefReg->NdefTypeList->NdefType[NdefReg->RtdIndex],
533                                                 (int8_t *)(NdefReg->RecordsExtracted->Type),
534                                                 NdefReg->RecordsExtracted->TypeLength))
535                                 {
536                                     matchFound = 1;
537                                 }
538                             break;
539 
540                             case 3:
541                                 /*  TNF = 0X03 Absolute URI as defined in RFC 3986 [RFC 3986]
542                                     Big issue concerning the Encoding, which is actually determined
543                                     by the application.Conclusion is that: Comparison to be used for
544                                     *types* in *registry*: NONE. only TNF ; type should be ignored,
545                                     and its comparison shall be done by the application. */
546                                 matchFound = 1;
547                             break;
548                             default:
549                             break;
550                         }
551                         if(matchFound == 1)
552                         {
553                             TnfMatchFound = 1;
554                             NdefReg->MainTnfFound  = 1;
555                         }
556                         else
557                         {
558                             TnfMatchFound = 0;
559                         }
560                     }
561                     else
562                     {
563                         TnfMatchFound = 0;
564                     }
565                 }
566 
567                 /*  we have found a matching TNF  */
568                 if(TnfMatchFound == 1)
569                 {
570                     /*  Copy the chunked flag info to the callback parameter */
571                     NdefReg->CbParam->Chunked[count] = NdefReg->IsChunked[NdefReg->RecordIndex];
572 
573                     /*  Copy the raw record to the callback parameter */
574                     NdefReg->CbParam->RawRecord[count] = NdefReg->NdefTypes[NdefReg->RecordIndex];
575 
576                     /*  Copy the raw record size to the callback parameter */
577                     NdefReg->CbParam->RawRecordSize[count] = phFriNfc_NdefRecord_GetLength(NdefReg->RecordsExtracted);
578 
579                     /*  Copy the record in the format phFriNfc_NdefRecord_t
580                         to the callback parameter */
581                     (void)  memcpy( &NdefReg->CbParam->Records[count],
582                                             NdefReg->RecordsExtracted,
583                                             sizeof(phFriNfc_NdefRecord_t));
584 
585 
586                     /*if count is greater than PH_FRINFC_NDEFREG_MAX_RTD (presently 8)
587                     then call the callback since there can be more than
588                     PH_FRINFC_NDEFREG_MAX_RTD of a single type with in the packet,as a result
589                     call the callback and initialize count to zero.This may also happen
590                     when there are chunked records */
591 
592                     count++;
593                     if(count >= PH_FRINFC_NDEFREG_MAX_RTD )
594                     {
595                         NdefReg->CbParam->Count = count;
596                         NdefReg->CbParam->CbContext = NdefReg->NdefTypeList->CbContext;
597                         NdefReg->NdefTypeList->NdefCallback (NdefReg->CbParam);
598                         count=0;
599                         /*  Only one callback per node. */
600                         NdefReg->RecordIndex++;
601                         return(0);
602                     }
603                 }
604 
605                 /*  If the match is already found for the UNCHANGED_TNF,
606                     don't comapre it again */
607                 if((NdefReg->RecordsExtracted->Tnf & PH_FRINFC_NDEFRECORD_TNF_MASK )
608                     == PH_FRINFC_NDEFRECORD_TNF_UNCHANGED &&
609                     TnfMatchFound == 1)
610                 {
611                     TnfMatchFound = 0;
612                     break;
613                 }
614 
615                 NdefReg->RtdIndex++;
616 
617                 NdefReg->newRecordextracted = 0;
618             }   /*  for each RTD in the present node
619                     while(NdefReg->RtdIndex < NdefReg->NdefTypeList->NumberOfRTDs) */
620 
621             /*   One Record processing done for this node */
622 
623             NdefReg->RtdIndex = 0;
624             NdefReg->RecordIndex++;
625         }   /*  while(NdefReg->RecordIndex<NdefReg->NumberOfNdefTypes)  */
626 
627         /*  One node has been checked. Move to the next node  */
628 
629         if(count>0)
630         {
631             NdefReg->CbParam->Count = count;
632             NdefReg->CbParam->CbContext = NdefReg->NdefTypeList->CbContext;
633             NdefReg->NdefTypeList->NdefCallback (NdefReg->CbParam);
634         }
635         else
636         {
637             NdefReg->CbParam->Count = 0;
638         }
639 
640         if(NdefReg->NdefTypeList->Next==NULL)
641         {
642             /*  All the nodes have been checked. Return */
643             NdefReg->State = PH_FRINFC_NDEFREG_STATE_INIT;
644             while(NdefReg->NdefTypeList->Previous!=NULL)
645             {
646                 NdefReg->NdefTypeList = NdefReg->NdefTypeList->Previous;
647             }
648             /*  No further node present in the list.
649                 End of Dispatch packet function. Return TRUE*/
650             ret_val = 1;
651         }
652         else
653         {
654             /* Move the linked list by one node.*/
655             NdefReg->NdefTypeList = NdefReg->NdefTypeList->Next;
656             /* list is not empty so come again */
657             ret_val = 0;
658         }
659 
660         /*  Start from the first record again. */
661         NdefReg->RecordIndex = 0;
662         NdefReg->RtdIndex = 0;
663 
664         break;
665 
666         default:
667             /* return error */
668             *Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_REGISTRY, NFCSTATUS_INVALID_DEVICE_REQUEST);
669             /* Unknown state Error exit from the process function */
670             ret_val= 1;
671         break;
672 
673     }
674 
675     return(ret_val);
676 
677 }
678 
679 
680