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_RFReaderB.c                                                 *
22 * \brief HCI Reader B Management Routines.                                    *
23 *                                                                             *
24 *                                                                             *
25 * Project: NFC-FRI-1.1                                                        *
26 *                                                                             *
27 * $Date: Mon Aug 17 15:17:07 2009 $                                           *
28 * $Author: ing04880 $                                                         *
29 * $Revision: 1.7 $                                                           *
30 * $Aliases: NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,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_B)
44 #include <phHciNfc_RFReaderB.h>
45 /*
46 ****************************** Macro Definitions *******************************
47 */
48 
49 #define RDR_B_SINGLE_TAG_FOUND              0x00U
50 #define RDR_B_MULTIPLE_TAGS_FOUND           0x03U
51 /* Commands exposed to the upper layer */
52 #define NXP_WRA_CONTINUE_ACTIVATION         0x12U
53 
54 #define RDR_B_PUPI_INDEX                    0x03U
55 #define RDR_B_APP_DATA_INDEX                0x04U
56 #define RDR_B_AFI_INDEX                     0x02U
57 #define RDR_B_HIGHER_LAYER_RESP_INDEX       0x01U
58 #define RDR_B_HIGHER_LAYER_DATA_INDEX       0x05U
59 
60 
61 /*
62 *************************** Structure and Enumeration ***************************
63 */
64 
65 
66 /*
67 *************************** Static Function Declaration **************************
68 */
69 
70 static
71 NFCSTATUS
72 phHciNfc_Recv_ReaderB_Response(
73                                void                *psContext,
74                                void                *pHwRef,
75                                uint8_t             *pResponse,
76 #ifdef ONE_BYTE_LEN
77                                uint8_t             length
78 #else
79                                uint16_t            length
80 #endif
81                                );
82 
83 static
84 NFCSTATUS
85 phHciNfc_Recv_ReaderB_Event(
86                             void               *psContext,
87                             void               *pHwRef,
88                             uint8_t            *pEvent,
89 #ifdef ONE_BYTE_LEN
90                             uint8_t             length
91 #else
92                             uint16_t            length
93 #endif
94                             );
95 
96 static
97 NFCSTATUS
98 phHciNfc_ReaderB_InfoUpdate(
99                             phHciNfc_sContext_t     *psHciContext,
100                             uint8_t                 index,
101                             uint8_t                 *reg_value,
102                             uint8_t                 reg_length
103                             );
104 
105 static
106 NFCSTATUS
107 phHciNfc_Recv_Iso_B_Packet(
108                            phHciNfc_sContext_t  *psHciContext,
109                            uint8_t              *pResponse,
110 #ifdef ONE_BYTE_LEN
111                            uint8_t             length
112 #else
113                            uint16_t            length
114 #endif
115                            );
116 /*
117 *************************** Function Definitions ***************************
118 */
119 
120 NFCSTATUS
phHciNfc_ReaderB_Get_PipeID(phHciNfc_sContext_t * psHciContext,uint8_t * ppipe_id)121 phHciNfc_ReaderB_Get_PipeID(
122                             phHciNfc_sContext_t        *psHciContext,
123                             uint8_t                    *ppipe_id
124                             )
125 {
126     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
127 
128     if( (NULL != psHciContext)
129         && ( NULL != ppipe_id )
130         && ( NULL != psHciContext->p_reader_b_info )
131         )
132     {
133         phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
134         p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
135                             psHciContext->p_reader_b_info ;
136         *ppipe_id =  p_rdr_b_info->pipe_id  ;
137     }
138     else
139     {
140         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
141     }
142     return status;
143 }
144 
145 NFCSTATUS
phHciNfc_ReaderB_Init_Resources(phHciNfc_sContext_t * psHciContext)146 phHciNfc_ReaderB_Init_Resources(
147                                 phHciNfc_sContext_t     *psHciContext
148                                 )
149 {
150     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
151     phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
152     if( NULL == psHciContext )
153     {
154         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
155     }
156     else
157     {
158         if(
159             ( NULL == psHciContext->p_reader_b_info ) &&
160                 (phHciNfc_Allocate_Resource((void **)(&p_rdr_b_info),
161                 sizeof(phHciNfc_ReaderB_Info_t))== NFCSTATUS_SUCCESS)
162             )
163         {
164             psHciContext->p_reader_b_info = p_rdr_b_info;
165             p_rdr_b_info->current_seq = RDR_B_INVALID_SEQ;
166             p_rdr_b_info->next_seq = RDR_B_INVALID_SEQ;
167             p_rdr_b_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
168         }
169         else
170         {
171             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
172         }
173 
174     }
175     return status;
176 }
177 
178 NFCSTATUS
phHciNfc_ReaderB_Update_Info(phHciNfc_sContext_t * psHciContext,uint8_t infotype,void * rdr_b_info)179 phHciNfc_ReaderB_Update_Info(
180                              phHciNfc_sContext_t        *psHciContext,
181                              uint8_t                    infotype,
182                              void                       *rdr_b_info
183                              )
184 {
185     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
186 
187     if (NULL == psHciContext)
188     {
189         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
190     }
191     else if(NULL == psHciContext->p_reader_b_info)
192     {
193         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
194     }
195     else
196     {
197         phHciNfc_ReaderB_Info_t     *ps_rdr_b_info=NULL;
198         ps_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
199                         psHciContext->p_reader_b_info ;
200 
201         switch(infotype)
202         {
203             case HCI_READER_B_ENABLE:
204             {
205                 if(NULL != rdr_b_info)
206                 {
207                     ps_rdr_b_info->enable_rdr_b_gate =
208                                 *((uint8_t *)rdr_b_info);
209                 }
210                 break;
211             }
212             case HCI_READER_B_INFO_SEQ:
213             {
214                 ps_rdr_b_info->current_seq = RDR_B_PUPI;
215                 ps_rdr_b_info->next_seq = RDR_B_PUPI;
216                 break;
217             }
218             default:
219             {
220                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
221                 break;
222             }
223         }
224     }
225     return status;
226 }
227 
228 
229 NFCSTATUS
phHciNfc_ReaderB_Update_PipeInfo(phHciNfc_sContext_t * psHciContext,uint8_t pipeID,phHciNfc_Pipe_Info_t * pPipeInfo)230 phHciNfc_ReaderB_Update_PipeInfo(
231                                  phHciNfc_sContext_t     *psHciContext,
232                                  uint8_t                 pipeID,
233                                  phHciNfc_Pipe_Info_t    *pPipeInfo
234                                  )
235 {
236     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
237 
238     if( NULL == psHciContext )
239     {
240         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
241     }
242     else if(NULL == psHciContext->p_reader_b_info)
243     {
244         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
245     }
246     else
247     {
248         phHciNfc_ReaderB_Info_t *p_rdr_b_info=NULL;
249         p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
250                             psHciContext->p_reader_b_info ;
251         /* Update the pipe_id of the reader B Gate obtained from the HCI Response */
252         p_rdr_b_info->pipe_id = pipeID;
253         p_rdr_b_info->p_pipe_info = pPipeInfo;
254         /* Update the Response Receive routine of the reader B Gate */
255         pPipeInfo->recv_resp = &phHciNfc_Recv_ReaderB_Response;
256         /* Update the event Receive routine of the reader B Gate */
257         pPipeInfo->recv_event = &phHciNfc_Recv_ReaderB_Event;
258     }
259 
260     return status;
261 }
262 
263 NFCSTATUS
phHciNfc_ReaderB_Info_Sequence(void * psHciHandle,void * pHwRef)264 phHciNfc_ReaderB_Info_Sequence (
265                                 void             *psHciHandle,
266                                 void             *pHwRef
267                                 )
268 {
269     NFCSTATUS               status = NFCSTATUS_SUCCESS;
270     phHciNfc_sContext_t     *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
271     if( (NULL == psHciContext)
272         || (NULL == pHwRef)
273         )
274     {
275         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
276     }
277     else if((NULL == psHciContext->p_reader_b_info) ||
278         (HCI_READER_B_ENABLE !=
279         ((phHciNfc_ReaderB_Info_t *)(psHciContext->p_reader_b_info))->
280         enable_rdr_b_gate))
281     {
282         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
283     }
284     else
285     {
286         phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
287         phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
288         uint8_t                     pipeid = 0;
289 
290         p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
291                             psHciContext->p_reader_b_info ;
292         p_pipe_info = p_rdr_b_info->p_pipe_info;
293         if(NULL == p_pipe_info )
294         {
295             status = PHNFCSTVAL(CID_NFC_HCI,
296                 NFCSTATUS_INVALID_HCI_SEQUENCE);
297         }
298         else
299         {
300             switch(p_rdr_b_info->current_seq)
301             {
302                 case RDR_B_PUPI:
303                 {
304                     p_pipe_info->reg_index = RDR_B_PUPI_INDEX;
305                     pipeid = p_rdr_b_info->pipe_id ;
306                     /* Fill the data buffer and send the command to the
307                     device */
308                     status =
309                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
310                         pipeid, (uint8_t)ANY_GET_PARAMETER);
311                     if(NFCSTATUS_PENDING == status )
312                     {
313                         p_rdr_b_info->next_seq = RDR_B_APP_DATA;
314                     }
315                     break;
316                 }
317                 case RDR_B_APP_DATA:
318                 {
319                     p_pipe_info->reg_index = RDR_B_APP_DATA_INDEX;
320                     pipeid = p_rdr_b_info->pipe_id ;
321                     /* Fill the data buffer and send the command to the
322                     device */
323                     status =
324                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
325                         pipeid, (uint8_t)ANY_GET_PARAMETER);
326                     if(NFCSTATUS_PENDING == status )
327                     {
328                         p_rdr_b_info->next_seq = RDR_B_AFI;
329                     }
330                     break;
331                 }
332                 case RDR_B_AFI:
333                 {
334                     /* RW to the registry */
335                     p_pipe_info->reg_index = RDR_B_AFI_INDEX;
336                     pipeid = p_rdr_b_info->pipe_id ;
337                     /* Fill the data buffer and send the command to the
338                     device */
339                     status =
340                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
341                         pipeid, (uint8_t)ANY_GET_PARAMETER);
342                     if(NFCSTATUS_PENDING == status )
343                     {
344                         p_rdr_b_info->next_seq = RDR_B_HIGHER_LAYER_RESP;
345                     }
346                     break;
347                 }
348 
349                 case RDR_B_HIGHER_LAYER_RESP:
350                 {
351                     p_pipe_info->reg_index = RDR_B_HIGHER_LAYER_RESP_INDEX;
352                     pipeid = p_rdr_b_info->pipe_id ;
353                     /* Fill the data buffer and send the command to the
354                         device */
355                     status =
356                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
357                                     pipeid, (uint8_t)ANY_GET_PARAMETER);
358                     if(NFCSTATUS_PENDING == status )
359                     {
360                         p_rdr_b_info->next_seq = RDR_B_HIGHER_LAYER_DATA;
361                     }
362                     break;
363                 }
364 
365                 case RDR_B_HIGHER_LAYER_DATA:
366                 {
367                     /* RW to the registry */
368                     p_pipe_info->reg_index = RDR_B_HIGHER_LAYER_DATA_INDEX;
369                     pipeid = p_rdr_b_info->pipe_id ;
370                     /* Fill the data buffer and send the command to the
371                     device */
372                     status =
373                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
374                         pipeid, (uint8_t)ANY_GET_PARAMETER);
375                     if(NFCSTATUS_PENDING == status )
376                     {
377                         p_rdr_b_info->next_seq = RDR_B_END_SEQUENCE;
378                     }
379                     break;
380                 }
381                 case RDR_B_END_SEQUENCE:
382                 {
383                     phNfc_sCompletionInfo_t     CompInfo;
384                     if (RDR_B_MULTIPLE_TAGS_FOUND ==
385                         p_rdr_b_info->multiple_tgts_found)
386                     {
387                         CompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
388                     }
389                     else
390                     {
391                         CompInfo.status = NFCSTATUS_SUCCESS;
392                     }
393 
394                     CompInfo.info = &(p_rdr_b_info->reader_b_info);
395 
396                     p_rdr_b_info->reader_b_info.RemDevType = phHal_eISO14443_B_PICC;
397                     p_rdr_b_info->current_seq = RDR_B_PUPI;
398                     p_rdr_b_info->next_seq = RDR_B_PUPI;
399                     status = NFCSTATUS_SUCCESS;
400                     /* Notify to the upper layer */
401                     phHciNfc_Tag_Notify(psHciContext,
402                                         pHwRef,
403                                         NFC_NOTIFY_TARGET_DISCOVERED,
404                                         &CompInfo);
405                     break;
406                 }
407                 default:
408                 {
409                     status = PHNFCSTVAL(CID_NFC_HCI,
410                         NFCSTATUS_INVALID_HCI_RESPONSE);
411                     break;
412                 }
413             }
414         }
415     }
416     return status;
417 }
418 
419 static
420 NFCSTATUS
phHciNfc_Recv_ReaderB_Response(void * psContext,void * pHwRef,uint8_t * pResponse,uint8_t length)421 phHciNfc_Recv_ReaderB_Response(
422                                void                *psContext,
423                                void                *pHwRef,
424                                uint8_t             *pResponse,
425 #ifdef ONE_BYTE_LEN
426                                uint8_t              length
427 #else
428                                uint16_t             length
429 #endif
430                                )
431 {
432     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
433     phHciNfc_sContext_t         *psHciContext =
434                                 (phHciNfc_sContext_t *)psContext ;
435 
436     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
437         || (length == 0))
438     {
439         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
440     }
441     else if(NULL == psHciContext->p_reader_b_info)
442     {
443         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
444     }
445     else
446     {
447         phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
448         uint8_t                     prev_cmd = ANY_GET_PARAMETER;
449 
450         p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
451                                 psHciContext->p_reader_b_info ;
452         if( NULL == p_rdr_b_info->p_pipe_info)
453         {
454             status = PHNFCSTVAL(CID_NFC_HCI,
455                                 NFCSTATUS_INVALID_HCI_SEQUENCE);
456         }
457         else
458         {
459             prev_cmd = p_rdr_b_info->p_pipe_info->prev_msg ;
460             switch(prev_cmd)
461             {
462             case ANY_GET_PARAMETER:
463                 {
464                     status = phHciNfc_ReaderB_InfoUpdate(psHciContext,
465                                         p_rdr_b_info->p_pipe_info->reg_index,
466                                         &pResponse[HCP_HEADER_LEN],
467                                         (uint8_t)(length - HCP_HEADER_LEN));
468                     break;
469                 }
470                 case ANY_SET_PARAMETER:
471                 {
472                     HCI_PRINT("Reader B Parameter Set \n");
473                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
474                                                                 UPDATE_SEQ);
475                     p_rdr_b_info->next_seq = RDR_B_PUPI;
476                     break;
477                 }
478                 case ANY_OPEN_PIPE:
479                 {
480                     HCI_PRINT("Reader B open pipe complete\n");
481                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
482                                                                 UPDATE_SEQ);
483                     p_rdr_b_info->next_seq = RDR_B_PUPI;
484                     break;
485                 }
486                 case ANY_CLOSE_PIPE:
487                 {
488                     HCI_PRINT("Reader B close pipe complete\n");
489                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
490                                                                 UPDATE_SEQ);
491                     break;
492                 }
493                 case NXP_WRA_CONTINUE_ACTIVATION:
494                 case NXP_WR_ACTIVATE_ID:
495                 {
496                     HCI_PRINT("Reader B continue activation or ");
497                     HCI_PRINT("reactivation completed \n");
498                     status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
499                                                     UPDATE_SEQ);
500                     break;
501                 }
502                 case WR_XCHGDATA:
503                 {
504                     if (length >= HCP_HEADER_LEN)
505                     {
506                         uint8_t         i = 1;
507                         HCI_PRINT("ISO 14443-4B received \n");
508                         /* Copy buffer to the receive buffer */
509                         phHciNfc_Append_HCPFrame(psHciContext->recv_buffer,
510                                                 0, pResponse, length);
511                         psHciContext->rx_total = (length - i);
512                         status = phHciNfc_Recv_Iso_B_Packet(psHciContext,
513                                                     &pResponse[HCP_HEADER_LEN],
514                                                     (length - HCP_HEADER_LEN));
515                     }
516                     else
517                     {
518                         status = PHNFCSTVAL(CID_NFC_HCI,
519                                             NFCSTATUS_INVALID_HCI_RESPONSE);
520                     }
521                     break;
522                 }
523                 case NXP_WR_PRESCHECK:
524                 {
525                     HCI_PRINT("Presence check completed \n");
526                     break;
527                 }
528                 case NXP_WR_ACTIVATE_NEXT:
529                 {
530                     if (length > HCP_HEADER_LEN)
531                     {
532                         if (RDR_B_MULTIPLE_TAGS_FOUND == pResponse[HCP_HEADER_LEN])
533                         {
534                             p_rdr_b_info->multiple_tgts_found =
535                                 RDR_B_MULTIPLE_TAGS_FOUND;
536                         }
537                         else
538                         {
539                             p_rdr_b_info->multiple_tgts_found = FALSE;
540                         }
541                         HCI_PRINT("Activate next completed \n");
542                     }
543                     else
544                     {
545                         status = PHNFCSTVAL(CID_NFC_HCI,
546                                             NFCSTATUS_INVALID_HCI_RESPONSE);
547                     }
548                     break;
549                 }
550                 case NXP_WR_DISPATCH_TO_UICC:
551                 {
552                     switch(length)
553                     {
554                         case HCP_HEADER_LEN:
555                         {
556                             /* Error code field is optional, if no error
557                                 code field in the response, then the command
558                                 is successfully completed */
559                             p_rdr_b_info->uicc_activation =
560                                         UICC_CARD_ACTIVATION_SUCCESS;
561                             break;
562                         }
563                         case (HCP_HEADER_LEN + 1):
564                         {
565                             p_rdr_b_info->uicc_activation =
566                                         pResponse[HCP_HEADER_LEN];
567                             break;
568                         } /* End of case (HCP_HEADER_LEN + index) */
569                         default:
570                         {
571                             status = PHNFCSTVAL(CID_NFC_HCI,
572                                                 NFCSTATUS_INVALID_HCI_RESPONSE);
573                             break;
574                         }
575                     } /* End of switch(length) */
576                     if (NFCSTATUS_SUCCESS == status)
577                     {
578                         status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext,
579                                                                     UPDATE_SEQ);
580                     }
581                     break;
582                 }
583                 default:
584                 {
585                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
586                     break;
587                 }
588             }
589             if( NFCSTATUS_SUCCESS == status )
590             {
591                 p_rdr_b_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
592                 p_rdr_b_info->current_seq = p_rdr_b_info->next_seq;
593             }
594         }
595     }
596     return status;
597 }
598 
599 
600 static
601 NFCSTATUS
phHciNfc_Recv_ReaderB_Event(void * psContext,void * pHwRef,uint8_t * pEvent,uint8_t length)602 phHciNfc_Recv_ReaderB_Event(
603                             void               *psContext,
604                             void               *pHwRef,
605                             uint8_t            *pEvent,
606 #ifdef ONE_BYTE_LEN
607                             uint8_t             length
608 #else
609                             uint16_t            length
610 #endif
611                             )
612 {
613     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
614     phHciNfc_sContext_t         *psHciContext =
615                                 (phHciNfc_sContext_t *)psContext ;
616     if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
617         || (length == 0))
618     {
619         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
620     }
621     else if((NULL == psHciContext->p_reader_b_info) ||
622         (HCI_READER_B_ENABLE !=
623         ((phHciNfc_ReaderB_Info_t *)(psHciContext->p_reader_b_info))->
624         enable_rdr_b_gate))
625     {
626         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
627     }
628     else
629     {
630         phHciNfc_HCP_Packet_t       *p_packet = NULL;
631         phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
632         phHciNfc_HCP_Message_t      *message = NULL;
633         uint8_t                     instruction=0,
634                                     i = 0;
635 
636         p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
637                                     psHciContext->p_reader_b_info ;
638         p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
639         message = &p_packet->msg.message;
640         /* Get the instruction bits from the Message Header */
641         instruction = (uint8_t) GET_BITS8( message->msg_header,
642                         HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
643 
644         if ((EVT_TARGET_DISCOVERED == instruction)
645             && ((RDR_B_MULTIPLE_TAGS_FOUND == message->payload[i] )
646             || (RDR_B_SINGLE_TAG_FOUND == message->payload[i]))
647             )
648         {
649             phNfc_sCompletionInfo_t pCompInfo;
650 
651             if (RDR_B_MULTIPLE_TAGS_FOUND == message->payload[i])
652             {
653                 p_rdr_b_info->multiple_tgts_found = RDR_B_MULTIPLE_TAGS_FOUND;
654                 pCompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
655             }
656             else
657             {
658                 p_rdr_b_info->multiple_tgts_found = FALSE;
659                 pCompInfo.status = NFCSTATUS_SUCCESS;
660             }
661 
662             psHciContext->host_rf_type = phHal_eISO14443_B_PCD;
663             p_rdr_b_info->reader_b_info.RemDevType = phHal_eISO14443_B_PICC;
664             p_rdr_b_info->current_seq = RDR_B_PUPI;
665 
666             /* Notify to the HCI Generic layer To Update the FSM */
667             phHciNfc_Notify_Event(psHciContext, pHwRef,
668                                     NFC_NOTIFY_TARGET_DISCOVERED,
669                                     &pCompInfo);
670 
671         }
672         else
673         {
674             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
675         }
676     }
677     return status;
678 }
679 
680 static
681 NFCSTATUS
phHciNfc_ReaderB_InfoUpdate(phHciNfc_sContext_t * psHciContext,uint8_t index,uint8_t * reg_value,uint8_t reg_length)682 phHciNfc_ReaderB_InfoUpdate(
683                             phHciNfc_sContext_t     *psHciContext,
684                             uint8_t                 index,
685                             uint8_t                 *reg_value,
686                             uint8_t                 reg_length
687                             )
688 {
689     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
690     phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
691     phHal_sIso14443BInfo_t      *p_tag_b_info = NULL;
692 
693     p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
694                     (psHciContext->p_reader_b_info );
695     p_tag_b_info = &(p_rdr_b_info->reader_b_info.RemoteDevInfo.Iso14443B_Info);
696 
697     switch(index)
698     {
699         case RDR_B_PUPI_INDEX:
700         {
701             HCI_PRINT_BUFFER("\tReader B PUPI", reg_value, reg_length);
702             /* Update PUPI buffer and length in the remote device info,
703                 PUPI length is 4 bytes */
704             if(PHHAL_PUPI_LENGTH == reg_length)
705             {
706                 (void)memcpy((void *)p_tag_b_info->AtqB.AtqResInfo.Pupi,
707                             (void *)reg_value, reg_length);
708             }
709             else
710             {
711                 status = PHNFCSTVAL(CID_NFC_HCI,
712                                     NFCSTATUS_INVALID_HCI_RESPONSE);
713             }
714             break;
715         }
716         case RDR_B_APP_DATA_INDEX:
717         {
718             HCI_PRINT_BUFFER("\tReader B Application data", reg_value, reg_length);
719             /* Update application data buffer and length, 3 bytes,
720                 this includes CRC_B and number of application
721              */
722             if(PHHAL_APP_DATA_B_LENGTH == reg_length)
723             {
724                 (void)memcpy((void *)p_tag_b_info->AtqB.AtqResInfo.AppData,
725                             (void *)reg_value, reg_length);
726             }
727             else
728             {
729                 status = PHNFCSTVAL(CID_NFC_HCI,
730                                     NFCSTATUS_INVALID_HCI_RESPONSE);
731             }
732             break;
733         }
734         case RDR_B_AFI_INDEX:
735         {
736             HCI_PRINT_BUFFER("\tReader B AFI", reg_value, reg_length);
737             /* Update AFI byte, Only one byte */
738             if(sizeof(*reg_value) == reg_length)
739             {
740                 p_tag_b_info->Afi = *reg_value;
741             }
742             else
743             {
744                 status = PHNFCSTVAL(CID_NFC_HCI,
745                                     NFCSTATUS_INVALID_HCI_RESPONSE);
746             }
747             break;
748         }
749 
750         case RDR_B_HIGHER_LAYER_RESP_INDEX:
751         {
752             HCI_PRINT_BUFFER("\tReader B higher layer response", reg_value, reg_length);
753             /* Update higher layer response buffer and length */
754             if (reg_length <= PHHAL_MAX_ATR_LENGTH)
755             {
756                 (void)memcpy((void *)p_tag_b_info->HiLayerResp,
757                                 (void *)reg_value, reg_length);
758             }
759             else
760             {
761                 status = PHNFCSTVAL(CID_NFC_HCI,
762                                     NFCSTATUS_INVALID_HCI_RESPONSE);
763             }
764             break;
765         }
766 
767         case RDR_B_HIGHER_LAYER_DATA_INDEX:
768         {
769             HCI_PRINT_BUFFER("\tReader B higher layer data", reg_value, reg_length);
770             /* Update higher layer data buffer and length */
771             break;
772         }
773         default:
774         {
775             status = PHNFCSTVAL(CID_NFC_HCI,
776                                 NFCSTATUS_INVALID_HCI_RESPONSE);
777             break;
778         }
779     }
780     return status;
781 }
782 
783 
784 static
785 NFCSTATUS
phHciNfc_Recv_Iso_B_Packet(phHciNfc_sContext_t * psHciContext,uint8_t * pResponse,uint8_t length)786 phHciNfc_Recv_Iso_B_Packet(
787                            phHciNfc_sContext_t  *psHciContext,
788                            uint8_t              *pResponse,
789 #ifdef ONE_BYTE_LEN
790                            uint8_t             length
791 #else
792                            uint16_t            length
793 #endif
794                            )
795 {
796     NFCSTATUS       status = NFCSTATUS_SUCCESS;
797     uint8_t         i = 1;
798 
799     psHciContext->rx_index = HCP_HEADER_LEN;
800     /* command WR_XCHG_DATA: so give ISO 14443-4B data to the upper layer */
801     HCI_PRINT_BUFFER("ISO 14443-4B Bytes received", pResponse, length);
802     if(FALSE != pResponse[(length - i)])
803     {
804         status = PHNFCSTVAL(CID_NFC_HCI,
805                             NFCSTATUS_RF_ERROR);
806     }
807     return status;
808 }
809 
810 
811 NFCSTATUS
phHciNfc_ReaderB_Set_AFI(void * psContext,void * pHwRef,uint8_t afi_value)812 phHciNfc_ReaderB_Set_AFI(
813                         void         *psContext,
814                         void         *pHwRef,
815                         uint8_t      afi_value
816                         )
817 {
818     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
819     phHciNfc_sContext_t         *psHciContext =
820                                 (phHciNfc_sContext_t *)psContext ;
821     if( (NULL == psHciContext) || (NULL == pHwRef))
822     {
823         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
824     }
825     else if((NULL == psHciContext->p_reader_b_info) ||
826         (HCI_READER_B_ENABLE !=
827         ((phHciNfc_ReaderB_Info_t *)(psHciContext->p_reader_b_info))->
828         enable_rdr_b_gate))
829     {
830         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
831     }
832     else
833     {
834         phHciNfc_ReaderB_Info_t     *ps_rdr_b_info=NULL;
835         phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
836         uint8_t                     pipeid = 0;
837 
838         ps_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
839                         psHciContext->p_reader_b_info ;
840         p_pipe_info = ps_rdr_b_info->p_pipe_info;
841         if(NULL == p_pipe_info )
842         {
843             status = PHNFCSTVAL(CID_NFC_HCI,
844                 NFCSTATUS_INVALID_HCI_SEQUENCE);
845         }
846         else
847         {
848             pipeid = ps_rdr_b_info->pipe_id ;
849             p_pipe_info->reg_index = RDR_B_AFI_INDEX;
850 
851             p_pipe_info->param_info = &afi_value;
852             p_pipe_info->param_length = sizeof(uint8_t);
853             /* Fill the data buffer and send the command to the
854             device */
855             status =
856                 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
857                                 pipeid, (uint8_t)ANY_SET_PARAMETER);
858         }
859     }
860     return status;
861 }
862 
863 NFCSTATUS
phHciNfc_ReaderB_Set_LayerData(void * psContext,void * pHwRef,phNfc_sData_t * layer_data_info)864 phHciNfc_ReaderB_Set_LayerData(
865                         void            *psContext,
866                         void            *pHwRef,
867                         phNfc_sData_t   *layer_data_info
868                         )
869 {
870     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
871     phHciNfc_sContext_t         *psHciContext =
872                                 (phHciNfc_sContext_t *)psContext ;
873 
874     if( (NULL == psHciContext) || (NULL == pHwRef) ||
875         (NULL == layer_data_info) || (NULL == layer_data_info->buffer)
876         || (0 == layer_data_info->length))
877     {
878         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
879     }
880     else if((NULL == psHciContext->p_reader_b_info) ||
881         (HCI_READER_B_ENABLE !=
882         ((phHciNfc_ReaderB_Info_t *)(psHciContext->p_reader_b_info))->
883         enable_rdr_b_gate))
884     {
885         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
886     }
887     else
888     {
889         phHciNfc_ReaderB_Info_t     *ps_rdr_b_info=NULL;
890         phHciNfc_Pipe_Info_t        *p_pipe_info=NULL;
891         uint8_t                     pipeid = 0;
892 
893         ps_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
894                         psHciContext->p_reader_b_info ;
895         p_pipe_info = ps_rdr_b_info->p_pipe_info;
896         if(NULL == p_pipe_info )
897         {
898             status = PHNFCSTVAL(CID_NFC_HCI,
899                 NFCSTATUS_INVALID_HCI_SEQUENCE);
900         }
901         else
902         {
903             p_pipe_info->reg_index = RDR_B_HIGHER_LAYER_DATA_INDEX;
904             pipeid = ps_rdr_b_info->pipe_id ;
905             p_pipe_info->param_info = (void *)layer_data_info->buffer;
906             p_pipe_info->param_length = (uint8_t)
907                                         layer_data_info->length;
908             /* Fill the data buffer and send the command to the
909             device */
910             status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
911                                 pipeid, (uint8_t)ANY_SET_PARAMETER);
912         }
913     }
914     return status;
915 }
916 #endif /* #if defined (TYPE_B) */
917 
918 
919