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 file contains the action functions for the NFA HCI. 22 * 23 ******************************************************************************/ 24#include <string.h> 25#include "nfa_dm_int.h" 26#include "nfa_hci_api.h" 27#include "nfa_hci_defs.h" 28#include "nfa_hci_int.h" 29#include "nfa_mem_co.h" 30#include "nfa_nv_co.h" 31#include "nfa_sys.h" 32#include "nfa_sys_int.h" 33#include "nfc_api.h" 34#include "trace_api.h" 35 36/* Static local functions */ 37static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data); 38static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data); 39static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data); 40static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data); 41static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data); 42static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data); 43static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 44static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 45static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 46static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 47static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data); 48static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data); 49static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data); 50static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 51 52static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data, 53 tNFA_HCI_DYN_PIPE* p_pipe); 54static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len, 55 tNFA_HCI_DYN_PIPE* p_pipe); 56static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data, 57 uint16_t data_len, 58 tNFA_HCI_DYN_PIPE* p_pipe); 59static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len, 60 tNFA_HCI_DYN_GATE* p_gate, 61 tNFA_HCI_DYN_PIPE* p_pipe); 62static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len, 63 tNFA_HCI_DYN_GATE* p_gate, 64 tNFA_HCI_DYN_PIPE* p_pipe); 65static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len, 66 tNFA_HCI_DYN_GATE* p_gate, 67 tNFA_HCI_DYN_PIPE* p_pipe); 68 69/******************************************************************************* 70** 71** Function nfa_hci_check_pending_api_requests 72** 73** Description This function handles pending API requests 74** 75** Returns none 76** 77*******************************************************************************/ 78void nfa_hci_check_pending_api_requests(void) { 79 NFC_HDR* p_msg; 80 tNFA_HCI_EVENT_DATA* p_evt_data; 81 bool b_free; 82 83 /* If busy, or API queue is empty, then exit */ 84 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) || 85 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) == 86 NULL)) 87 return; 88 89 /* Process API request */ 90 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg; 91 92 /* Save the application handle */ 93 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle; 94 95 b_free = true; 96 switch (p_msg->event) { 97 case NFA_HCI_API_CREATE_PIPE_EVT: 98 if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false; 99 break; 100 101 case NFA_HCI_API_GET_REGISTRY_EVT: 102 if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false; 103 break; 104 105 case NFA_HCI_API_SET_REGISTRY_EVT: 106 if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false; 107 break; 108 109 case NFA_HCI_API_SEND_CMD_EVT: 110 if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false; 111 break; 112 case NFA_HCI_API_SEND_EVENT_EVT: 113 if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false; 114 break; 115 } 116 117 if (b_free) GKI_freebuf(p_msg); 118} 119 120/******************************************************************************* 121** 122** Function nfa_hci_check_api_requests 123** 124** Description This function handles API requests 125** 126** Returns none 127** 128*******************************************************************************/ 129void nfa_hci_check_api_requests(void) { 130 NFC_HDR* p_msg; 131 tNFA_HCI_EVENT_DATA* p_evt_data; 132 133 for (;;) { 134 /* If busy, or API queue is empty, then exit */ 135 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) || 136 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == NULL)) 137 break; 138 139 /* Process API request */ 140 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg; 141 142 /* Save the application handle */ 143 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle; 144 145 switch (p_msg->event) { 146 case NFA_HCI_API_REGISTER_APP_EVT: 147 nfa_hci_api_register(p_evt_data); 148 break; 149 150 case NFA_HCI_API_DEREGISTER_APP_EVT: 151 nfa_hci_api_deregister(p_evt_data); 152 break; 153 154 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT: 155 nfa_hci_api_get_gate_pipe_list(p_evt_data); 156 break; 157 158 case NFA_HCI_API_ALLOC_GATE_EVT: 159 nfa_hci_api_alloc_gate(p_evt_data); 160 break; 161 162 case NFA_HCI_API_DEALLOC_GATE_EVT: 163 nfa_hci_api_dealloc_gate(p_evt_data); 164 break; 165 166 case NFA_HCI_API_GET_HOST_LIST_EVT: 167 nfa_hci_api_get_host_list(p_evt_data); 168 break; 169 170 case NFA_HCI_API_GET_REGISTRY_EVT: 171 if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue; 172 break; 173 174 case NFA_HCI_API_SET_REGISTRY_EVT: 175 if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue; 176 break; 177 178 case NFA_HCI_API_CREATE_PIPE_EVT: 179 if (nfa_hci_api_create_pipe(p_evt_data) == false) continue; 180 break; 181 182 case NFA_HCI_API_OPEN_PIPE_EVT: 183 nfa_hci_api_open_pipe(p_evt_data); 184 break; 185 186 case NFA_HCI_API_CLOSE_PIPE_EVT: 187 nfa_hci_api_close_pipe(p_evt_data); 188 break; 189 190 case NFA_HCI_API_DELETE_PIPE_EVT: 191 nfa_hci_api_delete_pipe(p_evt_data); 192 break; 193 194 case NFA_HCI_API_SEND_CMD_EVT: 195 if (nfa_hci_api_send_cmd(p_evt_data) == false) continue; 196 break; 197 198 case NFA_HCI_API_SEND_RSP_EVT: 199 nfa_hci_api_send_rsp(p_evt_data); 200 break; 201 202 case NFA_HCI_API_SEND_EVENT_EVT: 203 if (nfa_hci_api_send_event(p_evt_data) == false) continue; 204 break; 205 206 case NFA_HCI_API_ADD_STATIC_PIPE_EVT: 207 nfa_hci_api_add_static_pipe(p_evt_data); 208 break; 209 210 default: 211 NFA_TRACE_ERROR1("nfa_hci_check_api_requests () Unknown event: 0x%04x", 212 p_msg->event); 213 break; 214 } 215 216 GKI_freebuf(p_msg); 217 } 218} 219 220/******************************************************************************* 221** 222** Function nfa_hci_api_register 223** 224** Description action function to register the events for the given AID 225** 226** Returns None 227** 228*******************************************************************************/ 229static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) { 230 tNFA_HCI_EVT_DATA evt_data; 231 char* p_app_name = p_evt_data->app_info.app_name; 232 tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback; 233 int xx, yy; 234 uint8_t num_gates = 0, num_pipes = 0; 235 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates; 236 237 /* First, see if the application was already registered */ 238 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 239 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) && 240 !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], 241 strlen(p_app_name))) { 242 NFA_TRACE_EVENT2("nfa_hci_api_register (%s) Reusing: %u", p_app_name, 243 xx); 244 break; 245 } 246 } 247 248 if (xx != NFA_HCI_MAX_APP_CB) { 249 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI); 250 /* The app was registered, find the number of gates and pipes associated to 251 * the app */ 252 253 for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) { 254 if (pg->gate_owner == nfa_hci_cb.app_in_use) { 255 num_gates++; 256 num_pipes += nfa_hciu_count_pipes_on_gate(pg); 257 } 258 } 259 } else { 260 /* Not registered, look for a free entry */ 261 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 262 if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) { 263 memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0, 264 sizeof(nfa_hci_cb.cfg.reg_app_names[xx])); 265 strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name, 266 NFA_MAX_HCI_APP_NAME_LEN); 267 nfa_hci_cb.nv_write_needed = true; 268 NFA_TRACE_EVENT2("nfa_hci_api_register (%s) Allocated: %u", p_app_name, 269 xx); 270 break; 271 } 272 } 273 274 if (xx == NFA_HCI_MAX_APP_CB) { 275 NFA_TRACE_ERROR1("nfa_hci_api_register (%s) NO ENTRIES", p_app_name); 276 277 evt_data.hci_register.status = NFA_STATUS_FAILED; 278 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data); 279 return; 280 } 281 } 282 283 evt_data.hci_register.num_pipes = num_pipes; 284 evt_data.hci_register.num_gates = num_gates; 285 nfa_hci_cb.p_app_cback[xx] = p_cback; 286 287 nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts; 288 289 evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI); 290 291 evt_data.hci_register.status = NFA_STATUS_OK; 292 293 /* notify NFA_HCI_REGISTER_EVT to the application */ 294 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data); 295} 296 297/******************************************************************************* 298** 299** Function nfa_hci_api_deregister 300** 301** Description action function to deregister the given application 302** 303** Returns None 304** 305*******************************************************************************/ 306void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) { 307 tNFA_HCI_EVT_DATA evt_data; 308 tNFA_HCI_CBACK* p_cback = NULL; 309 int xx; 310 tNFA_HCI_DYN_PIPE* p_pipe; 311 tNFA_HCI_DYN_GATE* p_gate; 312 313 /* If needed, find the application registration handle */ 314 if (p_evt_data != NULL) { 315 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 316 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) && 317 !strncmp(p_evt_data->app_info.app_name, 318 &nfa_hci_cb.cfg.reg_app_names[xx][0], 319 strlen(p_evt_data->app_info.app_name))) { 320 NFA_TRACE_EVENT2("nfa_hci_api_deregister (%s) inx: %u", 321 p_evt_data->app_info.app_name, xx); 322 break; 323 } 324 } 325 326 if (xx == NFA_HCI_MAX_APP_CB) { 327 NFA_TRACE_WARNING1("nfa_hci_api_deregister () Unknown app: %s", 328 p_evt_data->app_info.app_name); 329 return; 330 } 331 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI); 332 p_cback = nfa_hci_cb.p_app_cback[xx]; 333 } else { 334 nfa_sys_stop_timer(&nfa_hci_cb.timer); 335 /* We are recursing through deleting all the app's pipes and gates */ 336 p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]; 337 } 338 339 /* See if any pipe is owned by this app */ 340 if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == NULL) { 341 /* No pipes, release all gates owned by this app */ 342 while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) != 343 NULL) 344 nfa_hciu_release_gate(p_gate->gate_id); 345 346 memset(&nfa_hci_cb.cfg 347 .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0], 348 0, NFA_MAX_HCI_APP_NAME_LEN + 1); 349 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL; 350 351 nfa_hci_cb.nv_write_needed = true; 352 353 evt_data.hci_deregister.status = NFC_STATUS_OK; 354 355 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 356 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 357 358 /* notify NFA_HCI_DEREGISTER_EVT to the application */ 359 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data); 360 } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner( 361 nfa_hci_cb.app_in_use)) == NULL) { 362 /* No pipes, release all gates owned by this app */ 363 while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner( 364 nfa_hci_cb.app_in_use)) != NULL) 365 nfa_hciu_release_gate(p_gate->gate_id); 366 367 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL; 368 369 nfa_hci_cb.nv_write_needed = true; 370 371 evt_data.hci_deregister.status = NFC_STATUS_FAILED; 372 373 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 374 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 375 376 /* notify NFA_HCI_DEREGISTER_EVT to the application */ 377 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data); 378 } else { 379 /* Delete all active pipes created for the application before de registering 380 **/ 381 nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER; 382 383 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id); 384 } 385} 386 387/******************************************************************************* 388** 389** Function nfa_hci_api_get_gate_pipe_list 390** 391** Description action function to get application allocated gates and 392** application created pipes 393** 394** Returns None 395** 396*******************************************************************************/ 397static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) { 398 tNFA_HCI_EVT_DATA evt_data; 399 int xx, yy; 400 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates; 401 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes; 402 403 evt_data.gates_pipes.num_gates = 0; 404 evt_data.gates_pipes.num_pipes = 0; 405 406 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) { 407 if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) { 408 evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id; 409 410 pp = nfa_hci_cb.cfg.dyn_pipes; 411 412 /* Loop through looking for a match */ 413 for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) { 414 if (pp->local_gate == pg->gate_id) 415 evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] = 416 *(tNFA_HCI_PIPE_INFO*)pp; 417 } 418 } 419 } 420 421 evt_data.gates_pipes.num_uicc_created_pipes = 0; 422 /* Loop through all pipes that are connected to connectivity gate */ 423 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; 424 xx++, pp++) { 425 if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) { 426 memcpy(&evt_data.gates_pipes.uicc_created_pipe 427 [evt_data.gates_pipes.num_uicc_created_pipes++], 428 pp, sizeof(tNFA_HCI_PIPE_INFO)); 429 } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) { 430 memcpy(&evt_data.gates_pipes.uicc_created_pipe 431 [evt_data.gates_pipes.num_uicc_created_pipes++], 432 pp, sizeof(tNFA_HCI_PIPE_INFO)); 433 } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE && 434 pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id && 435 pp->local_gate >= NFA_HCI_FIRST_PROP_GATE && 436 pp->local_gate <= NFA_HCI_LAST_PROP_GATE) { 437 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; 438 xx++, pg++) { 439 if (pp->local_gate == pg->gate_id) { 440 if (!pg->gate_owner) 441 memcpy(&evt_data.gates_pipes.uicc_created_pipe 442 [evt_data.gates_pipes.num_uicc_created_pipes++], 443 pp, sizeof(tNFA_HCI_PIPE_INFO)); 444 break; 445 } 446 } 447 } 448 } 449 450 evt_data.gates_pipes.status = NFA_STATUS_OK; 451 452 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */ 453 nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, 454 p_evt_data->get_gate_pipe_list.hci_handle); 455} 456 457/******************************************************************************* 458** 459** Function nfa_hci_api_alloc_gate 460** 461** Description action function to allocate gate 462** 463** Returns None 464** 465*******************************************************************************/ 466static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) { 467 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle; 468 tNFA_HCI_EVT_DATA evt_data; 469 tNFA_HCI_DYN_GATE* p_gate; 470 471 p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle); 472 473 if (p_gate) { 474 if (!p_gate->gate_owner) { 475 /* No app owns the gate yet */ 476 p_gate->gate_owner = app_handle; 477 } else if (p_gate->gate_owner != app_handle) { 478 /* Some other app owns the gate */ 479 p_gate = NULL; 480 NFA_TRACE_ERROR1( 481 "nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!", 482 p_evt_data->gate_info.gate); 483 } 484 } 485 486 evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0; 487 evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED; 488 489 /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */ 490 nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle); 491} 492 493/******************************************************************************* 494** 495** Function nfa_hci_api_dealloc_gate 496** 497** Description action function to deallocate the given generic gate 498** 499** Returns None 500** 501*******************************************************************************/ 502void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) { 503 tNFA_HCI_EVT_DATA evt_data; 504 uint8_t gate_id; 505 tNFA_HCI_DYN_GATE* p_gate; 506 tNFA_HCI_DYN_PIPE* p_pipe; 507 tNFA_HANDLE app_handle; 508 509 /* p_evt_data may be NULL if we are recursively deleting pipes */ 510 if (p_evt_data) { 511 gate_id = p_evt_data->gate_dealloc.gate; 512 app_handle = p_evt_data->gate_dealloc.hci_handle; 513 514 } else { 515 nfa_sys_stop_timer(&nfa_hci_cb.timer); 516 gate_id = nfa_hci_cb.local_gate_in_use; 517 app_handle = nfa_hci_cb.app_in_use; 518 } 519 520 evt_data.deallocated.gate = gate_id; 521 ; 522 523 p_gate = nfa_hciu_find_gate_by_gid(gate_id); 524 525 if (p_gate == NULL) { 526 evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID; 527 } else if (p_gate->gate_owner != app_handle) { 528 evt_data.deallocated.status = NFA_STATUS_FAILED; 529 } else { 530 /* See if any pipe is owned by this app */ 531 if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == NULL) { 532 nfa_hciu_release_gate(p_gate->gate_id); 533 534 nfa_hci_cb.nv_write_needed = true; 535 evt_data.deallocated.status = NFA_STATUS_OK; 536 537 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 538 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 539 } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) == 540 NULL) { 541 /* UICC is not active at the moment and cannot delete the pipe */ 542 nfa_hci_cb.nv_write_needed = true; 543 evt_data.deallocated.status = NFA_STATUS_FAILED; 544 545 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 546 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 547 } else { 548 /* Delete pipes on the gate */ 549 nfa_hci_cb.local_gate_in_use = gate_id; 550 nfa_hci_cb.app_in_use = app_handle; 551 nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE; 552 553 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id); 554 return; 555 } 556 } 557 558 nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle); 559} 560 561/******************************************************************************* 562** 563** Function nfa_hci_api_get_host_list 564** 565** Description action function to get the host list from HCI network 566** 567** Returns None 568** 569*******************************************************************************/ 570static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) { 571 uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK; 572 573 nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle; 574 575 /* Send Get Host List command on "Internal request" or requested by registered 576 * application with valid handle and callback function */ 577 if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) || 578 ((app_inx < NFA_HCI_MAX_APP_CB) && 579 (nfa_hci_cb.p_app_cback[app_inx] != NULL))) { 580 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX); 581 } 582} 583 584/******************************************************************************* 585** 586** Function nfa_hci_api_create_pipe 587** 588** Description action function to create a pipe 589** 590** Returns TRUE, if the command is processed 591** FALSE, if command is queued for processing later 592** 593*******************************************************************************/ 594static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 595 tNFA_HCI_DYN_GATE* p_gate = 596 nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate); 597 tNFA_HCI_EVT_DATA evt_data; 598 bool report_failed = false; 599 600 /* Verify that the app owns the gate that the pipe is being created on */ 601 if ((p_gate == NULL) || 602 (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) { 603 report_failed = true; 604 NFA_TRACE_ERROR2( 605 "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own " 606 "the gate:0x%x", 607 p_evt_data->create_pipe.hci_handle, 608 p_evt_data->create_pipe.source_gate); 609 } else if (nfa_hciu_check_pipe_between_gates( 610 p_evt_data->create_pipe.source_gate, 611 p_evt_data->create_pipe.dest_host, 612 p_evt_data->create_pipe.dest_gate)) { 613 report_failed = true; 614 NFA_TRACE_ERROR0( 615 "nfa_hci_api_create_pipe : Cannot create multiple pipe between the " 616 "same two gates!"); 617 } 618 619 if (report_failed) { 620 evt_data.created.source_gate = p_evt_data->create_pipe.source_gate; 621 evt_data.created.status = NFA_STATUS_FAILED; 622 623 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data, 624 p_evt_data->open_pipe.hci_handle); 625 } else { 626 if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) { 627 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 628 return false; 629 } 630 631 nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate; 632 nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate; 633 nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host; 634 nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle; 635 636 nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate, 637 p_evt_data->create_pipe.dest_host, 638 p_evt_data->create_pipe.dest_gate); 639 } 640 return true; 641} 642 643/******************************************************************************* 644** 645** Function nfa_hci_api_open_pipe 646** 647** Description action function to open a pipe 648** 649** Returns None 650** 651*******************************************************************************/ 652static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 653 tNFA_HCI_EVT_DATA evt_data; 654 tNFA_HCI_DYN_PIPE* p_pipe = 655 nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe); 656 tNFA_HCI_DYN_GATE* p_gate = NULL; 657 658 if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 659 660 if ((p_pipe != NULL) && (p_gate != NULL) && 661 (nfa_hciu_is_active_host(p_pipe->dest_host)) && 662 (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) { 663 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) { 664 nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe); 665 } else { 666 evt_data.opened.pipe = p_evt_data->open_pipe.pipe; 667 evt_data.opened.status = NFA_STATUS_OK; 668 669 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, 670 p_evt_data->open_pipe.hci_handle); 671 } 672 } else { 673 evt_data.opened.pipe = p_evt_data->open_pipe.pipe; 674 evt_data.opened.status = NFA_STATUS_FAILED; 675 676 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, 677 p_evt_data->open_pipe.hci_handle); 678 } 679} 680 681/******************************************************************************* 682** 683** Function nfa_hci_api_get_reg_value 684** 685** Description action function to get the reg value of the specified index 686** 687** Returns TRUE, if the command is processed 688** FALSE, if command is queued for processing later 689** 690*******************************************************************************/ 691static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) { 692 tNFA_HCI_DYN_PIPE* p_pipe = 693 nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe); 694 tNFA_HCI_DYN_GATE* p_gate; 695 tNFA_STATUS status = NFA_STATUS_FAILED; 696 tNFA_HCI_EVT_DATA evt_data; 697 698 if (p_pipe != NULL) { 699 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 700 701 if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) && 702 (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) { 703 nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle; 704 705 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 706 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 707 return false; 708 } 709 710 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) { 711 NFA_TRACE_WARNING1("nfa_hci_api_get_reg_value pipe:%d not open", 712 p_evt_data->get_registry.pipe); 713 } else { 714 status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe, 715 p_evt_data->get_registry.reg_inx); 716 if (status == NFA_STATUS_OK) return true; 717 } 718 } 719 } 720 721 evt_data.cmd_sent.status = status; 722 723 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 724 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 725 p_evt_data->get_registry.hci_handle); 726 return true; 727} 728 729/******************************************************************************* 730** 731** Function nfa_hci_api_set_reg_value 732** 733** Description action function to set the reg value at specified index 734** 735** Returns TRUE, if the command is processed 736** FALSE, if command is queued for processing later 737** 738*******************************************************************************/ 739static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) { 740 tNFA_HCI_DYN_PIPE* p_pipe = 741 nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe); 742 tNFA_HCI_DYN_GATE* p_gate; 743 tNFA_STATUS status = NFA_STATUS_FAILED; 744 tNFA_HCI_EVT_DATA evt_data; 745 746 if (p_pipe != NULL) { 747 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 748 749 if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) && 750 (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) { 751 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle; 752 753 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 754 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 755 return false; 756 } 757 758 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) { 759 NFA_TRACE_WARNING1("nfa_hci_api_set_reg_value pipe:%d not open", 760 p_evt_data->set_registry.pipe); 761 } else { 762 status = nfa_hciu_send_set_param_cmd( 763 p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx, 764 p_evt_data->set_registry.size, p_evt_data->set_registry.data); 765 if (status == NFA_STATUS_OK) return true; 766 } 767 } 768 } 769 evt_data.cmd_sent.status = status; 770 771 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 772 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 773 p_evt_data->set_registry.hci_handle); 774 return true; 775} 776 777/******************************************************************************* 778** 779** Function nfa_hci_api_close_pipe 780** 781** Description action function to close a pipe 782** 783** Returns None 784** 785*******************************************************************************/ 786static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 787 tNFA_HCI_EVT_DATA evt_data; 788 tNFA_HCI_DYN_PIPE* p_pipe = 789 nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe); 790 tNFA_HCI_DYN_GATE* p_gate = NULL; 791 792 if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 793 794 if ((p_pipe != NULL) && (p_gate != NULL) && 795 (nfa_hciu_is_active_host(p_pipe->dest_host)) && 796 (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) { 797 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 798 nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe); 799 } else { 800 evt_data.closed.status = NFA_STATUS_OK; 801 evt_data.closed.pipe = p_evt_data->close_pipe.pipe; 802 803 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 804 p_evt_data->close_pipe.hci_handle); 805 } 806 } else { 807 evt_data.closed.status = NFA_STATUS_FAILED; 808 evt_data.closed.pipe = 0x00; 809 810 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 811 p_evt_data->close_pipe.hci_handle); 812 } 813} 814 815/******************************************************************************* 816** 817** Function nfa_hci_api_delete_pipe 818** 819** Description action function to delete a pipe 820** 821** Returns None 822** 823*******************************************************************************/ 824static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 825 tNFA_HCI_EVT_DATA evt_data; 826 tNFA_HCI_DYN_PIPE* p_pipe = 827 nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe); 828 tNFA_HCI_DYN_GATE* p_gate = NULL; 829 830 if (p_pipe != NULL) { 831 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 832 if ((p_gate != NULL) && 833 (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) && 834 (nfa_hciu_is_active_host(p_pipe->dest_host))) { 835 nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe); 836 return; 837 } 838 } 839 840 evt_data.deleted.status = NFA_STATUS_FAILED; 841 evt_data.deleted.pipe = 0x00; 842 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, 843 p_evt_data->close_pipe.hci_handle); 844} 845 846/******************************************************************************* 847** 848** Function nfa_hci_api_send_cmd 849** 850** Description action function to send command on the given pipe 851** 852** Returns TRUE, if the command is processed 853** FALSE, if command is queued for processing later 854** 855*******************************************************************************/ 856static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) { 857 tNFA_STATUS status = NFA_STATUS_FAILED; 858 tNFA_HCI_DYN_PIPE* p_pipe; 859 tNFA_HCI_EVT_DATA evt_data; 860 tNFA_HANDLE app_handle; 861 862 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != NULL) { 863 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe); 864 865 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 866 ((app_handle == p_evt_data->send_cmd.hci_handle || 867 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 868 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 869 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 870 return false; 871 } 872 873 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 874 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe; 875 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, 876 p_evt_data->send_cmd.cmd_code, 877 p_evt_data->send_cmd.cmd_len, 878 p_evt_data->send_cmd.data); 879 if (status == NFA_STATUS_OK) return true; 880 } else { 881 NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not open", 882 p_pipe->pipe_id); 883 } 884 } else { 885 NFA_TRACE_WARNING1( 886 "nfa_hci_api_send_cmd pipe:%d Owned by different application or " 887 "Destination host is not active", 888 p_pipe->pipe_id); 889 } 890 } else { 891 NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not found", 892 p_evt_data->send_cmd.pipe); 893 } 894 895 evt_data.cmd_sent.status = status; 896 897 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 898 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 899 p_evt_data->send_cmd.hci_handle); 900 return true; 901} 902 903/******************************************************************************* 904** 905** Function nfa_hci_api_send_rsp 906** 907** Description action function to send response on the given pipe 908** 909** Returns None 910** 911*******************************************************************************/ 912static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) { 913 tNFA_STATUS status = NFA_STATUS_FAILED; 914 tNFA_HCI_DYN_PIPE* p_pipe; 915 tNFA_HCI_EVT_DATA evt_data; 916 tNFA_HANDLE app_handle; 917 918 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != NULL) { 919 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe); 920 921 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 922 ((app_handle == p_evt_data->send_rsp.hci_handle || 923 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 924 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 925 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 926 p_evt_data->send_rsp.response, 927 p_evt_data->send_rsp.size, 928 p_evt_data->send_rsp.data); 929 if (status == NFA_STATUS_OK) return; 930 } else { 931 NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not open", 932 p_pipe->pipe_id); 933 } 934 } else { 935 NFA_TRACE_WARNING1( 936 "nfa_hci_api_send_rsp pipe:%d Owned by different application or " 937 "Destination host is not active", 938 p_pipe->pipe_id); 939 } 940 } else { 941 NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not found", 942 p_evt_data->send_rsp.pipe); 943 } 944 945 evt_data.rsp_sent.status = status; 946 947 /* Send NFA_HCI_RSP_SENT_EVT to notify failure */ 948 nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data, 949 p_evt_data->send_rsp.hci_handle); 950} 951 952/******************************************************************************* 953** 954** Function nfa_hci_api_send_event 955** 956** Description action function to send an event to the given pipe 957** 958** Returns TRUE, if the event is processed 959** FALSE, if event is queued for processing later 960** 961*******************************************************************************/ 962static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) { 963 tNFA_STATUS status = NFA_STATUS_FAILED; 964 tNFA_HCI_DYN_PIPE* p_pipe; 965 tNFA_HCI_EVT_DATA evt_data; 966 tNFA_HANDLE app_handle; 967 968 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != NULL) { 969 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe); 970 971 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 972 ((app_handle == p_evt_data->send_evt.hci_handle || 973 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 974 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 975 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 976 return false; 977 } 978 979 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 980 status = nfa_hciu_send_msg( 981 p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code, 982 p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf); 983 984 if (status == NFA_STATUS_OK) { 985 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 986 nfa_hci_cb.w4_rsp_evt = true; 987 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 988 } 989 990 if (p_evt_data->send_evt.rsp_len) { 991 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 992 nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len; 993 nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf; 994 if (p_evt_data->send_evt.rsp_timeout) { 995 nfa_hci_cb.w4_rsp_evt = true; 996 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 997 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 998 p_evt_data->send_evt.rsp_timeout); 999 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1000 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1001 p_nfa_hci_cfg->hcp_response_timeout); 1002 } 1003 } else { 1004 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1005 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 1006 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1007 p_nfa_hci_cfg->hcp_response_timeout); 1008 } 1009 nfa_hci_cb.rsp_buf_size = 0; 1010 nfa_hci_cb.p_rsp_buf = NULL; 1011 } 1012 } 1013 } else { 1014 NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not open", 1015 p_pipe->pipe_id); 1016 } 1017 } else { 1018 NFA_TRACE_WARNING1( 1019 "nfa_hci_api_send_event pipe:%d Owned by different application or " 1020 "Destination host is not active", 1021 p_pipe->pipe_id); 1022 } 1023 } else { 1024 NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not found", 1025 p_evt_data->send_evt.pipe); 1026 } 1027 1028 evt_data.evt_sent.status = status; 1029 1030 /* Send NFC_HCI_EVENT_SENT_EVT to notify status */ 1031 nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data, 1032 p_evt_data->send_evt.hci_handle); 1033 return true; 1034} 1035 1036/******************************************************************************* 1037** 1038** Function nfa_hci_api_add_static_pipe 1039** 1040** Description action function to add static pipe 1041** 1042** Returns None 1043** 1044*******************************************************************************/ 1045static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 1046 tNFA_HCI_DYN_GATE* pg; 1047 tNFA_HCI_DYN_PIPE* pp; 1048 tNFA_HCI_EVT_DATA evt_data; 1049 1050 /* Allocate a proprietary gate */ 1051 pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate, 1052 p_evt_data->add_static_pipe.hci_handle); 1053 if (pg != NULL) { 1054 /* Assign new owner to the gate */ 1055 pg->gate_owner = p_evt_data->add_static_pipe.hci_handle; 1056 1057 /* Add the dynamic pipe to the proprietary gate */ 1058 if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id, 1059 p_evt_data->add_static_pipe.host, 1060 p_evt_data->add_static_pipe.gate) != 1061 NFA_HCI_ANY_OK) { 1062 /* Unable to add the dynamic pipe, so release the gate */ 1063 nfa_hciu_release_gate(pg->gate_id); 1064 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1065 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1066 p_evt_data->add_static_pipe.hci_handle); 1067 return; 1068 } 1069 pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe); 1070 if (pp != NULL) { 1071 /* This pipe is always opened */ 1072 pp->pipe_state = NFA_HCI_PIPE_OPENED; 1073 evt_data.pipe_added.status = NFA_STATUS_OK; 1074 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1075 p_evt_data->add_static_pipe.hci_handle); 1076 return; 1077 } 1078 } 1079 /* Unable to add static pipe */ 1080 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1081 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1082 p_evt_data->add_static_pipe.hci_handle); 1083} 1084 1085/******************************************************************************* 1086** 1087** Function nfa_hci_handle_link_mgm_gate_cmd 1088** 1089** Description This function handles incoming link management gate hci 1090** commands 1091** 1092** Returns none 1093** 1094*******************************************************************************/ 1095void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) { 1096 uint8_t index; 1097 uint8_t data[2]; 1098 uint8_t rsp_len = 0; 1099 uint8_t response = NFA_HCI_ANY_OK; 1100 1101 if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) && 1102 (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) { 1103 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, 1104 NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL); 1105 return; 1106 } 1107 1108 switch (nfa_hci_cb.inst) { 1109 case NFA_HCI_ANY_SET_PARAMETER: 1110 STREAM_TO_UINT8(index, p_data); 1111 1112 if (index == 1) { 1113 STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data); 1114 } else 1115 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1116 break; 1117 1118 case NFA_HCI_ANY_GET_PARAMETER: 1119 STREAM_TO_UINT8(index, p_data); 1120 if (index == 1) { 1121 data[0] = 1122 (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF); 1123 data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F); 1124 rsp_len = 2; 1125 } else 1126 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1127 break; 1128 1129 case NFA_HCI_ANY_OPEN_PIPE: 1130 data[0] = 0; 1131 rsp_len = 1; 1132 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED; 1133 break; 1134 1135 case NFA_HCI_ANY_CLOSE_PIPE: 1136 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1137 break; 1138 1139 default: 1140 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1141 break; 1142 } 1143 1144 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, 1145 response, rsp_len, data); 1146} 1147 1148/******************************************************************************* 1149** 1150** Function nfa_hci_handle_pipe_open_close_cmd 1151** 1152** Description This function handles all generic gates (excluding 1153** connectivity gate) commands 1154** 1155** Returns none 1156** 1157*******************************************************************************/ 1158void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) { 1159 uint8_t data[1]; 1160 uint8_t rsp_len = 0; 1161 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1162 tNFA_HCI_DYN_GATE* p_gate; 1163 1164 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) { 1165 if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL) 1166 data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate); 1167 else 1168 data[0] = 0; 1169 1170 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1171 rsp_len = 1; 1172 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) { 1173 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1174 } 1175 1176 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 1177 data); 1178} 1179 1180/******************************************************************************* 1181** 1182** Function nfa_hci_handle_admin_gate_cmd 1183** 1184** Description This function handles incoming commands on ADMIN gate 1185** 1186** Returns none 1187** 1188*******************************************************************************/ 1189void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) { 1190 uint8_t source_host, source_gate, dest_host, dest_gate, pipe; 1191 uint8_t data = 0; 1192 uint8_t rsp_len = 0; 1193 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1194 tNFA_HCI_DYN_GATE* pgate; 1195 tNFA_HCI_EVT_DATA evt_data; 1196 1197 switch (nfa_hci_cb.inst) { 1198 case NFA_HCI_ANY_OPEN_PIPE: 1199 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED; 1200 data = 0; 1201 rsp_len = 1; 1202 break; 1203 1204 case NFA_HCI_ANY_CLOSE_PIPE: 1205 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1206 /* Reopen the pipe immediately */ 1207 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, 1208 rsp_len, &data); 1209 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1210 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1211 return; 1212 break; 1213 1214 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED: 1215 STREAM_TO_UINT8(source_host, p_data); 1216 STREAM_TO_UINT8(source_gate, p_data); 1217 STREAM_TO_UINT8(dest_host, p_data); 1218 STREAM_TO_UINT8(dest_gate, p_data); 1219 STREAM_TO_UINT8(pipe, p_data); 1220 1221 if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) || 1222 (dest_gate == NFA_HCI_LOOP_BACK_GATE)) { 1223 response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe, 1224 source_host, source_gate); 1225 } else { 1226 if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != NULL) { 1227 /* If the gate is valid, add the pipe to it */ 1228 if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host, 1229 source_gate)) { 1230 /* Already, there is a pipe between these two gates, so will reject 1231 */ 1232 response = NFA_HCI_ANY_E_NOK; 1233 } else { 1234 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host, 1235 source_gate); 1236 if (response == NFA_HCI_ANY_OK) { 1237 /* Tell the application a pipe was created with its gate */ 1238 1239 evt_data.created.status = NFA_STATUS_OK; 1240 evt_data.created.pipe = pipe; 1241 evt_data.created.source_gate = dest_gate; 1242 evt_data.created.dest_host = source_host; 1243 evt_data.created.dest_gate = source_gate; 1244 1245 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data, 1246 pgate->gate_owner); 1247 } 1248 } 1249 } else { 1250 response = NFA_HCI_ANY_E_NOK; 1251 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) && 1252 (dest_gate <= NFA_HCI_LAST_PROP_GATE)) { 1253 if (nfa_hciu_alloc_gate(dest_gate, 0)) 1254 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host, 1255 source_gate); 1256 } 1257 } 1258 } 1259 break; 1260 1261 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED: 1262 STREAM_TO_UINT8(pipe, p_data); 1263 response = nfa_hciu_release_pipe(pipe); 1264 break; 1265 1266 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: 1267 STREAM_TO_UINT8(source_host, p_data); 1268 1269 nfa_hciu_remove_all_pipes_from_host(source_host); 1270 1271 if (source_host == NFA_HCI_HOST_CONTROLLER) { 1272 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1273 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1274 1275 /* Reopen the admin pipe immediately */ 1276 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1277 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1278 return; 1279 } else { 1280 if ((source_host >= NFA_HCI_HOST_ID_UICC0) && 1281 (source_host < 1282 (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))) { 1283 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = 1284 source_host; 1285 } 1286 } 1287 break; 1288 1289 default: 1290 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1291 break; 1292 } 1293 1294 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, 1295 rsp_len, &data); 1296} 1297 1298/******************************************************************************* 1299** 1300** Function nfa_hci_handle_admin_gate_rsp 1301** 1302** Description This function handles response received on admin gate 1303** 1304** Returns none 1305** 1306*******************************************************************************/ 1307void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) { 1308 uint8_t source_host; 1309 uint8_t source_gate = nfa_hci_cb.local_gate_in_use; 1310 uint8_t dest_host = nfa_hci_cb.remote_host_in_use; 1311 uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use; 1312 uint8_t pipe = 0; 1313 tNFA_STATUS status; 1314 tNFA_HCI_EVT_DATA evt_data; 1315 uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 1316 0xFF, 0xFF, 0xFF, 0xFF}; 1317 uint8_t host_count = 0; 1318 uint8_t host_id = 0; 1319 uint32_t os_tick; 1320 1321#if (BT_TRACE_VERBOSE == TRUE) 1322 NFA_TRACE_DEBUG4( 1323 "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: " 1324 "0x%02x Pipe: 0x%02x", 1325 nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use, 1326 nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use); 1327#else 1328 NFA_TRACE_DEBUG4( 1329 "nfa_hci_handle_admin_gate_rsp LastCmdSent: %u App: 0x%04x Gate: " 1330 "0x%02x Pipe: 0x%02x", 1331 nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, 1332 nfa_hci_cb.pipe_in_use); 1333#endif 1334 1335 /* If starting up, handle events here */ 1336 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || 1337 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) || 1338 (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) || 1339 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) { 1340 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) { 1341 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1342 return; 1343 } 1344 1345 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) { 1346 NFA_TRACE_ERROR0("nfa_hci_handle_admin_gate_rsp - Initialization failed"); 1347 nfa_hci_startup_complete(NFA_STATUS_FAILED); 1348 return; 1349 } 1350 1351 switch (nfa_hci_cb.cmd_sent) { 1352 case NFA_HCI_ANY_SET_PARAMETER: 1353 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) { 1354 /* Set WHITELIST */ 1355 nfa_hciu_send_set_param_cmd( 1356 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 1357 p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist); 1358 } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) { 1359 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || 1360 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) 1361 nfa_hci_dh_startup_complete(); 1362 } 1363 break; 1364 1365 case NFA_HCI_ANY_GET_PARAMETER: 1366 if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) { 1367 host_count = 0; 1368 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) { 1369 nfa_hci_cb.inactive_host[host_count] = 1370 NFA_HCI_HOST_ID_UICC0 + host_count; 1371 host_count++; 1372 } 1373 1374 host_count = 0; 1375 /* Collect active host in the Host Network */ 1376 while (host_count < data_len) { 1377 host_id = (uint8_t)*p_data++; 1378 1379 if ((host_id >= NFA_HCI_HOST_ID_UICC0) && 1380 (host_id < 1381 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) { 1382 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1383 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1384 } 1385 1386 host_count++; 1387 } 1388 nfa_hci_startup_complete(NFA_STATUS_OK); 1389 } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) { 1390 /* The only parameter we get when initializing is the session ID. 1391 * Check for match. */ 1392 if (!memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data, 1393 NFA_HCI_SESSION_ID_LEN)) { 1394 /* Session has not changed, Set WHITELIST */ 1395 nfa_hciu_send_set_param_cmd( 1396 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 1397 p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist); 1398 } else { 1399 /* Something wrong, NVRAM data could be corrupt or first start with 1400 * default session id */ 1401 nfa_hciu_send_clear_all_pipe_cmd(); 1402 nfa_hci_cb.b_hci_netwk_reset = true; 1403 } 1404 } 1405 break; 1406 1407 case NFA_HCI_ANY_OPEN_PIPE: 1408 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED; 1409 1410 if (nfa_hci_cb.b_hci_netwk_reset) { 1411 nfa_hci_cb.b_hci_netwk_reset = false; 1412 /* Session ID is reset, Set New session id */ 1413 memcpy( 1414 &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2], 1415 nfa_hci_cb.cfg.admin_gate.session_id, 1416 (NFA_HCI_SESSION_ID_LEN / 2)); 1417 os_tick = GKI_get_os_tick_count(); 1418 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick, 1419 (NFA_HCI_SESSION_ID_LEN / 2)); 1420 nfa_hciu_send_set_param_cmd( 1421 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, 1422 NFA_HCI_SESSION_ID_LEN, 1423 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id); 1424 } else { 1425 /* First thing is to get the session ID */ 1426 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, 1427 NFA_HCI_SESSION_IDENTITY_INDEX); 1428 } 1429 break; 1430 1431 case NFA_HCI_ADM_CLEAR_ALL_PIPE: 1432 nfa_hciu_remove_all_pipes_from_host(0); 1433 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1434 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1435 nfa_hci_cb.nv_write_needed = true; 1436 1437 /* Open admin */ 1438 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1439 break; 1440 } 1441 } else { 1442 status = 1443 (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 1444 1445 switch (nfa_hci_cb.cmd_sent) { 1446 case NFA_HCI_ANY_SET_PARAMETER: 1447 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1448 nfa_hci_api_deregister(NULL); 1449 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1450 nfa_hci_api_dealloc_gate(NULL); 1451 break; 1452 1453 case NFA_HCI_ANY_GET_PARAMETER: 1454 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) { 1455 if (!memcmp((uint8_t*)default_session, p_data, 1456 NFA_HCI_SESSION_ID_LEN)) { 1457 memcpy(&nfa_hci_cb.cfg.admin_gate 1458 .session_id[(NFA_HCI_SESSION_ID_LEN / 2)], 1459 nfa_hci_cb.cfg.admin_gate.session_id, 1460 (NFA_HCI_SESSION_ID_LEN / 2)); 1461 os_tick = GKI_get_os_tick_count(); 1462 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick, 1463 (NFA_HCI_SESSION_ID_LEN / 2)); 1464 nfa_hci_cb.nv_write_needed = true; 1465 nfa_hciu_send_set_param_cmd( 1466 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, 1467 NFA_HCI_SESSION_ID_LEN, 1468 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id); 1469 } else { 1470 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1471 nfa_hci_api_deregister(NULL); 1472 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1473 nfa_hci_api_dealloc_gate(NULL); 1474 } 1475 } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) { 1476 evt_data.hosts.status = status; 1477 evt_data.hosts.num_hosts = data_len; 1478 memcpy(evt_data.hosts.host, p_data, data_len); 1479 1480 host_count = 0; 1481 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) { 1482 nfa_hci_cb.inactive_host[host_count] = 1483 NFA_HCI_HOST_ID_UICC0 + host_count; 1484 host_count++; 1485 } 1486 1487 host_count = 0; 1488 /* Collect active host in the Host Network */ 1489 while (host_count < data_len) { 1490 host_id = (uint8_t)*p_data++; 1491 1492 if ((host_id >= NFA_HCI_HOST_ID_UICC0) && 1493 (host_id < 1494 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) { 1495 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1496 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1497 } 1498 host_count++; 1499 } 1500 if (nfa_hciu_is_no_host_resetting()) 1501 nfa_hci_check_pending_api_requests(); 1502 nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data, 1503 nfa_hci_cb.app_in_use); 1504 } 1505 break; 1506 1507 case NFA_HCI_ADM_CREATE_PIPE: 1508 if (status == NFA_STATUS_OK) { 1509 STREAM_TO_UINT8(source_host, p_data); 1510 STREAM_TO_UINT8(source_gate, p_data); 1511 STREAM_TO_UINT8(dest_host, p_data); 1512 STREAM_TO_UINT8(dest_gate, p_data); 1513 STREAM_TO_UINT8(pipe, p_data); 1514 1515 /* Sanity check */ 1516 if (source_gate != nfa_hci_cb.local_gate_in_use) { 1517 NFA_TRACE_WARNING2( 1518 "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u " 1519 "got back: %u", 1520 nfa_hci_cb.local_gate_in_use, source_gate); 1521 break; 1522 } 1523 1524 nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate); 1525 } 1526 1527 /* Tell the application his pipe was created or not */ 1528 evt_data.created.status = status; 1529 evt_data.created.pipe = pipe; 1530 evt_data.created.source_gate = source_gate; 1531 evt_data.created.dest_host = dest_host; 1532 evt_data.created.dest_gate = dest_gate; 1533 1534 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data, 1535 nfa_hci_cb.app_in_use); 1536 break; 1537 1538 case NFA_HCI_ADM_DELETE_PIPE: 1539 if (status == NFA_STATUS_OK) { 1540 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use); 1541 1542 /* If only deleting one pipe, tell the app we are done */ 1543 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) { 1544 evt_data.deleted.status = status; 1545 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use; 1546 1547 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, 1548 nfa_hci_cb.app_in_use); 1549 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1550 nfa_hci_api_deregister(NULL); 1551 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1552 nfa_hci_api_dealloc_gate(NULL); 1553 } else { 1554 /* If only deleting one pipe, tell the app we are done */ 1555 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) { 1556 evt_data.deleted.status = status; 1557 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use; 1558 1559 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, 1560 nfa_hci_cb.app_in_use); 1561 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) { 1562 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use); 1563 nfa_hci_api_deregister(NULL); 1564 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) { 1565 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use); 1566 nfa_hci_api_dealloc_gate(NULL); 1567 } 1568 } 1569 break; 1570 1571 case NFA_HCI_ANY_OPEN_PIPE: 1572 nfa_hci_cb.cfg.admin_gate.pipe01_state = 1573 status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED; 1574 nfa_hci_cb.nv_write_needed = true; 1575 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) { 1576 /* First thing is to get the session ID */ 1577 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, 1578 NFA_HCI_SESSION_IDENTITY_INDEX); 1579 } 1580 break; 1581 1582 case NFA_HCI_ADM_CLEAR_ALL_PIPE: 1583 nfa_hciu_remove_all_pipes_from_host(0); 1584 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1585 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1586 nfa_hci_cb.nv_write_needed = true; 1587 /* Open admin */ 1588 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1589 break; 1590 } 1591 } 1592} 1593 1594/******************************************************************************* 1595** 1596** Function nfa_hci_handle_admin_gate_evt 1597** 1598** Description This function handles events received on admin gate 1599** 1600** Returns none 1601** 1602*******************************************************************************/ 1603void nfa_hci_handle_admin_gate_evt(uint8_t* p_data) { 1604 tNFA_HCI_EVT_DATA evt_data; 1605 tNFA_HCI_API_GET_HOST_LIST* p_msg; 1606 1607 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) { 1608 NFA_TRACE_ERROR0( 1609 "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe"); 1610 return; 1611 } 1612 1613 NFA_TRACE_DEBUG0( 1614 "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe"); 1615 nfa_hci_cb.num_hot_plug_evts++; 1616 1617 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) || 1618 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) { 1619 /* Received Hot Plug evt while waiting for other Host in the network to 1620 * bootup after DH host bootup is complete */ 1621 if ((nfa_hci_cb.ee_disable_disc) && 1622 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) && 1623 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) { 1624 /* Received expected number of Hot Plug event(s) before as many number of 1625 * EE DISC REQ Ntf(s) are received */ 1626 nfa_sys_stop_timer(&nfa_hci_cb.timer); 1627 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ 1628 * Ntf(s) */ 1629 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1630 p_nfa_hci_cfg->hci_netwk_enable_timeout); 1631 } 1632 } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || 1633 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) { 1634 /* Received Hot Plug evt during DH host bootup */ 1635 if ((nfa_hci_cb.ee_disable_disc) && 1636 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) && 1637 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) { 1638 /* Received expected number of Hot Plug event(s) before as many number of 1639 * EE DISC REQ Ntf(s) are received */ 1640 nfa_hci_cb.w4_hci_netwk_init = false; 1641 } 1642 } else { 1643 /* Received Hot Plug evt on UICC self reset */ 1644 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 1645 /* Notify all registered application with the HOT_PLUG_EVT */ 1646 nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data); 1647 1648 /* Send Get Host List after receiving any pending response */ 1649 p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf( 1650 sizeof(tNFA_HCI_API_GET_HOST_LIST)); 1651 if (p_msg != NULL) { 1652 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT; 1653 /* Set Invalid handle to identify this Get Host List command is internal 1654 */ 1655 p_msg->hci_handle = NFA_HANDLE_INVALID; 1656 1657 nfa_sys_sendmsg(p_msg); 1658 } 1659 } 1660} 1661 1662/******************************************************************************* 1663** 1664** Function nfa_hci_handle_dyn_pipe_pkt 1665** 1666** Description This function handles data received via dynamic pipe 1667** 1668** Returns none 1669** 1670*******************************************************************************/ 1671void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data, 1672 uint16_t data_len) { 1673 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id); 1674 tNFA_HCI_DYN_GATE* p_gate; 1675 1676 if (p_pipe == NULL) { 1677 /* Invalid pipe ID */ 1678 NFA_TRACE_ERROR1("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d", pipe_id); 1679 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1680 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, 1681 NULL); 1682 return; 1683 } 1684 1685 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) { 1686 nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe); 1687 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1688 nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe); 1689 } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) { 1690 nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe); 1691 } else { 1692 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 1693 if (p_gate == NULL) { 1694 NFA_TRACE_ERROR1( 1695 "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt", 1696 p_pipe->local_gate); 1697 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1698 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, 1699 NULL); 1700 return; 1701 } 1702 1703 /* Check if data packet is a command, response or event */ 1704 switch (nfa_hci_cb.type) { 1705 case NFA_HCI_COMMAND_TYPE: 1706 nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_gate, 1707 p_pipe); 1708 break; 1709 1710 case NFA_HCI_RESPONSE_TYPE: 1711 nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_gate, 1712 p_pipe); 1713 break; 1714 1715 case NFA_HCI_EVENT_TYPE: 1716 nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe); 1717 break; 1718 } 1719 } 1720} 1721 1722/******************************************************************************* 1723** 1724** Function nfa_hci_handle_identity_mgmt_gate_pkt 1725** 1726** Description This function handles incoming Identity Management gate hci 1727** commands 1728** 1729** Returns none 1730** 1731*******************************************************************************/ 1732static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data, 1733 tNFA_HCI_DYN_PIPE* p_pipe) { 1734 uint8_t data[20]; 1735 uint8_t index; 1736 uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates; 1737 uint16_t rsp_len = 0; 1738 uint8_t* p_rsp = data; 1739 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1740 1741 /* We never send commands on a pipe where the local gate is the identity 1742 * management 1743 * gate, so only commands should be processed. 1744 */ 1745 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return; 1746 1747 switch (nfa_hci_cb.inst) { 1748 case NFA_HCI_ANY_GET_PARAMETER: 1749 index = *(p_data++); 1750 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 1751 switch (index) { 1752 case NFA_HCI_VERSION_SW_INDEX: 1753 data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF); 1754 data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF); 1755 data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF); 1756 rsp_len = 3; 1757 break; 1758 1759 case NFA_HCI_HCI_VERSION_INDEX: 1760 data[0] = NFA_HCI_VERSION; 1761 rsp_len = 1; 1762 break; 1763 1764 case NFA_HCI_VERSION_HW_INDEX: 1765 data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF); 1766 data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF); 1767 data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF); 1768 rsp_len = 3; 1769 break; 1770 1771 case NFA_HCI_VENDOR_NAME_INDEX: 1772 memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME)); 1773 rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME); 1774 break; 1775 1776 case NFA_HCI_MODEL_ID_INDEX: 1777 data[0] = NFA_HCI_MODEL_ID; 1778 rsp_len = 1; 1779 break; 1780 1781 case NFA_HCI_GATES_LIST_INDEX: 1782 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE; 1783 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE; 1784 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE; 1785 num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]); 1786 rsp_len = num_gates + 3; 1787 p_rsp = gate_rsp; 1788 break; 1789 1790 default: 1791 response = NFA_HCI_ANY_E_NOK; 1792 break; 1793 } 1794 } else { 1795 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED; 1796 } 1797 break; 1798 1799 case NFA_HCI_ANY_OPEN_PIPE: 1800 data[0] = 0; 1801 rsp_len = 1; 1802 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1803 break; 1804 1805 case NFA_HCI_ANY_CLOSE_PIPE: 1806 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1807 break; 1808 1809 default: 1810 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1811 break; 1812 } 1813 1814 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 1815 p_rsp); 1816} 1817 1818/******************************************************************************* 1819** 1820** Function nfa_hci_handle_generic_gate_cmd 1821** 1822** Description This function handles all generic gates (excluding 1823** connectivity gate) commands 1824** 1825** Returns none 1826** 1827*******************************************************************************/ 1828static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len, 1829 tNFA_HCI_DYN_GATE* p_gate, 1830 tNFA_HCI_DYN_PIPE* p_pipe) { 1831 tNFA_HCI_EVT_DATA evt_data; 1832 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id); 1833 1834 switch (nfa_hci_cb.inst) { 1835 case NFA_HCI_ANY_SET_PARAMETER: 1836 evt_data.registry.pipe = p_pipe->pipe_id; 1837 evt_data.registry.index = *p_data++; 1838 if (data_len > 0) data_len--; 1839 evt_data.registry.data_len = data_len; 1840 1841 memcpy(evt_data.registry.reg_data, p_data, data_len); 1842 1843 nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle); 1844 break; 1845 1846 case NFA_HCI_ANY_GET_PARAMETER: 1847 evt_data.registry.pipe = p_pipe->pipe_id; 1848 evt_data.registry.index = *p_data; 1849 evt_data.registry.data_len = 0; 1850 1851 nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle); 1852 break; 1853 1854 case NFA_HCI_ANY_OPEN_PIPE: 1855 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1856 1857 evt_data.opened.pipe = p_pipe->pipe_id; 1858 evt_data.opened.status = NFA_STATUS_OK; 1859 1860 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle); 1861 break; 1862 1863 case NFA_HCI_ANY_CLOSE_PIPE: 1864 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1865 1866 evt_data.closed.pipe = p_pipe->pipe_id; 1867 evt_data.opened.status = NFA_STATUS_OK; 1868 1869 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle); 1870 break; 1871 1872 default: 1873 /* Could be application specific command, pass it on */ 1874 evt_data.cmd_rcvd.status = NFA_STATUS_OK; 1875 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id; 1876 ; 1877 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst; 1878 evt_data.cmd_rcvd.cmd_len = data_len; 1879 1880 if (data_len <= NFA_MAX_HCI_CMD_LEN) 1881 memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len); 1882 1883 nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle); 1884 break; 1885 } 1886} 1887 1888/******************************************************************************* 1889** 1890** Function nfa_hci_handle_generic_gate_rsp 1891** 1892** Description This function handles all generic gates (excluding 1893** connectivity) response 1894** 1895** Returns none 1896** 1897*******************************************************************************/ 1898static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len, 1899 tNFA_HCI_DYN_GATE* p_gate, 1900 tNFA_HCI_DYN_PIPE* p_pipe) { 1901 tNFA_HCI_EVT_DATA evt_data; 1902 tNFA_STATUS status = NFA_STATUS_OK; 1903 1904 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED; 1905 1906 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) { 1907 if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1908 1909 nfa_hci_cb.nv_write_needed = true; 1910 /* Tell application */ 1911 evt_data.opened.status = status; 1912 evt_data.opened.pipe = p_pipe->pipe_id; 1913 1914 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, 1915 nfa_hci_cb.app_in_use); 1916 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) { 1917 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1918 1919 nfa_hci_cb.nv_write_needed = true; 1920 /* Tell application */ 1921 evt_data.opened.status = status; 1922 ; 1923 evt_data.opened.pipe = p_pipe->pipe_id; 1924 1925 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 1926 nfa_hci_cb.app_in_use); 1927 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) { 1928 /* Tell application */ 1929 evt_data.registry.status = status; 1930 evt_data.registry.pipe = p_pipe->pipe_id; 1931 evt_data.registry.data_len = data_len; 1932 evt_data.registry.index = nfa_hci_cb.param_in_use; 1933 1934 memcpy(evt_data.registry.reg_data, p_data, data_len); 1935 1936 nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data, 1937 nfa_hci_cb.app_in_use); 1938 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) { 1939 /* Tell application */ 1940 evt_data.registry.status = status; 1941 ; 1942 evt_data.registry.pipe = p_pipe->pipe_id; 1943 1944 nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data, 1945 nfa_hci_cb.app_in_use); 1946 } else { 1947 /* Could be a response to application specific command sent, pass it on */ 1948 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 1949 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 1950 ; 1951 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 1952 evt_data.rsp_rcvd.rsp_len = data_len; 1953 1954 if (data_len <= NFA_MAX_HCI_RSP_LEN) 1955 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 1956 1957 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 1958 nfa_hci_cb.app_in_use); 1959 } 1960} 1961 1962/******************************************************************************* 1963** 1964** Function nfa_hci_handle_connectivity_gate_pkt 1965** 1966** Description This function handles incoming connectivity gate packets 1967** 1968** Returns none 1969** 1970*******************************************************************************/ 1971static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data, 1972 uint16_t data_len, 1973 tNFA_HCI_DYN_PIPE* p_pipe) { 1974 tNFA_HCI_EVT_DATA evt_data; 1975 1976 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) { 1977 switch (nfa_hci_cb.inst) { 1978 case NFA_HCI_ANY_OPEN_PIPE: 1979 case NFA_HCI_ANY_CLOSE_PIPE: 1980 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1981 break; 1982 1983 case NFA_HCI_CON_PRO_HOST_REQUEST: 1984 /* A request to the DH to activate another host. This is not supported 1985 * for */ 1986 /* now, we will implement it when the spec is clearer and UICCs need it. 1987 */ 1988 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 1989 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 1990 break; 1991 1992 default: 1993 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 1994 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 1995 break; 1996 } 1997 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) { 1998 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && 1999 (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 2000 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2001 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 2002 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2003 2004 /* Could be a response to application specific command sent, pass it on */ 2005 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2006 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 2007 ; 2008 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2009 evt_data.rsp_rcvd.rsp_len = data_len; 2010 2011 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2012 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2013 2014 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 2015 nfa_hci_cb.app_in_use); 2016 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) { 2017 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2018 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2019 evt_data.rcvd_evt.evt_len = data_len; 2020 evt_data.rcvd_evt.p_evt_buf = p_data; 2021 2022 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2023 nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT, 2024 &evt_data); 2025 } 2026} 2027 2028/******************************************************************************* 2029** 2030** Function nfa_hci_handle_loopback_gate_pkt 2031** 2032** Description This function handles incoming loopback gate hci events 2033** 2034** Returns none 2035** 2036*******************************************************************************/ 2037static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len, 2038 tNFA_HCI_DYN_PIPE* p_pipe) { 2039 uint8_t data[1]; 2040 uint8_t rsp_len = 0; 2041 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 2042 tNFA_HCI_EVT_DATA evt_data; 2043 2044 /* Check if data packet is a command, response or event */ 2045 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) { 2046 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) { 2047 data[0] = 0; 2048 rsp_len = 1; 2049 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2050 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) { 2051 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2052 } else 2053 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 2054 2055 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 2056 data); 2057 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) { 2058 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && 2059 (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 2060 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2061 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 2062 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2063 2064 /* Could be a response to application specific command sent, pass it on */ 2065 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2066 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 2067 ; 2068 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2069 evt_data.rsp_rcvd.rsp_len = data_len; 2070 2071 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2072 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2073 2074 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 2075 nfa_hci_cb.app_in_use); 2076 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) { 2077 if (nfa_hci_cb.w4_rsp_evt) { 2078 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2079 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2080 evt_data.rcvd_evt.evt_len = data_len; 2081 evt_data.rcvd_evt.p_evt_buf = p_data; 2082 2083 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, 2084 nfa_hci_cb.app_in_use); 2085 } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) { 2086 /* Send back the same data we got */ 2087 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, 2088 NFA_HCI_EVT_POST_DATA, data_len, p_data); 2089 } 2090 } 2091} 2092 2093/******************************************************************************* 2094** 2095** Function nfa_hci_handle_generic_gate_evt 2096** 2097** Description This function handles incoming Generic gate hci events 2098** 2099** Returns none 2100** 2101*******************************************************************************/ 2102static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len, 2103 tNFA_HCI_DYN_GATE* p_gate, 2104 tNFA_HCI_DYN_PIPE* p_pipe) { 2105 tNFA_HCI_EVT_DATA evt_data; 2106 2107 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2108 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2109 evt_data.rcvd_evt.evt_len = data_len; 2110 2111 if (nfa_hci_cb.assembly_failed) 2112 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL; 2113 else 2114 evt_data.rcvd_evt.status = NFA_STATUS_OK; 2115 2116 evt_data.rcvd_evt.p_evt_buf = p_data; 2117 nfa_hci_cb.rsp_buf_size = 0; 2118 nfa_hci_cb.p_rsp_buf = NULL; 2119 2120 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2121 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner); 2122} 2123