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