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
phHciNfc_Admin_Initialise(phHciNfc_sContext_t * psHciContext,void * pHwRef)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
phHciNfc_Admin_CE_Init(phHciNfc_sContext_t * psHciContext,void * pHwRef,phHciNfc_GateID_t ce_gate)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
phHciNfc_Admin_Release(phHciNfc_sContext_t * psHciContext,void * pHwRef,phHciNfc_HostID_t host_type)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
phHciNfc_Send_Admin_Event(phHciNfc_sContext_t * psHciContext,void * pHwRef,uint8_t event,uint8_t length,void * params)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
phHciNfc_Send_Admin_Cmd(phHciNfc_sContext_t * psHciContext,void * pHwRef,uint8_t cmd,uint8_t length,void * params)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
phHciNfc_Recv_Admin_Response(void * psContext,void * pHwRef,uint8_t * pResponse,uint8_t length)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
phHciNfc_Recv_Admin_Cmd(void * psContext,void * pHwRef,uint8_t * pCmd,uint8_t length)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 memset(p_pipe_info, 0, sizeof(phHciNfc_Pipe_Info_t));
1001 if(NULL != p_pipe_info)
1002 {
1003 /* The Source Host is the UICC Host */
1004 p_pipe_info->pipe.source.host_id =
1005 hcp_message->payload[index++];
1006 /* The Source Gate is same as the Destination Gate */
1007 p_pipe_info->pipe.source.gate_id =
1008 hcp_message->payload[index++];
1009 /* The Source Host is the Terminal Host */
1010 p_pipe_info->pipe.dest.host_id =
1011 hcp_message->payload[index++];
1012 p_pipe_info->pipe.dest.gate_id =
1013 hcp_message->payload[index++];
1014 p_pipe_info->pipe.pipe_id =
1015 hcp_message->payload[index++];
1016 }
1017 status = phHciNfc_Update_PipeInfo(psHciContext,
1018 &(p_admin_info->pipe_seq), pipe_id, p_pipe_info);
1019
1020 if( NFCSTATUS_SUCCESS == status )
1021 {
1022 psHciContext->p_pipe_list[pipe_id] = p_pipe_info;
1023 if (NULL != p_pipe_info)
1024 {
1025 p_pipe_info->pipe.pipe_id = pipe_id;
1026 }
1027 }
1028 break;
1029 }
1030 case ADM_NOTIFY_PIPE_DELETED:
1031 {
1032 pipe_id = hcp_message->payload[index++];
1033 p_pipe_info = psHciContext->p_pipe_list[pipe_id];
1034 if ( NULL != p_pipe_info )
1035 {
1036 status = phHciNfc_Update_PipeInfo(
1037 psHciContext, &(p_admin_info->pipe_seq),
1038 (uint8_t) HCI_UNKNOWN_PIPE_ID, p_pipe_info);
1039 if(NFCSTATUS_SUCCESS == status )
1040 {
1041 phOsalNfc_FreeMemory(p_pipe_info);
1042 psHciContext->p_pipe_list[pipe_id] = NULL;
1043 }
1044 }
1045 break;
1046 }
1047 /* TODO: Since we receive the Host ID, we need to clear
1048 * all the pipes created with the host
1049 */
1050 case ADM_NOTIFY_ALL_PIPE_CLEARED:
1051 {
1052 break;
1053 }
1054 /* case ADM_CREATE_PIPE: */
1055 /* case ADM_DELETE_PIPE: */
1056 /* case ADM_CLEAR_ALL_PIPE: */
1057 default:
1058 {
1059 response = ANY_E_CMD_NOT_SUPPORTED;
1060 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_COMMAND_NOT_SUPPORTED);
1061 break;
1062 }
1063 }
1064 hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
1065 phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
1066 (uint8_t) HCI_ADMIN_PIPE_ID,
1067 HCP_MSG_TYPE_RESPONSE, response );
1068 psHciContext->tx_total = HCP_HEADER_LEN;
1069 status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
1070
1071 p_admin_info->admin_pipe_info->recv_msg_type = HCP_MSG_TYPE_COMMAND;
1072 p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_RESPONSE;
1073 p_admin_info->admin_pipe_info->prev_msg = response;
1074 p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
1075 }
1076 return status;
1077 }
1078
1079 /*!
1080 * \brief Receives the HCI Admin Event from the corresponding peripheral device.
1081 *
1082 * This function receives the HCI Admin Events from the connected NFC Pheripheral
1083 * device
1084 */
1085 static
1086 NFCSTATUS
phHciNfc_Recv_Admin_Event(void * psContext,void * pHwRef,uint8_t * pEvent,uint8_t length)1087 phHciNfc_Recv_Admin_Event (
1088 void *psContext,
1089 void *pHwRef,
1090 uint8_t *pEvent,
1091 #ifdef ONE_BYTE_LEN
1092 uint8_t length
1093 #else
1094 uint16_t length
1095 #endif
1096 )
1097 {
1098 phHciNfc_sContext_t *psHciContext =
1099 (phHciNfc_sContext_t *)psContext ;
1100 phHciNfc_HCP_Packet_t *hcp_packet = NULL;
1101 phHciNfc_HCP_Message_t *hcp_message = NULL;
1102 uint8_t event = (uint8_t) HCP_MSG_INSTRUCTION_INVALID;
1103 NFCSTATUS status = NFCSTATUS_SUCCESS;
1104
1105 if( (NULL == psHciContext)
1106 || (NULL == pHwRef)
1107 || (HCP_HEADER_LEN > length )
1108 )
1109 {
1110 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
1111 }
1112 else
1113 {
1114 hcp_packet = (phHciNfc_HCP_Packet_t *)pEvent;
1115 hcp_message = &hcp_packet->msg.message;
1116 /* Get the Command instruction bits from the Message Header */
1117 event = (uint8_t) GET_BITS8( hcp_message->msg_header,
1118 HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
1119
1120 if( EVT_HOT_PLUG == event )
1121 {
1122 status = phHciNfc_Send_Admin_Event ( psHciContext, pHwRef,
1123 EVT_HOT_PLUG, 0 ,NULL);
1124
1125 }
1126 else
1127 {
1128 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION);
1129 }
1130
1131
1132 }
1133 return status;
1134 }
1135
1136
1137 static
1138 NFCSTATUS
phHciNfc_Admin_InfoUpdate(phHciNfc_sContext_t * psHciContext,phHal_sHwReference_t * pHwRef,uint8_t index,uint8_t * reg_value,uint8_t reg_length)1139 phHciNfc_Admin_InfoUpdate(
1140 phHciNfc_sContext_t *psHciContext,
1141 phHal_sHwReference_t *pHwRef,
1142 uint8_t index,
1143 uint8_t *reg_value,
1144 uint8_t reg_length
1145 )
1146 {
1147 phHciNfc_AdminGate_Info_t *p_admin_info=NULL;
1148 uint8_t i=0;
1149 NFCSTATUS status = NFCSTATUS_SUCCESS;
1150 if(NULL == reg_value)
1151 {
1152 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
1153 }
1154 else
1155 {
1156 p_admin_info = psHciContext->p_admin_info ;
1157 HCI_PRINT_BUFFER("Admin Mgmt Info Buffer",reg_value,reg_length);
1158 switch(index)
1159 {
1160 case SESSION_INDEX :
1161 {
1162 for(i=0 ;(reg_length == SESSIONID_LEN)&&(i < reg_length); i++)
1163 {
1164 p_admin_info->session_id[i] = reg_value[i];
1165 pHwRef->session_id[i] = reg_value[i];
1166 }
1167 break;
1168 }
1169 case MAX_PIPE_INDEX :
1170 {
1171 p_admin_info->max_pipe = reg_value[i];
1172 break;
1173 }
1174 case WHITELIST_INDEX :
1175 {
1176 for(i=0 ;(reg_length <= WHITELIST_MAX_LEN)&&(i < reg_length); i++)
1177 {
1178 p_admin_info->whitelist[i] = reg_value[i];
1179 }
1180 break;
1181 }
1182 case HOST_LIST_INDEX :
1183 {
1184 for(i=0 ;(reg_length <= HOST_LIST_MAX_LEN)&&(i < reg_length); i++)
1185 {
1186 p_admin_info->host_list[i] = reg_value[i];
1187 }
1188 break;
1189 }
1190 default:
1191 {
1192 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
1193 break;
1194 } /*End of the default Switch Case */
1195
1196 } /*End of the Index Switch */
1197
1198 } /* End of Context and the Identity information validity check */
1199
1200 return status;
1201 }
1202
1203