nfa_hci_main.c revision e29968cf3e053557a9c2efc5a7a42d0767c51d9d
1/***************************************************************************** 2** 3** Name: nfa_hci_main.c 4** 5** Description: This is the main implementation file for the NFA HCI. 6** 7** Copyright (c) 2010-2011, Broadcom Corp., All Rights Reserved. 8** Broadcom Bluetooth Core. Proprietary and confidential. 9** 10*****************************************************************************/ 11#include <string.h> 12#include "nfc_api.h" 13#include "nfa_sys.h" 14#include "nfa_sys_int.h" 15#include "nfa_dm_int.h" 16#include "nfa_hci_api.h" 17#include "nfa_hci_int.h" 18#include "nfa_ee_api.h" 19#include "nfa_ee_int.h" 20#include "nfa_nv_co.h" 21#include "nfa_mem_co.h" 22#include "nfa_hci_defs.h" 23#include "trace_api.h" 24 25 26/***************************************************************************** 27** Global Variables 28*****************************************************************************/ 29 30tNFA_HCI_CB nfa_hci_cb; 31 32#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL 33#define NFA_HCI_NV_READ_TIMEOUT_VAL 1000 34#endif 35 36#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL 37#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000 38#endif 39 40/***************************************************************************** 41** Static Functions 42*****************************************************************************/ 43 44/* event handler function type */ 45static BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg); 46 47static void nfa_hci_sys_enable (void); 48static void nfa_hci_sys_disable (void); 49static void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data); 50static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data); 51static void nfa_hci_set_receive_buf (UINT8 pipe); 52static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len); 53static void nfa_hci_handle_nv_read (UINT8 block, tNFA_STATUS status); 54 55/***************************************************************************** 56** Constants 57*****************************************************************************/ 58static const tNFA_SYS_REG nfa_hci_sys_reg = 59{ 60 nfa_hci_sys_enable, 61 nfa_hci_evt_hdlr, 62 nfa_hci_sys_disable, 63 nfa_hci_proc_nfcc_power_mode 64}; 65 66/******************************************************************************* 67** 68** Function nfa_hci_ee_info_cback 69** 70** Description Callback function 71** 72** Returns None 73** 74*******************************************************************************/ 75void nfa_hci_ee_info_cback (BOOLEAN disable_discover) 76{ 77 tNFA_HCI_EVENT_DATA *p_msg; 78 79 NFA_TRACE_DEBUG0 ("nfa_hci_ee_info_cback ()"); 80 81 memset (nfa_hci_cb.inactive_host, 0, NFA_HCI_MAX_HOST_IN_NETWORK); 82 83 /* Notify EE Discovery is complete */ 84 if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL) 85 { 86 p_msg->ee_disc_cmplt.hdr.event = NFA_HCI_EE_DISC_CMPLT_EVT; 87 p_msg->ee_disc_cmplt.b_disc_cmplt = disable_discover; 88 p_msg->ee_disc_cmplt.status = NFA_STATUS_OK; 89 nfa_hci_evt_hdlr ((BT_HDR *) p_msg); 90 } 91} 92 93/******************************************************************************* 94** 95** Function nfa_hci_init 96** 97** Description Initialize NFA HCI 98** 99** Returns None 100** 101*******************************************************************************/ 102void nfa_hci_init (void) 103{ 104 NFA_TRACE_DEBUG0 ("nfa_hci_init ()"); 105 106 /* initialize control block */ 107 memset (&nfa_hci_cb, 0, sizeof (tNFA_HCI_CB)); 108 109 nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP; 110 111 /* By Default, do not wait for any Vendor specific initialization or Vendor specific handling of EE discovery */ 112 nfa_hci_cb.w4_vsc_init = FALSE; 113 114 /* register message handler on NFA SYS */ 115 nfa_sys_register (NFA_ID_HCI, &nfa_hci_sys_reg); 116} 117 118/******************************************************************************* 119** 120** Function nfa_hci_is_valid_cfg 121** 122** Description Validate hci control block config parameters 123** 124** Returns None 125** 126*******************************************************************************/ 127BOOLEAN nfa_hci_is_valid_cfg (void) 128{ 129 UINT8 xx,yy,zz; 130 tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB]; 131 UINT8 valid_gate[NFA_HCI_MAX_GATE_CB]; 132 UINT8 app_count = 0; 133 UINT8 gate_count = 0; 134 UINT32 pipe_inx_mask = 0; 135 136 /* First, see if valid values are stored in app names, send connectivity events flag */ 137 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) 138 { 139 /* Check if app name is valid with null terminated string */ 140 if (strlen (&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN) 141 return FALSE; 142 143 /* Send Connectivity event flag can be either TRUE or FALSE */ 144 if ( (nfa_hci_cb.cfg.b_send_conn_evts[xx] != TRUE) 145 &&(nfa_hci_cb.cfg.b_send_conn_evts[xx] != FALSE)) 146 return FALSE; 147 148 if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) 149 { 150 /* Check if the app name is present more than one time in the control block */ 151 for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++) 152 { 153 if ( (nfa_hci_cb.cfg.reg_app_names[yy][0] != 0) 154 &&(!strncmp (&nfa_hci_cb.cfg.reg_app_names[xx][0], &nfa_hci_cb.cfg.reg_app_names[yy][0], strlen (nfa_hci_cb.cfg.reg_app_names[xx]))) ) 155 { 156 /* Two app cannot have the same name , NVRAM is corrupted */ 157 NFA_TRACE_EVENT2 ("nfa_hci_is_valid_cfg (%s) Reusing: %u", &nfa_hci_cb.cfg.reg_app_names[xx][0], xx); 158 return FALSE; 159 } 160 } 161 /* Collect list of hci handle */ 162 reg_app[app_count++] = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI); 163 } 164 } 165 166 /* Validate Gate Control block */ 167 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++) 168 { 169 if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0) 170 { 171 if ( ( (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE) 172 &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_IDENTITY_MANAGEMENT_GATE) 173 &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id < NFA_HCI_FIRST_DYNAMIC_GATE)) 174 ||(nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_DYNAMIC_GATE)) 175 return FALSE; 176 177 /* Check if the same gate id is present more than once in the control block */ 178 for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++) 179 { 180 if ( (nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0) 181 &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id == nfa_hci_cb.cfg.dyn_gates[yy].gate_id) ) 182 { 183 NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg Reusing: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_id); 184 return FALSE; 185 } 186 } 187 if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >= NFA_HCI_MAX_APP_CB) 188 { 189 NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg Invalid Gate owner: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_owner); 190 return FALSE; 191 } 192 if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_CONNECTIVITY_GATE) 193 { 194 /* The gate owner should be one of the registered application */ 195 for (zz = 0; zz < app_count; zz++) 196 { 197 if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz]) 198 break; 199 } 200 if (zz == app_count) 201 { 202 NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg Invalid Gate owner: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_owner); 203 return FALSE; 204 } 205 } 206 /* Collect list of allocated gates */ 207 valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id; 208 209 /* No two gates can own a same pipe */ 210 if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0) 211 return FALSE; 212 /* Collect the list of pipes on this gate */ 213 pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask; 214 } 215 } 216 217 for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB)); xx++,pipe_inx_mask >>= 1) 218 { 219 /* Every bit set in pipe increment mask indicates a valid pipe */ 220 if (pipe_inx_mask & 1) 221 { 222 /* Check if the pipe is valid one */ 223 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE) 224 return FALSE; 225 } 226 } 227 228 if (xx == NFA_HCI_MAX_PIPE_CB) 229 return FALSE; 230 231 /* Validate Gate Control block */ 232 for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) 233 { 234 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0) 235 { 236 /* Check if pipe id is valid */ 237 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE) 238 return FALSE; 239 240 /* Check if pipe state is valid */ 241 if ( (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED) 242 &&(nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED)) 243 return FALSE; 244 245 /* Check if local gate on which the pipe is created is valid */ 246 if ( (((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_LOOP_BACK_GATE) && (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) && (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate < NFA_HCI_FIRST_DYNAMIC_GATE)) 247 ||(nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_DYNAMIC_GATE)) 248 return FALSE; 249 250 /* Check if the peer gate on which the pipe is created is valid */ 251 if ( (((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate != NFA_HCI_LOOP_BACK_GATE) && (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) && (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate < NFA_HCI_FIRST_DYNAMIC_GATE)) 252 ||(nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_DYNAMIC_GATE)) 253 return FALSE; 254 255 /* Check if the same pipe is present more than once in the control block */ 256 for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++) 257 { 258 if ( (nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0) 259 &&(nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id == nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id) ) 260 { 261 NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg Reusing: %u", nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id); 262 return FALSE; 263 } 264 } 265 /* The local gate should be one of the element in gate control block */ 266 for (zz = 0; zz < gate_count; zz++) 267 { 268 if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) 269 break; 270 } 271 if (zz == gate_count) 272 { 273 NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg Invalid Gate: %u", nfa_hci_cb.cfg.dyn_pipes[xx].local_gate); 274 return FALSE; 275 } 276 } 277 } 278 279 /* Check if admin pipe state is valid */ 280 if ( (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED) 281 &&(nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED)) 282 return FALSE; 283 284 /* Check if link management pipe state is valid */ 285 if ( (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) 286 &&(nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED)) 287 return FALSE; 288 289 pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask; 290 for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB)); xx++,pipe_inx_mask >>= 1) 291 { 292 /* Every bit set in pipe increment mask indicates a valid pipe */ 293 if (pipe_inx_mask & 1) 294 { 295 /* Check if the pipe is valid one */ 296 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE) 297 return FALSE; 298 /* Check if the pipe is connected to Identity management gate */ 299 if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE) 300 return FALSE; 301 } 302 } 303 if (xx == NFA_HCI_MAX_PIPE_CB) 304 return FALSE; 305 306 return TRUE; 307} 308 309/******************************************************************************* 310** 311** Function nfa_hci_cfg_default 312** 313** Description Configure default values for hci control block 314** 315** Returns None 316** 317*******************************************************************************/ 318void nfa_hci_restore_default_config (UINT64 session_id) 319{ 320 memset (&nfa_hci_cb.cfg, 0, sizeof (nfa_hci_cb.cfg)); 321 nfa_hci_cb.cfg.admin_gate.session_id = session_id; 322 nfa_hci_cb.nv_write_needed = TRUE; 323} 324 325/******************************************************************************* 326** 327** Function nfa_hci_proc_nfcc_power_mode 328** 329** Description Restore NFA HCI sub-module 330** 331** Returns None 332** 333*******************************************************************************/ 334void nfa_hci_proc_nfcc_power_mode (UINT8 nfcc_power_mode) 335{ 336 NFA_TRACE_DEBUG1 ("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d", nfcc_power_mode); 337 338 /* if NFCC power mode is change to full power */ 339 if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) 340 { 341 nfa_hci_cb.b_low_power_mode = FALSE; 342 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) 343 { 344 nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE; 345 nfa_hci_cb.ee_disc_cmplt = FALSE; 346 } 347 else 348 { 349 NFA_TRACE_ERROR0 ("nfa_hci_proc_nfcc_power_mode (): Cannot restore now"); 350 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI); 351 } 352 } 353 else 354 { 355 nfa_sys_stop_timer (&nfa_hci_cb.timer); 356 nfa_hci_cb.b_low_power_mode = TRUE; 357 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI); 358 } 359} 360 361/******************************************************************************* 362** 363** Function nfa_hci_dh_startup_complete 364** 365** Description Initialization of terminal host in HCI Network is completed 366** Wait for other host in the network to initialize 367** 368** Returns None 369** 370*******************************************************************************/ 371void nfa_hci_dh_startup_complete (void) 372{ 373 if (nfa_hci_cb.w4_hci_netwk_init) 374 { 375 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE; 376 /* No HCP packet to DH for a specified period of time indicates all host in the network is initialized */ 377 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NETWK_INIT_TIMEOUT); 378 } 379 else 380 nfa_hci_startup_complete (NFA_STATUS_OK); 381} 382 383/******************************************************************************* 384** 385** Function nfa_hci_startup_complete 386** 387** Description HCI network initialization is completed 388** 389** Returns None 390** 391*******************************************************************************/ 392void nfa_hci_startup_complete (tNFA_STATUS status) 393{ 394 tNFA_HCI_EVT_DATA evt_data; 395 396 NFA_TRACE_EVENT1 ("nfa_hci_startup_complete (): Status: %u", status); 397 398 nfa_sys_stop_timer (&nfa_hci_cb.timer); 399 400 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) 401 { 402 nfa_ee_proc_hci_info_cback (); 403 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI); 404 } 405 else 406 { 407 evt_data.hci_init.status = status; 408 409 nfa_hciu_send_to_all_apps (NFA_HCI_INIT_EVT, &evt_data); 410 nfa_sys_cback_notify_enable_complete (NFA_ID_HCI); 411 } 412 413 if (status == NFA_STATUS_OK) 414 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 415 416 else 417 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED; 418} 419 420/******************************************************************************* 421** 422** Function nfa_hci_startup 423** 424** Description Perform HCI startup 425** 426** Returns None 427** 428*******************************************************************************/ 429void nfa_hci_startup (void) 430{ 431 tNFA_STATUS status = NFA_STATUS_FAILED; 432 tNFA_EE_INFO ee_info[2]; 433 UINT8 num_nfcee = 2; 434 UINT8 target_handle; 435 UINT8 count = 0; 436 BOOLEAN found = FALSE; 437 438 if (HCI_LOOPBACK_DEBUG) 439 { 440 /* First step in initialization is to open the admin pipe */ 441 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 442 return; 443 } 444 445 /* We can only start up if NV Ram is read and EE discovery is complete */ 446 if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt && !nfa_hci_cb.w4_vsc_init) 447 { 448 NFA_EeGetInfo (&num_nfcee, ee_info); 449 nfa_hci_cb.num_nfcee = num_nfcee; 450 451 while ((count < num_nfcee) && (!found)) 452 { 453 target_handle = (UINT8) ee_info[count].ee_handle; 454 455 if(ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS) 456 { 457 found = TRUE; 458 459 if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) 460 { 461 NFC_NfceeModeSet (target_handle, NFC_MODE_ACTIVATE); 462 } 463 if ((status = NFC_ConnCreate (NCI_DEST_TYPE_NFCEE, target_handle, NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback)) == NFA_STATUS_OK) 464 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_CON_CREATE_TIMEOUT_VAL); 465 else 466 { 467 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED; 468 NFA_TRACE_ERROR0 ("nfa_hci_startup - Failed to Create Logical connection. HCI Initialization/Restore failed"); 469 nfa_hci_startup_complete (NFA_STATUS_FAILED); 470 } 471 } 472 count++; 473 } 474 if (!found) 475 { 476 NFA_TRACE_ERROR0 ("nfa_hci_startup - HCI ACCESS Interface not discovered. HCI Initialization/Restore failed"); 477 nfa_hci_startup_complete (NFA_STATUS_FAILED); 478 } 479 } 480} 481 482/******************************************************************************* 483** 484** Function nfa_hci_sys_enable 485** 486** Description Enable NFA HCI 487** 488** Returns None 489** 490*******************************************************************************/ 491static void nfa_hci_sys_enable (void) 492{ 493 NFA_TRACE_DEBUG0 ("nfa_hci_sys_enable ()"); 494 nfa_ee_reg_cback_enable_done (&nfa_hci_ee_info_cback); 495 496 nfa_nv_co_read ((UINT8 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK); 497 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NV_READ_TIMEOUT_VAL); 498} 499 500/******************************************************************************* 501** 502** Function nfa_hci_sys_disable 503** 504** Description Disable NFA HCI 505** 506** Returns None 507** 508*******************************************************************************/ 509static void nfa_hci_sys_disable (void) 510{ 511 tNFA_HCI_EVT_DATA evt_data; 512 513 nfa_sys_stop_timer (&nfa_hci_cb.timer); 514 515 if (nfa_hci_cb.conn_id) 516 { 517 if (nfa_sys_is_graceful_disable ()) 518 { 519 /* Tell all applications stack is down */ 520 nfa_hciu_send_to_all_apps (NFA_HCI_EXIT_EVT, &evt_data); 521 NFC_ConnClose (nfa_hci_cb.conn_id); 522 return; 523 } 524 nfa_hci_cb.conn_id = 0; 525 } 526 527 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED; 528 /* deregister message handler on NFA SYS */ 529 nfa_sys_deregister (NFA_ID_HCI); 530} 531 532/******************************************************************************* 533** 534** Function nfa_hci_conn_cback 535** 536** Description This function Process event from NCI 537** 538** Returns None 539** 540*******************************************************************************/ 541static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 542{ 543 UINT8 *p; 544 BT_HDR *p_pkt = (BT_HDR *) p_data->data.p_data; 545 UINT8 chaining_bit; 546 UINT8 pipe; 547 UINT16 pkt_len; 548 tNFA_HCI_EVENT_DATA *p_msg; 549 550 if (event == NFC_CONN_CREATE_CEVT) 551 { 552 nfa_hci_cb.conn_id = conn_id; 553 nfa_hci_cb.buff_size = p_data->conn_create.buff_size; 554 555 /* Notify HCP connection is created */ 556 if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL) 557 { 558 p_msg->conn_create.hdr.event = NFA_HCI_HCP_CONN_CREATE_EVT; 559 p_msg->conn_create.status = NFA_STATUS_OK; 560 nfa_hci_evt_hdlr ((BT_HDR *) p_msg); 561 } 562 563 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) 564 { 565 nfa_hci_cb.w4_hci_netwk_init = TRUE; 566 nfa_hciu_alloc_gate (NFA_HCI_CONNECTIVITY_GATE,0); 567 } 568 569 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED) 570 { 571 /* First step in initialization/restore is to open the admin pipe */ 572 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 573 } 574 else 575 { 576 /* Read session id, to know DH session id is correct */ 577 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX); 578 } 579 } 580 else if (event == NFC_CONN_CLOSE_CEVT) 581 { 582 nfa_hci_cb.conn_id = 0; 583 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED; 584 /* deregister message handler on NFA SYS */ 585 nfa_sys_deregister (NFA_ID_HCI); 586 } 587 588 if ((event != NFC_DATA_CEVT) || (p_pkt == NULL)) 589 return; 590 591 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) 592 { 593 /* Received HCP Packet before timeout, Other Host initialization is not complete */ 594 nfa_sys_stop_timer (&nfa_hci_cb.timer); 595 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NETWK_INIT_TIMEOUT); 596 } 597 598 p = (UINT8 *) (p_pkt + 1) + p_pkt->offset; 599 pkt_len = p_pkt->len; 600 601#if (BT_TRACE_PROTOCOL == TRUE) 602 DispHcp (p, pkt_len, TRUE, (BOOLEAN) !nfa_hci_cb.assembling); 603#endif 604 605 chaining_bit = ((*p) >> 0x07) & 0x01; 606 pipe = (*p++) & 0x7F; 607 if (pkt_len != 0) 608 pkt_len--; 609 610 if (nfa_hci_cb.assembling == FALSE) 611 { 612 /* First Segment of a packet */ 613 nfa_hci_cb.type = ((*p) >> 0x06) & 0x03; 614 nfa_hci_cb.inst = (*p++ & 0x3F); 615 if (pkt_len != 0) 616 pkt_len--; 617 nfa_hci_cb.assembly_failed = FALSE; 618 nfa_hci_cb.msg_len = 0; 619 620 if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) 621 { 622 nfa_hci_cb.assembling = TRUE; 623 nfa_hci_set_receive_buf (pipe); 624 nfa_hci_assemble_msg (p, pkt_len); 625 } 626 else 627 { 628 if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) 629 { 630 nfa_hci_set_receive_buf (pipe); 631 nfa_hci_assemble_msg (p, pkt_len); 632 p = nfa_hci_cb.p_msg_data; 633 } 634 } 635 } 636 else 637 { 638 if (nfa_hci_cb.assembly_failed) 639 { 640 /* If Reassembly failed because of insufficient buffer, just drop the new segmented packets */ 641 NFA_TRACE_ERROR1 ("nfa_hci_conn_cback (): Insufficient buffer to Reassemble HCP packet! Dropping :%u bytes", pkt_len); 642 } 643 else 644 { 645 /* Reassemble the packet */ 646 nfa_hci_assemble_msg (p, pkt_len); 647 } 648 649 if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION) 650 { 651 /* Just added the last segment in the chain. Reset pointers */ 652 nfa_hci_cb.assembling = FALSE; 653 p = nfa_hci_cb.p_msg_data; 654 pkt_len = nfa_hci_cb.msg_len; 655 } 656 } 657 658#if (BT_TRACE_VERBOSE == TRUE) 659 NFA_TRACE_EVENT5 ("nfa_hci_conn_cback Recvd data pipe:%d %s chain:%d assmbl:%d len:%d", 660 (UINT8)pipe, nfa_hciu_get_type_inst_names (pipe, nfa_hci_cb.type, nfa_hci_cb.inst), 661 (UINT8)chaining_bit, (UINT8)nfa_hci_cb.assembling, p_pkt->len); 662#else 663 NFA_TRACE_EVENT6 ("nfa_hci_conn_cback Recvd data pipe:%d Type: %u Inst: %u chain:%d reassm:%d len:%d", 664 pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit, nfa_hci_cb.assembling, p_pkt->len); 665#endif 666 667 668 /* If still reassembling fragments, just return */ 669 if (nfa_hci_cb.assembling) 670 { 671 /* if not last packet, release GKI buffer */ 672 GKI_freebuf (p_pkt); 673 return; 674 } 675 676 /* If we got a response, cancel the response timer. Also, if waiting for */ 677 /* a single response, we can go back to idle state */ 678 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) 679 { 680 nfa_sys_stop_timer (&nfa_hci_cb.timer); 681 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 682 nfa_hci_cb.w4_rsp_evt = FALSE; 683 } 684 685 switch (pipe) 686 { 687 case NFA_HCI_ADMIN_PIPE: 688 /* Check if data packet is a command, response or event */ 689 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 690 { 691 nfa_hci_handle_admin_gate_cmd (p); 692 } 693 else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) 694 { 695 nfa_hci_handle_admin_gate_rsp (p, (UINT8) pkt_len); 696 } 697 else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) 698 { 699 nfa_hci_handle_admin_gate_evt (p); 700 } 701 break; 702 703 case NFA_HCI_LINK_MANAGEMENT_PIPE: 704 /* We don't send Link Management commands, we only get them */ 705 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 706 nfa_hci_handle_link_mgm_gate_cmd (p); 707 break; 708 709 default: 710 if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) 711 nfa_hci_handle_dyn_pipe_pkt (pipe, p, pkt_len); 712 break; 713 } 714 715 /* Send a message to ouselves to check for anything to do */ 716 p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT; 717 p_pkt->len = 0; 718 nfa_sys_sendmsg (p_pkt); 719} 720 721/******************************************************************************* 722** 723** Function nfa_hci_handle_nv_read 724** 725** Description handler function for nv read complete event 726** 727** Returns None 728** 729*******************************************************************************/ 730void nfa_hci_handle_nv_read (UINT8 block, tNFA_STATUS status) 731{ 732 UINT64 session_id; 733 734 if (block == DH_NV_BLOCK) 735 { 736 /* Stop timer as NVDATA Read Completed */ 737 nfa_sys_stop_timer (&nfa_hci_cb.timer); 738 nfa_hci_cb.nv_read_cmplt = TRUE; 739 if ( (status != NFA_STATUS_OK) 740 ||(!nfa_hci_is_valid_cfg ()) 741 ||(nfa_hci_cb.cfg.admin_gate.session_id == (UINT64) NFA_HCI_DEFAULT_SESSION) 742 ||(nfa_hci_cb.cfg.admin_gate.session_id == 0) ) 743 { 744 /* Set a new session id so that we clear all pipes later after seeing a difference with the HC Session ID */ 745 session_id = nfa_hci_cb.cfg.admin_gate.session_id << 32; 746 session_id |= GKI_get_os_tick_count (); 747 nfa_hci_restore_default_config (session_id); 748 } 749 nfa_hci_startup (); 750 } 751} 752 753/******************************************************************************* 754** 755** Function nfa_hci_rsp_timeout 756** 757** Description action function to process timeout 758** 759** Returns None 760** 761*******************************************************************************/ 762void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data) 763{ 764 tNFA_HCI_EVT evt = 0; 765 tNFA_HCI_EVT_DATA evt_data; 766 767 NFA_TRACE_EVENT2 ("nfa_hci_rsp_timeout () State: %u Cmd: %u", nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent); 768 769 evt_data.status = NFA_STATUS_FAILED; 770 771 switch (nfa_hci_cb.hci_state) 772 { 773 case NFA_HCI_STATE_STARTUP: 774 case NFA_HCI_STATE_RESTORE: 775 NFA_TRACE_ERROR0 ("nfa_hci_rsp_timeout - Initialization failed!"); 776 nfa_hci_startup_complete (NFA_STATUS_TIMEOUT); 777 break; 778 779 case NFA_HCI_STATE_WAIT_NETWK_ENABLE: 780 /* HCI Network is enabled */ 781 nfa_hci_cb.w4_hci_netwk_init = FALSE; 782 nfa_hci_startup_complete (NFA_STATUS_OK); 783 break; 784 785 case NFA_HCI_STATE_REMOVE_GATE: 786 /* Something wrong, NVRAM data could be corrupt */ 787 if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) 788 { 789 nfa_hciu_send_clear_all_pipe_cmd (); 790 } 791 else 792 { 793 nfa_hciu_remove_all_pipes_from_host (0); 794 nfa_hci_api_dealloc_gate (NULL); 795 } 796 break; 797 798 case NFA_HCI_STATE_APP_DEREGISTER: 799 /* Something wrong, NVRAM data could be corrupt */ 800 if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) 801 { 802 nfa_hciu_send_clear_all_pipe_cmd (); 803 } 804 else 805 { 806 nfa_hciu_remove_all_pipes_from_host (0); 807 nfa_hci_api_deregister (NULL); 808 } 809 break; 810 811 case NFA_HCI_STATE_WAIT_RSP: 812 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 813 814 if (nfa_hci_cb.w4_rsp_evt) 815 { 816 nfa_hci_cb.w4_rsp_evt = FALSE; 817 evt = NFA_HCI_EVENT_RCVD_EVT; 818 evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use; 819 evt_data.rcvd_evt.evt_code = 0; 820 evt_data.rcvd_evt.evt_len = 0; 821 evt_data.rcvd_evt.p_evt_buf = NULL; 822 nfa_hci_cb.rsp_buf_size = 0; 823 nfa_hci_cb.p_rsp_buf = NULL; 824 825 break; 826 } 827 828 switch (nfa_hci_cb.cmd_sent) 829 { 830 case NFA_HCI_ANY_SET_PARAMETER: 831 /* 832 * As no response to the command sent on this pipe, we may assume the pipe is 833 * deleted already and release the pipe. But still send delete pipe command to be safe. 834 */ 835 nfa_hciu_send_delete_pipe_cmd (nfa_hci_cb.pipe_in_use); 836 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 837 evt_data.registry.pipe = nfa_hci_cb.pipe_in_use; 838 evt_data.registry.data_len = 0; 839 evt_data.registry.index = nfa_hci_cb.param_in_use; 840 evt = NFA_HCI_SET_REG_CMD_EVT; 841 break; 842 843 case NFA_HCI_ANY_GET_PARAMETER: 844 /* 845 * As no response to the command sent on this pipe, we may assume the pipe is 846 * deleted already and release the pipe. But still send delete pipe command to be safe. 847 */ 848 nfa_hciu_send_delete_pipe_cmd (nfa_hci_cb.pipe_in_use); 849 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 850 evt_data.registry.pipe = nfa_hci_cb.pipe_in_use; 851 evt_data.registry.data_len = 0; 852 evt_data.registry.index = nfa_hci_cb.param_in_use; 853 evt = NFA_HCI_GET_REG_CMD_EVT; 854 break; 855 856 case NFA_HCI_ANY_OPEN_PIPE: 857 /* 858 * As no response to the command sent on this pipe, we may assume the pipe is 859 * deleted already and release the pipe. But still send delete pipe command to be safe. 860 */ 861 nfa_hciu_send_delete_pipe_cmd (nfa_hci_cb.pipe_in_use); 862 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 863 evt_data.opened.pipe = nfa_hci_cb.pipe_in_use; 864 evt = NFA_HCI_OPEN_PIPE_EVT; 865 break; 866 867 case NFA_HCI_ANY_CLOSE_PIPE: 868 /* 869 * As no response to the command sent on this pipe, we may assume the pipe is 870 * deleted already and release the pipe. But still send delete pipe command to be safe. 871 */ 872 nfa_hciu_send_delete_pipe_cmd (nfa_hci_cb.pipe_in_use); 873 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 874 evt_data.closed.pipe = nfa_hci_cb.pipe_in_use; 875 evt = NFA_HCI_CLOSE_PIPE_EVT; 876 break; 877 878 case NFA_HCI_ADM_CREATE_PIPE: 879 evt_data.created.pipe = nfa_hci_cb.pipe_in_use; 880 evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use; 881 evt_data.created.dest_host = nfa_hci_cb.remote_host_in_use; 882 evt_data.created.dest_gate = nfa_hci_cb.remote_gate_in_use; 883 evt = NFA_HCI_CREATE_PIPE_EVT; 884 break; 885 886 case NFA_HCI_ADM_DELETE_PIPE: 887 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 888 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use; 889 evt = NFA_HCI_DELETE_PIPE_EVT; 890 /* 891 * As no response to the command sent on this pipe, we may assume the pipe is 892 * deleted already. Just release the pipe. 893 */ 894 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 895 break; 896 897 default: 898 /* 899 * As no response to the command sent on this pipe, we may assume the pipe is 900 * deleted already and release the pipe. But still send delete pipe command to be safe. 901 */ 902 nfa_hciu_send_delete_pipe_cmd (nfa_hci_cb.pipe_in_use); 903 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 904 break; 905 } 906 break; 907 case NFA_HCI_STATE_DISABLED: 908 default: 909 NFA_TRACE_DEBUG0 ("nfa_hci_rsp_timeout () Timeout in DISABLED/ Invalid state"); 910 break; 911 } 912 if (evt != 0) 913 nfa_hciu_send_to_app (evt, &evt_data, nfa_hci_cb.app_in_use); 914} 915 916/******************************************************************************* 917** 918** Function nfa_hci_set_receive_buf 919** 920** Description Set reassembly buffer for incoming message 921** 922** Returns status 923** 924*******************************************************************************/ 925static void nfa_hci_set_receive_buf (UINT8 pipe) 926{ 927 if ( (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) 928 &&(nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) ) 929 { 930 if ( (nfa_hci_cb.rsp_buf_size) 931 &&(nfa_hci_cb.p_rsp_buf != NULL) ) 932 { 933 nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf; 934 nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size; 935 return; 936 } 937 } 938 nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data; 939 nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN; 940} 941 942/******************************************************************************* 943** 944** Function nfa_hci_assemble_msg 945** 946** Description Reassemble the incoming message 947** 948** Returns None 949** 950*******************************************************************************/ 951static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len) 952{ 953 if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) 954 { 955 /* Fill the buffer as much it can hold */ 956 memcpy (&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len)); 957 nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len; 958 /* Set Reassembly failed */ 959 nfa_hci_cb.assembly_failed = TRUE; 960 NFA_TRACE_ERROR1 ("nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP packet! Dropping :%u bytes", ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len)); 961 } 962 else 963 { 964 memcpy (&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len); 965 nfa_hci_cb.msg_len += data_len; 966 } 967} 968 969/******************************************************************************* 970** 971** Function nfa_hci_evt_hdlr 972** 973** Description Processing all event for NFA HCI 974** 975** Returns TRUE if p_msg needs to be deallocated 976** 977*******************************************************************************/ 978static BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg) 979{ 980 tNFA_HCI_EVENT_DATA *p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg; 981 982 983#if (BT_TRACE_VERBOSE == TRUE) 984 NFA_TRACE_EVENT4 ("nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)", 985 nfa_hciu_get_state_name (nfa_hci_cb.hci_state), nfa_hci_cb.hci_state, 986 nfa_hciu_get_event_name (p_evt_data->hdr.event), p_evt_data->hdr.event); 987#else 988 NFA_TRACE_EVENT2 ("nfa_hci_evt_hdlr state: %d event: 0x%04x", nfa_hci_cb.hci_state, p_evt_data->hdr.event); 989#endif 990 991 /* If this is an API request, queue it up */ 992 if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) && (p_msg->event <= NFA_HCI_LAST_API_EVENT)) 993 { 994 GKI_enqueue (&nfa_hci_cb.hci_api_q, p_msg); 995 } 996 else 997 { 998 switch (p_msg->event) 999 { 1000 case NFA_HCI_VSC_INIT_EVT: 1001 if (p_evt_data->vsc_init.status == NFA_STATUS_OK) 1002 nfa_hci_startup (); 1003 else 1004 nfa_hci_startup_complete (p_evt_data->vsc_init.status); 1005 break; 1006 1007 case NFA_HCI_EE_DISC_CMPLT_EVT: 1008 if (!p_evt_data->ee_disc_cmplt.b_disc_cmplt) 1009 { 1010 nfa_hci_cb.ee_disc_cmplt = TRUE; 1011 nfa_hci_startup (); 1012 } 1013 break; 1014 1015 case NFA_HCI_RSP_NV_READ_EVT: 1016 nfa_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status); 1017 break; 1018 1019 case NFA_HCI_RSP_NV_WRITE_EVT: 1020 /* NV Ram write completed - nothing to do... */ 1021 break; 1022 1023 case NFA_HCI_RSP_TIMEOUT_EVT: 1024 nfa_hci_rsp_timeout ((tNFA_HCI_EVENT_DATA *)p_msg); 1025 break; 1026 1027 case NFA_HCI_HCP_CONN_CREATE_EVT: 1028 break; 1029 1030 case NFA_HCI_CHECK_QUEUE_EVT: 1031 if (HCI_LOOPBACK_DEBUG) 1032 { 1033 if (p_msg->len != 0) 1034 { 1035 tNFC_DATA_CEVT xx; 1036 xx.p_data = p_msg; 1037 nfa_hci_conn_cback (0, NFC_DATA_CEVT, (tNFC_CONN *)&xx); 1038 return FALSE; 1039 } 1040 } 1041 break; 1042 } 1043 } 1044 1045 if (nfa_hci_cb.p_vs_evt_hdlr) 1046 { 1047 (*(nfa_hci_cb.p_vs_evt_hdlr)) (p_evt_data); 1048 } 1049 1050 if ((p_msg->event > NFA_HCI_LAST_API_EVENT)) 1051 GKI_freebuf (p_msg); 1052 1053 nfa_hci_check_api_requests (); 1054 1055 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) && (nfa_hci_cb.nv_write_needed)) 1056 { 1057 nfa_hci_cb.nv_write_needed = FALSE; 1058 nfa_nv_co_write ((UINT8 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK); 1059 } 1060 1061 return FALSE; 1062} 1063 1064