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 * =========================================================================== *
19 *                                                                             *
20 *                                                                             *
21 * \file  phHciNfc_Jewel.c                                                 *
22 * \brief HCI Jewel/Topaz Management Routines.                                    *
23 *                                                                             *
24 *                                                                             *
25 * Project: NFC-FRI-1.1                                                        *
26 *                                                                             *
27 * $Date: Mon Mar 29 17:34:47 2010 $                                           *
28 * $Author: ing04880 $                                                         *
29 * $Revision: 1.8 $                                                           *
30 * $Aliases: 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 $
31 *                                                                             *
32 * =========================================================================== *
33 */
34 
35 /*
36 ***************************** Header File Inclusion ****************************
37 */
38 #include <phNfcCompId.h>
39 #include <phHciNfc_Pipe.h>
40 #include <phHciNfc_RFReader.h>
41 #include <phOsalNfc.h>
42 
43 #if defined(TYPE_JEWEL)
44 #include <phHciNfc_Jewel.h>
45 
46 /*
47 ****************************** Macro Definitions *******************************
48 */
49 #define JEWEL_SINGLE_TAG_FOUND              0x00U
50 #define JEWEL_MULTIPLE_TAGS_FOUND           0x03U
51 #define NXP_WRA_CONTINUE_ACTIVATION         0x12U
52 
53 #define NXP_JEWEL_READID                    0x78U
54 #define NXP_JEWEL_READID_LENGTH             0x06U
55 
56 /*
57 *************************** Structure and Enumeration ***************************
58 */
59 
60 /*
61 *************************** Static Function Declaration **************************
62 */
63 
64 static
65 NFCSTATUS
66 phHciNfc_Recv_Jewel_Response(
67                                void                *psContext,
68                                void                *pHwRef,
69                                uint8_t             *pResponse,
70 #ifdef ONE_BYTE_LEN
71                                uint8_t             length
72 #else
73                                uint16_t            length
74 #endif
75                                );
76 
77 static
78 NFCSTATUS
79 phHciNfc_Recv_Jewel_Event(
80                             void               *psContext,
81                             void               *pHwRef,
82                             uint8_t            *pEvent,
83 #ifdef ONE_BYTE_LEN
84                              uint8_t             length
85 #else
86                              uint16_t            length
87 #endif
88                             );
89 
90 static
91 NFCSTATUS
92 phHciNfc_Jewel_InfoUpdate(
93                             phHciNfc_sContext_t     *psHciContext,
94                             uint8_t                 index,
95                             uint8_t                 *reg_value,
96                             uint8_t                 reg_length
97                             );
98 
99 static
100 NFCSTATUS
101 phHciNfc_Recv_Jewel_Packet(
102                             phHciNfc_sContext_t  *psHciContext,
103                             uint8_t              *pResponse,
104 #ifdef ONE_BYTE_LEN
105                             uint8_t             length
106 #else
107                             uint16_t            length
108 #endif
109                             );
110 
111 
112 NFCSTATUS
phHciNfc_Jewel_Get_PipeID(phHciNfc_sContext_t * psHciContext,uint8_t * ppipe_id)113 phHciNfc_Jewel_Get_PipeID(
114                            phHciNfc_sContext_t     *psHciContext,
115                            uint8_t                 *ppipe_id
116                            )
117 {
118     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
119 
120     if( (NULL != psHciContext)
121         && ( NULL != ppipe_id )
122         && ( NULL != psHciContext->p_jewel_info )
123         )
124     {
125         phHciNfc_Jewel_Info_t     *ps_jewel_info = NULL;
126         ps_jewel_info = (phHciNfc_Jewel_Info_t *)psHciContext->p_jewel_info;
127         *ppipe_id =  ps_jewel_info->pipe_id;
128     }
129     else
130     {
131         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
132     }
133     return status;
134 }
135 
136 NFCSTATUS
phHciNfc_Jewel_Init_Resources(phHciNfc_sContext_t * psHciContext)137 phHciNfc_Jewel_Init_Resources(
138                                phHciNfc_sContext_t     *psHciContext
139                                )
140 {
141     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
142     phHciNfc_Jewel_Info_t      *ps_jewel_info = NULL;
143     if( NULL == psHciContext )
144     {
145         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
146     }
147     else
148     {
149         if(
150             ( NULL == psHciContext->p_jewel_info ) &&
151             (phHciNfc_Allocate_Resource((void **)(&ps_jewel_info),
152             sizeof(phHciNfc_Jewel_Info_t))== NFCSTATUS_SUCCESS)
153             )
154         {
155             psHciContext->p_jewel_info = ps_jewel_info;
156             ps_jewel_info->current_seq = JEWEL_INVALID_SEQ;
157             ps_jewel_info->next_seq = JEWEL_INVALID_SEQ;
158             ps_jewel_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
159         }
160         else
161         {
162             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
163         }
164 
165     }
166     return status;
167 }
168 
169 NFCSTATUS
phHciNfc_Jewel_Update_PipeInfo(phHciNfc_sContext_t * psHciContext,uint8_t pipeID,phHciNfc_Pipe_Info_t * pPipeInfo)170 phHciNfc_Jewel_Update_PipeInfo(
171                                 phHciNfc_sContext_t     *psHciContext,
172                                 uint8_t                 pipeID,
173                                 phHciNfc_Pipe_Info_t    *pPipeInfo
174                                 )
175 {
176     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
177 
178     if( NULL == psHciContext )
179     {
180         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
181     }
182     else if(NULL == psHciContext->p_jewel_info)
183     {
184         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
185     }
186     else
187     {
188         phHciNfc_Jewel_Info_t      *ps_jewel_info=NULL;
189         ps_jewel_info = (phHciNfc_Jewel_Info_t *)psHciContext->p_jewel_info ;
190 
191         /* Update the pipe_id of the Jewel Gate obtained from the HCI
192         Response */
193         ps_jewel_info->pipe_id = pipeID;
194         ps_jewel_info->p_pipe_info = pPipeInfo;
195         /* Update the Response Receive routine of the Jewel Gate */
196         pPipeInfo->recv_resp = phHciNfc_Recv_Jewel_Response;
197         /* Update the event Receive routine of the Jewel Gate */
198         pPipeInfo->recv_event = phHciNfc_Recv_Jewel_Event;
199     }
200 
201     return status;
202 }
203 
204 
205 NFCSTATUS
phHciNfc_Jewel_Update_Info(phHciNfc_sContext_t * psHciContext,uint8_t infotype,void * jewel_info)206 phHciNfc_Jewel_Update_Info(
207                              phHciNfc_sContext_t        *psHciContext,
208                              uint8_t                    infotype,
209                              void                       *jewel_info
210                              )
211 {
212     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
213 
214     if (NULL == psHciContext)
215     {
216         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
217     }
218     else if(NULL == psHciContext->p_jewel_info)
219     {
220         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
221     }
222     else
223     {
224         phHciNfc_Jewel_Info_t     *ps_jewel_info=NULL;
225         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
226                         psHciContext->p_jewel_info ;
227 
228         switch(infotype)
229         {
230             case HCI_JEWEL_ENABLE:
231             {
232                 if (NULL != jewel_info)
233                 {
234                     ps_jewel_info->enable_jewel_gate =
235                                         *((uint8_t *)jewel_info);
236                 }
237                 break;
238             }
239             case HCI_JEWEL_INFO_SEQ:
240             {
241                 ps_jewel_info->current_seq = JEWEL_READID_SEQUENCE;
242                 ps_jewel_info->next_seq = JEWEL_READID_SEQUENCE;
243                 break;
244             }
245             default:
246             {
247                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
248                 break;
249             }
250         }
251     }
252     return status;
253 }
254 
255 NFCSTATUS
phHciNfc_Jewel_Info_Sequence(void * psHciHandle,void * pHwRef)256 phHciNfc_Jewel_Info_Sequence (
257                                void             *psHciHandle,
258                                void             *pHwRef
259                                )
260 {
261     NFCSTATUS               status = NFCSTATUS_SUCCESS;
262     phHciNfc_sContext_t     *psHciContext =
263                             ((phHciNfc_sContext_t *)psHciHandle);
264     static uint8_t          paraminfo[NXP_JEWEL_READID_LENGTH + 1] = {0};
265 
266     if( (NULL == psHciContext)
267         || (NULL == pHwRef)
268         )
269     {
270         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
271     }
272     else if((NULL == psHciContext->p_jewel_info) ||
273         (HCI_JEWEL_ENABLE !=
274         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
275         enable_jewel_gate))
276     {
277         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
278     }
279     else
280     {
281         phHciNfc_Jewel_Info_t      *ps_jewel_info=NULL;
282         phHciNfc_Pipe_Info_t        *ps_pipe_info=NULL;
283         uint8_t                     pipeid = 0;
284 
285         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
286                         psHciContext->p_jewel_info ;
287         ps_pipe_info = ps_jewel_info->p_pipe_info;
288         if(NULL == ps_pipe_info )
289         {
290             status = PHNFCSTVAL(CID_NFC_HCI,
291                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
292         }
293         else
294         {
295             switch(ps_jewel_info->current_seq)
296             {
297                 case JEWEL_READID_SEQUENCE:
298                 {
299                     pipeid = ps_pipe_info->pipe.pipe_id;
300                     ps_pipe_info->reg_index = NXP_JEWEL_READID;
301                     paraminfo[0] = NXP_JEWEL_READID;
302 
303                     ps_pipe_info->param_info = (void *)&paraminfo;
304                     ps_pipe_info->param_length = NXP_JEWEL_READID_LENGTH + 1;
305 
306                     status = phHciNfc_Send_Jewel_Command(psHciContext,
307                                             pHwRef, pipeid,
308                                             NXP_JEWEL_RAW);
309 
310                     if(NFCSTATUS_PENDING == status )
311                     {
312                         ps_jewel_info->next_seq = JEWEL_END_SEQUENCE;
313                     }
314                     break;
315                 }
316                 case JEWEL_END_SEQUENCE:
317                 {
318                     phNfc_sCompletionInfo_t     CompInfo;
319 
320                     ps_pipe_info->reg_index = JEWEL_END_SEQUENCE;
321                     if (JEWEL_MULTIPLE_TAGS_FOUND ==
322                         ps_jewel_info->multiple_tgts_found)
323                     {
324                         CompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
325                     }
326                     else
327                     {
328                         CompInfo.status = NFCSTATUS_SUCCESS;
329                     }
330 
331                     CompInfo.info = &(ps_jewel_info->s_jewel_info);
332 
333                     ps_jewel_info->s_jewel_info.RemDevType = phHal_eJewel_PICC;
334                     ps_jewel_info->current_seq = JEWEL_READID_SEQUENCE;
335                     ps_jewel_info->next_seq = JEWEL_READID_SEQUENCE;
336                     status = NFCSTATUS_SUCCESS;
337                     /* Notify to the upper layer */
338                     phHciNfc_Tag_Notify(psHciContext, pHwRef,
339                                         NFC_NOTIFY_TARGET_DISCOVERED,
340                                         &CompInfo);
341                     break;
342                 }
343                 default:
344                 {
345                     status = PHNFCSTVAL(CID_NFC_HCI,
346                                         NFCSTATUS_INVALID_HCI_RESPONSE);
347                     break;
348                 }
349             }
350         }
351     }
352     return status;
353 }
354 
355 static
356 NFCSTATUS
phHciNfc_Jewel_InfoUpdate(phHciNfc_sContext_t * psHciContext,uint8_t index,uint8_t * reg_value,uint8_t reg_length)357 phHciNfc_Jewel_InfoUpdate(
358                             phHciNfc_sContext_t     *psHciContext,
359                             uint8_t                 index,
360                             uint8_t                 *reg_value,
361                             uint8_t                 reg_length
362                             )
363 {
364     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
365     phHciNfc_Jewel_Info_t       *ps_jewel_info = NULL;
366     phHal_sJewelInfo_t          *ps_jewel_tag_info = NULL;
367 
368     ps_jewel_info = (phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info);
369     ps_jewel_tag_info = &(ps_jewel_info->s_jewel_info.RemoteDevInfo.Jewel_Info);
370 
371     switch(index)
372     {
373         case NXP_JEWEL_READID:
374         {
375             HCI_PRINT_BUFFER("\tJewel ID", reg_value, reg_length);
376             if(NXP_JEWEL_READID_LENGTH == reg_length)
377             {
378                 uint8_t     i = 0;
379                 ps_jewel_tag_info->HeaderRom0 = reg_value[i++];
380                 ps_jewel_tag_info->HeaderRom1 = reg_value[i++];
381                 (void)memcpy(ps_jewel_tag_info->Uid,
382                             &(reg_value[i]),
383                             (reg_length - i));
384 
385                 ps_jewel_tag_info->UidLength = (reg_length - i);
386             }
387             else
388             {
389                 status = PHNFCSTVAL(CID_NFC_HCI,
390                                 NFCSTATUS_INVALID_HCI_RESPONSE);
391             }
392             break;
393         }
394         default:
395         {
396             status = PHNFCSTVAL(CID_NFC_HCI,
397                                 NFCSTATUS_INVALID_HCI_RESPONSE);
398             break;
399         }
400     }
401     return status;
402 }
403 
404 static
405 NFCSTATUS
phHciNfc_Recv_Jewel_Packet(phHciNfc_sContext_t * psHciContext,uint8_t * pResponse,uint8_t length)406 phHciNfc_Recv_Jewel_Packet(
407                             phHciNfc_sContext_t  *psHciContext,
408                             uint8_t              *pResponse,
409 #ifdef ONE_BYTE_LEN
410                             uint8_t            length
411 #else
412                             uint16_t           length
413 #endif
414                             )
415 {
416     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
417     phHciNfc_Jewel_Info_t       *ps_jewel_info = (phHciNfc_Jewel_Info_t *)
418                                 (psHciContext->p_jewel_info);
419 
420     if (NXP_JEWEL_READID == ps_jewel_info->p_pipe_info->reg_index)
421     {
422         status = phHciNfc_Jewel_InfoUpdate(psHciContext,
423                             ps_jewel_info->p_pipe_info->reg_index,
424                             pResponse, (uint8_t)length);
425     }
426     else
427     {
428         /* Send Jewel data to the upper layer */
429         HCI_PRINT_BUFFER("Jewel Bytes received", pResponse, length);
430         psHciContext->rx_index = HCP_HEADER_LEN;
431     }
432     return status;
433 }
434 
435 
436 static
437 NFCSTATUS
phHciNfc_Recv_Jewel_Response(void * psContext,void * pHwRef,uint8_t * pResponse,uint8_t length)438 phHciNfc_Recv_Jewel_Response(
439                                void                *psContext,
440                                void                *pHwRef,
441                                uint8_t             *pResponse,
442 #ifdef ONE_BYTE_LEN
443                                uint8_t            length
444 #else
445                                uint16_t           length
446 #endif
447                                )
448 {
449     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
450     phHciNfc_sContext_t         *psHciContext =
451                                 (phHciNfc_sContext_t *)psContext;
452 
453 
454     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
455         || (0 == length))
456     {
457         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
458     }
459     else if(NULL == psHciContext->p_jewel_info)
460     {
461         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
462     }
463     else
464     {
465         phHciNfc_Jewel_Info_t       *ps_jewel_info=NULL;
466         uint8_t                     prev_cmd = ANY_GET_PARAMETER;
467         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
468                         psHciContext->p_jewel_info ;
469         if( NULL == ps_jewel_info->p_pipe_info)
470         {
471             status = PHNFCSTVAL(CID_NFC_HCI,
472                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
473         }
474         else
475         {
476             prev_cmd = ps_jewel_info->p_pipe_info->prev_msg ;
477             switch(prev_cmd)
478             {
479                 case ANY_GET_PARAMETER:
480                 {
481                     if (length >= HCP_HEADER_LEN)
482                     {
483                         status = phHciNfc_Jewel_InfoUpdate(psHciContext,
484                                             ps_jewel_info->p_pipe_info->reg_index,
485                                             &pResponse[HCP_HEADER_LEN],
486                                             (uint8_t)(length - HCP_HEADER_LEN));
487                     }
488                     else
489                     {
490                         status = PHNFCSTVAL(CID_NFC_HCI,
491                                             NFCSTATUS_INVALID_HCI_RESPONSE);
492                     }
493                     break;
494                 }
495                 case ANY_SET_PARAMETER:
496                 {
497                     HCI_PRINT("Jewel Parameter Set \n");
498                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
499                                                                 UPDATE_SEQ);
500                     ps_jewel_info->next_seq = JEWEL_READID_SEQUENCE;
501                     break;
502                 }
503                 case ANY_OPEN_PIPE:
504                 {
505                     HCI_PRINT("Jewel open pipe complete\n");
506                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
507                                                                 UPDATE_SEQ);
508                     ps_jewel_info->next_seq = JEWEL_READID_SEQUENCE;
509                     break;
510                 }
511                 case ANY_CLOSE_PIPE:
512                 {
513                     HCI_PRINT("Jewel close pipe complete\n");
514                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
515                                                                 UPDATE_SEQ);
516                     break;
517                 }
518                 case NXP_JEWEL_RAW:
519                 {
520                     HCI_PRINT("Jewel packet received \n");
521                     if (length >= HCP_HEADER_LEN)
522                     {
523                         phHciNfc_Append_HCPFrame(psHciContext->recv_buffer,
524                                                     0, pResponse, length);
525                         psHciContext->rx_total = length;
526                         status = phHciNfc_Recv_Jewel_Packet(psHciContext,
527                                                     &pResponse[HCP_HEADER_LEN],
528                                                     (length - HCP_HEADER_LEN));
529                     }
530                     else
531                     {
532                         status = PHNFCSTVAL(CID_NFC_HCI,
533                                             NFCSTATUS_INVALID_HCI_RESPONSE);
534                     }
535                     break;
536                 }
537                 case NXP_WRA_CONTINUE_ACTIVATION:
538                 case NXP_WR_ACTIVATE_ID:
539                 {
540                     HCI_PRINT("Jewel continue activation or ");
541                     HCI_PRINT("reactivation completed \n");
542                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
543                                                                 UPDATE_SEQ);
544                     break;
545                 }
546                 case NXP_WR_PRESCHECK:
547                 {
548                     HCI_PRINT("Presence check completed \n");
549                     break;
550                 }
551                 case NXP_WR_ACTIVATE_NEXT:
552                 {
553                     HCI_PRINT("Activate next completed \n");
554                     if (length > HCP_HEADER_LEN)
555                     {
556                         if (JEWEL_MULTIPLE_TAGS_FOUND ==
557                             pResponse[HCP_HEADER_LEN])
558                         {
559                             ps_jewel_info->multiple_tgts_found =
560                                             JEWEL_MULTIPLE_TAGS_FOUND;
561                         }
562                         else
563                         {
564                             ps_jewel_info->multiple_tgts_found = FALSE;
565                         }
566                     }
567                     else
568                     {
569                         status = PHNFCSTVAL(CID_NFC_HCI,
570                                             NFCSTATUS_INVALID_HCI_RESPONSE);
571                     }
572                     break;
573                 }
574                 case NXP_WR_DISPATCH_TO_UICC:
575                 {
576                     switch(length)
577                     {
578                         case HCP_HEADER_LEN:
579                         {
580                             /* Optional error code, if no error code field
581                                 in the response, then this command is
582                                 successfully completed */
583                             ps_jewel_info->uicc_activation =
584                                         UICC_CARD_ACTIVATION_SUCCESS;
585                             break;
586                         }
587                         case (HCP_HEADER_LEN + 1):
588                         {
589                             ps_jewel_info->uicc_activation =
590                                         pResponse[HCP_HEADER_LEN];
591                             break;
592                         } /* End of case (HCP_HEADER_LEN + index) */
593                         default:
594                         {
595                             status = PHNFCSTVAL(CID_NFC_HCI,
596                                                 NFCSTATUS_INVALID_HCI_RESPONSE);
597                             break;
598                         }
599                     }
600                     if (NFCSTATUS_SUCCESS == status)
601                     {
602                         status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
603                                                                     UPDATE_SEQ);
604                     }
605                     break;
606                 }
607                 default:
608                 {
609                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
610                     break;
611                 }
612             }
613             if( NFCSTATUS_SUCCESS == status )
614             {
615                 ps_jewel_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
616                 ps_jewel_info->current_seq = ps_jewel_info->next_seq;
617             }
618         }
619     }
620     return status;
621 }
622 
623 static
624 NFCSTATUS
phHciNfc_Recv_Jewel_Event(void * psContext,void * pHwRef,uint8_t * pEvent,uint8_t length)625 phHciNfc_Recv_Jewel_Event(
626                             void               *psContext,
627                             void               *pHwRef,
628                             uint8_t            *pEvent,
629 #ifdef ONE_BYTE_LEN
630                             uint8_t            length
631 #else
632                             uint16_t           length
633 #endif
634                             )
635 {
636     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
637     phHciNfc_sContext_t         *psHciContext =
638                                 (phHciNfc_sContext_t *)psContext ;
639 
640     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
641         || (0 == length))
642     {
643         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
644     }
645     else if((NULL == psHciContext->p_jewel_info) ||
646         (HCI_JEWEL_ENABLE !=
647         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
648         enable_jewel_gate))
649     {
650         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
651     }
652     else
653     {
654         phHciNfc_HCP_Packet_t       *p_packet = NULL;
655         phHciNfc_Jewel_Info_t       *ps_jewel_info = NULL;
656         phHciNfc_HCP_Message_t      *message = NULL;
657         uint8_t                     instruction=0,
658                                     i = 0;
659 
660         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
661                                 psHciContext->p_jewel_info ;
662         p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
663         message = &p_packet->msg.message;
664         /* Get the instruction bits from the Message Header */
665         instruction = (uint8_t) GET_BITS8( message->msg_header,
666                     HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
667 
668         if ((EVT_TARGET_DISCOVERED == instruction)
669             && ((JEWEL_MULTIPLE_TAGS_FOUND == message->payload[i] )
670             || (JEWEL_SINGLE_TAG_FOUND == message->payload[i]))
671             )
672         {
673             static phNfc_sCompletionInfo_t      pCompInfo;
674 
675             if (JEWEL_MULTIPLE_TAGS_FOUND == message->payload[i])
676             {
677                 ps_jewel_info->multiple_tgts_found =
678                                         JEWEL_MULTIPLE_TAGS_FOUND;
679                 pCompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
680             }
681             else
682             {
683                 ps_jewel_info->multiple_tgts_found = FALSE;
684                 pCompInfo.status = NFCSTATUS_SUCCESS;
685             }
686 
687             psHciContext->host_rf_type = phHal_eJewel_PCD;
688             ps_jewel_info->s_jewel_info.RemDevType = phHal_eJewel_PICC;
689             ps_jewel_info->current_seq = JEWEL_READID_SEQUENCE;
690 
691             /* Notify to the HCI Generic layer To Update the FSM */
692             phHciNfc_Notify_Event(psHciContext, pHwRef,
693                                 NFC_NOTIFY_TARGET_DISCOVERED,
694                                 &pCompInfo);
695 
696         }
697         else
698         {
699             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
700         }
701     }
702     return status;
703 }
704 
705 NFCSTATUS
phHciNfc_Send_Jewel_Command(phHciNfc_sContext_t * psContext,void * pHwRef,uint8_t pipe_id,uint8_t cmd)706 phHciNfc_Send_Jewel_Command(
707                               phHciNfc_sContext_t   *psContext,
708                               void                  *pHwRef,
709                               uint8_t               pipe_id,
710                               uint8_t               cmd
711                               )
712 {
713     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
714     phHciNfc_sContext_t         *psHciContext =
715                                 (phHciNfc_sContext_t *)psContext ;
716     if( (NULL == psHciContext) || (NULL == pHwRef) )
717     {
718         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
719     }
720     else if((NULL == psHciContext->p_jewel_info) ||
721         (HCI_JEWEL_ENABLE !=
722         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
723         enable_jewel_gate) ||
724         (HCI_UNKNOWN_PIPE_ID ==
725         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
726         pipe_id) ||
727         (pipe_id !=
728         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
729         pipe_id))
730     {
731         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
732     }
733     else
734     {
735         phHciNfc_Jewel_Info_t       *ps_jewel_info=NULL;
736         phHciNfc_Pipe_Info_t        *ps_pipe_info=NULL;
737         phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
738         phHciNfc_HCP_Message_t      *hcp_message = NULL;
739         uint8_t                     i = 0,
740                                     length = HCP_HEADER_LEN;
741 
742         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
743                             psHciContext->p_jewel_info ;
744         ps_pipe_info = ps_jewel_info->p_pipe_info;
745         if(NULL == ps_pipe_info )
746         {
747             status = PHNFCSTVAL(CID_NFC_HCI,
748                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
749         }
750         else
751         {
752             psHciContext->tx_total = 0 ;
753             hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
754 
755             if (NXP_JEWEL_RAW == cmd)
756             {
757                 /* Construct the HCP Frame */
758                 phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
759                                 (uint8_t) pipe_id, HCP_MSG_TYPE_COMMAND, cmd);
760                 hcp_message = &(hcp_packet->msg.message);
761                 phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload,
762                                     i, (uint8_t *)ps_pipe_info->param_info,
763                                     ps_pipe_info->param_length);
764                 length =(uint8_t)(length + i + ps_pipe_info->param_length);
765             }
766             else
767             {
768                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_COMMAND);
769             }
770 
771             if (NFCSTATUS_SUCCESS == status)
772             {
773                 ps_pipe_info->sent_msg_type = (uint8_t)HCP_MSG_TYPE_COMMAND;
774                 ps_pipe_info->prev_msg = cmd;
775                 psHciContext->tx_total = length;
776                 psHciContext->response_pending = TRUE;
777 
778                 /* Send the Constructed HCP packet to the lower layer */
779                 status = phHciNfc_Send_HCP( psHciContext, pHwRef);
780                 ps_pipe_info->prev_status = status;
781             }
782         }
783     }
784     return status;
785 }
786 
787 NFCSTATUS
phHciNfc_Jewel_GetRID(phHciNfc_sContext_t * psHciContext,void * pHwRef)788 phHciNfc_Jewel_GetRID(
789                 phHciNfc_sContext_t   *psHciContext,
790                 void                  *pHwRef)
791 {
792     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
793     static uint8_t              reader_id_info[NXP_JEWEL_READID_LENGTH] = {0};
794 
795     if( (NULL == psHciContext) || (NULL == pHwRef))
796     {
797         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
798     }
799     else if((NULL == psHciContext->p_jewel_info) ||
800         (HCI_JEWEL_ENABLE !=
801         ((phHciNfc_Jewel_Info_t *)(psHciContext->p_jewel_info))->
802         enable_jewel_gate))
803     {
804         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
805     }
806     else
807     {
808         phHciNfc_Jewel_Info_t      *ps_jewel_info=NULL;
809         phHciNfc_Pipe_Info_t        *ps_pipe_info=NULL;
810         uint8_t                     pipeid = 0;
811 
812         ps_jewel_info = (phHciNfc_Jewel_Info_t *)
813                         psHciContext->p_jewel_info ;
814 
815         ps_pipe_info = ps_jewel_info->p_pipe_info;
816         if(NULL == ps_pipe_info )
817         {
818             status = PHNFCSTVAL(CID_NFC_HCI,
819                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
820         }
821         else
822         {
823             pipeid = ps_jewel_info->pipe_id ;
824             reader_id_info[0] = NXP_JEWEL_READID;
825 
826             ps_pipe_info->param_info = (void *)&reader_id_info;
827             ps_pipe_info->param_length = NXP_JEWEL_READID_LENGTH + 1 ;
828 
829             status = phHciNfc_Send_Jewel_Command(psHciContext,
830                                     pHwRef, pipeid,
831                                     NXP_JEWEL_RAW);
832         }
833     }
834     return status;
835 }
836 
837 #endif /* #if defined(TYPE_JEWEL) */
838 
839 
840