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_PollingLoop.c                                               *
22* \brief HCI polling loop Management Routines.                                *
23*                                                                             *
24*                                                                             *
25* Project: NFC-FRI-1.1                                                        *
26*                                                                             *
27* $Date: Mon Mar 29 17:34:48 2010 $                                           *
28* $Author: ing04880 $                                                         *
29* $Revision: 1.35 $                                                           *
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 <phNfcHalTypes.h>
40#include <phHciNfc_Pipe.h>
41#include <phHciNfc_PollingLoop.h>
42#include <phOsalNfc.h>
43/*
44****************************** Macro Definitions *******************************
45*/
46
47/* Registry index to which command has to be sent */
48#define PL_PAUSE_INDEX                  0x08U
49#define PL_EMULATION_INDEX              0x07U
50#define PL_RD_PHASES_INDEX              0x06U
51#define PL_DISABLE_TARGET_INDEX         0x09U
52
53/* Events */
54#define NXP_EVT_CLK_ACK                 0x01U
55#define NXP_EVT_CLK_REQUEST             0x02U
56#define NXP_EVT_ACTIVATE_RDPHASES       0x03U
57#define NXP_EVT_DEACTIVATE_RDPHASES     0x04U
58
59/* Command length */
60#define PL_DURATION_LENGTH              0x02U
61#define PL_BYTE_LEN_1                   0x01U
62
63#define PL_BIT_FIELD_ENABLED            0x01U
64
65
66#define PL_EMULATION_FACTOR             0x0AU
67/* Default duration  (100 ms * 1000) micro seconds,
68    always duration shall be less then 3145680
69    micro seconds */
70#define PL_DEFAULT_DURATION             100000U
71/* Maximum duration */
72#define PL_MAX_DURATION                 3145000U
73#define PL_DURATION_MIN_VALUE           48U
74#define PL_DURATION_CALC(duration)      \
75                    ((uint16_t)((duration)/PL_DURATION_MIN_VALUE))
76
77/*
78*************************** Structure and Enumeration ***************************
79*/
80
81typedef enum phHciNfc_Poll_Seq{
82    PL_PIPE_OPEN                    =   0x00U,
83    PL_PIPE_CLOSE,
84    PL_SET_DURATION,
85    PL_GET_DURATION,
86    PL_GET_RD_PHASES,
87    PL_SET_RD_PHASES,
88    PL_GET_DISABLE_TARGET,
89    PL_SET_DISABLE_TARGET,
90    PL_END_SEQUENCE
91} phHciNfc_Poll_Seq_t;
92
93/* Information structure for the polling loop Gate */
94typedef struct phHciNfc_PollLoop_Info{
95    /* Current running Sequence of the polling loop Management */
96    phHciNfc_Poll_Seq_t             current_seq;
97    /* Next running Sequence of the polling loop Management */
98    phHciNfc_Poll_Seq_t             next_seq;
99    /* Pointer to the polling loop pipe information */
100    phHciNfc_Pipe_Info_t            *p_pipe_info;
101    uint8_t                         pipe_id;
102} phHciNfc_PollLoop_Info_t;
103
104/*
105*************************** Static Function Declaration **************************
106*/
107
108static
109NFCSTATUS
110phHciNfc_PollLoop_InfoUpdate(
111                                phHciNfc_sContext_t     *psHciContext,
112                                uint8_t                 index,
113                                uint8_t                 *reg_value,
114                                uint8_t                 reg_length
115                         );
116/**
117 * \ingroup grp_hci_nfc
118 *
119 *  The phHciNfc_Recv_Pl_Response function interprets the received polling loop
120 *  response from the Host Controller Gate.
121 *
122 *  \param[in]  psHciContext            psHciContext is the pointer to HCI Layer
123 *                                      context Structure.
124 *  \param[in]  pHwRef                  pHwRef is the Information of
125 *                                      the Device Interface Link .
126 *  \param[in,out]  pResponse           Response received from the Host Cotroller
127 *                                      polling loop gate.
128 *  \param[in]  length                  length contains the length of the
129 *                                      response received from the Host Controller.
130 *
131 *  \retval NFCSTATUS_PENDING           Polling loop gate Response to be received
132 *                                      is pending.
133 *  \retval NFCSTATUS_SUCCESS           Polling loop gate Response received
134 *                                      Successfully.
135 *  \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
136 *                                      could not be interpreted properly.
137 *  \retval Other errors                Errors related to the other layers
138 *
139 */
140
141static
142NFCSTATUS
143phHciNfc_Recv_PollLoop_Response(
144                        void                *psContext,
145                        void                *pHwRef,
146                        uint8_t             *pResponse,
147#ifdef ONE_BYTE_LEN
148                        uint8_t            length
149#else
150                        uint16_t           length
151#endif
152                       );
153
154static
155NFCSTATUS
156phHciNfc_Recv_PollLoop_Event(
157                             void               *psContext,
158                             void               *pHwRef,
159                             uint8_t            *pEvent,
160#ifdef ONE_BYTE_LEN
161                             uint8_t            length
162#else
163                             uint16_t           length
164#endif
165                       );
166/*
167*************************** Function Definitions ***************************
168*/
169
170NFCSTATUS
171phHciNfc_PollLoop_Get_PipeID(
172                                phHciNfc_sContext_t     *psHciContext,
173                                uint8_t                 *ppipe_id
174                           )
175{
176    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
177
178    if( (NULL != psHciContext)
179        && ( NULL != ppipe_id )
180        && ( NULL != psHciContext->p_poll_loop_info )
181      )
182    {
183        phHciNfc_PollLoop_Info_t        *p_poll_info=NULL;
184        p_poll_info = (phHciNfc_PollLoop_Info_t *)
185                            psHciContext->p_poll_loop_info ;
186        *ppipe_id =  p_poll_info->pipe_id  ;
187    }
188    else
189    {
190        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
191    }
192    return status;
193}
194
195NFCSTATUS
196phHciNfc_PollLoop_Init_Resources(
197                                phHciNfc_sContext_t     *psHciContext
198                         )
199{
200    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
201    phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
202    if( NULL == psHciContext )
203    {
204        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
205    }
206    else
207    {
208        if(
209            ( NULL == psHciContext->p_poll_loop_info )
210            && (phHciNfc_Allocate_Resource((void **)(&p_poll_info),
211            sizeof(phHciNfc_PollLoop_Info_t))== NFCSTATUS_SUCCESS)
212          )
213        {
214            psHciContext->p_poll_loop_info = p_poll_info;
215            p_poll_info->current_seq = PL_PIPE_OPEN;
216            p_poll_info->next_seq = PL_PIPE_CLOSE;
217            p_poll_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
218        }
219        else
220        {
221            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
222        }
223
224    }
225    return status;
226}
227
228/*!
229 * \brief Initialisation of polling loop Gate and Establish the Session .
230 *
231 * This function initialses the polling loop Gates and
232 * all the required pipes and sets the Session ID
233 *
234 */
235NFCSTATUS
236phHciNfc_PollLoop_Initialise(
237                                phHciNfc_sContext_t     *psHciContext,
238                                void                    *pHwRef
239                         )
240{
241    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
242
243    if( NULL == psHciContext )
244    {
245        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
246    }
247    else
248    {
249        if( NULL == psHciContext->p_poll_loop_info )
250        {
251            status = PHNFCSTVAL(CID_NFC_HCI,
252                        NFCSTATUS_INVALID_HCI_INFORMATION);
253        }
254        else
255        {
256            phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
257            phHciNfc_Pipe_Info_t        *p_pipe_info = NULL;
258            p_poll_info = (phHciNfc_PollLoop_Info_t *)
259                                psHciContext->p_poll_loop_info ;
260            p_pipe_info = p_poll_info->p_pipe_info;
261            if(NULL == p_pipe_info )
262            {
263                status = PHNFCSTVAL(CID_NFC_HCI,
264                                NFCSTATUS_INVALID_HCI_SEQUENCE);
265            }
266            else
267            {
268                HCI_PRINT("Polling loop open pipe in progress ...\n");
269                status = phHciNfc_Open_Pipe( psHciContext,
270                                            pHwRef, p_pipe_info );
271                if(NFCSTATUS_SUCCESS == status)
272                {
273                    p_poll_info->next_seq = PL_PIPE_CLOSE;
274                }
275            }
276        }
277    }
278    return status;
279}
280
281NFCSTATUS
282phHciNfc_PollLoop_Release(
283                                phHciNfc_sContext_t     *psHciContext,
284                                void                    *pHwRef
285                     )
286{
287    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
288    if( (NULL == psHciContext) || (NULL == pHwRef) )
289    {
290      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
291    }
292    else
293    {
294        if( NULL != psHciContext->p_poll_loop_info )
295        {
296            phHciNfc_PollLoop_Info_t            *p_poll_info=NULL;
297            p_poll_info = (phHciNfc_PollLoop_Info_t *)
298                                psHciContext->p_poll_loop_info ;
299            if (PL_PIPE_CLOSE == p_poll_info->current_seq)
300            {
301                phHciNfc_Pipe_Info_t            *p_pipe_info = NULL;
302                p_pipe_info = p_poll_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_PRINT("Polling loop close pipe in progress ...\n");
311                    status = phHciNfc_Close_Pipe( psHciContext,
312                                                pHwRef, p_pipe_info );
313                    if(status == NFCSTATUS_SUCCESS)
314                    {
315                        p_poll_info->next_seq = PL_PIPE_OPEN;
316                    }
317                }
318            }
319            else
320            {
321                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE);
322            } /* End of if (PL_PIPE_CLOSE == p_pl_info->cur_seq) */
323        }
324        else
325        {
326            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
327        } /* End of if( NULL != psHciContext->p_poll_loop_info ) */
328    } /* End of if( (NULL == psHciContext) || (NULL == pHwRef) ) */
329    return status;
330}
331
332NFCSTATUS
333phHciNfc_PollLoop_Cfg (
334                        void                *psHciHandle,
335                        void                *pHwRef,
336                        uint8_t             cfg_type,
337                        void                *pcfg_info
338                     )
339{
340    NFCSTATUS               status = NFCSTATUS_SUCCESS;
341    phHciNfc_sContext_t     *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
342    uint8_t                 poll_cfg;
343    static uint16_t         pl_duration = 0;
344
345    /* To remove "warning (VS C4100) : unreferenced formal parameter" */
346    PHNFC_UNUSED_VARIABLE(pcfg_info);
347
348    if( (NULL == psHciContext)
349        || (NULL == pHwRef)
350      )
351    {
352      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
353    }
354    else if(NULL == psHciContext->p_poll_loop_info)
355    {
356        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
357    }
358    else
359    {
360        phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
361        phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
362        phHal_sADD_Cfg_t            *p_poll_cfg = NULL;
363        uint8_t                     pipeid = 0;
364
365        p_poll_cfg = (phHal_sADD_Cfg_t*)psHciContext->p_config_params;
366        p_poll_info = (phHciNfc_PollLoop_Info_t *)
367                                psHciContext->p_poll_loop_info ;
368        p_pipe_info = p_poll_info->p_pipe_info;
369        if((NULL == p_pipe_info) || (NULL == p_poll_cfg))
370        {
371            status = PHNFCSTVAL(CID_NFC_HCI,
372                            NFCSTATUS_INVALID_HCI_SEQUENCE);
373        }
374        else
375        {
376            switch(cfg_type)
377            {
378                case PL_DURATION:
379                {
380                    /*
381                        Data memory has to be copied to
382                        param_info and also depending on the
383                        CARD_EMULATION or PAUSE, change the
384                        p_pipe_info->reg_index
385                    */
386                    if(p_poll_cfg->Duration > PL_MAX_DURATION)
387                    {
388                        p_poll_cfg->Duration = PL_MAX_DURATION;
389                    }
390
391
392                    if (FALSE ==
393                        p_poll_cfg->PollDevInfo.PollCfgInfo.DisableCardEmulation)
394                    {
395                        p_poll_cfg->Duration = ((p_poll_cfg->Duration <
396                                                PL_DURATION_MIN_VALUE)?
397                                                (PL_DEFAULT_DURATION *
398                                                PL_EMULATION_FACTOR):
399                                                p_poll_cfg->Duration );
400                        p_pipe_info->reg_index = PL_EMULATION_INDEX;
401                    }
402                    else
403                    {
404                        p_poll_cfg->Duration = ((p_poll_cfg->Duration <
405                                                PL_DURATION_MIN_VALUE)?
406                                                PL_DEFAULT_DURATION :
407                                                p_poll_cfg->Duration);
408                        p_pipe_info->reg_index = PL_PAUSE_INDEX;
409                    }
410                    p_pipe_info->param_length = PL_DURATION_LENGTH;
411
412                    /* Calculate duration */
413                    pl_duration = (uint16_t)
414                                PL_DURATION_CALC(p_poll_cfg->Duration);
415
416                    /* Swap the 2 byte value */
417                    pl_duration = (uint16_t)((pl_duration << BYTE_SIZE) |
418                                ((uint8_t)(pl_duration >> BYTE_SIZE)));
419                    /* Copy the duration from poll config structure,
420                        provided by the upper layer */
421                    p_pipe_info->param_info = (void *)&(pl_duration);
422
423                    pipeid = p_poll_info->pipe_id ;
424                    if (PL_GET_DURATION == p_poll_info->current_seq)
425                    {
426                        status =
427                            phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
428                            pipeid, (uint8_t)ANY_GET_PARAMETER);
429                        if (NFCSTATUS_PENDING == status)
430                        {
431                            p_poll_info->next_seq = PL_PIPE_CLOSE;
432                            status = NFCSTATUS_SUCCESS;
433                        }
434                    }
435                    else
436                    {
437                        status =
438                            phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
439                                pipeid, (uint8_t)ANY_SET_PARAMETER);
440                        if(NFCSTATUS_PENDING == status )
441                        {
442#ifdef ENABLE_VERIFY_PARAM
443                            p_poll_info->next_seq = PL_GET_DURATION;
444#else
445                            status = NFCSTATUS_SUCCESS;
446#endif /* #ifdef ENABLE_VERIFY_PARAM */
447                        }
448                    }
449                    break;
450                }
451                case PL_RD_PHASES:
452                {
453                    poll_cfg = (uint8_t) p_poll_cfg->PollDevInfo.PollEnabled;
454                    p_pipe_info->param_length = PL_BYTE_LEN_1;
455                    p_pipe_info->reg_index = PL_RD_PHASES_INDEX;
456
457                    /* Data memory has to be copied to
458                        param_info */
459                    p_pipe_info->param_info = (void *)&(poll_cfg);
460                    pipeid = p_poll_info->pipe_id ;
461                    if (PL_GET_RD_PHASES == p_poll_info->current_seq)
462                    {
463                        status =
464                            phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
465                            pipeid, (uint8_t)ANY_GET_PARAMETER);
466                        if (NFCSTATUS_PENDING == status)
467                        {
468                            status = NFCSTATUS_SUCCESS;
469                        }
470                    }
471                    else
472                    {
473                        status =
474                            phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
475                                pipeid, (uint8_t)ANY_SET_PARAMETER);
476                        if(NFCSTATUS_PENDING == status )
477                        {
478#ifdef ENABLE_VERIFY_PARAM
479                            p_poll_info->next_seq = PL_GET_RD_PHASES;
480#else
481                            status = NFCSTATUS_SUCCESS;
482#endif /* #ifdef ENABLE_VERIFY_PARAM */
483                        }
484                    }
485                    break;
486                }
487                case PL_DISABLE_TARGET:
488                {
489                    if (NULL == pcfg_info)
490                    {
491                        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
492                    }
493                    else
494                    {
495                        /* poll_cfg = (uint8_t) p_poll_cfg->NfcIP_Tgt_Disable; */
496                        p_pipe_info->param_length = PL_BYTE_LEN_1;
497                        p_pipe_info->reg_index = PL_DISABLE_TARGET_INDEX;
498
499                        /* Data memory has to be copied to
500                        param_info */
501                        p_pipe_info->param_info = pcfg_info;
502                        pipeid = p_poll_info->pipe_id ;
503                        if (PL_GET_DISABLE_TARGET == p_poll_info->current_seq)
504                        {
505                            status =
506                                phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
507                                pipeid, (uint8_t)ANY_GET_PARAMETER);
508                            if (NFCSTATUS_PENDING == status)
509                            {
510                                status = NFCSTATUS_SUCCESS;
511                            }
512                        }
513                        else
514                        {
515                            status =
516                                phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
517                                pipeid, (uint8_t)ANY_SET_PARAMETER);
518                            if( NFCSTATUS_PENDING == status )
519                            {
520#ifdef ENABLE_VERIFY_PARAM
521                                /* p_poll_info->current_seq = PL_GET_DISABLE_TARGET; */
522                                p_poll_info->next_seq = PL_GET_DISABLE_TARGET;
523#else
524                                status = NFCSTATUS_SUCCESS;
525#endif /* #ifdef ENABLE_VERIFY_PARAM */
526                            }
527                        }
528                    }
529                    break;
530                }
531                default:
532                {
533                    status = PHNFCSTVAL(CID_NFC_HCI,
534                                    NFCSTATUS_INVALID_PARAMETER);
535                    break;
536                }
537            }
538        }
539    }
540    return status;
541}
542
543/* Function to assign pipe ID */
544NFCSTATUS
545phHciNfc_PollLoop_Update_PipeInfo(
546                                phHciNfc_sContext_t     *psHciContext,
547                                uint8_t                 pipeID,
548                                phHciNfc_Pipe_Info_t    *pPipeInfo
549                                )
550{
551    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
552
553    if( NULL == psHciContext )
554    {
555        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
556    }
557    else if ( NULL == psHciContext->p_poll_loop_info )
558    {
559        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
560    }
561    else
562    {
563        phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
564        p_poll_info = (phHciNfc_PollLoop_Info_t *)
565                                psHciContext->p_poll_loop_info ;
566        /* Update the pipe_id of the ID Mgmt Gate obtained from the HCI Response */
567        p_poll_info->pipe_id = pipeID;
568        p_poll_info->p_pipe_info = pPipeInfo;
569        if (NULL != pPipeInfo)
570        {
571            /* Update the Response Receive routine of the IDMgmt Gate */
572            pPipeInfo->recv_resp = &phHciNfc_Recv_PollLoop_Response;
573            /* Update the event Receive routine of the IDMgmt Gate */
574            pPipeInfo->recv_event = &phHciNfc_Recv_PollLoop_Event;
575        }
576    }
577
578    return status;
579}
580
581static
582NFCSTATUS
583phHciNfc_Recv_PollLoop_Response(
584                        void                *psContext,
585                        void                *pHwRef,
586                        uint8_t             *pResponse,
587#ifdef ONE_BYTE_LEN
588                        uint8_t            length
589#else
590                        uint16_t           length
591#endif
592                       )
593{
594    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
595    phHciNfc_sContext_t         *psHciContext =
596                                (phHciNfc_sContext_t *)psContext ;
597
598
599    if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
600        || (length == 0))
601    {
602      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
603    }
604    else if(  NULL == psHciContext->p_poll_loop_info )
605    {
606        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
607    }
608    else
609    {
610        phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
611        uint8_t                     prev_cmd = ANY_GET_PARAMETER;
612        p_poll_info = (phHciNfc_PollLoop_Info_t *)
613                            psHciContext->p_poll_loop_info ;
614        if( NULL == p_poll_info->p_pipe_info)
615        {
616            status = PHNFCSTVAL(CID_NFC_HCI,
617                        NFCSTATUS_INVALID_HCI_SEQUENCE);
618        }
619        else
620        {
621            prev_cmd = p_poll_info->p_pipe_info->prev_msg ;
622            switch(prev_cmd)
623            {
624                case ANY_SET_PARAMETER:
625                {
626                    HCI_PRINT("Polling loop Set Param complete\n");
627                    break;
628                }
629                case ANY_GET_PARAMETER:
630                {
631                    status = phHciNfc_PollLoop_InfoUpdate(psHciContext,
632                                p_poll_info->p_pipe_info->reg_index,
633                                &pResponse[HCP_HEADER_LEN],
634                                    (uint8_t)(length - HCP_HEADER_LEN));
635                    break;
636                }
637                case ANY_OPEN_PIPE:
638                {
639                    HCI_PRINT("Polling loop open pipe complete\n");
640                    break;
641                }
642                case ANY_CLOSE_PIPE:
643                {
644                    HCI_PRINT("Polling loop close pipe complete\n");
645                    break;
646                }
647                default:
648                {
649                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
650                    break;
651                }
652            }
653            if( NFCSTATUS_SUCCESS == status )
654            {
655                p_poll_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
656                p_poll_info->current_seq = p_poll_info->next_seq;
657            }
658        }
659    }
660    return status;
661}
662
663static
664NFCSTATUS
665phHciNfc_Recv_PollLoop_Event(
666                             void               *psContext,
667                             void               *pHwRef,
668                             uint8_t            *pEvent,
669#ifdef ONE_BYTE_LEN
670                             uint8_t            length
671#else
672                             uint16_t           length
673#endif
674                       )
675{
676    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
677    phHciNfc_sContext_t         *psHciContext =
678                                (phHciNfc_sContext_t *)psContext ;
679    if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
680        || (length <= HCP_HEADER_LEN))
681    {
682        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
683    }
684    else if(  NULL == psHciContext->p_poll_loop_info )
685    {
686        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
687    }
688    else
689    {
690        phHciNfc_HCP_Packet_t       *p_packet = NULL;
691        phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
692        phHciNfc_HCP_Message_t      *message = NULL;
693        static phHal_sEventInfo_t   event_info;
694        uint8_t                     instruction=0;
695
696        p_poll_info = (phHciNfc_PollLoop_Info_t *)
697                        psHciContext->p_poll_loop_info ;
698
699        PHNFC_UNUSED_VARIABLE(p_poll_info);
700        p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
701        message = &p_packet->msg.message;
702        /* Get the instruction bits from the Message Header */
703        instruction = (uint8_t) GET_BITS8( message->msg_header,
704            HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
705
706        switch(instruction)
707        {
708            case NXP_EVT_CLK_ACK:
709            {
710                break;
711            }
712            case NXP_EVT_CLK_REQUEST:
713            {
714                break;
715            }
716            case NXP_EVT_ACTIVATE_RDPHASES:
717            {
718                HCI_PRINT("Polling loop activate read phase complete\n");
719                event_info.eventHost = phHal_eHostController;
720                event_info.eventType = NFC_UICC_RDPHASES_ACTIVATE_REQ;
721                event_info.eventInfo.rd_phases = pEvent[HCP_HEADER_LEN];
722                ((phHal_sHwReference_t *)pHwRef)->uicc_rdr_active = TRUE;
723                phHciNfc_Notify_Event((void *)psHciContext,
724                                            pHwRef,
725                                            NFC_NOTIFY_EVENT,
726                                            &(event_info));
727                break;
728            }
729            case NXP_EVT_DEACTIVATE_RDPHASES:
730            {
731                HCI_PRINT("Polling loop deactivate read phase complete\n");
732                event_info.eventHost = phHal_eHostController;
733                event_info.eventType = NFC_UICC_RDPHASES_DEACTIVATE_REQ;
734                event_info.eventInfo.rd_phases = pEvent[HCP_HEADER_LEN];
735                ((phHal_sHwReference_t *)pHwRef)->uicc_rdr_active = FALSE;
736                phHciNfc_Notify_Event((void *)psHciContext,
737                                            pHwRef,
738                                            NFC_NOTIFY_EVENT,
739                                            &(event_info));
740                break;
741            }
742            default:
743            {
744                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
745                break;
746            }
747        }
748    }
749    return status;
750}
751
752
753static
754NFCSTATUS
755phHciNfc_PollLoop_InfoUpdate(
756                                phHciNfc_sContext_t     *psHciContext,
757                                uint8_t                 index,
758                                uint8_t                 *reg_value,
759                                uint8_t                 reg_length
760                          )
761{
762    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
763    phHciNfc_PollLoop_Info_t    *p_poll_info=NULL;
764    p_poll_info = (phHciNfc_PollLoop_Info_t *)
765                            (psHciContext->p_poll_loop_info );
766    /* To remove "warning (VS 4100) : unreferenced formal parameter" */
767    PHNFC_UNUSED_VARIABLE(reg_value);
768    PHNFC_UNUSED_VARIABLE(reg_length);
769    /* Variable was set but never used (ARM warning) */
770    PHNFC_UNUSED_VARIABLE(p_poll_info);
771    switch(index)
772    {
773        case PL_EMULATION_INDEX:
774        case PL_PAUSE_INDEX:
775        {
776            HCI_PRINT_BUFFER("\tPoll duration", reg_value, reg_length);
777            break;
778        }
779        case PL_RD_PHASES_INDEX:
780        {
781            HCI_PRINT_BUFFER("\tPoll read phase", reg_value, reg_length);
782            break;
783        }
784#if defined (CLK_REQUEST)
785        case PL_CLK_REQUEST_INDEX:
786        {
787            HCI_PRINT_BUFFER("\tPoll clock request", reg_value, reg_length);
788            break;
789        }
790#endif /* #if defined (CLK_REQUEST) */
791#if defined (INPUT_CLK)
792        case PL_INPUT_CLK_INDEX:
793        {
794            HCI_PRINT_BUFFER("\tPoll input clock", reg_value, reg_length);
795            break;
796        }
797#endif/* #if defined (INPUT_CLK) */
798        default:
799        {
800            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
801            break;
802        }
803    }
804    return status;
805}
806
807
808