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 
81 typedef 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 */
94 typedef 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 
108 static
109 NFCSTATUS
110 phHciNfc_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 
141 static
142 NFCSTATUS
143 phHciNfc_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 
154 static
155 NFCSTATUS
156 phHciNfc_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 
170 NFCSTATUS
phHciNfc_PollLoop_Get_PipeID(phHciNfc_sContext_t * psHciContext,uint8_t * ppipe_id)171 phHciNfc_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 
195 NFCSTATUS
phHciNfc_PollLoop_Init_Resources(phHciNfc_sContext_t * psHciContext)196 phHciNfc_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  */
235 NFCSTATUS
phHciNfc_PollLoop_Initialise(phHciNfc_sContext_t * psHciContext,void * pHwRef)236 phHciNfc_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 
281 NFCSTATUS
phHciNfc_PollLoop_Release(phHciNfc_sContext_t * psHciContext,void * pHwRef)282 phHciNfc_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 
332 NFCSTATUS
phHciNfc_PollLoop_Cfg(void * psHciHandle,void * pHwRef,uint8_t cfg_type,void * pcfg_info)333 phHciNfc_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 */
544 NFCSTATUS
phHciNfc_PollLoop_Update_PipeInfo(phHciNfc_sContext_t * psHciContext,uint8_t pipeID,phHciNfc_Pipe_Info_t * pPipeInfo)545 phHciNfc_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 
581 static
582 NFCSTATUS
phHciNfc_Recv_PollLoop_Response(void * psContext,void * pHwRef,uint8_t * pResponse,uint8_t length)583 phHciNfc_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 
663 static
664 NFCSTATUS
phHciNfc_Recv_PollLoop_Event(void * psContext,void * pHwRef,uint8_t * pEvent,uint8_t length)665 phHciNfc_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 
753 static
754 NFCSTATUS
phHciNfc_PollLoop_InfoUpdate(phHciNfc_sContext_t * psHciContext,uint8_t index,uint8_t * reg_value,uint8_t reg_length)755 phHciNfc_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