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 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 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 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