Initialize Tizen 2.3
[adaptation/devices/nfc-plugin-nxp.git] / src / phHciNfc_AdminMgmt.c
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  hHciNfc_AdminMgmt.c                                                  *
22 * \brief HCI Admin Gate Management Routines.                                  *
23 *                                                                             *
24 *                                                                             *
25 * Project: NFC-FRI-1.1                                                        *
26 *                                                                             *
27 * $Date: Mon Apr  5 19:23:34 2010 $                                           *
28 * $Author: ing04880 $                                                         *
29 * $Revision: 1.47 $                                                           *
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 <phHciNfc_Pipe.h>
40 #include <phHciNfc_AdminMgmt.h>
41 #include <phHciNfc_DevMgmt.h>
42 #include <phOsalNfc.h>
43 /*
44 ****************************** Macro Definitions *******************************
45 */
46
47 #define SESSION_INDEX       0x01U
48 #define MAX_PIPE_INDEX      0x02U
49 #define WHITELIST_INDEX     0x03U
50 #define HOST_LIST_INDEX     0x04U
51
52 /* Max Whitelist Supported by the Device*/
53 #define SESSIONID_LEN       0x08U
54 #define WHITELIST_MAX_LEN   0x03U
55 #define HOST_LIST_MAX_LEN   0x05U
56
57 /* Address Definitions for HW Configuration */
58 #define NFC_ADDRESS_UICC_SESSION        0x9EA2U
59
60
61
62 /*
63 *************************** Structure and Enumeration ***************************
64 */
65
66 typedef enum phHciNfc_Admin_Seq{
67     ADMIN_PIPE_OPEN     = 0x00U,
68     ADMIN_GET_HOST_LIST,
69     ADMIN_GET_WHITE_LIST,
70     ADMIN_GET_SESSION,
71     ADMIN_VERIFY_SESSION,
72     ADMIN_CLEAR_UICC_PIPES,
73     ADMIN_CLEAR_PIPES,
74     ADMIN_PIPE_REOPEN,
75     ADMIN_CREATE_PIPES,
76     ADMIN_SET_SESSION,
77     ADMIN_SET_WHITE_LIST,
78     ADMIN_UPDATE_PIPES,
79     ADMIN_PIPE_CLOSE,
80     ADMIN_DELETE_PIPES,
81     ADMIN_END_SEQUENCE
82 } phHciNfc_Admin_Seq_t;
83
84
85 /* Information structure for the Admin Gate */
86 typedef struct phHciNfc_AdminGate_Info{
87     /* Current running Sequence of the Admin Management */
88     phHciNfc_Admin_Seq_t            current_seq;
89     /* Next running Sequence of the Admin Management */
90     phHciNfc_Admin_Seq_t            next_seq;
91     /* Pointer to the Admin Pipe Information */
92     phHciNfc_Pipe_Info_t            *admin_pipe_info;
93     /* Sequence for the Pipe Initialisation */
94     phHciNfc_PipeMgmt_Seq_t         pipe_seq;
95     /* Session ID of the Device */
96     uint8_t                         session_id[SESSIONID_LEN];
97     /* Max number of pipes that can be created on the Device */
98     uint8_t                         max_pipe;
99     /* List of Hosts that can be access the device Admin Gate. */
100     uint8_t                         whitelist[WHITELIST_MAX_LEN];
101     /* Host List from the Host Controller */
102     uint8_t                         host_list[HOST_LIST_MAX_LEN];
103 } phHciNfc_AdminGate_Info_t;
104
105 /*
106 *************************** Static Function Declaration **************************
107 */
108
109 /**
110  * \ingroup grp_hci_nfc
111  *
112  *  The phHciNfc_Recv_Admin_Response function interprets the received AdminGate
113  *  response from the Host Controller Gate.
114  *
115  *  \param[in]  psHciContext            psHciContext is the pointer to HCI Layer
116  *                                      context Structure.
117  *  \param[in]  pHwRef                  pHwRef is the Information of
118  *                                      the Device Interface Link .
119  *  \param[in,out]  pResponse           Response received from the Host Cotroller
120  *                                      Admin gate.
121  *  \param[in]  length                  length contains the length of the
122  *                                      response received from the Host Controller.
123  *
124  *  \retval NFCSTATUS_PENDING           AdminGate Response to be received is pending.
125  *  \retval NFCSTATUS_SUCCESS           AdminGate Response received Successfully.
126  *  \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
127  *                                      could not be interpreted properly.
128  *  \retval Other errors                Errors related to the other layers
129  *
130  */
131
132 static
133 NFCSTATUS
134 phHciNfc_Recv_Admin_Response(
135                         void                *psHciContext,
136                         void                *pHwRef,
137                         uint8_t             *pResponse,
138 #ifdef ONE_BYTE_LEN
139                         uint8_t             length
140 #else
141                         uint16_t            length
142 #endif
143                        );
144
145
146 static
147 NFCSTATUS
148 phHciNfc_Admin_InfoUpdate(
149                                 phHciNfc_sContext_t     *psHciContext,
150                                 phHal_sHwReference_t    *pHwRef,
151                                 uint8_t                 index,
152                                 uint8_t                 *reg_value,
153                                 uint8_t                 reg_length
154                          );
155
156 static
157  NFCSTATUS
158  phHciNfc_Recv_Admin_Cmd (
159                         void                *psContext,
160                         void                *pHwRef,
161                         uint8_t             *pCmd,
162 #ifdef ONE_BYTE_LEN
163                         uint8_t             length
164 #else
165                         uint16_t            length
166 #endif
167                      );
168
169
170 static
171  NFCSTATUS
172  phHciNfc_Recv_Admin_Event (
173                         void                *psContext,
174                         void                *pHwRef,
175                         uint8_t             *pEvent,
176 #ifdef ONE_BYTE_LEN
177                         uint8_t             length
178 #else
179                         uint16_t            length
180 #endif
181                      );
182
183
184 /*
185 *************************** Function Definitions ***************************
186 */
187
188
189
190 /*!
191  * \brief Initialisation of Admin Gate and Establish the Session .
192  *
193  * This function initialses the Admin Gates and Establishes the Session by creating
194  * all the required pipes and sets the Session ID
195  * 
196  */
197
198 NFCSTATUS
199 phHciNfc_Admin_Initialise(
200                                 phHciNfc_sContext_t     *psHciContext,
201                                 void                    *pHwRef
202                          )
203 {
204     NFCSTATUS                           status = NFCSTATUS_SUCCESS;
205     phHciNfc_Pipe_Info_t                *p_pipe_info = NULL;
206     phHciNfc_AdminGate_Info_t           *p_admin_info=NULL;
207     uint8_t                             length = 0;
208
209     if( (NULL == psHciContext)
210         || (NULL == pHwRef )
211         )
212     {
213         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
214     }
215     else
216     {
217         if( ( NULL == psHciContext->p_admin_info )
218             && (phHciNfc_Allocate_Resource((void **)(&p_admin_info),
219                     sizeof(phHciNfc_AdminGate_Info_t))== NFCSTATUS_SUCCESS)
220           )
221         {
222             psHciContext->p_admin_info = (void *) p_admin_info;
223             p_admin_info->current_seq = ADMIN_PIPE_OPEN;
224             p_admin_info->next_seq = ADMIN_END_SEQUENCE;
225             p_admin_info->admin_pipe_info = NULL;
226         }
227         else
228         {
229             p_admin_info = (phHciNfc_AdminGate_Info_t * )
230                                 psHciContext->p_admin_info ;
231         }
232
233         if( NULL == p_admin_info)
234         {
235             status = PHNFCSTVAL(CID_NFC_HCI,
236                         NFCSTATUS_INSUFFICIENT_RESOURCES);
237         }
238         else
239         {
240             switch(p_admin_info->current_seq)
241             {
242                 /* Admin pipe open sequence , Initially open the Admin Pipe */
243                 case ADMIN_PIPE_OPEN:
244                 {
245                     if(phHciNfc_Allocate_Resource((void **)(&p_pipe_info),
246                         sizeof(phHciNfc_Pipe_Info_t))!= NFCSTATUS_SUCCESS)
247                     {
248                         status = PHNFCSTVAL(CID_NFC_HCI,
249                                 NFCSTATUS_INSUFFICIENT_RESOURCES);
250                     }
251                     else
252                     {
253                         /* Populate the pipe information in the pipe handle */
254                         ((phHciNfc_Pipe_Info_t *)p_pipe_info)->pipe.pipe_id = 
255                                         PIPETYPE_STATIC_ADMIN;
256                         ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_resp = 
257                                         &phHciNfc_Recv_Admin_Response;
258                         ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_cmd = 
259                                         &phHciNfc_Recv_Admin_Cmd;
260                         ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_event = 
261                                         &phHciNfc_Recv_Admin_Event;
262                         psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN] =
263                                                                     p_pipe_info ;
264                         status = phHciNfc_Open_Pipe( psHciContext,
265                                                             pHwRef,p_pipe_info );
266                         if(status == NFCSTATUS_SUCCESS)
267                         {
268                             p_admin_info->admin_pipe_info = p_pipe_info ;
269                             p_admin_info->next_seq = ADMIN_GET_SESSION;
270                             status = NFCSTATUS_PENDING;
271                         }
272                     }
273                     break;
274                 }
275                 case ADMIN_GET_SESSION:
276                 {
277                     p_pipe_info = p_admin_info->admin_pipe_info;
278                     p_pipe_info->reg_index = SESSION_INDEX;
279                     p_pipe_info->prev_status = 
280                         phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, 
281                             (uint8_t)HCI_ADMIN_PIPE_ID,
282                                 (uint8_t)ANY_GET_PARAMETER);
283                     if(NFCSTATUS_PENDING == p_pipe_info->prev_status )
284                     {
285 #ifdef UICC_SESSION_RESET
286                         p_admin_info->next_seq = ADMIN_CLEAR_UICC_PIPES;
287 #elif defined (ESTABLISH_SESSION)
288                         p_admin_info->next_seq = ADMIN_VERIFY_SESSION;
289 #else
290                         p_admin_info->next_seq = ADMIN_CLEAR_PIPES;
291 #endif
292                         status = NFCSTATUS_PENDING;
293                     }
294                     break;
295                 }
296 #ifdef UICC_SESSION_RESET
297                 case ADMIN_CLEAR_UICC_PIPES:
298                 {
299                     uint8_t config = 0x00;
300                     p_pipe_info = p_admin_info->admin_pipe_info;
301                      /* TODO: Implement the Clear UICC PIPES Using
302                       * Memory configuration.
303                       */
304                     status = phHciNfc_DevMgmt_Configure( psHciContext, pHwRef,
305                             NFC_ADDRESS_UICC_SESSION , config );
306                     if(NFCSTATUS_PENDING == status )
307                     {
308                         p_admin_info->next_seq = ADMIN_CLEAR_PIPES;
309                         status = NFCSTATUS_PENDING;
310                     }
311                     break;
312                 }
313 #endif
314                 case ADMIN_VERIFY_SESSION:
315                 {
316                     phHal_sHwConfig_t *p_hw_config = 
317                              (phHal_sHwConfig_t *) psHciContext->p_config_params;
318                     phHal_sHwReference_t *p_hw_ref = 
319                              (phHal_sHwReference_t *) pHwRef;
320                     int             cmp_val = 0;
321                     p_pipe_info = p_admin_info->admin_pipe_info;
322                     cmp_val = phOsalNfc_MemCompare(p_hw_config->session_id , 
323                                  p_hw_ref->session_id , 
324                                          sizeof(p_hw_ref->session_id));
325                     if((cmp_val == 0) 
326                         && ( HCI_SESSION == psHciContext->init_mode)
327                         )
328                     {
329                         psHciContext->hci_mode = hciMode_Session;
330                         status = phHciNfc_Update_Pipe( psHciContext, pHwRef,
331                                                 &p_admin_info->pipe_seq );
332                         if((status == NFCSTATUS_SUCCESS) 
333                             && (NULL != p_pipe_info))
334                         {
335                             
336                             p_pipe_info->reg_index = MAX_PIPE_INDEX;
337                             status = phHciNfc_Send_Generic_Cmd( psHciContext,  
338                                     pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
339                                                     (uint8_t)ANY_GET_PARAMETER );
340                             p_pipe_info->prev_status = status;
341                             if(NFCSTATUS_PENDING == status )
342                             {
343                                 p_admin_info->next_seq = ADMIN_PIPE_CLOSE;
344                                 status = NFCSTATUS_SUCCESS;
345                             }
346                         }
347                         else
348                         {
349                             status = PHNFCSTVAL(CID_NFC_HCI, 
350                                             NFCSTATUS_INVALID_HCI_SEQUENCE);
351                         }
352                         break;
353                     }
354                     else
355                     {
356                         /* To clear the pipe information*/
357                         psHciContext->hci_mode = hciMode_Override;
358                         p_admin_info->current_seq = ADMIN_CLEAR_PIPES;
359                     }
360                 }
361                 /* fall through */
362                 case ADMIN_CLEAR_PIPES:
363                 {
364                     p_pipe_info = p_admin_info->admin_pipe_info;
365                     p_pipe_info->prev_status = 
366                                     phHciNfc_Send_Admin_Cmd( psHciContext,
367                                         pHwRef, ADM_CLEAR_ALL_PIPE,
368                                             length, p_pipe_info);
369                     status = ((p_pipe_info->prev_status == NFCSTATUS_PENDING)?
370                                             NFCSTATUS_SUCCESS : 
371                                                 p_pipe_info->prev_status);
372                     if(status == NFCSTATUS_SUCCESS) 
373                     {
374                         p_admin_info->next_seq = ADMIN_PIPE_REOPEN;
375                         status = NFCSTATUS_PENDING;
376                     }
377                     break;
378                 }
379                 /* Admin pipe Re-Open sequence , Re-Open the Admin Pipe */
380                 case ADMIN_PIPE_REOPEN:
381                 {
382                     p_pipe_info = p_admin_info->admin_pipe_info;
383                     status = phHciNfc_Open_Pipe( psHciContext,
384                                                         pHwRef,p_pipe_info );
385                     if(status == NFCSTATUS_SUCCESS)
386                     {
387                         p_admin_info->next_seq = ADMIN_CREATE_PIPES;
388                         status = NFCSTATUS_PENDING;
389                     }
390                     break;
391                 }
392                 case ADMIN_CREATE_PIPES:
393                 {
394                     status = phHciNfc_Create_All_Pipes( psHciContext, pHwRef,
395                                                         &p_admin_info->pipe_seq );
396                     if(status == NFCSTATUS_SUCCESS) 
397                     {
398                         p_admin_info->next_seq = ADMIN_GET_WHITE_LIST;
399                         status = NFCSTATUS_PENDING;
400                     }
401                     break;
402                 }
403                 case ADMIN_GET_WHITE_LIST:
404                 {
405                     p_pipe_info = p_admin_info->admin_pipe_info;
406                     if(NULL == p_pipe_info )
407                     {
408                         status = PHNFCSTVAL(CID_NFC_HCI, 
409                                         NFCSTATUS_INVALID_HCI_SEQUENCE);
410                     }
411                     else
412                     {
413                         p_pipe_info->reg_index = WHITELIST_INDEX;
414                         status = phHciNfc_Send_Generic_Cmd( psHciContext,  
415                                 pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
416                                                 (uint8_t)ANY_GET_PARAMETER );
417                         p_pipe_info->prev_status = status;
418                         if(HCI_SELF_TEST == psHciContext->init_mode)
419                         {
420                             status = ((NFCSTATUS_PENDING == status )?
421                                             NFCSTATUS_SUCCESS : status);
422                         }
423                         else 
424                         {
425                             if(NFCSTATUS_PENDING == status )
426                             {
427                                 p_admin_info->next_seq = ADMIN_GET_HOST_LIST;
428                                 /* status = NFCSTATUS_SUCCESS; */
429                             }
430                         }
431                     }
432                     break;
433                 }
434                 case ADMIN_GET_HOST_LIST:
435                 {
436                     p_pipe_info = p_admin_info->admin_pipe_info;
437                     if(NULL == p_pipe_info )
438                     {
439                         status = PHNFCSTVAL(CID_NFC_HCI, 
440                                         NFCSTATUS_INVALID_HCI_SEQUENCE);
441                     }
442                     else
443                     {
444                         p_pipe_info->reg_index = HOST_LIST_INDEX;
445                         status = phHciNfc_Send_Generic_Cmd( psHciContext,  
446                                 pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
447                                                 (uint8_t)ANY_GET_PARAMETER );
448                         p_pipe_info->prev_status = status;
449                         if(NFCSTATUS_PENDING == status )
450                         {
451
452 #if defined(HOST_WHITELIST)
453                             p_admin_info->next_seq = ADMIN_SET_WHITE_LIST;
454 #else
455                             p_admin_info->next_seq = ADMIN_SET_SESSION;
456                             status = NFCSTATUS_SUCCESS;
457 #endif
458                         }
459                     }
460                     break;
461                 }
462                 case ADMIN_SET_WHITE_LIST:
463                 {
464                     p_pipe_info = p_admin_info->admin_pipe_info;
465                     if(NULL == p_pipe_info )
466                     {
467                         status = PHNFCSTVAL(CID_NFC_HCI, 
468                                         NFCSTATUS_INVALID_HCI_SEQUENCE);
469                     }
470                     else
471                     {
472                         uint8_t             i = 0;
473
474                         for (i = 0; i < WHITELIST_MAX_LEN - 2; i++ )
475                         {
476                             p_admin_info->whitelist[i] = i + 2;
477                         }
478                         status = phHciNfc_Set_Param(psHciContext, pHwRef,
479                                       p_pipe_info, WHITELIST_INDEX, 
480                                         (uint8_t *)p_admin_info->whitelist, i );
481                         if(NFCSTATUS_PENDING == status )
482                         {
483                             p_admin_info->next_seq = ADMIN_SET_SESSION;
484                             status = NFCSTATUS_SUCCESS;
485                         }
486                     }
487                     break;
488                 }
489                 case ADMIN_SET_SESSION:
490                 {
491                     phHal_sHwConfig_t *p_hw_config = 
492                              (phHal_sHwConfig_t *) psHciContext->p_config_params;
493                     p_pipe_info = p_admin_info->admin_pipe_info;
494                     status = phHciNfc_Set_Param(psHciContext, pHwRef, p_pipe_info,
495                         SESSION_INDEX, (uint8_t *)(p_hw_config->session_id),
496                             sizeof(p_hw_config->session_id));
497                     if(NFCSTATUS_PENDING == p_pipe_info->prev_status )
498                     {
499                         p_admin_info->next_seq = ADMIN_PIPE_CLOSE;
500                         status = NFCSTATUS_SUCCESS;
501                     }
502                     break;
503                 }
504                 default:
505                 {
506                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE);
507                     break;
508                 }
509
510             }/* End of the Sequence Switch */
511
512         }/* End of the Admin Info Memory Check */
513
514     }/* End of Null context Check */
515
516     return status;
517 }
518
519 #ifdef HOST_EMULATION
520
521 /*!
522  * \brief Creates the Card Emulation Gate Pipes .
523  *
524  * This function Creates the Card Emulation Gate.
525  */
526
527 NFCSTATUS
528 phHciNfc_Admin_CE_Init(
529                                 phHciNfc_sContext_t     *psHciContext,
530                                 void                    *pHwRef,
531                                 phHciNfc_GateID_t       ce_gate
532
533                              )
534 {
535     NFCSTATUS                           status = NFCSTATUS_SUCCESS;
536     /* phHciNfc_Pipe_Info_t             *pipe_info = NULL; */
537     phHciNfc_AdminGate_Info_t           *p_admin_info=NULL;
538
539     if( (NULL == psHciContext) || (NULL == pHwRef) )
540     {
541       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
542     }
543     else
544     {
545         if( NULL != psHciContext->p_admin_info )
546         {
547             p_admin_info = psHciContext->p_admin_info;
548
549             switch(ce_gate)
550             {
551                 /* Card Emulation A Gate Pipe Creation */
552                 case phHciNfc_CETypeAGate:
553                 {
554                     p_admin_info->pipe_seq = PIPE_CARD_A_CREATE;
555                     break;
556                 }
557                 /* Card Emulation B Gate Pipe Creation */
558                 case phHciNfc_CETypeBGate:
559                 {
560                     p_admin_info->pipe_seq = PIPE_CARD_B_CREATE;
561                     break;
562                 }
563                 default:
564                 {
565                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_HCI_GATE_NOT_SUPPORTED);
566                     break;
567                 }
568             } /* End of CE Gate Switch */
569
570             if (NFCSTATUS_SUCCESS == status)
571             {
572                 status = phHciNfc_CE_Pipes_OP( psHciContext,
573                                         pHwRef, &p_admin_info->pipe_seq );
574                 if(status == NFCSTATUS_SUCCESS)
575                 {
576                     p_admin_info->next_seq = ADMIN_END_SEQUENCE;
577                     /* status = NFCSTATUS_PENDING; */
578                 }
579             }
580
581         }/* End of NULL Check for the Admin_Info */
582     } /* End of Null Check for the Context */
583     return status;
584 }
585
586 #endif
587
588 /*!
589  * \brief Releases the resources allocated the Admin Management.
590  *
591  * This function Releases the resources allocated the Admin Management
592  * and resets the hardware to the reset state.
593  */
594
595 NFCSTATUS
596 phHciNfc_Admin_Release(
597                                 phHciNfc_sContext_t     *psHciContext,
598                                 void                    *pHwRef,
599                                 phHciNfc_HostID_t        host_type
600                              )
601 {
602     NFCSTATUS                           status = NFCSTATUS_SUCCESS;
603     phHciNfc_Pipe_Info_t                *p_pipe_info = NULL;
604
605     if( (NULL == psHciContext) || (NULL == pHwRef) )
606     {
607       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
608     }
609     else
610     {
611         if( NULL != psHciContext->p_admin_info )
612         {
613             if(phHciNfc_UICCHostID != host_type)
614             {
615                 p_pipe_info = psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN];
616
617                 status = phHciNfc_Close_Pipe( psHciContext,
618                                                     pHwRef, p_pipe_info );
619             }
620
621         }/* End of NULL Check for the Admin_Info */
622     } /* End of Null Check for the Context */
623     return status;
624 }
625
626
627 /*!
628  * \brief Sends the HCI Admin Event to the corresponding peripheral device.
629  *
630  * This function sends the HCI Admin Events to the connected NFC Pheripheral
631  * device
632  */
633
634  NFCSTATUS
635  phHciNfc_Send_Admin_Event (
636                       phHciNfc_sContext_t   *psHciContext,
637                       void                  *pHwRef,
638                       uint8_t               event,
639                       uint8_t               length,
640                       void                  *params
641                      )
642 {
643     phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
644     phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
645     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
646
647     if( (NULL == psHciContext) 
648         || (NULL == pHwRef) 
649       )
650     {
651       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
652     }
653     else
654     {
655         psHciContext->tx_total = 0 ;
656         length +=  HCP_HEADER_LEN ;
657         p_admin_info = psHciContext->p_admin_info;
658
659         if( EVT_HOT_PLUG ==   event )
660         {
661
662             /* Use the HCP Packet Structure to Construct the send HCP
663                 * Packet data.
664                 */
665             hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
666             phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
667                                     (uint8_t) HCI_ADMIN_PIPE_ID,
668                                     HCP_MSG_TYPE_EVENT, event);
669         }
670         else
671         {
672             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION);
673         }
674
675         if( NFCSTATUS_SUCCESS == status )
676         {
677             p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_EVENT;
678             p_admin_info->admin_pipe_info->prev_msg = event ;
679             p_admin_info->admin_pipe_info->param_info = params ;
680             psHciContext->tx_total = length;
681             psHciContext->response_pending = FALSE ;
682             status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
683             p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
684         }
685     }
686
687     return status;
688 }
689
690
691 /*!
692  * \brief Sends the HCI Admin Commands to the corresponding peripheral device.
693  *
694  * This function sends the HCI Admin Commands to the connected NFC Pheripheral
695  * device
696  */
697
698  NFCSTATUS
699  phHciNfc_Send_Admin_Cmd (
700                       phHciNfc_sContext_t   *psHciContext,
701                       void                  *pHwRef,
702                       uint8_t               cmd,
703                       uint8_t               length,
704                       void                  *params
705                      )
706 {
707     phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
708     phHciNfc_HCP_Message_t      *hcp_message = NULL;
709     phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
710     phHciNfc_Pipe_Info_t        *p_pipe_info = NULL;
711     uint8_t                     i=0;
712     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
713
714     if( (NULL == psHciContext) 
715         || (NULL == pHwRef) 
716         || (NULL == params)
717       )
718     {
719       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
720     }
721     else
722     {
723         p_pipe_info = (phHciNfc_Pipe_Info_t *)  params;
724         psHciContext->tx_total = 0 ;
725         length +=  HCP_HEADER_LEN ;
726         p_admin_info = psHciContext->p_admin_info;
727         switch(  cmd )
728         {
729             case ADM_CREATE_PIPE:
730             {
731                 hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
732                 /* Use the HCP Packet Structure to Construct the send HCP
733                 * Packet data.
734                 */
735                 phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
736                                         (uint8_t) HCI_ADMIN_PIPE_ID,
737                                         HCP_MSG_TYPE_COMMAND, cmd);
738                 hcp_message = &(hcp_packet->msg.message);
739
740                 /* Source HOST ID Parameter is not passed as a 
741                  * parameter in the HCI SPEC */
742
743                 /* hcp_message->payload[i++] = p_pipe_info->pipe.source.host_id; */
744                 hcp_message->payload[i++] = p_pipe_info->pipe.source.gate_id;
745                 hcp_message->payload[i++] = p_pipe_info->pipe.dest.host_id;
746                 hcp_message->payload[i++] = p_pipe_info->pipe.dest.gate_id;
747                 break;
748             }
749             case ADM_DELETE_PIPE:
750             {
751                 uint8_t     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;
752
753                 pipe_id = p_pipe_info->pipe.pipe_id;
754                 if( pipe_id < PIPETYPE_DYNAMIC )
755                 {
756                     /* The Static Pipes cannot be Deleted */
757                     status = PHNFCSTVAL(CID_NFC_HCI,
758                                     NFCSTATUS_INVALID_PARAMETER );
759                     HCI_DEBUG("phHciNfc_Send_Admin_Cmd: Static Pipe %u "
760                                                 "Cannot be Deleted \n",pipe_id);
761                 }
762                 else
763                 {
764
765                     /* Use the HCP Packet Structure to Construct the send HCP
766                      * Packet data.
767                      */
768                     hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
769                     phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
770                                             (uint8_t) HCI_ADMIN_PIPE_ID,
771                                             HCP_MSG_TYPE_COMMAND, cmd);
772                     hcp_message = &(hcp_packet->msg.message);
773                     hcp_message->payload[i++] = pipe_id ;
774                 }
775                 break;
776             }
777             case ADM_CLEAR_ALL_PIPE:
778             {
779
780                 /* Use the HCP Packet Structure to Construct the send HCP
781                  * Packet data.
782                  */
783                 hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
784                 phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
785                                         (uint8_t) HCI_ADMIN_PIPE_ID,
786                                         HCP_MSG_TYPE_COMMAND, cmd);
787                 hcp_message = &(hcp_packet->msg.message);
788                 break;
789             }
790             /* These are notifications and can not be sent by the Host */
791             /* case ADM_NOTIFY_PIPE_CREATED: */
792             /* case ADM_NOTIFY_PIPE_DELETED: */
793             /* case ADM_NOTIFY_ALL_PIPE_CLEARED: */
794             default:
795                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_COMMAND);
796                 break;
797         }
798         if( NFCSTATUS_SUCCESS == status )
799         {
800             p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_COMMAND;
801             p_admin_info->admin_pipe_info->prev_msg = cmd;
802             p_admin_info->admin_pipe_info->param_info = p_pipe_info;
803             psHciContext->tx_total = length;
804             psHciContext->response_pending = TRUE;
805             status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
806             p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
807         }
808     }
809
810     return status;
811 }
812
813
814 /*!
815  * \brief Receives the HCI Response from the corresponding peripheral device.
816  *
817  * This function receives the HCI Command Response from the connected NFC
818  * Pheripheral device.
819  */
820
821 static
822 NFCSTATUS
823 phHciNfc_Recv_Admin_Response(
824                         void                *psContext,
825                         void                *pHwRef,
826                         uint8_t             *pResponse,
827 #ifdef ONE_BYTE_LEN
828                         uint8_t             length
829 #else
830                         uint16_t            length
831 #endif
832                     )
833 {
834     phHciNfc_sContext_t         *psHciContext = 
835                                     (phHciNfc_sContext_t *)psContext ;
836     phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
837     phHciNfc_HCP_Message_t      *hcp_message = NULL;
838     phHciNfc_Pipe_Info_t        *p_pipe_info = NULL;
839     phHciNfc_AdminGate_Info_t   *p_admin_info = NULL;
840     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
841     uint8_t                     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;
842     uint8_t                     prev_cmd = 0;
843     NFCSTATUS                   prev_status = NFCSTATUS_SUCCESS;
844
845     if( (NULL == psHciContext) || (NULL == pHwRef) )
846     {
847       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
848     }
849     else if ( NULL == psHciContext->p_admin_info )
850     {
851         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION);
852     }
853     else
854     {
855         hcp_packet = (phHciNfc_HCP_Packet_t *)pResponse;
856         hcp_message = &hcp_packet->msg.message;
857         p_admin_info = psHciContext->p_admin_info;
858         prev_cmd = p_admin_info->admin_pipe_info->prev_msg ;
859         prev_status = p_admin_info->admin_pipe_info->prev_status ;
860         if(prev_status == NFCSTATUS_PENDING)
861         {
862             switch(prev_cmd)
863             {
864                 case ANY_SET_PARAMETER:
865                 {
866                     break;
867                 }
868                 case ANY_GET_PARAMETER:
869                 {
870                     status = phHciNfc_Admin_InfoUpdate(psHciContext,
871                                 (phHal_sHwReference_t *)pHwRef,
872                                 p_admin_info->admin_pipe_info->reg_index, 
873                                     &pResponse[HCP_HEADER_LEN],
874                                         (uint8_t)(length - HCP_HEADER_LEN));
875                     break;
876                 }
877                 case ANY_OPEN_PIPE:
878                 {
879                     break;
880                 }
881                 case ANY_CLOSE_PIPE:
882                 {
883                     phOsalNfc_FreeMemory(p_admin_info->admin_pipe_info);
884                     p_admin_info->admin_pipe_info = NULL;
885                     psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN] = NULL;
886                     break;
887                 }
888                 case ADM_CREATE_PIPE:
889                 {
890                     p_pipe_info = (phHciNfc_Pipe_Info_t *)
891                                         p_admin_info->admin_pipe_info->param_info;
892                     pipe_id = hcp_message->payload[RESPONSE_PIPEID_OFFSET];
893                     status = phHciNfc_Update_PipeInfo(psHciContext,
894                         &(p_admin_info->pipe_seq), pipe_id, p_pipe_info);
895                     if(NFCSTATUS_SUCCESS == status )
896                     {
897                         psHciContext->p_pipe_list[pipe_id] = p_pipe_info;
898                         p_pipe_info->pipe.pipe_id = pipe_id;
899                     }
900                     break;
901                 }
902                 case ADM_DELETE_PIPE:
903                 {
904                     p_pipe_info = (phHciNfc_Pipe_Info_t *)
905                                     p_admin_info->admin_pipe_info->param_info;
906                     if ( NULL != p_pipe_info )
907                     {
908                         pipe_id = p_pipe_info->pipe.pipe_id;
909                         status = phHciNfc_Update_PipeInfo(
910                             psHciContext, &(p_admin_info->pipe_seq),
911                              (uint8_t) HCI_UNKNOWN_PIPE_ID, p_pipe_info);
912                         if(NFCSTATUS_SUCCESS == status )
913                         {
914                             phOsalNfc_FreeMemory(p_pipe_info);
915                             psHciContext->p_pipe_list[pipe_id] = NULL;
916                         }
917                     }
918                     break;
919                 }
920                 case ADM_CLEAR_ALL_PIPE:
921                 {
922                     break;
923                 }
924                 default:
925                 {
926                     status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
927                     HCI_DEBUG("%s: Default Statement Should Not Occur \n",
928                                                     "phHciNfc_Recv_Admin_Response");
929                     break;
930                 }
931             }
932         }
933         if( NFCSTATUS_SUCCESS == status )
934         {
935             if( NULL != p_admin_info->admin_pipe_info)
936             {
937                 p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_SUCCESS;
938             }
939             p_admin_info->current_seq = p_admin_info->next_seq;
940         }
941     }
942     return status;
943 }
944
945 /*!
946  * \brief Receives the HCI Admin Commands from the corresponding peripheral device.
947  *
948  * This function receives  the HCI Admin Commands from the connected NFC Pheripheral
949  * device
950  */
951 static
952  NFCSTATUS
953  phHciNfc_Recv_Admin_Cmd (
954                         void                *psContext,
955                         void                *pHwRef,
956                         uint8_t             *pCmd,
957 #ifdef ONE_BYTE_LEN
958                         uint8_t             length
959 #else
960                         uint16_t            length
961 #endif
962                      )
963 {
964     phHciNfc_sContext_t         *psHciContext = 
965                                     (phHciNfc_sContext_t *)psContext ;
966     phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
967     phHciNfc_HCP_Message_t      *hcp_message = NULL;
968     phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
969     phHciNfc_Pipe_Info_t        *p_pipe_info = NULL;
970     uint8_t                     index=0;
971     uint8_t                     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;
972     uint8_t                     cmd = (uint8_t) HCP_MSG_INSTRUCTION_INVALID;
973     uint8_t                     response = (uint8_t) ANY_OK;
974     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
975
976     if( (NULL == psHciContext) 
977         || (NULL == pHwRef) 
978         || (HCP_HEADER_LEN > length ) 
979       )
980     {
981       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
982     }
983     else
984     {
985         hcp_packet = (phHciNfc_HCP_Packet_t *)pCmd;
986         hcp_message = &hcp_packet->msg.message;
987         p_admin_info = psHciContext->p_admin_info;
988         /* Get the Command instruction bits from the Message Header */
989         cmd = (uint8_t) GET_BITS8( hcp_message->msg_header,
990             HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
991
992         switch( cmd )
993         {
994             /* These are notifications sent by the Host Controller */
995             case ADM_NOTIFY_PIPE_CREATED:
996             {
997                 pipe_id = hcp_message->payload[RESPONSE_PIPEID_OFFSET];
998                 p_pipe_info = (phHciNfc_Pipe_Info_t *)
999                         phOsalNfc_GetMemory(sizeof(phHciNfc_Pipe_Info_t));
1000                 if(NULL != p_pipe_info)
1001                 {
1002                     /* The Source Host is the UICC Host */
1003                     p_pipe_info->pipe.source.host_id = 
1004                                     hcp_message->payload[index++];
1005                     /* The Source Gate is same as the Destination Gate */
1006                     p_pipe_info->pipe.source.gate_id    = 
1007                                     hcp_message->payload[index++];
1008                     /* The Source Host is the Terminal Host */
1009                     p_pipe_info->pipe.dest.host_id = 
1010                                     hcp_message->payload[index++];
1011                     p_pipe_info->pipe.dest.gate_id  = 
1012                                     hcp_message->payload[index++];
1013                     p_pipe_info->pipe.pipe_id   = 
1014                                     hcp_message->payload[index++];
1015                 }
1016                 status = phHciNfc_Update_PipeInfo(psHciContext,
1017                     &(p_admin_info->pipe_seq), pipe_id, p_pipe_info);
1018
1019                 if( NFCSTATUS_SUCCESS == status )
1020                 {
1021                     psHciContext->p_pipe_list[pipe_id] = p_pipe_info;
1022                     if (NULL != p_pipe_info)
1023                     {
1024                         p_pipe_info->pipe.pipe_id = pipe_id;
1025                     }
1026                 }
1027                 break;
1028             }
1029             case ADM_NOTIFY_PIPE_DELETED:
1030             {
1031                 pipe_id = hcp_message->payload[index++];
1032                 p_pipe_info = psHciContext->p_pipe_list[pipe_id];
1033                 if ( NULL != p_pipe_info )
1034                 {
1035                         status = phHciNfc_Update_PipeInfo(
1036                             psHciContext, &(p_admin_info->pipe_seq),
1037                              (uint8_t) HCI_UNKNOWN_PIPE_ID, p_pipe_info);
1038                     if(NFCSTATUS_SUCCESS == status )
1039                     {
1040                         phOsalNfc_FreeMemory(p_pipe_info);
1041                         psHciContext->p_pipe_list[pipe_id] = NULL;
1042                     }
1043                 }
1044                 break;
1045             }
1046             /* TODO: Since we receive the Host ID, we need to clear
1047              * all the pipes created with the host
1048              */
1049             case ADM_NOTIFY_ALL_PIPE_CLEARED:
1050             {
1051                 break;
1052             }
1053             /* case ADM_CREATE_PIPE: */
1054             /* case ADM_DELETE_PIPE: */
1055             /* case ADM_CLEAR_ALL_PIPE: */
1056             default:
1057             {
1058                 response = ANY_E_CMD_NOT_SUPPORTED;
1059                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_COMMAND_NOT_SUPPORTED);
1060                 break;
1061             }
1062         }
1063         hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
1064         phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
1065                                 (uint8_t) HCI_ADMIN_PIPE_ID,
1066                                 HCP_MSG_TYPE_RESPONSE, response );
1067         psHciContext->tx_total = HCP_HEADER_LEN;
1068         status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
1069
1070         p_admin_info->admin_pipe_info->recv_msg_type = HCP_MSG_TYPE_COMMAND;
1071         p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_RESPONSE;
1072         p_admin_info->admin_pipe_info->prev_msg = response;
1073         p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
1074     }
1075     return status;
1076 }
1077
1078 /*!
1079  * \brief Receives the HCI Admin Event from the corresponding peripheral device.
1080  *
1081  * This function receives  the HCI Admin Events from the connected NFC Pheripheral
1082  * device
1083  */
1084 static
1085  NFCSTATUS
1086  phHciNfc_Recv_Admin_Event (
1087                         void                *psContext,
1088                         void                *pHwRef,
1089                         uint8_t             *pEvent,
1090 #ifdef ONE_BYTE_LEN
1091                         uint8_t             length
1092 #else
1093                         uint16_t            length
1094 #endif
1095                      )
1096 {
1097     phHciNfc_sContext_t         *psHciContext = 
1098                                     (phHciNfc_sContext_t *)psContext ;
1099     phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
1100     phHciNfc_HCP_Message_t      *hcp_message = NULL;
1101     uint8_t                     event = (uint8_t) HCP_MSG_INSTRUCTION_INVALID;
1102     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
1103
1104     if( (NULL == psHciContext) 
1105         || (NULL == pHwRef) 
1106         || (HCP_HEADER_LEN > length ) 
1107       )
1108     {
1109       status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
1110     }
1111     else
1112     {
1113         hcp_packet = (phHciNfc_HCP_Packet_t *)pEvent;
1114         hcp_message = &hcp_packet->msg.message;
1115         /* Get the Command instruction bits from the Message Header */
1116         event = (uint8_t) GET_BITS8( hcp_message->msg_header,
1117             HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
1118
1119         if( EVT_HOT_PLUG ==   event )
1120         {
1121             status = phHciNfc_Send_Admin_Event ( psHciContext, pHwRef, 
1122                                 EVT_HOT_PLUG, 0 ,NULL);
1123
1124         }
1125         else
1126         {
1127             status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION);
1128         }
1129
1130
1131     }
1132     return status;
1133 }
1134
1135
1136 static
1137 NFCSTATUS
1138 phHciNfc_Admin_InfoUpdate(
1139                                 phHciNfc_sContext_t     *psHciContext,
1140                                 phHal_sHwReference_t    *pHwRef,
1141                                 uint8_t                 index,
1142                                 uint8_t                 *reg_value,
1143                                 uint8_t             reg_length
1144                           )
1145 {
1146     phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
1147     uint8_t                     i=0;
1148     NFCSTATUS                   status = NFCSTATUS_SUCCESS;
1149     if(NULL == reg_value)
1150     {
1151         status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
1152     }
1153     else
1154     {
1155         p_admin_info = psHciContext->p_admin_info ;
1156         HCI_PRINT_BUFFER("Admin Mgmt Info Buffer",reg_value,reg_length);
1157         switch(index)
1158         {
1159             case SESSION_INDEX :
1160             {
1161                 for(i=0 ;(reg_length == SESSIONID_LEN)&&(i < reg_length); i++)
1162                 {
1163                     p_admin_info->session_id[i] = reg_value[i];
1164                     pHwRef->session_id[i] = reg_value[i];
1165                 }
1166                 break;
1167             }
1168             case MAX_PIPE_INDEX :
1169             {
1170                 p_admin_info->max_pipe = reg_value[i];
1171                 break;
1172             }
1173             case WHITELIST_INDEX :
1174             {
1175                 for(i=0 ;(reg_length <= WHITELIST_MAX_LEN)&&(i < reg_length); i++)
1176                 {
1177                     p_admin_info->whitelist[i] = reg_value[i];
1178                 }
1179                 break;
1180             }
1181             case HOST_LIST_INDEX :
1182             {
1183                 for(i=0 ;(reg_length <= HOST_LIST_MAX_LEN)&&(i < reg_length); i++)
1184                 {
1185                     p_admin_info->host_list[i] = reg_value[i];
1186                 }
1187                 break;
1188             }
1189             default:
1190             {
1191                 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
1192                 break;
1193             } /*End of the default Switch Case */
1194
1195         } /*End of the Index Switch */
1196
1197     } /* End of Context and the Identity information validity check */
1198
1199     return status;
1200 }
1201