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
63uint8_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*/
76static
77NFCSTATUS
78phHciNfc_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
89static
90NFCSTATUS
91phHciNfc_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
102static
103NFCSTATUS
104phHciNfc_Felica_InfoUpdate(
105                            phHciNfc_sContext_t     *psHciContext,
106                            uint8_t                 index,
107                            uint8_t                 *reg_value,
108                            uint8_t                 reg_length
109                            );
110
111static
112NFCSTATUS
113phHciNfc_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
127NFCSTATUS
128phHciNfc_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
152NFCSTATUS
153phHciNfc_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
185NFCSTATUS
186phHciNfc_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
220NFCSTATUS
221phHciNfc_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
270NFCSTATUS
271phHciNfc_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
401static
402NFCSTATUS
403phHciNfc_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
478static
479NFCSTATUS
480phHciNfc_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
557static
558NFCSTATUS
559phHciNfc_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
739static
740NFCSTATUS
741phHciNfc_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
829NFCSTATUS
830phHciNfc_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
880NFCSTATUS
881phHciNfc_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