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 26 #include <android-base/stringprintf.h> 27 #include <base/logging.h> 28 29 #include "nfa_dm_int.h" 30 #include "nfa_hci_api.h" 31 #include "nfa_hci_defs.h" 32 #include "nfa_hci_int.h" 33 34 using android::base::StringPrintf; 35 36 extern bool nfc_debug_enabled; 37 38 /* Static local functions */ 39 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data); 40 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data); 41 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data); 42 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data); 43 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data); 44 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data); 45 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 46 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 47 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 48 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 49 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data); 50 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data); 51 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data); 52 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data); 53 54 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data, 55 tNFA_HCI_DYN_PIPE* p_pipe); 56 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len, 57 tNFA_HCI_DYN_PIPE* p_pipe); 58 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data, 59 uint16_t data_len, 60 tNFA_HCI_DYN_PIPE* p_pipe); 61 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len, 62 tNFA_HCI_DYN_PIPE* p_pipe); 63 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len, 64 tNFA_HCI_DYN_PIPE* p_pipe); 65 static 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 *******************************************************************************/ 78 void 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 *******************************************************************************/ 129 void 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 LOG(ERROR) << StringPrintf("Unknown event: 0x%04x", p_msg->event); 212 break; 213 } 214 215 GKI_freebuf(p_msg); 216 } 217 } 218 219 /******************************************************************************* 220 ** 221 ** Function nfa_hci_api_register 222 ** 223 ** Description action function to register the events for the given AID 224 ** 225 ** Returns None 226 ** 227 *******************************************************************************/ 228 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) { 229 tNFA_HCI_EVT_DATA evt_data; 230 char* p_app_name = p_evt_data->app_info.app_name; 231 tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback; 232 int xx, yy; 233 uint8_t num_gates = 0, num_pipes = 0; 234 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates; 235 236 /* First, see if the application was already registered */ 237 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 238 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) && 239 !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], 240 strlen(p_app_name))) { 241 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 242 "nfa_hci_api_register (%s) Reusing: %u", p_app_name, xx); 243 break; 244 } 245 } 246 247 if (xx != NFA_HCI_MAX_APP_CB) { 248 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI); 249 /* The app was registered, find the number of gates and pipes associated to 250 * the app */ 251 252 for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) { 253 if (pg->gate_owner == nfa_hci_cb.app_in_use) { 254 num_gates++; 255 num_pipes += nfa_hciu_count_pipes_on_gate(pg); 256 } 257 } 258 } else { 259 /* Not registered, look for a free entry */ 260 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 261 if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) { 262 memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0, 263 sizeof(nfa_hci_cb.cfg.reg_app_names[xx])); 264 strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name, 265 NFA_MAX_HCI_APP_NAME_LEN); 266 nfa_hci_cb.nv_write_needed = true; 267 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 268 "nfa_hci_api_register (%s) Allocated: %u", p_app_name, xx); 269 break; 270 } 271 } 272 273 if (xx == NFA_HCI_MAX_APP_CB) { 274 LOG(ERROR) << StringPrintf("nfa_hci_api_register (%s) NO ENTRIES", 275 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 *******************************************************************************/ 306 void 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 DLOG_IF(INFO, nfc_debug_enabled) 321 << StringPrintf("nfa_hci_api_deregister (%s) inx: %u", 322 p_evt_data->app_info.app_name, xx); 323 break; 324 } 325 } 326 327 if (xx == NFA_HCI_MAX_APP_CB) { 328 LOG(WARNING) << StringPrintf("Unknown app: %s", 329 p_evt_data->app_info.app_name); 330 return; 331 } 332 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI); 333 p_cback = nfa_hci_cb.p_app_cback[xx]; 334 } else { 335 nfa_sys_stop_timer(&nfa_hci_cb.timer); 336 /* We are recursing through deleting all the app's pipes and gates */ 337 p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]; 338 } 339 340 /* See if any pipe is owned by this app */ 341 if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == NULL) { 342 /* No pipes, release all gates owned by this app */ 343 while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) != 344 NULL) 345 nfa_hciu_release_gate(p_gate->gate_id); 346 347 memset(&nfa_hci_cb.cfg 348 .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0], 349 0, NFA_MAX_HCI_APP_NAME_LEN + 1); 350 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL; 351 352 nfa_hci_cb.nv_write_needed = true; 353 354 evt_data.hci_deregister.status = NFC_STATUS_OK; 355 356 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 357 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 358 359 /* notify NFA_HCI_DEREGISTER_EVT to the application */ 360 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data); 361 } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner( 362 nfa_hci_cb.app_in_use)) == NULL) { 363 /* No pipes, release all gates owned by this app */ 364 while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner( 365 nfa_hci_cb.app_in_use)) != NULL) 366 nfa_hciu_release_gate(p_gate->gate_id); 367 368 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL; 369 370 nfa_hci_cb.nv_write_needed = true; 371 372 evt_data.hci_deregister.status = NFC_STATUS_FAILED; 373 374 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 375 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 376 377 /* notify NFA_HCI_DEREGISTER_EVT to the application */ 378 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data); 379 } else { 380 /* Delete all active pipes created for the application before de registering 381 **/ 382 nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER; 383 384 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id); 385 } 386 } 387 388 /******************************************************************************* 389 ** 390 ** Function nfa_hci_api_get_gate_pipe_list 391 ** 392 ** Description action function to get application allocated gates and 393 ** application created pipes 394 ** 395 ** Returns None 396 ** 397 *******************************************************************************/ 398 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) { 399 tNFA_HCI_EVT_DATA evt_data; 400 int xx, yy; 401 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates; 402 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes; 403 404 evt_data.gates_pipes.num_gates = 0; 405 evt_data.gates_pipes.num_pipes = 0; 406 407 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) { 408 if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) { 409 evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id; 410 411 pp = nfa_hci_cb.cfg.dyn_pipes; 412 413 /* Loop through looking for a match */ 414 for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) { 415 if (pp->local_gate == pg->gate_id) 416 evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] = 417 *(tNFA_HCI_PIPE_INFO*)pp; 418 } 419 } 420 } 421 422 evt_data.gates_pipes.num_uicc_created_pipes = 0; 423 /* Loop through all pipes that are connected to connectivity gate */ 424 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; 425 xx++, pp++) { 426 if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) { 427 memcpy(&evt_data.gates_pipes.uicc_created_pipe 428 [evt_data.gates_pipes.num_uicc_created_pipes++], 429 pp, sizeof(tNFA_HCI_PIPE_INFO)); 430 } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) { 431 memcpy(&evt_data.gates_pipes.uicc_created_pipe 432 [evt_data.gates_pipes.num_uicc_created_pipes++], 433 pp, sizeof(tNFA_HCI_PIPE_INFO)); 434 } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE && 435 pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id && 436 pp->local_gate >= NFA_HCI_FIRST_PROP_GATE && 437 pp->local_gate <= NFA_HCI_LAST_PROP_GATE) { 438 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; 439 xx++, pg++) { 440 if (pp->local_gate == pg->gate_id) { 441 if (!pg->gate_owner) 442 memcpy(&evt_data.gates_pipes.uicc_created_pipe 443 [evt_data.gates_pipes.num_uicc_created_pipes++], 444 pp, sizeof(tNFA_HCI_PIPE_INFO)); 445 break; 446 } 447 } 448 } 449 } 450 451 evt_data.gates_pipes.status = NFA_STATUS_OK; 452 453 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */ 454 nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, 455 p_evt_data->get_gate_pipe_list.hci_handle); 456 } 457 458 /******************************************************************************* 459 ** 460 ** Function nfa_hci_api_alloc_gate 461 ** 462 ** Description action function to allocate gate 463 ** 464 ** Returns None 465 ** 466 *******************************************************************************/ 467 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) { 468 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle; 469 tNFA_HCI_EVT_DATA evt_data; 470 tNFA_HCI_DYN_GATE* p_gate; 471 472 p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle); 473 474 if (p_gate) { 475 if (!p_gate->gate_owner) { 476 /* No app owns the gate yet */ 477 p_gate->gate_owner = app_handle; 478 } else if (p_gate->gate_owner != app_handle) { 479 /* Some other app owns the gate */ 480 p_gate = NULL; 481 LOG(ERROR) << StringPrintf("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 *******************************************************************************/ 502 void 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 *******************************************************************************/ 570 static 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 *******************************************************************************/ 594 static 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 LOG(ERROR) << StringPrintf( 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 LOG(ERROR) << StringPrintf( 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 *******************************************************************************/ 652 static 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 *******************************************************************************/ 691 static 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 LOG(WARNING) << StringPrintf( 712 "nfa_hci_api_get_reg_value pipe:%d not open", 713 p_evt_data->get_registry.pipe); 714 } else { 715 status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe, 716 p_evt_data->get_registry.reg_inx); 717 if (status == NFA_STATUS_OK) return true; 718 } 719 } 720 } 721 722 evt_data.cmd_sent.status = status; 723 724 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 725 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 726 p_evt_data->get_registry.hci_handle); 727 return true; 728 } 729 730 /******************************************************************************* 731 ** 732 ** Function nfa_hci_api_set_reg_value 733 ** 734 ** Description action function to set the reg value at specified index 735 ** 736 ** Returns TRUE, if the command is processed 737 ** FALSE, if command is queued for processing later 738 ** 739 *******************************************************************************/ 740 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) { 741 tNFA_HCI_DYN_PIPE* p_pipe = 742 nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe); 743 tNFA_HCI_DYN_GATE* p_gate; 744 tNFA_STATUS status = NFA_STATUS_FAILED; 745 tNFA_HCI_EVT_DATA evt_data; 746 747 if (p_pipe != NULL) { 748 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 749 750 if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) && 751 (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) { 752 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle; 753 754 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 755 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 756 return false; 757 } 758 759 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) { 760 LOG(WARNING) << StringPrintf( 761 "nfa_hci_api_set_reg_value pipe:%d not open", 762 p_evt_data->set_registry.pipe); 763 } else { 764 status = nfa_hciu_send_set_param_cmd( 765 p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx, 766 p_evt_data->set_registry.size, p_evt_data->set_registry.data); 767 if (status == NFA_STATUS_OK) return true; 768 } 769 } 770 } 771 evt_data.cmd_sent.status = status; 772 773 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 774 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 775 p_evt_data->set_registry.hci_handle); 776 return true; 777 } 778 779 /******************************************************************************* 780 ** 781 ** Function nfa_hci_api_close_pipe 782 ** 783 ** Description action function to close a pipe 784 ** 785 ** Returns None 786 ** 787 *******************************************************************************/ 788 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 789 tNFA_HCI_EVT_DATA evt_data; 790 tNFA_HCI_DYN_PIPE* p_pipe = 791 nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe); 792 tNFA_HCI_DYN_GATE* p_gate = NULL; 793 794 if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 795 796 if ((p_pipe != NULL) && (p_gate != NULL) && 797 (nfa_hciu_is_active_host(p_pipe->dest_host)) && 798 (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) { 799 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 800 nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe); 801 } else { 802 evt_data.closed.status = NFA_STATUS_OK; 803 evt_data.closed.pipe = p_evt_data->close_pipe.pipe; 804 805 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 806 p_evt_data->close_pipe.hci_handle); 807 } 808 } else { 809 evt_data.closed.status = NFA_STATUS_FAILED; 810 evt_data.closed.pipe = 0x00; 811 812 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 813 p_evt_data->close_pipe.hci_handle); 814 } 815 } 816 817 /******************************************************************************* 818 ** 819 ** Function nfa_hci_api_delete_pipe 820 ** 821 ** Description action function to delete a pipe 822 ** 823 ** Returns None 824 ** 825 *******************************************************************************/ 826 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 827 tNFA_HCI_EVT_DATA evt_data; 828 tNFA_HCI_DYN_PIPE* p_pipe = 829 nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe); 830 tNFA_HCI_DYN_GATE* p_gate = NULL; 831 832 if (p_pipe != NULL) { 833 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 834 if ((p_gate != NULL) && 835 (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) && 836 (nfa_hciu_is_active_host(p_pipe->dest_host))) { 837 nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe); 838 return; 839 } 840 } 841 842 evt_data.deleted.status = NFA_STATUS_FAILED; 843 evt_data.deleted.pipe = 0x00; 844 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, 845 p_evt_data->close_pipe.hci_handle); 846 } 847 848 /******************************************************************************* 849 ** 850 ** Function nfa_hci_api_send_cmd 851 ** 852 ** Description action function to send command on the given pipe 853 ** 854 ** Returns TRUE, if the command is processed 855 ** FALSE, if command is queued for processing later 856 ** 857 *******************************************************************************/ 858 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) { 859 tNFA_STATUS status = NFA_STATUS_FAILED; 860 tNFA_HCI_DYN_PIPE* p_pipe; 861 tNFA_HCI_EVT_DATA evt_data; 862 tNFA_HANDLE app_handle; 863 864 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != NULL) { 865 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe); 866 867 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 868 ((app_handle == p_evt_data->send_cmd.hci_handle || 869 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 870 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 871 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 872 return false; 873 } 874 875 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 876 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe; 877 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, 878 p_evt_data->send_cmd.cmd_code, 879 p_evt_data->send_cmd.cmd_len, 880 p_evt_data->send_cmd.data); 881 if (status == NFA_STATUS_OK) return true; 882 } else { 883 LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not open", 884 p_pipe->pipe_id); 885 } 886 } else { 887 LOG(WARNING) << StringPrintf( 888 "nfa_hci_api_send_cmd pipe:%d Owned by different application or " 889 "Destination host is not active", 890 p_pipe->pipe_id); 891 } 892 } else { 893 LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not found", 894 p_evt_data->send_cmd.pipe); 895 } 896 897 evt_data.cmd_sent.status = status; 898 899 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 900 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data, 901 p_evt_data->send_cmd.hci_handle); 902 return true; 903 } 904 905 /******************************************************************************* 906 ** 907 ** Function nfa_hci_api_send_rsp 908 ** 909 ** Description action function to send response on the given pipe 910 ** 911 ** Returns None 912 ** 913 *******************************************************************************/ 914 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) { 915 tNFA_STATUS status = NFA_STATUS_FAILED; 916 tNFA_HCI_DYN_PIPE* p_pipe; 917 tNFA_HCI_EVT_DATA evt_data; 918 tNFA_HANDLE app_handle; 919 920 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != NULL) { 921 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe); 922 923 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 924 ((app_handle == p_evt_data->send_rsp.hci_handle || 925 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 926 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 927 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 928 p_evt_data->send_rsp.response, 929 p_evt_data->send_rsp.size, 930 p_evt_data->send_rsp.data); 931 if (status == NFA_STATUS_OK) return; 932 } else { 933 LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not open", 934 p_pipe->pipe_id); 935 } 936 } else { 937 LOG(WARNING) << StringPrintf( 938 "nfa_hci_api_send_rsp pipe:%d Owned by different application or " 939 "Destination host is not active", 940 p_pipe->pipe_id); 941 } 942 } else { 943 LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not found", 944 p_evt_data->send_rsp.pipe); 945 } 946 947 evt_data.rsp_sent.status = status; 948 949 /* Send NFA_HCI_RSP_SENT_EVT to notify failure */ 950 nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data, 951 p_evt_data->send_rsp.hci_handle); 952 } 953 954 /******************************************************************************* 955 ** 956 ** Function nfa_hci_api_send_event 957 ** 958 ** Description action function to send an event to the given pipe 959 ** 960 ** Returns TRUE, if the event is processed 961 ** FALSE, if event is queued for processing later 962 ** 963 *******************************************************************************/ 964 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) { 965 tNFA_STATUS status = NFA_STATUS_FAILED; 966 tNFA_HCI_DYN_PIPE* p_pipe; 967 tNFA_HCI_EVT_DATA evt_data; 968 tNFA_HANDLE app_handle; 969 970 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != NULL) { 971 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe); 972 973 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) && 974 ((app_handle == p_evt_data->send_evt.hci_handle || 975 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) { 976 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) { 977 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data); 978 return false; 979 } 980 981 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 982 status = nfa_hciu_send_msg( 983 p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code, 984 p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf); 985 986 if (status == NFA_STATUS_OK) { 987 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 988 nfa_hci_cb.w4_rsp_evt = true; 989 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 990 } 991 992 if (p_evt_data->send_evt.rsp_len) { 993 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 994 nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len; 995 nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf; 996 if (p_evt_data->send_evt.rsp_timeout) { 997 nfa_hci_cb.w4_rsp_evt = true; 998 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 999 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1000 p_evt_data->send_evt.rsp_timeout); 1001 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1002 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1003 p_nfa_hci_cfg->hcp_response_timeout); 1004 } 1005 } else { 1006 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1007 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 1008 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 1009 p_nfa_hci_cfg->hcp_response_timeout); 1010 } 1011 nfa_hci_cb.rsp_buf_size = 0; 1012 nfa_hci_cb.p_rsp_buf = NULL; 1013 } 1014 } 1015 } else { 1016 LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not open", 1017 p_pipe->pipe_id); 1018 } 1019 } else { 1020 LOG(WARNING) << StringPrintf( 1021 "nfa_hci_api_send_event pipe:%d Owned by different application or " 1022 "Destination host is not active", 1023 p_pipe->pipe_id); 1024 } 1025 } else { 1026 LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not found", 1027 p_evt_data->send_evt.pipe); 1028 } 1029 1030 evt_data.evt_sent.status = status; 1031 1032 /* Send NFC_HCI_EVENT_SENT_EVT to notify status */ 1033 nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data, 1034 p_evt_data->send_evt.hci_handle); 1035 return true; 1036 } 1037 1038 /******************************************************************************* 1039 ** 1040 ** Function nfa_hci_api_add_static_pipe 1041 ** 1042 ** Description action function to add static pipe 1043 ** 1044 ** Returns None 1045 ** 1046 *******************************************************************************/ 1047 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) { 1048 tNFA_HCI_DYN_GATE* pg; 1049 tNFA_HCI_DYN_PIPE* pp; 1050 tNFA_HCI_EVT_DATA evt_data; 1051 1052 /* Allocate a proprietary gate */ 1053 pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate, 1054 p_evt_data->add_static_pipe.hci_handle); 1055 if (pg != NULL) { 1056 /* Assign new owner to the gate */ 1057 pg->gate_owner = p_evt_data->add_static_pipe.hci_handle; 1058 1059 /* Add the dynamic pipe to the proprietary gate */ 1060 if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id, 1061 p_evt_data->add_static_pipe.host, 1062 p_evt_data->add_static_pipe.gate) != 1063 NFA_HCI_ANY_OK) { 1064 /* Unable to add the dynamic pipe, so release the gate */ 1065 nfa_hciu_release_gate(pg->gate_id); 1066 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1067 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1068 p_evt_data->add_static_pipe.hci_handle); 1069 return; 1070 } 1071 pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe); 1072 if (pp != NULL) { 1073 /* This pipe is always opened */ 1074 pp->pipe_state = NFA_HCI_PIPE_OPENED; 1075 evt_data.pipe_added.status = NFA_STATUS_OK; 1076 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1077 p_evt_data->add_static_pipe.hci_handle); 1078 return; 1079 } 1080 } 1081 /* Unable to add static pipe */ 1082 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1083 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, 1084 p_evt_data->add_static_pipe.hci_handle); 1085 } 1086 1087 /******************************************************************************* 1088 ** 1089 ** Function nfa_hci_handle_link_mgm_gate_cmd 1090 ** 1091 ** Description This function handles incoming link management gate hci 1092 ** commands 1093 ** 1094 ** Returns none 1095 ** 1096 *******************************************************************************/ 1097 void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) { 1098 uint8_t index; 1099 uint8_t data[2]; 1100 uint8_t rsp_len = 0; 1101 uint8_t response = NFA_HCI_ANY_OK; 1102 1103 if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) && 1104 (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) { 1105 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, 1106 NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL); 1107 return; 1108 } 1109 1110 switch (nfa_hci_cb.inst) { 1111 case NFA_HCI_ANY_SET_PARAMETER: 1112 STREAM_TO_UINT8(index, p_data); 1113 1114 if (index == 1) { 1115 STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data); 1116 } else 1117 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1118 break; 1119 1120 case NFA_HCI_ANY_GET_PARAMETER: 1121 STREAM_TO_UINT8(index, p_data); 1122 if (index == 1) { 1123 data[0] = 1124 (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF); 1125 data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F); 1126 rsp_len = 2; 1127 } else 1128 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1129 break; 1130 1131 case NFA_HCI_ANY_OPEN_PIPE: 1132 data[0] = 0; 1133 rsp_len = 1; 1134 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED; 1135 break; 1136 1137 case NFA_HCI_ANY_CLOSE_PIPE: 1138 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1139 break; 1140 1141 default: 1142 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1143 break; 1144 } 1145 1146 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, 1147 response, rsp_len, data); 1148 } 1149 1150 /******************************************************************************* 1151 ** 1152 ** Function nfa_hci_handle_pipe_open_close_cmd 1153 ** 1154 ** Description This function handles all generic gates (excluding 1155 ** connectivity gate) commands 1156 ** 1157 ** Returns none 1158 ** 1159 *******************************************************************************/ 1160 void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) { 1161 uint8_t data[1]; 1162 uint8_t rsp_len = 0; 1163 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1164 tNFA_HCI_DYN_GATE* p_gate; 1165 1166 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) { 1167 if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL) 1168 data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate); 1169 else 1170 data[0] = 0; 1171 1172 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1173 rsp_len = 1; 1174 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) { 1175 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1176 } 1177 1178 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 1179 data); 1180 } 1181 1182 /******************************************************************************* 1183 ** 1184 ** Function nfa_hci_handle_admin_gate_cmd 1185 ** 1186 ** Description This function handles incoming commands on ADMIN gate 1187 ** 1188 ** Returns none 1189 ** 1190 *******************************************************************************/ 1191 void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) { 1192 uint8_t source_host, source_gate, dest_host, dest_gate, pipe; 1193 uint8_t data = 0; 1194 uint8_t rsp_len = 0; 1195 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1196 tNFA_HCI_DYN_GATE* pgate; 1197 tNFA_HCI_EVT_DATA evt_data; 1198 1199 switch (nfa_hci_cb.inst) { 1200 case NFA_HCI_ANY_OPEN_PIPE: 1201 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED; 1202 data = 0; 1203 rsp_len = 1; 1204 break; 1205 1206 case NFA_HCI_ANY_CLOSE_PIPE: 1207 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1208 /* Reopen the pipe immediately */ 1209 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, 1210 rsp_len, &data); 1211 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1212 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1213 return; 1214 break; 1215 1216 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED: 1217 STREAM_TO_UINT8(source_host, p_data); 1218 STREAM_TO_UINT8(source_gate, p_data); 1219 STREAM_TO_UINT8(dest_host, p_data); 1220 STREAM_TO_UINT8(dest_gate, p_data); 1221 STREAM_TO_UINT8(pipe, p_data); 1222 1223 if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) || 1224 (dest_gate == NFA_HCI_LOOP_BACK_GATE)) { 1225 response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe, 1226 source_host, source_gate); 1227 } else { 1228 if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != NULL) { 1229 /* If the gate is valid, add the pipe to it */ 1230 if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host, 1231 source_gate)) { 1232 /* Already, there is a pipe between these two gates, so will reject 1233 */ 1234 response = NFA_HCI_ANY_E_NOK; 1235 } else { 1236 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host, 1237 source_gate); 1238 if (response == NFA_HCI_ANY_OK) { 1239 /* Tell the application a pipe was created with its gate */ 1240 1241 evt_data.created.status = NFA_STATUS_OK; 1242 evt_data.created.pipe = pipe; 1243 evt_data.created.source_gate = dest_gate; 1244 evt_data.created.dest_host = source_host; 1245 evt_data.created.dest_gate = source_gate; 1246 1247 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data, 1248 pgate->gate_owner); 1249 } 1250 } 1251 } else { 1252 response = NFA_HCI_ANY_E_NOK; 1253 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) && 1254 (dest_gate <= NFA_HCI_LAST_PROP_GATE)) { 1255 if (nfa_hciu_alloc_gate(dest_gate, 0)) 1256 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host, 1257 source_gate); 1258 } 1259 } 1260 } 1261 break; 1262 1263 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED: 1264 STREAM_TO_UINT8(pipe, p_data); 1265 response = nfa_hciu_release_pipe(pipe); 1266 break; 1267 1268 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: 1269 STREAM_TO_UINT8(source_host, p_data); 1270 1271 nfa_hciu_remove_all_pipes_from_host(source_host); 1272 1273 if (source_host == NFA_HCI_HOST_CONTROLLER) { 1274 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1275 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1276 1277 /* Reopen the admin pipe immediately */ 1278 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1279 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1280 return; 1281 } else { 1282 if ((source_host >= NFA_HCI_HOST_ID_UICC0) && 1283 (source_host < 1284 (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))) { 1285 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = 1286 source_host; 1287 } 1288 } 1289 break; 1290 1291 default: 1292 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1293 break; 1294 } 1295 1296 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, 1297 rsp_len, &data); 1298 } 1299 1300 /******************************************************************************* 1301 ** 1302 ** Function nfa_hci_handle_admin_gate_rsp 1303 ** 1304 ** Description This function handles response received on admin gate 1305 ** 1306 ** Returns none 1307 ** 1308 *******************************************************************************/ 1309 void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) { 1310 uint8_t source_host; 1311 uint8_t source_gate = nfa_hci_cb.local_gate_in_use; 1312 uint8_t dest_host = nfa_hci_cb.remote_host_in_use; 1313 uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use; 1314 uint8_t pipe = 0; 1315 tNFA_STATUS status; 1316 tNFA_HCI_EVT_DATA evt_data; 1317 uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 1318 0xFF, 0xFF, 0xFF, 0xFF}; 1319 uint8_t host_count = 0; 1320 uint8_t host_id = 0; 1321 uint32_t os_tick; 1322 1323 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1324 "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: " 1325 "0x%02x Pipe: 0x%02x", 1326 nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent).c_str(), nfa_hci_cb.app_in_use, 1327 nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use); 1328 1329 /* If starting up, handle events here */ 1330 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || 1331 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) || 1332 (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) || 1333 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) { 1334 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) { 1335 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE); 1336 return; 1337 } 1338 1339 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) { 1340 LOG(ERROR) << StringPrintf( 1341 "nfa_hci_handle_admin_gate_rsp - Initialization failed"); 1342 nfa_hci_startup_complete(NFA_STATUS_FAILED); 1343 return; 1344 } 1345 1346 switch (nfa_hci_cb.cmd_sent) { 1347 case NFA_HCI_ANY_SET_PARAMETER: 1348 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) { 1349 /* Set WHITELIST */ 1350 nfa_hciu_send_set_param_cmd( 1351 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 1352 p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist); 1353 } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) { 1354 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || 1355 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) 1356 nfa_hci_dh_startup_complete(); 1357 if (NFA_GetNCIVersion() == NCI_VERSION_2_0) { 1358 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE; 1359 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info); 1360 nfa_hci_enable_one_nfcee(); 1361 } 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 LOG(WARNING) << StringPrintf( 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 *******************************************************************************/ 1603 void nfa_hci_handle_admin_gate_evt() { 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 LOG(ERROR) << StringPrintf( 1609 "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe"); 1610 return; 1611 } 1612 1613 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 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 *******************************************************************************/ 1671 void 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 LOG(ERROR) << StringPrintf("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d", 1679 pipe_id); 1680 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1681 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, 1682 NULL); 1683 return; 1684 } 1685 1686 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) { 1687 nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe); 1688 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) { 1689 nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe); 1690 } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) { 1691 nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe); 1692 } else { 1693 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate); 1694 if (p_gate == NULL) { 1695 LOG(ERROR) << StringPrintf( 1696 "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt", 1697 p_pipe->local_gate); 1698 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1699 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, 1700 NULL); 1701 return; 1702 } 1703 1704 /* Check if data packet is a command, response or event */ 1705 switch (nfa_hci_cb.type) { 1706 case NFA_HCI_COMMAND_TYPE: 1707 nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, 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_pipe); 1712 break; 1713 1714 case NFA_HCI_EVENT_TYPE: 1715 nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe); 1716 break; 1717 } 1718 } 1719 } 1720 1721 /******************************************************************************* 1722 ** 1723 ** Function nfa_hci_handle_identity_mgmt_gate_pkt 1724 ** 1725 ** Description This function handles incoming Identity Management gate hci 1726 ** commands 1727 ** 1728 ** Returns none 1729 ** 1730 *******************************************************************************/ 1731 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data, 1732 tNFA_HCI_DYN_PIPE* p_pipe) { 1733 uint8_t data[20]; 1734 uint8_t index; 1735 uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates; 1736 uint16_t rsp_len = 0; 1737 uint8_t* p_rsp = data; 1738 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1739 1740 /* We never send commands on a pipe where the local gate is the identity 1741 * management 1742 * gate, so only commands should be processed. 1743 */ 1744 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return; 1745 1746 switch (nfa_hci_cb.inst) { 1747 case NFA_HCI_ANY_GET_PARAMETER: 1748 index = *(p_data++); 1749 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) { 1750 switch (index) { 1751 case NFA_HCI_VERSION_SW_INDEX: 1752 data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF); 1753 data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF); 1754 data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF); 1755 rsp_len = 3; 1756 break; 1757 1758 case NFA_HCI_HCI_VERSION_INDEX: 1759 data[0] = NFA_HCI_VERSION; 1760 rsp_len = 1; 1761 break; 1762 1763 case NFA_HCI_VERSION_HW_INDEX: 1764 data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF); 1765 data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF); 1766 data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF); 1767 rsp_len = 3; 1768 break; 1769 1770 case NFA_HCI_VENDOR_NAME_INDEX: 1771 memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME)); 1772 rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME); 1773 break; 1774 1775 case NFA_HCI_MODEL_ID_INDEX: 1776 data[0] = NFA_HCI_MODEL_ID; 1777 rsp_len = 1; 1778 break; 1779 1780 case NFA_HCI_GATES_LIST_INDEX: 1781 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE; 1782 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE; 1783 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE; 1784 num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]); 1785 rsp_len = num_gates + 3; 1786 p_rsp = gate_rsp; 1787 break; 1788 1789 default: 1790 response = NFA_HCI_ANY_E_NOK; 1791 break; 1792 } 1793 } else { 1794 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED; 1795 } 1796 break; 1797 1798 case NFA_HCI_ANY_OPEN_PIPE: 1799 data[0] = 0; 1800 rsp_len = 1; 1801 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1802 break; 1803 1804 case NFA_HCI_ANY_CLOSE_PIPE: 1805 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1806 break; 1807 1808 default: 1809 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1810 break; 1811 } 1812 1813 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 1814 p_rsp); 1815 } 1816 1817 /******************************************************************************* 1818 ** 1819 ** Function nfa_hci_handle_generic_gate_cmd 1820 ** 1821 ** Description This function handles all generic gates (excluding 1822 ** connectivity gate) commands 1823 ** 1824 ** Returns none 1825 ** 1826 *******************************************************************************/ 1827 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len, 1828 tNFA_HCI_DYN_PIPE* p_pipe) { 1829 tNFA_HCI_EVT_DATA evt_data; 1830 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id); 1831 1832 switch (nfa_hci_cb.inst) { 1833 case NFA_HCI_ANY_SET_PARAMETER: 1834 evt_data.registry.pipe = p_pipe->pipe_id; 1835 evt_data.registry.index = *p_data++; 1836 if (data_len > 0) data_len--; 1837 evt_data.registry.data_len = data_len; 1838 1839 memcpy(evt_data.registry.reg_data, p_data, data_len); 1840 1841 nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle); 1842 break; 1843 1844 case NFA_HCI_ANY_GET_PARAMETER: 1845 evt_data.registry.pipe = p_pipe->pipe_id; 1846 evt_data.registry.index = *p_data; 1847 evt_data.registry.data_len = 0; 1848 1849 nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle); 1850 break; 1851 1852 case NFA_HCI_ANY_OPEN_PIPE: 1853 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1854 1855 evt_data.opened.pipe = p_pipe->pipe_id; 1856 evt_data.opened.status = NFA_STATUS_OK; 1857 1858 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle); 1859 break; 1860 1861 case NFA_HCI_ANY_CLOSE_PIPE: 1862 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1863 1864 evt_data.closed.pipe = p_pipe->pipe_id; 1865 evt_data.opened.status = NFA_STATUS_OK; 1866 1867 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle); 1868 break; 1869 1870 default: 1871 /* Could be application specific command, pass it on */ 1872 evt_data.cmd_rcvd.status = NFA_STATUS_OK; 1873 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id; 1874 ; 1875 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst; 1876 evt_data.cmd_rcvd.cmd_len = data_len; 1877 1878 if (data_len <= NFA_MAX_HCI_CMD_LEN) 1879 memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len); 1880 1881 nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle); 1882 break; 1883 } 1884 } 1885 1886 /******************************************************************************* 1887 ** 1888 ** Function nfa_hci_handle_generic_gate_rsp 1889 ** 1890 ** Description This function handles all generic gates (excluding 1891 ** connectivity) response 1892 ** 1893 ** Returns none 1894 ** 1895 *******************************************************************************/ 1896 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len, 1897 tNFA_HCI_DYN_PIPE* p_pipe) { 1898 tNFA_HCI_EVT_DATA evt_data; 1899 tNFA_STATUS status = NFA_STATUS_OK; 1900 1901 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED; 1902 1903 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) { 1904 if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1905 1906 nfa_hci_cb.nv_write_needed = true; 1907 /* Tell application */ 1908 evt_data.opened.status = status; 1909 evt_data.opened.pipe = p_pipe->pipe_id; 1910 1911 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, 1912 nfa_hci_cb.app_in_use); 1913 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) { 1914 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1915 1916 nfa_hci_cb.nv_write_needed = true; 1917 /* Tell application */ 1918 evt_data.opened.status = status; 1919 ; 1920 evt_data.opened.pipe = p_pipe->pipe_id; 1921 1922 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, 1923 nfa_hci_cb.app_in_use); 1924 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) { 1925 /* Tell application */ 1926 evt_data.registry.status = status; 1927 evt_data.registry.pipe = p_pipe->pipe_id; 1928 evt_data.registry.data_len = data_len; 1929 evt_data.registry.index = nfa_hci_cb.param_in_use; 1930 1931 memcpy(evt_data.registry.reg_data, p_data, data_len); 1932 1933 nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data, 1934 nfa_hci_cb.app_in_use); 1935 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) { 1936 /* Tell application */ 1937 evt_data.registry.status = status; 1938 ; 1939 evt_data.registry.pipe = p_pipe->pipe_id; 1940 1941 nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data, 1942 nfa_hci_cb.app_in_use); 1943 } else { 1944 /* Could be a response to application specific command sent, pass it on */ 1945 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 1946 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 1947 ; 1948 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 1949 evt_data.rsp_rcvd.rsp_len = data_len; 1950 1951 if (data_len <= NFA_MAX_HCI_RSP_LEN) 1952 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 1953 1954 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 1955 nfa_hci_cb.app_in_use); 1956 } 1957 } 1958 1959 /******************************************************************************* 1960 ** 1961 ** Function nfa_hci_handle_connectivity_gate_pkt 1962 ** 1963 ** Description This function handles incoming connectivity gate packets 1964 ** 1965 ** Returns none 1966 ** 1967 *******************************************************************************/ 1968 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data, 1969 uint16_t data_len, 1970 tNFA_HCI_DYN_PIPE* p_pipe) { 1971 tNFA_HCI_EVT_DATA evt_data; 1972 1973 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) { 1974 switch (nfa_hci_cb.inst) { 1975 case NFA_HCI_ANY_OPEN_PIPE: 1976 case NFA_HCI_ANY_CLOSE_PIPE: 1977 nfa_hci_handle_pipe_open_close_cmd(p_pipe); 1978 break; 1979 1980 case NFA_HCI_CON_PRO_HOST_REQUEST: 1981 /* A request to the DH to activate another host. This is not supported 1982 * for */ 1983 /* now, we will implement it when the spec is clearer and UICCs need it. 1984 */ 1985 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 1986 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 1987 break; 1988 1989 default: 1990 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, 1991 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 1992 break; 1993 } 1994 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) { 1995 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && 1996 (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 1997 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1998 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 1999 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2000 2001 /* Could be a response to application specific command sent, pass it on */ 2002 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2003 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 2004 ; 2005 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2006 evt_data.rsp_rcvd.rsp_len = data_len; 2007 2008 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2009 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2010 2011 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 2012 nfa_hci_cb.app_in_use); 2013 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) { 2014 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2015 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2016 evt_data.rcvd_evt.evt_len = data_len; 2017 evt_data.rcvd_evt.p_evt_buf = p_data; 2018 2019 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2020 nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT, 2021 &evt_data); 2022 } 2023 } 2024 2025 /******************************************************************************* 2026 ** 2027 ** Function nfa_hci_handle_loopback_gate_pkt 2028 ** 2029 ** Description This function handles incoming loopback gate hci events 2030 ** 2031 ** Returns none 2032 ** 2033 *******************************************************************************/ 2034 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len, 2035 tNFA_HCI_DYN_PIPE* p_pipe) { 2036 uint8_t data[1]; 2037 uint8_t rsp_len = 0; 2038 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 2039 tNFA_HCI_EVT_DATA evt_data; 2040 2041 /* Check if data packet is a command, response or event */ 2042 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) { 2043 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) { 2044 data[0] = 0; 2045 rsp_len = 1; 2046 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2047 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) { 2048 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2049 } else 2050 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 2051 2052 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, 2053 data); 2054 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) { 2055 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && 2056 (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 2057 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2058 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 2059 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2060 2061 /* Could be a response to application specific command sent, pass it on */ 2062 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2063 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id; 2064 ; 2065 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2066 evt_data.rsp_rcvd.rsp_len = data_len; 2067 2068 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2069 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2070 2071 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data, 2072 nfa_hci_cb.app_in_use); 2073 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) { 2074 if (nfa_hci_cb.w4_rsp_evt) { 2075 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2076 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2077 evt_data.rcvd_evt.evt_len = data_len; 2078 evt_data.rcvd_evt.p_evt_buf = p_data; 2079 2080 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, 2081 nfa_hci_cb.app_in_use); 2082 } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) { 2083 /* Send back the same data we got */ 2084 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, 2085 NFA_HCI_EVT_POST_DATA, data_len, p_data); 2086 } 2087 } 2088 } 2089 2090 /******************************************************************************* 2091 ** 2092 ** Function nfa_hci_handle_generic_gate_evt 2093 ** 2094 ** Description This function handles incoming Generic gate hci events 2095 ** 2096 ** Returns none 2097 ** 2098 *******************************************************************************/ 2099 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len, 2100 tNFA_HCI_DYN_GATE* p_gate, 2101 tNFA_HCI_DYN_PIPE* p_pipe) { 2102 tNFA_HCI_EVT_DATA evt_data; 2103 2104 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2105 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2106 evt_data.rcvd_evt.evt_len = data_len; 2107 2108 if (nfa_hci_cb.assembly_failed) 2109 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL; 2110 else 2111 evt_data.rcvd_evt.status = NFA_STATUS_OK; 2112 2113 evt_data.rcvd_evt.p_evt_buf = p_data; 2114 nfa_hci_cb.rsp_buf_size = 0; 2115 nfa_hci_cb.p_rsp_buf = NULL; 2116 2117 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2118 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner); 2119 } 2120