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_Felica.c                                                 *
22 * \brief HCI Felica Management Routines.                                    *
23 *                                                                             *
24 *                                                                             *
25 * Project: NFC-FRI-1.1                                                        *
26 *                                                                             *
27 * $Date: Wed Feb 17 16:19:04 2010 $                                           *
28 * $Author: ing02260 $                                                         *
29 * $Revision: 1.11 $                                                           *
30 * $Aliases: 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 $
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_FELICA)
44 #include <phHciNfc_Felica.h>
45 /*
46 ****************************** Macro Definitions *******************************
47 */
48 
49 #define FEL_SINGLE_TAG_FOUND                0x00U
50 #define FEL_MULTIPLE_TAGS_FOUND             0x03U
51 #define NXP_WRA_CONTINUE_ACTIVATION         0x12U
52 
53 #define NXP_FEL_SYS_CODE                    0x01U
54 #define NXP_FEL_POLREQ_SYS_CODE             0x02U
55 #define NXP_FEL_CURRENTIDM                  0x04U
56 #define NXP_FEL_CURRENTPMM                  0x05U
57 
58 #define NXP_FEL_SYS_CODE_LEN                0x02U
59 #define NXP_FEL_CUR_IDM_PMM_LEN             0x08U
60 
61 #define FELICA_STATUS                       0x00U
62 
63 uint8_t nxp_nfc_felica_timeout = NXP_FELICA_XCHG_TIMEOUT;
64 
65 /* Presence check command for felica tag */
66 #define FELICA_REQ_MODE                     0x04U
67 
68 /*
69 *************************** Structure and Enumeration ***************************
70 */
71 
72 
73 /*
74 *************************** Static Function Declaration **************************
75 */
76 static
77 NFCSTATUS
78 phHciNfc_Recv_Felica_Response(
79                                void                *psContext,
80                                void                *pHwRef,
81                                uint8_t             *pResponse,
82 #ifdef ONE_BYTE_LEN
83                                uint8_t              length
84 #else
85                                uint16_t             length
86 #endif
87                                );
88 
89 static
90 NFCSTATUS
91 phHciNfc_Recv_Felica_Event(
92                             void               *psContext,
93                             void               *pHwRef,
94                             uint8_t            *pEvent,
95 #ifdef ONE_BYTE_LEN
96                             uint8_t            length
97 #else
98                             uint16_t           length
99 #endif
100                             );
101 
102 static
103 NFCSTATUS
104 phHciNfc_Felica_InfoUpdate(
105                             phHciNfc_sContext_t     *psHciContext,
106                             uint8_t                 index,
107                             uint8_t                 *reg_value,
108                             uint8_t                 reg_length
109                             );
110 
111 static
112 NFCSTATUS
113 phHciNfc_Recv_Felica_Packet(
114                            phHciNfc_sContext_t  *psHciContext,
115                            uint8_t              cmd,
116                            uint8_t              *pResponse,
117 #ifdef ONE_BYTE_LEN
118                            uint8_t              length
119 #else
120                            uint16_t             length
121 #endif
122                            );
123 /*
124 *************************** Function Definitions ***************************
125 */
126 
127 NFCSTATUS
phHciNfc_Felica_Get_PipeID(phHciNfc_sContext_t * psHciContext,uint8_t * ppipe_id)128 phHciNfc_Felica_Get_PipeID(
129                            phHciNfc_sContext_t     *psHciContext,
130                            uint8_t                 *ppipe_id
131                            )
132 {
133     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
134 
135     if( (NULL != psHciContext)
136         && ( NULL != ppipe_id )
137         && ( NULL != psHciContext->p_felica_info )
138         )
139     {
140         phHciNfc_Felica_Info_t     *p_fel_info = NULL;
141         p_fel_info = (phHciNfc_Felica_Info_t *)psHciContext->p_felica_info ;
142         *ppipe_id =  p_fel_info->pipe_id  ;
143     }
144     else
145     {
146         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
147     }
148     return status;
149 }
150 
151 
152 NFCSTATUS
phHciNfc_Felica_Init_Resources(phHciNfc_sContext_t * psHciContext)153 phHciNfc_Felica_Init_Resources(
154                                phHciNfc_sContext_t     *psHciContext
155                                )
156 {
157     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
158     phHciNfc_Felica_Info_t      *p_fel_info = NULL;
159     if( NULL == psHciContext )
160     {
161         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
162     }
163     else
164     {
165         if(
166             ( NULL == psHciContext->p_felica_info ) &&
167             (phHciNfc_Allocate_Resource((void **)(&p_fel_info),
168             sizeof(phHciNfc_Felica_Info_t))== NFCSTATUS_SUCCESS)
169             )
170         {
171             psHciContext->p_felica_info = p_fel_info;
172             p_fel_info->current_seq = FELICA_INVALID_SEQ;
173             p_fel_info->next_seq = FELICA_INVALID_SEQ;
174             p_fel_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
175         }
176         else
177         {
178             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
179         }
180 
181     }
182     return status;
183 }
184 
185 NFCSTATUS
phHciNfc_Felica_Update_PipeInfo(phHciNfc_sContext_t * psHciContext,uint8_t pipeID,phHciNfc_Pipe_Info_t * pPipeInfo)186 phHciNfc_Felica_Update_PipeInfo(
187                                 phHciNfc_sContext_t     *psHciContext,
188                                 uint8_t                 pipeID,
189                                 phHciNfc_Pipe_Info_t    *pPipeInfo
190                                 )
191 {
192     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
193 
194     if( NULL == psHciContext )
195     {
196         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
197     }
198     else if(NULL == psHciContext->p_felica_info)
199     {
200         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
201     }
202     else
203     {
204         phHciNfc_Felica_Info_t *p_fel_info=NULL;
205         p_fel_info = (phHciNfc_Felica_Info_t *)psHciContext->p_felica_info ;
206 
207         /* Update the pipe_id of the Felica Gate obtained from the HCI
208         Response */
209         p_fel_info->pipe_id = pipeID;
210         p_fel_info->p_pipe_info = pPipeInfo;
211         /* Update the Response Receive routine of the Felica Gate */
212         pPipeInfo->recv_resp = phHciNfc_Recv_Felica_Response;
213         /* Update the event Receive routine of the Felica Gate */
214         pPipeInfo->recv_event = phHciNfc_Recv_Felica_Event;
215     }
216 
217     return status;
218 }
219 
220 NFCSTATUS
phHciNfc_Felica_Update_Info(phHciNfc_sContext_t * psHciContext,uint8_t infotype,void * fel_info)221 phHciNfc_Felica_Update_Info(
222                              phHciNfc_sContext_t        *psHciContext,
223                              uint8_t                    infotype,
224                              void                       *fel_info
225                              )
226 {
227     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
228 
229     if (NULL == psHciContext)
230     {
231         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
232     }
233     else if(NULL == psHciContext->p_felica_info)
234     {
235         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
236     }
237     else
238     {
239         phHciNfc_Felica_Info_t     *p_fel_info=NULL;
240         p_fel_info = (phHciNfc_Felica_Info_t *)
241                         psHciContext->p_felica_info ;
242 
243         switch(infotype)
244         {
245             case HCI_FELICA_ENABLE:
246             {
247                 if (NULL != fel_info)
248                 {
249                     p_fel_info->enable_felica_gate =
250                                         *((uint8_t *)fel_info);
251                 }
252                 break;
253             }
254             case HCI_FELICA_INFO_SEQ:
255             {
256                 p_fel_info->current_seq = FELICA_SYSTEMCODE;
257                 p_fel_info->next_seq = FELICA_SYSTEMCODE;
258                 break;
259             }
260             default:
261             {
262                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
263                 break;
264             }
265         }
266     }
267     return status;
268 }
269 
270 NFCSTATUS
phHciNfc_Felica_Info_Sequence(void * psHciHandle,void * pHwRef)271 phHciNfc_Felica_Info_Sequence (
272                                void             *psHciHandle,
273                                void             *pHwRef
274                                )
275 {
276     NFCSTATUS               status = NFCSTATUS_SUCCESS;
277     phHciNfc_sContext_t     *psHciContext =
278                             ((phHciNfc_sContext_t *)psHciHandle);
279 
280     HCI_PRINT ("HCI : phHciNfc_Felica_Info_Sequence called... \n");
281     if( (NULL == psHciContext)
282         || (NULL == pHwRef)
283         )
284     {
285         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
286     }
287     else if((NULL == psHciContext->p_felica_info) ||
288         (HCI_FELICA_ENABLE !=
289         ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
290         enable_felica_gate))
291     {
292         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
293     }
294     else
295     {
296         phHciNfc_Felica_Info_t      *p_fel_info=NULL;
297         phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
298         uint8_t                     pipeid = 0;
299 
300         p_fel_info = (phHciNfc_Felica_Info_t *)
301                         psHciContext->p_felica_info ;
302         p_pipe_info = p_fel_info->p_pipe_info;
303         if(NULL == p_pipe_info )
304         {
305             status = PHNFCSTVAL(CID_NFC_HCI,
306                 NFCSTATUS_INVALID_HCI_SEQUENCE);
307         }
308         else
309         {
310             HCI_DEBUG ("HCI : p_fel_info->current_seq : %02X\n", p_fel_info->current_seq);
311             switch(p_fel_info->current_seq)
312             {
313                 case FELICA_SYSTEMCODE:
314                 {
315                     p_pipe_info->reg_index = NXP_FEL_SYS_CODE;
316                     pipeid = p_fel_info->pipe_id ;
317                     /* Fill the data buffer and send the command to the
318                         device */
319                     status =
320                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
321                         pipeid, (uint8_t)ANY_GET_PARAMETER);
322                     if(NFCSTATUS_PENDING == status )
323                     {
324                         p_fel_info->next_seq = FELICA_CURRENTIDM;
325                     }
326                     break;
327                 }
328                 case FELICA_CURRENTIDM:
329                 {
330                     p_pipe_info->reg_index = NXP_FEL_CURRENTIDM;
331                     pipeid = p_fel_info->pipe_id ;
332                     /* Fill the data buffer and send the command to the
333                         device */
334                     status =
335                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
336                         pipeid, (uint8_t)ANY_GET_PARAMETER);
337                     if(NFCSTATUS_PENDING == status )
338                     {
339                         p_fel_info->next_seq = FELICA_CURRENTPMM;
340                     }
341                     break;
342                 }
343                 case FELICA_CURRENTPMM:
344                 {
345                     p_pipe_info->reg_index = NXP_FEL_CURRENTPMM;
346                     pipeid = p_fel_info->pipe_id ;
347                     /* Fill the data buffer and send the command to the
348                         device */
349                     status =
350                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
351                         pipeid, (uint8_t)ANY_GET_PARAMETER);
352                     if(NFCSTATUS_PENDING == status )
353                     {
354                         p_fel_info->next_seq = FELICA_END_SEQUENCE;
355                     }
356                     break;
357                 }
358                 case FELICA_END_SEQUENCE:
359                 {
360                     phNfc_sCompletionInfo_t     CompInfo;
361                     if (FEL_MULTIPLE_TAGS_FOUND ==
362                         p_fel_info->multiple_tgts_found)
363                     {
364                         CompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
365                     }
366                     else
367                     {
368                         CompInfo.status = NFCSTATUS_SUCCESS;
369                     }
370 
371                     CompInfo.info = &(p_fel_info->felica_info);
372 
373                     p_fel_info->felica_info.RemDevType = phHal_eFelica_PICC;
374                     p_fel_info->current_seq = FELICA_SYSTEMCODE;
375                     p_fel_info->next_seq = FELICA_SYSTEMCODE;
376                     status = NFCSTATUS_SUCCESS;
377                     HCI_DEBUG ("HCI : p_fel_info->felica_info.RemDevType : %02X\n", p_fel_info->felica_info.RemDevType);
378                     HCI_DEBUG ("HCI : status notified: %02X\n", CompInfo.status);
379                     /* Notify to the upper layer */
380                     phHciNfc_Tag_Notify(psHciContext,
381                                         pHwRef,
382                                         NFC_NOTIFY_TARGET_DISCOVERED,
383                                         &CompInfo);
384                     break;
385                 }
386                 default:
387                 {
388                     status = PHNFCSTVAL(CID_NFC_HCI,
389                         NFCSTATUS_INVALID_HCI_RESPONSE);
390                     break;
391                 }
392             }
393             HCI_DEBUG ("HCI : p_fel_info->current_seq after : %02X\n", p_fel_info->current_seq);
394             HCI_DEBUG ("HCI : p_fel_info->next_seq : %02X\n", p_fel_info->next_seq);
395         }
396     }
397     HCI_PRINT ("HCI : phHciNfc_Felica_Info_Sequence end\n");
398     return status;
399 }
400 
401 static
402 NFCSTATUS
phHciNfc_Felica_InfoUpdate(phHciNfc_sContext_t * psHciContext,uint8_t index,uint8_t * reg_value,uint8_t reg_length)403 phHciNfc_Felica_InfoUpdate(
404                             phHciNfc_sContext_t     *psHciContext,
405                             uint8_t                 index,
406                             uint8_t                 *reg_value,
407                             uint8_t                 reg_length
408                             )
409 {
410     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
411     phHciNfc_Felica_Info_t     *p_fel_info=NULL;
412     phHal_sFelicaInfo_t        *p_fel_tag_info = NULL;
413 
414     p_fel_info = (phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info );
415     p_fel_tag_info = &(p_fel_info->felica_info.RemoteDevInfo.Felica_Info);
416 
417     switch(index)
418     {
419         case NXP_FEL_SYS_CODE:
420         {
421             if (NXP_FEL_SYS_CODE_LEN == reg_length)
422             {
423                 /* System code from registry is invalid in this case */
424 		p_fel_tag_info->SystemCode[0] = 0;
425                 p_fel_tag_info->SystemCode[1] = 0;
426             }
427             else
428             {
429                 status = PHNFCSTVAL(CID_NFC_HCI,
430                                     NFCSTATUS_INVALID_HCI_RESPONSE);
431             }
432             break;
433         }
434         case NXP_FEL_CURRENTIDM:
435         {
436             if (NXP_FEL_CUR_IDM_PMM_LEN == reg_length)
437             {
438                 HCI_PRINT_BUFFER("\tFelica ID data", reg_value, reg_length);
439                 /* Update current PM values */
440                 (void)memcpy(p_fel_tag_info->IDm, reg_value,
441                             reg_length);
442                 p_fel_tag_info->IDmLength = reg_length;
443             }
444             else
445             {
446                 status = PHNFCSTVAL(CID_NFC_HCI,
447                                     NFCSTATUS_INVALID_HCI_RESPONSE);
448             }
449             break;
450         }
451         case NXP_FEL_CURRENTPMM:
452         {
453             if (NXP_FEL_CUR_IDM_PMM_LEN == reg_length)
454             {
455                 HCI_PRINT_BUFFER("\tFelica PM data", reg_value, reg_length);
456                 /* Update current PM values */
457                 (void)memcpy(p_fel_tag_info->PMm, reg_value,
458                             reg_length);
459             }
460             else
461             {
462                 status = PHNFCSTVAL(CID_NFC_HCI,
463                                     NFCSTATUS_INVALID_HCI_RESPONSE);
464             }
465             break;
466         }
467         default:
468         {
469             status = PHNFCSTVAL(CID_NFC_HCI,
470                                 NFCSTATUS_INVALID_HCI_RESPONSE);
471             break;
472         }
473     }
474     return status;
475 }
476 
477 
478 static
479 NFCSTATUS
phHciNfc_Recv_Felica_Packet(phHciNfc_sContext_t * psHciContext,uint8_t cmd,uint8_t * pResponse,uint8_t length)480 phHciNfc_Recv_Felica_Packet(
481                             phHciNfc_sContext_t  *psHciContext,
482                             uint8_t              cmd,
483                             uint8_t              *pResponse,
484 #ifdef ONE_BYTE_LEN
485                             uint8_t             length
486 #else
487                             uint16_t            length
488 #endif
489                             )
490 {
491     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
492     uint8_t                     index = 0;
493 
494     /* To remove "warning (VS C4100) : unreferenced formal parameter" */
495 
496     PHNFC_UNUSED_VARIABLE(length);
497 
498     if (NXP_FELICA_RAW == cmd)
499     {
500         if (FELICA_STATUS == pResponse[index])  /* Status byte */
501         {
502             index = (index + 1);
503             psHciContext->rx_index = (HCP_HEADER_LEN + 1);
504             HCI_PRINT_BUFFER("Felica Bytes received", &pResponse[index], (length - index));
505             /* If Poll response received then update IDm and PMm parameters, when presence check going on */
506             if (pResponse[index + 1] == 0x01)
507             {
508                 if (length >= 19)
509                 {
510                     /* IDm */
511                     (void) memcpy(psHciContext->p_target_info->RemoteDevInfo.Felica_Info.IDm,
512                                   &pResponse[index + 2], 8);
513                     /* PMm */
514                     (void) memcpy(psHciContext->p_target_info->RemoteDevInfo.Felica_Info.PMm,
515                                   &pResponse[index + 2 + 8], 8);
516                     index = index + 2 + 8 + 8;
517 
518                     /* SC */
519                     if (length >= 21)
520                     {
521                         /* Copy SC if available */
522                         psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[0] = pResponse[index];
523                         psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[1] = pResponse[index + 1];
524                     }
525                     else
526                     {
527                         /* If SC is not available in packet then set to zero */
528                         psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[0] = 0;
529                         psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[1] = 0;
530                     }
531                 }
532                 else
533                 {
534                     status = PHNFCSTVAL(CID_NFC_HCI,
535                                         NFCSTATUS_INVALID_HCI_RESPONSE);
536                 }
537             }
538         }
539         else
540         {
541             status = PHNFCSTVAL(CID_NFC_HCI,
542                                 NFCSTATUS_INVALID_HCI_RESPONSE);
543         }
544     }
545     else
546     {
547         psHciContext->rx_index = HCP_HEADER_LEN;
548 
549         /* command NXP_FELICA_CMD: so give Felica data to the upper layer */
550         HCI_PRINT_BUFFER("Felica Bytes received", pResponse, length);
551     }
552 
553     return status;
554 }
555 
556 
557 static
558 NFCSTATUS
phHciNfc_Recv_Felica_Response(void * psContext,void * pHwRef,uint8_t * pResponse,uint8_t length)559 phHciNfc_Recv_Felica_Response(
560                                void                *psContext,
561                                void                *pHwRef,
562                                uint8_t             *pResponse,
563 #ifdef ONE_BYTE_LEN
564                                uint8_t          length
565 #else
566                                uint16_t             length
567 #endif
568                                )
569 {
570     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
571     phHciNfc_sContext_t         *psHciContext =
572                                     (phHciNfc_sContext_t *)psContext ;
573 
574 
575     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
576         || (0 == length))
577     {
578         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
579     }
580     else if(NULL == psHciContext->p_felica_info)
581     {
582         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
583     }
584     else
585     {
586         phHciNfc_Felica_Info_t     *p_fel_info=NULL;
587         uint8_t                     prev_cmd = ANY_GET_PARAMETER;
588         p_fel_info = (phHciNfc_Felica_Info_t *)
589                         psHciContext->p_felica_info ;
590         if( NULL == p_fel_info->p_pipe_info)
591         {
592             status = PHNFCSTVAL(CID_NFC_HCI,
593                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
594         }
595         else
596         {
597             prev_cmd = p_fel_info->p_pipe_info->prev_msg ;
598             switch(prev_cmd)
599             {
600                 case ANY_GET_PARAMETER:
601                 {
602                     status = phHciNfc_Felica_InfoUpdate(psHciContext,
603                                         p_fel_info->p_pipe_info->reg_index,
604                                         &pResponse[HCP_HEADER_LEN],
605                                         (uint8_t)(length - HCP_HEADER_LEN));
606                     break;
607                 }
608                 case ANY_SET_PARAMETER:
609                 {
610                     HCI_PRINT("Felica Parameter Set \n");
611                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
612                                                                 UPDATE_SEQ);
613                     p_fel_info->next_seq = FELICA_SYSTEMCODE;
614                     break;
615                 }
616                 case ANY_OPEN_PIPE:
617                 {
618                     HCI_PRINT("Felica open pipe complete\n");
619                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
620                                                                 UPDATE_SEQ);
621                     p_fel_info->next_seq = FELICA_SYSTEMCODE;
622                     break;
623                 }
624                 case ANY_CLOSE_PIPE:
625                 {
626                     HCI_PRINT("Felica close pipe complete\n");
627                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
628                                                                 UPDATE_SEQ);
629                     break;
630                 }
631 
632                 case NXP_FELICA_RAW:
633                 case NXP_FELICA_CMD:
634                 case WR_XCHGDATA:
635                 {
636                     HCI_PRINT("Felica packet received \n");
637                     if (length >= HCP_HEADER_LEN)
638                     {
639                         phHciNfc_Append_HCPFrame(psHciContext->recv_buffer,
640                                                     0, pResponse, length);
641                         psHciContext->rx_total = length;
642                         status = phHciNfc_Recv_Felica_Packet(psHciContext,
643                                                     prev_cmd,
644                                                     &pResponse[HCP_HEADER_LEN],
645                                                     (length - HCP_HEADER_LEN));
646                     }
647                     else
648                     {
649                         status = PHNFCSTVAL(CID_NFC_HCI,
650                                             NFCSTATUS_INVALID_HCI_RESPONSE);
651                     }
652                     break;
653                 }
654                 case NXP_WRA_CONTINUE_ACTIVATION:
655                 case NXP_WR_ACTIVATE_ID:
656                 {
657                     HCI_PRINT("Felica continue activation or ");
658                     HCI_PRINT("reactivation completed \n");
659                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
660                                                     UPDATE_SEQ);
661                     break;
662                 }
663                 case NXP_WR_PRESCHECK:
664                 {
665                     HCI_PRINT("Presence check completed \n");
666                     break;
667                 }
668                 case NXP_WR_ACTIVATE_NEXT:
669                 {
670                     HCI_PRINT("Activate next completed \n");
671                     if (length > HCP_HEADER_LEN)
672                     {
673                         if (FEL_MULTIPLE_TAGS_FOUND == pResponse[HCP_HEADER_LEN])
674                         {
675                             p_fel_info->multiple_tgts_found =
676                                             FEL_MULTIPLE_TAGS_FOUND;
677                         }
678                         else
679                         {
680                             p_fel_info->multiple_tgts_found = FALSE;
681                         }
682                     }
683                     else
684                     {
685                         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
686                     }
687                     break;
688                 }
689                 case NXP_WR_DISPATCH_TO_UICC:
690                 {
691                     switch(length)
692                     {
693                         case HCP_HEADER_LEN:
694                         {
695                             /* Optional error code, if no error code field
696                                 in the response, then this command is
697                                 successfully completed */
698                             p_fel_info->uicc_activation =
699                                         UICC_CARD_ACTIVATION_SUCCESS;
700                             break;
701                         }
702                         case (HCP_HEADER_LEN + 1):
703                         {
704                             p_fel_info->uicc_activation =
705                                         pResponse[HCP_HEADER_LEN];
706                             break;
707                         } /* End of case (HCP_HEADER_LEN + index) */
708                         default:
709                         {
710                             status = PHNFCSTVAL(CID_NFC_HCI,
711                                                 NFCSTATUS_INVALID_HCI_RESPONSE);
712                             break;
713                         }
714                     }
715                     if (NFCSTATUS_SUCCESS == status)
716                     {
717                         status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
718                                                                     UPDATE_SEQ);
719                     }
720                     break;
721                 }
722                 default:
723                 {
724                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
725                     break;
726                 }
727             }
728             if( NFCSTATUS_SUCCESS == status )
729             {
730                 p_fel_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
731                 p_fel_info->current_seq = p_fel_info->next_seq;
732             }
733         }
734     }
735     return status;
736 }
737 
738 
739 static
740 NFCSTATUS
phHciNfc_Recv_Felica_Event(void * psContext,void * pHwRef,uint8_t * pEvent,uint8_t length)741 phHciNfc_Recv_Felica_Event(
742                             void               *psContext,
743                             void               *pHwRef,
744                             uint8_t            *pEvent,
745 #ifdef ONE_BYTE_LEN
746                             uint8_t             length
747 #else
748                             uint16_t            length
749 #endif
750                             )
751 {
752     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
753     phHciNfc_sContext_t         *psHciContext =
754                                 (phHciNfc_sContext_t *)psContext ;
755 
756     HCI_PRINT ("HCI : phHciNfc_Recv_Felica_Event called...\n");
757     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
758         || (0 == length))
759     {
760         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
761     }
762     else if((NULL == psHciContext->p_felica_info) ||
763         (HCI_FELICA_ENABLE !=
764         ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
765         enable_felica_gate))
766     {
767         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
768     }
769     else
770     {
771         phHciNfc_HCP_Packet_t       *p_packet = NULL;
772         phHciNfc_Felica_Info_t      *p_fel_info = NULL;
773         phHciNfc_HCP_Message_t      *message = NULL;
774         uint8_t                     instruction=0,
775                                     i = 0;
776 
777         p_fel_info = (phHciNfc_Felica_Info_t *)
778                                 psHciContext->p_felica_info ;
779         p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
780         message = &p_packet->msg.message;
781         /* Get the instruction bits from the Message Header */
782         instruction = (uint8_t) GET_BITS8( message->msg_header,
783                     HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
784 
785         HCI_DEBUG ("HCI : instruction : %02X\n", instruction);
786         HCI_DEBUG ("HCI : Multiple tag found : %02X\n", message->payload[i]);
787         if ((EVT_TARGET_DISCOVERED == instruction)
788             && ((FEL_MULTIPLE_TAGS_FOUND == message->payload[i] )
789             || (FEL_SINGLE_TAG_FOUND == message->payload[i]))
790             )
791         {
792             static phNfc_sCompletionInfo_t      pCompInfo;
793 
794             if (FEL_MULTIPLE_TAGS_FOUND == message->payload[i])
795             {
796                 p_fel_info->multiple_tgts_found = FEL_MULTIPLE_TAGS_FOUND;
797                 pCompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
798             }
799             else
800             {
801                 p_fel_info->multiple_tgts_found = FALSE;
802                 pCompInfo.status = NFCSTATUS_SUCCESS;
803             }
804 
805             HCI_DEBUG ("HCI : psHciContext->host_rf_type : %02X\n", psHciContext->host_rf_type);
806             HCI_DEBUG ("HCI : p_fel_info->felica_info.RemDevType : %02X\n", p_fel_info->felica_info.RemDevType);
807             HCI_DEBUG ("HCI : p_fel_info->current_seq : %02X\n", p_fel_info->current_seq);
808 
809             psHciContext->host_rf_type = phHal_eFelica_PCD;
810             p_fel_info->felica_info.RemDevType = phHal_eFelica_PICC;
811             p_fel_info->current_seq = FELICA_SYSTEMCODE;
812 
813             /* Notify to the HCI Generic layer To Update the FSM */
814             phHciNfc_Notify_Event(psHciContext, pHwRef,
815                                 NFC_NOTIFY_TARGET_DISCOVERED,
816                                 &pCompInfo);
817 
818         }
819         else
820         {
821             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
822         }
823     }
824     HCI_PRINT ("HCI : phHciNfc_Recv_Felica_Event end\n");
825     return status;
826 }
827 
828 
829 NFCSTATUS
phHciNfc_Felica_Request_Mode(phHciNfc_sContext_t * psHciContext,void * pHwRef)830 phHciNfc_Felica_Request_Mode(
831                               phHciNfc_sContext_t   *psHciContext,
832                               void                  *pHwRef)
833 {
834     NFCSTATUS           status = NFCSTATUS_SUCCESS;
835     static uint8_t      pres_chk_data[6] = {0};
836 
837     if( (NULL == psHciContext) || (NULL == pHwRef) )
838     {
839         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
840     }
841     else
842     {
843         phHciNfc_Felica_Info_t          *ps_fel_info = NULL;
844         phHciNfc_Pipe_Info_t            *ps_pipe_info = NULL;
845         phHal_sFelicaInfo_t             *ps_rem_fel_info = NULL;
846 
847         ps_fel_info = (phHciNfc_Felica_Info_t *)
848                             psHciContext->p_felica_info ;
849         ps_pipe_info = ps_fel_info->p_pipe_info;
850 
851         if(NULL == ps_pipe_info )
852         {
853             status = PHNFCSTVAL(CID_NFC_HCI,
854                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
855         }
856         else
857         {
858             ps_rem_fel_info =
859                 &(ps_fel_info->felica_info.RemoteDevInfo.Felica_Info);
860 
861             pres_chk_data[0] = sizeof(pres_chk_data);
862             pres_chk_data[1] = 0x00; // Felica poll
863             pres_chk_data[2] = 0xFF;
864             pres_chk_data[3] = 0xFF;
865             pres_chk_data[4] = 0x01;
866             pres_chk_data[5] = 0x00;
867 
868             ps_pipe_info->param_info = pres_chk_data;
869             ps_pipe_info->param_length = sizeof(pres_chk_data);
870             status = phHciNfc_Send_Felica_Command(
871                                         psHciContext, pHwRef,
872                                         ps_pipe_info->pipe.pipe_id,
873                                         NXP_FELICA_RAW);
874         }
875     }
876 
877     return status;
878 }
879 
880 NFCSTATUS
phHciNfc_Send_Felica_Command(phHciNfc_sContext_t * psContext,void * pHwRef,uint8_t pipe_id,uint8_t cmd)881 phHciNfc_Send_Felica_Command(
882                               phHciNfc_sContext_t   *psContext,
883                               void                  *pHwRef,
884                               uint8_t               pipe_id,
885                               uint8_t               cmd
886                               )
887 {
888     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
889     phHciNfc_sContext_t         *psHciContext =
890                                 (phHciNfc_sContext_t *)psContext ;
891     if( (NULL == psHciContext) || (NULL == pHwRef) )
892     {
893         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
894     }
895     else if((NULL == psHciContext->p_felica_info) ||
896         (HCI_FELICA_ENABLE !=
897         ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
898         enable_felica_gate) ||
899         (HCI_UNKNOWN_PIPE_ID ==
900         ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
901         pipe_id) ||
902         (pipe_id !=
903         ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
904         pipe_id))
905     {
906         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
907     }
908     else
909     {
910         phHciNfc_Felica_Info_t     *p_fel_info=NULL;
911         phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
912         phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
913         phHciNfc_HCP_Message_t      *hcp_message = NULL;
914         uint8_t                     i = 0,
915                                     length = HCP_HEADER_LEN;
916 
917         p_fel_info = (phHciNfc_Felica_Info_t *)
918                             psHciContext->p_felica_info ;
919         p_pipe_info = p_fel_info->p_pipe_info;
920         if(NULL == p_pipe_info )
921         {
922             status = PHNFCSTVAL(CID_NFC_HCI,
923                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
924         }
925         else
926         {
927             psHciContext->tx_total = 0 ;
928             hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
929             /* Construct the HCP Frame */
930             phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
931                             (uint8_t) pipe_id, HCP_MSG_TYPE_COMMAND, cmd);
932             switch(cmd)
933             {
934                 case NXP_FELICA_RAW:
935                 {
936                     /*
937                     Buffer shall be updated with
938                     TO -              Time out (1 byte)
939                     Status -          b0 to b2 indicate valid bits (1 byte)
940                     Data  -           params received from this function
941                     */
942                     hcp_message = &(hcp_packet->msg.message);
943 
944                     /* Time out */
945                     hcp_message->payload[i++] = nxp_nfc_felica_timeout ;
946                     /* Status */
947                     hcp_message->payload[i++] = FELICA_STATUS;
948 
949                     phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload,
950                                         i, (uint8_t *)p_pipe_info->param_info,
951                                         p_pipe_info->param_length);
952                     length =(uint8_t)(length + i + p_pipe_info->param_length);
953                     break;
954                 }
955                 case NXP_FELICA_CMD:
956                 {
957                     /*
958                     Buffer shall be updated with
959                     Cmd -               Authentication A/B, read/write
960                     (1 byte)
961                     Data  -             params received from this function
962                     */
963                     hcp_message = &(hcp_packet->msg.message);
964 
965                     /* Command */
966                     hcp_message->payload[i++] =
967                                  psHciContext->p_xchg_info->params.tag_info.cmd_type ;
968                     phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload,
969                                         i, (uint8_t *)p_pipe_info->param_info,
970                                         p_pipe_info->param_length);
971                     length =(uint8_t)(length + i + p_pipe_info->param_length);
972                     break;
973                 }
974                 default:
975                 {
976                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_COMMAND);
977                     break;
978                 }
979             }
980             if (NFCSTATUS_SUCCESS == status)
981             {
982                 p_pipe_info->sent_msg_type = (uint8_t)HCP_MSG_TYPE_COMMAND;
983                 p_pipe_info->prev_msg = cmd;
984                 psHciContext->tx_total = length;
985                 psHciContext->response_pending = TRUE;
986 
987                 /* Send the Constructed HCP packet to the lower layer */
988                 status = phHciNfc_Send_HCP( psHciContext, pHwRef);
989                 p_pipe_info->prev_status = status;
990             }
991         }
992     }
993     return status;
994 }
995 
996 #endif /* #if defined(TYPE_FELICA) */
997