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