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 * 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 */ 39static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data); 40static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data); 41static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data); 42static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data); 43static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data); 44static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data); 45static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data); 46static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data); 47static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data); 48static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data); 49static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data); 50static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data); 51static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data); 52static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data); 53 54static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe); 55static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe); 56static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe); 57static 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); 58static 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); 59static 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*******************************************************************************/ 71void 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*******************************************************************************/ 129void 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*******************************************************************************/ 236static 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*******************************************************************************/ 318void 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*******************************************************************************/ 414static 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 else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE && pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id && pp->local_gate >= NFA_HCI_FIRST_PROP_GATE && pp->local_gate <= NFA_HCI_LAST_PROP_GATE) 454 { 455 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 456 { 457 if (pp->local_gate == pg->gate_id) 458 { 459 if (!pg->gate_owner) 460 memcpy (&evt_data.gates_pipes.uicc_created_pipe [evt_data.gates_pipes.num_uicc_created_pipes++], pp, sizeof (tNFA_HCI_PIPE_INFO)); 461 break; 462 } 463 } 464 } 465 } 466 467 evt_data.gates_pipes.status = NFA_STATUS_OK; 468 469 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */ 470 nfa_hciu_send_to_app (NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, p_evt_data->get_gate_pipe_list.hci_handle); 471} 472 473/******************************************************************************* 474** 475** Function nfa_hci_api_alloc_gate 476** 477** Description action function to allocate gate 478** 479** Returns None 480** 481*******************************************************************************/ 482static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data) 483{ 484 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle; 485 tNFA_HCI_EVT_DATA evt_data; 486 tNFA_HCI_DYN_GATE *p_gate; 487 488 p_gate = nfa_hciu_alloc_gate (p_evt_data->gate_info.gate, app_handle); 489 490 if (p_gate) 491 { 492 if (!p_gate->gate_owner) 493 { 494 /* No app owns the gate yet */ 495 p_gate->gate_owner = app_handle; 496 } 497 else if (p_gate->gate_owner != app_handle) 498 { 499 /* Some other app owns the gate */ 500 p_gate = NULL; 501 NFA_TRACE_ERROR1 ("nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!", p_evt_data->gate_info.gate); 502 } 503 } 504 505 evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0; 506 evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED; 507 508 /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */ 509 nfa_hciu_send_to_app (NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle); 510} 511 512/******************************************************************************* 513** 514** Function nfa_hci_api_dealloc_gate 515** 516** Description action function to deallocate the given generic gate 517** 518** Returns None 519** 520*******************************************************************************/ 521void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data) 522{ 523 tNFA_HCI_EVT_DATA evt_data; 524 UINT8 gate_id; 525 tNFA_HCI_DYN_GATE *p_gate; 526 tNFA_HCI_DYN_PIPE *p_pipe; 527 tNFA_HANDLE app_handle; 528 529 /* p_evt_data may be NULL if we are recursively deleting pipes */ 530 if (p_evt_data) 531 { 532 gate_id = p_evt_data->gate_dealloc.gate; 533 app_handle = p_evt_data->gate_dealloc.hci_handle; 534 535 } 536 else 537 { 538 nfa_sys_stop_timer (&nfa_hci_cb.timer); 539 gate_id = nfa_hci_cb.local_gate_in_use; 540 app_handle = nfa_hci_cb.app_in_use; 541 } 542 543 evt_data.deallocated.gate = gate_id;; 544 545 p_gate = nfa_hciu_find_gate_by_gid (gate_id); 546 547 if (p_gate == NULL) 548 { 549 evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID; 550 } 551 else if (p_gate->gate_owner != app_handle) 552 { 553 evt_data.deallocated.status = NFA_STATUS_FAILED; 554 } 555 else 556 { 557 /* See if any pipe is owned by this app */ 558 if (nfa_hciu_find_pipe_on_gate (p_gate->gate_id) == NULL) 559 { 560 nfa_hciu_release_gate (p_gate->gate_id); 561 562 nfa_hci_cb.nv_write_needed = TRUE; 563 evt_data.deallocated.status = NFA_STATUS_OK; 564 565 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 566 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 567 } 568 else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate (p_gate->gate_id)) == NULL) 569 { 570 /* UICC is not active at the moment and cannot delete the pipe */ 571 nfa_hci_cb.nv_write_needed = TRUE; 572 evt_data.deallocated.status = NFA_STATUS_FAILED; 573 574 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 575 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE; 576 } 577 else 578 { 579 /* Delete pipes on the gate */ 580 nfa_hci_cb.local_gate_in_use = gate_id; 581 nfa_hci_cb.app_in_use = app_handle; 582 nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE; 583 584 nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id); 585 return; 586 } 587 } 588 589 nfa_hciu_send_to_app (NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle); 590} 591 592/******************************************************************************* 593** 594** Function nfa_hci_api_get_host_list 595** 596** Description action function to get the host list from HCI network 597** 598** Returns None 599** 600*******************************************************************************/ 601static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data) 602{ 603 UINT8 app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK; 604 605 nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle; 606 607 /* Send Get Host List command on "Internal request" or requested by registered application with valid handle and callback function */ 608 if ( (nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) 609 ||((app_inx < NFA_HCI_MAX_APP_CB) && (nfa_hci_cb.p_app_cback[app_inx] != NULL)) ) 610 { 611 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX); 612 } 613} 614 615/******************************************************************************* 616** 617** Function nfa_hci_api_create_pipe 618** 619** Description action function to create a pipe 620** 621** Returns TRUE, if the command is processed 622** FALSE, if command is queued for processing later 623** 624*******************************************************************************/ 625static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data) 626{ 627 tNFA_HCI_DYN_GATE *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate); 628 tNFA_HCI_EVT_DATA evt_data; 629 BOOLEAN report_failed = FALSE; 630 631 /* Verify that the app owns the gate that the pipe is being created on */ 632 if ( (p_gate == NULL) 633 ||(p_gate->gate_owner != p_evt_data->create_pipe.hci_handle) ) 634 { 635 report_failed = TRUE; 636 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); 637 } 638 else if (nfa_hciu_check_pipe_between_gates (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate)) 639 { 640 report_failed = TRUE; 641 NFA_TRACE_ERROR0 ("nfa_hci_api_create_pipe : Cannot create multiple pipe between the same two gates!"); 642 } 643 644 if (report_failed) 645 { 646 evt_data.created.source_gate = p_evt_data->create_pipe.source_gate; 647 evt_data.created.status = NFA_STATUS_FAILED; 648 649 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle); 650 } 651 else 652 { 653 if (nfa_hciu_is_host_reseting (p_evt_data->create_pipe.dest_gate)) 654 { 655 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data); 656 return FALSE; 657 } 658 659 nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate; 660 nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate; 661 nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host; 662 nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle; 663 664 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); 665 } 666 return TRUE; 667} 668 669/******************************************************************************* 670** 671** Function nfa_hci_api_open_pipe 672** 673** Description action function to open a pipe 674** 675** Returns None 676** 677*******************************************************************************/ 678static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data) 679{ 680 tNFA_HCI_EVT_DATA evt_data; 681 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe); 682 tNFA_HCI_DYN_GATE *p_gate = NULL; 683 684 if (p_pipe != NULL) 685 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 686 687 if ( (p_pipe != NULL) 688 &&(p_gate != NULL) 689 &&(nfa_hciu_is_active_host (p_pipe->dest_host)) 690 &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) 691 { 692 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) 693 { 694 nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe); 695 } 696 else 697 { 698 evt_data.opened.pipe = p_evt_data->open_pipe.pipe; 699 evt_data.opened.status = NFA_STATUS_OK; 700 701 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle); 702 } 703 } 704 else 705 { 706 evt_data.opened.pipe = p_evt_data->open_pipe.pipe; 707 evt_data.opened.status = NFA_STATUS_FAILED; 708 709 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle); 710 } 711} 712 713/******************************************************************************* 714** 715** Function nfa_hci_api_get_reg_value 716** 717** Description action function to get the reg value of the specified index 718** 719** Returns TRUE, if the command is processed 720** FALSE, if command is queued for processing later 721** 722*******************************************************************************/ 723static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data) 724{ 725 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe); 726 tNFA_HCI_DYN_GATE *p_gate; 727 tNFA_STATUS status = NFA_STATUS_FAILED; 728 tNFA_HCI_EVT_DATA evt_data; 729 730 if (p_pipe != NULL) 731 { 732 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 733 734 if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) 735 { 736 nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle; 737 738 if (nfa_hciu_is_host_reseting (p_pipe->dest_host)) 739 { 740 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data); 741 return FALSE; 742 } 743 744 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) 745 { 746 NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe); 747 } 748 else 749 { 750 if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK) 751 return TRUE; 752 } 753 } 754 } 755 756 evt_data.cmd_sent.status = status; 757 758 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 759 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle); 760 return TRUE; 761} 762 763/******************************************************************************* 764** 765** Function nfa_hci_api_set_reg_value 766** 767** Description action function to set the reg value at specified index 768** 769** Returns TRUE, if the command is processed 770** FALSE, if command is queued for processing later 771** 772*******************************************************************************/ 773static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data) 774{ 775 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe); 776 tNFA_HCI_DYN_GATE *p_gate; 777 tNFA_STATUS status = NFA_STATUS_FAILED; 778 tNFA_HCI_EVT_DATA evt_data; 779 780 if (p_pipe != NULL) 781 { 782 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 783 784 if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) 785 { 786 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle; 787 788 if (nfa_hciu_is_host_reseting (p_pipe->dest_host)) 789 { 790 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data); 791 return FALSE; 792 } 793 794 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) 795 { 796 NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe); 797 } 798 else 799 { 800 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) 801 return TRUE; 802 } 803 } 804 } 805 evt_data.cmd_sent.status = status; 806 807 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 808 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle); 809 return TRUE; 810 811} 812 813/******************************************************************************* 814** 815** Function nfa_hci_api_close_pipe 816** 817** Description action function to close a pipe 818** 819** Returns None 820** 821*******************************************************************************/ 822static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data) 823{ 824 tNFA_HCI_EVT_DATA evt_data; 825 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe); 826 tNFA_HCI_DYN_GATE *p_gate = NULL; 827 828 if (p_pipe != NULL) 829 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 830 831 if ( (p_pipe != NULL) 832 &&(p_gate != NULL) 833 &&(nfa_hciu_is_active_host (p_pipe->dest_host)) 834 &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle) ) 835 { 836 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) 837 { 838 nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe); 839 } 840 else 841 { 842 evt_data.closed.status = NFA_STATUS_OK; 843 evt_data.closed.pipe = p_evt_data->close_pipe.pipe; 844 845 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle); 846 } 847 } 848 else 849 { 850 evt_data.closed.status = NFA_STATUS_FAILED; 851 evt_data.closed.pipe = 0x00; 852 853 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle); 854 } 855} 856 857/******************************************************************************* 858** 859** Function nfa_hci_api_delete_pipe 860** 861** Description action function to delete a pipe 862** 863** Returns None 864** 865*******************************************************************************/ 866static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data) 867{ 868 tNFA_HCI_EVT_DATA evt_data; 869 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe); 870 tNFA_HCI_DYN_GATE *p_gate = NULL; 871 872 if (p_pipe != NULL) 873 { 874 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 875 if ( (p_gate != NULL) 876 &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) 877 &&(nfa_hciu_is_active_host (p_pipe->dest_host)) ) 878 { 879 nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe); 880 return; 881 } 882 } 883 884 evt_data.deleted.status = NFA_STATUS_FAILED; 885 evt_data.deleted.pipe = 0x00; 886 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle); 887} 888 889/******************************************************************************* 890** 891** Function nfa_hci_api_send_cmd 892** 893** Description action function to send command on the given pipe 894** 895** Returns TRUE, if the command is processed 896** FALSE, if command is queued for processing later 897** 898*******************************************************************************/ 899static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data) 900{ 901 tNFA_STATUS status = NFA_STATUS_FAILED; 902 tNFA_HCI_DYN_PIPE *p_pipe; 903 tNFA_HCI_EVT_DATA evt_data; 904 tNFA_HANDLE app_handle; 905 906 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL) 907 { 908 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe); 909 910 if ( (nfa_hciu_is_active_host (p_pipe->dest_host)) 911 &&((app_handle == p_evt_data->send_cmd.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) ) 912 { 913 if (nfa_hciu_is_host_reseting (p_pipe->dest_host)) 914 { 915 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data); 916 return FALSE; 917 } 918 919 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) 920 { 921 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe; 922 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code, 923 p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK) 924 return TRUE; 925 } 926 else 927 { 928 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id); 929 } 930 } 931 else 932 { 933 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active", 934 p_pipe->pipe_id); 935 } 936 } 937 else 938 { 939 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe); 940 } 941 942 evt_data.cmd_sent.status = status; 943 944 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */ 945 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle); 946 return TRUE; 947} 948 949/******************************************************************************* 950** 951** Function nfa_hci_api_send_rsp 952** 953** Description action function to send response on the given pipe 954** 955** Returns None 956** 957*******************************************************************************/ 958static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data) 959{ 960 tNFA_STATUS status = NFA_STATUS_FAILED; 961 tNFA_HCI_DYN_PIPE *p_pipe; 962 tNFA_HCI_EVT_DATA evt_data; 963 tNFA_HANDLE app_handle; 964 965 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL) 966 { 967 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe); 968 969 if ( (nfa_hciu_is_active_host (p_pipe->dest_host)) 970 &&((app_handle == p_evt_data->send_rsp.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) ) 971 { 972 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) 973 { 974 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response, 975 p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK) 976 return; 977 } 978 else 979 { 980 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id); 981 } 982 } 983 else 984 { 985 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active", 986 p_pipe->pipe_id); 987 } 988 } 989 else 990 { 991 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe); 992 } 993 994 evt_data.rsp_sent.status = status; 995 996 /* Send NFA_HCI_RSP_SENT_EVT to notify failure */ 997 nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle); 998} 999 1000/******************************************************************************* 1001** 1002** Function nfa_hci_api_send_event 1003** 1004** Description action function to send an event to the given pipe 1005** 1006** Returns TRUE, if the event is processed 1007** FALSE, if event is queued for processing later 1008** 1009*******************************************************************************/ 1010static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data) 1011{ 1012 tNFA_STATUS status = NFA_STATUS_FAILED; 1013 tNFA_HCI_DYN_PIPE *p_pipe; 1014 tNFA_HCI_EVT_DATA evt_data; 1015 tNFA_HANDLE app_handle; 1016 1017 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL) 1018 { 1019 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe); 1020 1021 if ( (nfa_hciu_is_active_host (p_pipe->dest_host)) 1022 &&((app_handle == p_evt_data->send_evt.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) ) 1023 { 1024 if (nfa_hciu_is_host_reseting (p_pipe->dest_host)) 1025 { 1026 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data); 1027 return FALSE; 1028 } 1029 1030 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) 1031 { 1032 status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code, 1033 p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf); 1034 1035 if (status == NFA_STATUS_OK) 1036 { 1037 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) 1038 { 1039 nfa_hci_cb.w4_rsp_evt = TRUE; 1040 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 1041 } 1042 1043 if (p_evt_data->send_evt.rsp_len) 1044 { 1045 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 1046 nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len; 1047 nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf; 1048 if (p_evt_data->send_evt.rsp_timeout) 1049 { 1050 nfa_hci_cb.w4_rsp_evt = TRUE; 1051 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 1052 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_evt_data->send_evt.rsp_timeout); 1053 } 1054 else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) 1055 { 1056 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout); 1057 } 1058 } 1059 else 1060 { 1061 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) 1062 { 1063 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe; 1064 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout); 1065 } 1066 nfa_hci_cb.rsp_buf_size = 0; 1067 nfa_hci_cb.p_rsp_buf = NULL; 1068 } 1069 } 1070 } 1071 else 1072 { 1073 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not open", p_pipe->pipe_id); 1074 } 1075 } 1076 else 1077 { 1078 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d Owned by different application or Destination host is not active", 1079 p_pipe->pipe_id); 1080 } 1081 } 1082 else 1083 { 1084 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not found", p_evt_data->send_evt.pipe); 1085 } 1086 1087 evt_data.evt_sent.status = status; 1088 1089 /* Send NFC_HCI_EVENT_SENT_EVT to notify status */ 1090 nfa_hciu_send_to_app (NFA_HCI_EVENT_SENT_EVT, &evt_data, p_evt_data->send_evt.hci_handle); 1091 return TRUE; 1092} 1093 1094/******************************************************************************* 1095** 1096** Function nfa_hci_api_add_static_pipe 1097** 1098** Description action function to add static pipe 1099** 1100** Returns None 1101** 1102*******************************************************************************/ 1103static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data) 1104{ 1105 tNFA_HCI_DYN_GATE *pg; 1106 tNFA_HCI_DYN_PIPE *pp; 1107 tNFA_HCI_EVT_DATA evt_data; 1108 1109 /* Allocate a proprietary gate */ 1110 if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL) 1111 { 1112 /* Assign new owner to the gate */ 1113 pg->gate_owner = p_evt_data->add_static_pipe.hci_handle; 1114 1115 /* Add the dynamic pipe to the proprietary gate */ 1116 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) 1117 { 1118 /* Unable to add the dynamic pipe, so release the gate */ 1119 nfa_hciu_release_gate (pg->gate_id); 1120 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1121 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle); 1122 return; 1123 } 1124 if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL) 1125 { 1126 /* This pipe is always opened */ 1127 pp->pipe_state = NFA_HCI_PIPE_OPENED; 1128 evt_data.pipe_added.status = NFA_STATUS_OK; 1129 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle); 1130 return; 1131 } 1132 } 1133 /* Unable to add static pipe */ 1134 evt_data.pipe_added.status = NFA_STATUS_FAILED; 1135 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle); 1136 1137} 1138 1139/******************************************************************************* 1140** 1141** Function nfa_hci_handle_link_mgm_gate_cmd 1142** 1143** Description This function handles incoming link management gate hci 1144** commands 1145** 1146** Returns none 1147** 1148*******************************************************************************/ 1149void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data) 1150{ 1151 UINT8 index; 1152 UINT8 data[2]; 1153 UINT8 rsp_len = 0; 1154 UINT8 response = NFA_HCI_ANY_OK; 1155 1156 if ( (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) 1157 &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) ) 1158 { 1159 nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL); 1160 return; 1161 } 1162 1163 switch (nfa_hci_cb.inst) 1164 { 1165 case NFA_HCI_ANY_SET_PARAMETER: 1166 STREAM_TO_UINT8 (index, p_data); 1167 1168 if (index == 1) 1169 { 1170 STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data); 1171 } 1172 else 1173 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1174 break; 1175 1176 case NFA_HCI_ANY_GET_PARAMETER: 1177 STREAM_TO_UINT8 (index, p_data); 1178 if (index == 1) 1179 { 1180 data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF); 1181 data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F); 1182 rsp_len = 2; 1183 } 1184 else 1185 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN; 1186 break; 1187 1188 case NFA_HCI_ANY_OPEN_PIPE: 1189 data[0] = 0; 1190 rsp_len = 1; 1191 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED; 1192 break; 1193 1194 case NFA_HCI_ANY_CLOSE_PIPE: 1195 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1196 break; 1197 1198 default: 1199 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1200 break; 1201 } 1202 1203 nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data); 1204} 1205 1206 1207 1208/******************************************************************************* 1209** 1210** Function nfa_hci_handle_pipe_open_close_cmd 1211** 1212** Description This function handles all generic gates (excluding 1213** connectivity gate) commands 1214** 1215** Returns none 1216** 1217*******************************************************************************/ 1218void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe) 1219{ 1220 UINT8 data[1]; 1221 UINT8 rsp_len = 0; 1222 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1223 tNFA_HCI_DYN_GATE *p_gate; 1224 1225 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) 1226 { 1227 if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL) 1228 data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate); 1229 else 1230 data[0] = 0; 1231 1232 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1233 rsp_len = 1; 1234 } 1235 else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) 1236 { 1237 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1238 } 1239 1240 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data); 1241} 1242 1243/******************************************************************************* 1244** 1245** Function nfa_hci_handle_admin_gate_cmd 1246** 1247** Description This function handles incoming commands on ADMIN gate 1248** 1249** Returns none 1250** 1251*******************************************************************************/ 1252void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data) 1253{ 1254 UINT8 source_host, source_gate, dest_host, dest_gate, pipe; 1255 UINT8 data = 0; 1256 UINT8 rsp_len = 0; 1257 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1258 tNFA_HCI_DYN_GATE *pgate; 1259 tNFA_HCI_EVT_DATA evt_data; 1260 1261 switch (nfa_hci_cb.inst) 1262 { 1263 case NFA_HCI_ANY_OPEN_PIPE: 1264 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED; 1265 data = 0; 1266 rsp_len = 1; 1267 break; 1268 1269 case NFA_HCI_ANY_CLOSE_PIPE: 1270 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1271 /* Reopen the pipe immediately */ 1272 nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data); 1273 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1274 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 1275 return; 1276 break; 1277 1278 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED: 1279 STREAM_TO_UINT8 (source_host, p_data); 1280 STREAM_TO_UINT8 (source_gate, p_data); 1281 STREAM_TO_UINT8 (dest_host, p_data); 1282 STREAM_TO_UINT8 (dest_gate, p_data); 1283 STREAM_TO_UINT8 (pipe, p_data); 1284 1285 if ( (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) 1286 ||(dest_gate == NFA_HCI_LOOP_BACK_GATE) ) 1287 { 1288 response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate); 1289 } 1290 else 1291 { 1292 if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL) 1293 { 1294 /* If the gate is valid, add the pipe to it */ 1295 if (nfa_hciu_check_pipe_between_gates (dest_gate, source_host, source_gate)) 1296 { 1297 /* Already, there is a pipe between these two gates, so will reject */ 1298 response = NFA_HCI_ANY_E_NOK; 1299 } 1300 else if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK) 1301 { 1302 /* Tell the application a pipe was created with its gate */ 1303 1304 evt_data.created.status = NFA_STATUS_OK; 1305 evt_data.created.pipe = pipe; 1306 evt_data.created.source_gate = dest_gate; 1307 evt_data.created.dest_host = source_host; 1308 evt_data.created.dest_gate = source_gate; 1309 1310 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner); 1311 } 1312 } 1313 else 1314 { 1315 response = NFA_HCI_ANY_E_NOK; 1316 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) && (dest_gate <= NFA_HCI_LAST_PROP_GATE)) 1317 { 1318 if (nfa_hciu_alloc_gate (dest_gate, 0)) 1319 response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate); 1320 } 1321 } 1322 } 1323 break; 1324 1325 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED: 1326 STREAM_TO_UINT8 (pipe, p_data); 1327 response = nfa_hciu_release_pipe (pipe); 1328 break; 1329 1330 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: 1331 STREAM_TO_UINT8 (source_host, p_data); 1332 1333 nfa_hciu_remove_all_pipes_from_host (source_host); 1334 1335 if (source_host == NFA_HCI_HOST_CONTROLLER) 1336 { 1337 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1338 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1339 1340 /* Reopen the admin pipe immediately */ 1341 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID; 1342 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 1343 return; 1344 } 1345 else 1346 { 1347 if ( (source_host >= NFA_HCI_HOST_ID_UICC0) 1348 &&(source_host < (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) ) 1349 { 1350 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = source_host; 1351 } 1352 } 1353 break; 1354 1355 default: 1356 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1357 break; 1358 } 1359 1360 nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data); 1361} 1362 1363/******************************************************************************* 1364** 1365** Function nfa_hci_handle_admin_gate_rsp 1366** 1367** Description This function handles response received on admin gate 1368** 1369** Returns none 1370** 1371*******************************************************************************/ 1372void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len) 1373{ 1374 UINT8 source_host; 1375 UINT8 source_gate = nfa_hci_cb.local_gate_in_use; 1376 UINT8 dest_host = nfa_hci_cb.remote_host_in_use; 1377 UINT8 dest_gate = nfa_hci_cb.remote_gate_in_use; 1378 UINT8 pipe = 0; 1379 tNFA_STATUS status; 1380 tNFA_HCI_EVT_DATA evt_data; 1381 UINT8 default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 1382 UINT8 host_count = 0; 1383 UINT8 host_id = 0; 1384 UINT32 os_tick; 1385 1386#if (BT_TRACE_VERBOSE == TRUE) 1387 NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: 0x%02x Pipe: 0x%02x", 1388 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); 1389#else 1390 NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u App: 0x%04x Gate: 0x%02x Pipe: 0x%02x", 1391 nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use); 1392#endif 1393 1394 /* If starting up, handle events here */ 1395 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) 1396 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) 1397 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) 1398 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) 1399 { 1400 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) 1401 { 1402 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 1403 return; 1404 } 1405 1406 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) 1407 { 1408 NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed"); 1409 nfa_hci_startup_complete (NFA_STATUS_FAILED); 1410 return; 1411 } 1412 1413 switch (nfa_hci_cb.cmd_sent) 1414 { 1415 case NFA_HCI_ANY_SET_PARAMETER: 1416 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) 1417 { 1418 /* Set WHITELIST */ 1419 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist); 1420 } 1421 else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) 1422 { 1423 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) 1424 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ) 1425 nfa_hci_dh_startup_complete (); 1426 } 1427 break; 1428 1429 case NFA_HCI_ANY_GET_PARAMETER: 1430 if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) 1431 { 1432 host_count = 0; 1433 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) 1434 { 1435 nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count; 1436 host_count++; 1437 } 1438 1439 host_count = 0; 1440 /* Collect active host in the Host Network */ 1441 while (host_count < data_len) 1442 { 1443 host_id = (UINT8) *p_data++; 1444 1445 if ( (host_id >= NFA_HCI_HOST_ID_UICC0) 1446 &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) ) 1447 { 1448 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1449 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1450 } 1451 1452 host_count++; 1453 } 1454 nfa_hci_startup_complete (NFA_STATUS_OK); 1455 } 1456 else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) 1457 { 1458 /* The only parameter we get when initializing is the session ID. Check for match. */ 1459 if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) ) 1460 { 1461 /* Session has not changed, Set WHITELIST */ 1462 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist); 1463 } 1464 else 1465 { 1466 /* Something wrong, NVRAM data could be corrupt or first start with default session id */ 1467 nfa_hciu_send_clear_all_pipe_cmd (); 1468 nfa_hci_cb.b_hci_netwk_reset = TRUE; 1469 } 1470 } 1471 break; 1472 1473 case NFA_HCI_ANY_OPEN_PIPE: 1474 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED; 1475 1476 if (nfa_hci_cb.b_hci_netwk_reset) 1477 { 1478 nfa_hci_cb.b_hci_netwk_reset = FALSE; 1479 /* Session ID is reset, Set New session id */ 1480 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)); 1481 os_tick = GKI_get_os_tick_count (); 1482 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2)); 1483 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); 1484 } 1485 else 1486 { 1487 /* First thing is to get the session ID */ 1488 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX); 1489 } 1490 break; 1491 1492 case NFA_HCI_ADM_CLEAR_ALL_PIPE: 1493 nfa_hciu_remove_all_pipes_from_host (0); 1494 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1495 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1496 nfa_hci_cb.nv_write_needed = TRUE; 1497 1498 /* Open admin */ 1499 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 1500 break; 1501 } 1502 } 1503 else 1504 { 1505 status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 1506 1507 switch (nfa_hci_cb.cmd_sent) 1508 { 1509 case NFA_HCI_ANY_SET_PARAMETER: 1510 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1511 nfa_hci_api_deregister (NULL); 1512 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1513 nfa_hci_api_dealloc_gate (NULL); 1514 break; 1515 1516 case NFA_HCI_ANY_GET_PARAMETER: 1517 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) 1518 { 1519 if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN)) 1520 { 1521 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)); 1522 os_tick = GKI_get_os_tick_count (); 1523 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2)); 1524 nfa_hci_cb.nv_write_needed = TRUE; 1525 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); 1526 } 1527 else 1528 { 1529 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1530 nfa_hci_api_deregister (NULL); 1531 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1532 nfa_hci_api_dealloc_gate (NULL); 1533 } 1534 } 1535 else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) 1536 { 1537 evt_data.hosts.status = status; 1538 evt_data.hosts.num_hosts = data_len; 1539 memcpy (evt_data.hosts.host, p_data, data_len); 1540 1541 host_count = 0; 1542 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) 1543 { 1544 nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count; 1545 host_count++; 1546 } 1547 1548 host_count = 0; 1549 /* Collect active host in the Host Network */ 1550 while (host_count < data_len) 1551 { 1552 host_id = (UINT8) *p_data++; 1553 1554 if ( (host_id >= NFA_HCI_HOST_ID_UICC0) 1555 &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) ) 1556 { 1557 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1558 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00; 1559 } 1560 host_count++; 1561 } 1562 if (nfa_hciu_is_no_host_resetting ()) 1563 nfa_hci_check_pending_api_requests (); 1564 nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use); 1565 } 1566 break; 1567 1568 case NFA_HCI_ADM_CREATE_PIPE: 1569 if (status == NFA_STATUS_OK) 1570 { 1571 STREAM_TO_UINT8 (source_host, p_data); 1572 STREAM_TO_UINT8 (source_gate, p_data); 1573 STREAM_TO_UINT8 (dest_host, p_data); 1574 STREAM_TO_UINT8 (dest_gate, p_data); 1575 STREAM_TO_UINT8 (pipe, p_data); 1576 1577 /* Sanity check */ 1578 if (source_gate != nfa_hci_cb.local_gate_in_use) 1579 { 1580 NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u", 1581 nfa_hci_cb.local_gate_in_use, source_gate); 1582 break; 1583 } 1584 1585 nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate); 1586 1587 } 1588 1589 /* Tell the application his pipe was created or not */ 1590 evt_data.created.status = status; 1591 evt_data.created.pipe = pipe; 1592 evt_data.created.source_gate = source_gate; 1593 evt_data.created.dest_host = dest_host; 1594 evt_data.created.dest_gate = dest_gate; 1595 1596 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use); 1597 break; 1598 1599 case NFA_HCI_ADM_DELETE_PIPE: 1600 if (status == NFA_STATUS_OK) 1601 { 1602 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 1603 1604 /* If only deleting one pipe, tell the app we are done */ 1605 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) 1606 { 1607 evt_data.deleted.status = status; 1608 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use; 1609 1610 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use); 1611 } 1612 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1613 nfa_hci_api_deregister (NULL); 1614 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1615 nfa_hci_api_dealloc_gate (NULL); 1616 } 1617 else 1618 { 1619 /* If only deleting one pipe, tell the app we are done */ 1620 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) 1621 { 1622 evt_data.deleted.status = status; 1623 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use; 1624 1625 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use); 1626 } 1627 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) 1628 { 1629 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 1630 nfa_hci_api_deregister (NULL); 1631 } 1632 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) 1633 { 1634 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use); 1635 nfa_hci_api_dealloc_gate (NULL); 1636 } 1637 } 1638 break; 1639 1640 case NFA_HCI_ANY_OPEN_PIPE: 1641 nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED; 1642 nfa_hci_cb.nv_write_needed = TRUE; 1643 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) 1644 { 1645 /* First thing is to get the session ID */ 1646 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX); 1647 } 1648 break; 1649 1650 case NFA_HCI_ADM_CLEAR_ALL_PIPE: 1651 nfa_hciu_remove_all_pipes_from_host (0); 1652 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED; 1653 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED; 1654 nfa_hci_cb.nv_write_needed = TRUE; 1655 /* Open admin */ 1656 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE); 1657 break; 1658 1659 } 1660 } 1661} 1662 1663/******************************************************************************* 1664** 1665** Function nfa_hci_handle_admin_gate_evt 1666** 1667** Description This function handles events received on admin gate 1668** 1669** Returns none 1670** 1671*******************************************************************************/ 1672void nfa_hci_handle_admin_gate_evt (UINT8 *p_data) 1673{ 1674 tNFA_HCI_EVT_DATA evt_data; 1675 tNFA_HCI_API_GET_HOST_LIST *p_msg; 1676 1677 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) 1678 { 1679 NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe"); 1680 return; 1681 } 1682 1683 NFA_TRACE_DEBUG0 ("nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe"); 1684 nfa_hci_cb.num_hot_plug_evts++; 1685 1686 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) 1687 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE) ) 1688 { 1689 /* Received Hot Plug evt while waiting for other Host in the network to bootup after DH host bootup is complete */ 1690 if ( (nfa_hci_cb.ee_disable_disc) 1691 &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) 1692 &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1)) ) 1693 { 1694 /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */ 1695 nfa_sys_stop_timer (&nfa_hci_cb.timer); 1696 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ Ntf(s) */ 1697 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hci_netwk_enable_timeout); 1698 } 1699 } 1700 else if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) 1701 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ) 1702 { 1703 /* Received Hot Plug evt during DH host bootup */ 1704 if ( (nfa_hci_cb.ee_disable_disc) 1705 &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) 1706 &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1)) ) 1707 { 1708 /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */ 1709 nfa_hci_cb.w4_hci_netwk_init = FALSE; 1710 } 1711 } 1712 else 1713 { 1714 /* Received Hot Plug evt on UICC self reset */ 1715 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 1716 /* Notify all registered application with the HOT_PLUG_EVT */ 1717 nfa_hciu_send_to_all_apps (NFA_HCI_EVENT_RCVD_EVT, &evt_data); 1718 1719 /* Send Get Host List after receiving any pending response */ 1720 if ((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL) 1721 { 1722 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT; 1723 /* Set Invalid handle to identify this Get Host List command is internal */ 1724 p_msg->hci_handle = NFA_HANDLE_INVALID; 1725 1726 nfa_sys_sendmsg (p_msg); 1727 } 1728 } 1729} 1730 1731/******************************************************************************* 1732** 1733** Function nfa_hci_handle_dyn_pipe_pkt 1734** 1735** Description This function handles data received via dynamic pipe 1736** 1737** Returns none 1738** 1739*******************************************************************************/ 1740void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe_id, UINT8 *p_data, UINT16 data_len) 1741{ 1742 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id); 1743 tNFA_HCI_DYN_GATE *p_gate; 1744 1745 if (p_pipe == NULL) 1746 { 1747 /* Invalid pipe ID */ 1748 NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id); 1749 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1750 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL); 1751 return; 1752 } 1753 1754 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) 1755 { 1756 nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe); 1757 } 1758 else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) 1759 { 1760 nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe); 1761 } 1762 else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) 1763 { 1764 nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe); 1765 } 1766 else 1767 { 1768 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate); 1769 if (p_gate == NULL) 1770 { 1771 NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",p_pipe->local_gate); 1772 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 1773 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL); 1774 return; 1775 } 1776 1777 /* Check if data packet is a command, response or event */ 1778 switch (nfa_hci_cb.type) 1779 { 1780 case NFA_HCI_COMMAND_TYPE: 1781 nfa_hci_handle_generic_gate_cmd (p_data, (UINT8) data_len, p_gate, p_pipe); 1782 break; 1783 1784 case NFA_HCI_RESPONSE_TYPE: 1785 nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe); 1786 break; 1787 1788 case NFA_HCI_EVENT_TYPE: 1789 nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe); 1790 break; 1791 } 1792 } 1793} 1794 1795/******************************************************************************* 1796** 1797** Function nfa_hci_handle_identity_mgmt_gate_pkt 1798** 1799** Description This function handles incoming Identity Management gate hci 1800** commands 1801** 1802** Returns none 1803** 1804*******************************************************************************/ 1805static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe) 1806{ 1807 UINT8 data[20]; 1808 UINT8 index; 1809 UINT8 gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates; 1810 UINT16 rsp_len = 0; 1811 UINT8 *p_rsp = data; 1812 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 1813 1814 /* We never send commands on a pipe where the local gate is the identity management 1815 * gate, so only commands should be processed. 1816 */ 1817 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) 1818 return; 1819 1820 switch (nfa_hci_cb.inst) 1821 { 1822 case NFA_HCI_ANY_GET_PARAMETER: 1823 index = *(p_data++); 1824 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) 1825 { 1826 switch (index) 1827 { 1828 case NFA_HCI_VERSION_SW_INDEX: 1829 data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF); 1830 data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF); 1831 data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF); 1832 rsp_len = 3; 1833 break; 1834 1835 case NFA_HCI_HCI_VERSION_INDEX: 1836 data[0] = NFA_HCI_VERSION; 1837 rsp_len = 1; 1838 break; 1839 1840 case NFA_HCI_VERSION_HW_INDEX: 1841 data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF); 1842 data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF); 1843 data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF); 1844 rsp_len = 3; 1845 break; 1846 1847 case NFA_HCI_VENDOR_NAME_INDEX: 1848 memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME)); 1849 rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME); 1850 break; 1851 1852 case NFA_HCI_MODEL_ID_INDEX: 1853 data[0] = NFA_HCI_MODEL_ID; 1854 rsp_len = 1; 1855 break; 1856 1857 case NFA_HCI_GATES_LIST_INDEX: 1858 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE; 1859 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE; 1860 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE; 1861 num_gates = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]); 1862 rsp_len = num_gates + 3; 1863 p_rsp = gate_rsp; 1864 break; 1865 1866 default: 1867 response = NFA_HCI_ANY_E_NOK; 1868 break; 1869 } 1870 } 1871 else 1872 { 1873 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED; 1874 } 1875 break; 1876 1877 case NFA_HCI_ANY_OPEN_PIPE: 1878 data[0] = 0; 1879 rsp_len = 1; 1880 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1881 break; 1882 1883 case NFA_HCI_ANY_CLOSE_PIPE: 1884 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1885 break; 1886 1887 default: 1888 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 1889 break; 1890 } 1891 1892 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp); 1893} 1894 1895/******************************************************************************* 1896** 1897** Function nfa_hci_handle_generic_gate_cmd 1898** 1899** Description This function handles all generic gates (excluding 1900** connectivity gate) commands 1901** 1902** Returns none 1903** 1904*******************************************************************************/ 1905static 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) 1906{ 1907 tNFA_HCI_EVT_DATA evt_data; 1908 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id); 1909 1910 switch (nfa_hci_cb.inst) 1911 { 1912 case NFA_HCI_ANY_SET_PARAMETER: 1913 evt_data.registry.pipe = p_pipe->pipe_id; 1914 evt_data.registry.index = *p_data++; 1915 if (data_len > 0) 1916 data_len--; 1917 evt_data.registry.data_len = data_len; 1918 1919 memcpy (evt_data.registry.reg_data, p_data, data_len); 1920 1921 nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle); 1922 break; 1923 1924 case NFA_HCI_ANY_GET_PARAMETER: 1925 evt_data.registry.pipe = p_pipe->pipe_id; 1926 evt_data.registry.index = *p_data; 1927 evt_data.registry.data_len = 0; 1928 1929 nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle); 1930 break; 1931 1932 case NFA_HCI_ANY_OPEN_PIPE: 1933 nfa_hci_handle_pipe_open_close_cmd (p_pipe); 1934 1935 evt_data.opened.pipe = p_pipe->pipe_id; 1936 evt_data.opened.status = NFA_STATUS_OK; 1937 1938 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle); 1939 break; 1940 1941 case NFA_HCI_ANY_CLOSE_PIPE: 1942 nfa_hci_handle_pipe_open_close_cmd (p_pipe); 1943 1944 evt_data.closed.pipe = p_pipe->pipe_id; 1945 evt_data.opened.status = NFA_STATUS_OK; 1946 1947 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle); 1948 break; 1949 1950 default: 1951 /* Could be application specific command, pass it on */ 1952 evt_data.cmd_rcvd.status = NFA_STATUS_OK; 1953 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;; 1954 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst; 1955 evt_data.cmd_rcvd.cmd_len = data_len; 1956 1957 if (data_len <= NFA_MAX_HCI_CMD_LEN) 1958 memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len); 1959 1960 nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle); 1961 break; 1962 } 1963} 1964 1965/******************************************************************************* 1966** 1967** Function nfa_hci_handle_generic_gate_rsp 1968** 1969** Description This function handles all generic gates (excluding 1970** connectivity) response 1971** 1972** Returns none 1973** 1974*******************************************************************************/ 1975static 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) 1976{ 1977 tNFA_HCI_EVT_DATA evt_data; 1978 tNFA_STATUS status = NFA_STATUS_OK; 1979 1980 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) 1981 status = NFA_STATUS_FAILED; 1982 1983 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) 1984 { 1985 if (status == NFA_STATUS_OK) 1986 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 1987 1988 nfa_hci_cb.nv_write_needed = TRUE; 1989 /* Tell application */ 1990 evt_data.opened.status = status; 1991 evt_data.opened.pipe = p_pipe->pipe_id; 1992 1993 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use); 1994 } 1995 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 1996 { 1997 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 1998 1999 nfa_hci_cb.nv_write_needed = TRUE; 2000 /* Tell application */ 2001 evt_data.opened.status = status;; 2002 evt_data.opened.pipe = p_pipe->pipe_id; 2003 2004 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use); 2005 } 2006 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) 2007 { 2008 /* Tell application */ 2009 evt_data.registry.status = status; 2010 evt_data.registry.pipe = p_pipe->pipe_id; 2011 evt_data.registry.data_len = data_len; 2012 evt_data.registry.index = nfa_hci_cb.param_in_use; 2013 2014 memcpy (evt_data.registry.reg_data, p_data, data_len); 2015 2016 nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use); 2017 } 2018 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) 2019 { 2020 /* Tell application */ 2021 evt_data.registry.status = status;; 2022 evt_data.registry.pipe = p_pipe->pipe_id; 2023 2024 nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use); 2025 } 2026 else 2027 { 2028 /* Could be a response to application specific command sent, pass it on */ 2029 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2030 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;; 2031 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2032 evt_data.rsp_rcvd.rsp_len = data_len; 2033 2034 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2035 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2036 2037 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use); 2038 } 2039 2040} 2041 2042/******************************************************************************* 2043** 2044** Function nfa_hci_handle_connectivity_gate_pkt 2045** 2046** Description This function handles incoming connectivity gate packets 2047** 2048** Returns none 2049** 2050*******************************************************************************/ 2051static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe) 2052{ 2053 tNFA_HCI_EVT_DATA evt_data; 2054 2055 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 2056 { 2057 switch (nfa_hci_cb.inst) 2058 { 2059 case NFA_HCI_ANY_OPEN_PIPE: 2060 case NFA_HCI_ANY_CLOSE_PIPE: 2061 nfa_hci_handle_pipe_open_close_cmd (p_pipe); 2062 break; 2063 2064 case NFA_HCI_CON_PRO_HOST_REQUEST: 2065 /* A request to the DH to activate another host. This is not supported for */ 2066 /* now, we will implement it when the spec is clearer and UICCs need it. */ 2067 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 2068 break; 2069 2070 default: 2071 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL); 2072 break; 2073 } 2074 } 2075 else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) 2076 { 2077 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 2078 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2079 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 2080 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2081 2082 /* Could be a response to application specific command sent, pass it on */ 2083 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2084 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;; 2085 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2086 evt_data.rsp_rcvd.rsp_len = data_len; 2087 2088 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2089 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2090 2091 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use); 2092 } 2093 else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) 2094 { 2095 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2096 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2097 evt_data.rcvd_evt.evt_len = data_len; 2098 evt_data.rcvd_evt.p_evt_buf = p_data; 2099 2100 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2101 nfa_hciu_send_to_apps_handling_connectivity_evts (NFA_HCI_EVENT_RCVD_EVT, &evt_data); 2102 } 2103} 2104 2105/******************************************************************************* 2106** 2107** Function nfa_hci_handle_loopback_gate_pkt 2108** 2109** Description This function handles incoming loopback gate hci events 2110** 2111** Returns none 2112** 2113*******************************************************************************/ 2114static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe) 2115{ 2116 UINT8 data[1]; 2117 UINT8 rsp_len = 0; 2118 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK; 2119 tNFA_HCI_EVT_DATA evt_data; 2120 2121 /* Check if data packet is a command, response or event */ 2122 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) 2123 { 2124 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) 2125 { 2126 data[0] = 0; 2127 rsp_len = 1; 2128 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2129 } 2130 else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) 2131 { 2132 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2133 } 2134 else 2135 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED; 2136 2137 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data); 2138 } 2139 else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) 2140 { 2141 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) 2142 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED; 2143 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) 2144 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 2145 2146 /* Could be a response to application specific command sent, pass it on */ 2147 evt_data.rsp_rcvd.status = NFA_STATUS_OK; 2148 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;; 2149 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst; 2150 evt_data.rsp_rcvd.rsp_len = data_len; 2151 2152 if (data_len <= NFA_MAX_HCI_RSP_LEN) 2153 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len); 2154 2155 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use); 2156 } 2157 else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) 2158 { 2159 if (nfa_hci_cb.w4_rsp_evt) 2160 { 2161 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2162 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2163 evt_data.rcvd_evt.evt_len = data_len; 2164 evt_data.rcvd_evt.p_evt_buf = p_data; 2165 2166 nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use); 2167 } 2168 else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) 2169 { 2170 /* Send back the same data we got */ 2171 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, NFA_HCI_EVT_POST_DATA, data_len, p_data); 2172 } 2173 } 2174} 2175 2176/******************************************************************************* 2177** 2178** Function nfa_hci_handle_generic_gate_evt 2179** 2180** Description This function handles incoming Generic gate hci events 2181** 2182** Returns none 2183** 2184*******************************************************************************/ 2185static 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) 2186{ 2187 tNFA_HCI_EVT_DATA evt_data; 2188 2189 evt_data.rcvd_evt.pipe = p_pipe->pipe_id; 2190 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst; 2191 evt_data.rcvd_evt.evt_len = data_len; 2192 2193 if (nfa_hci_cb.assembly_failed) 2194 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL; 2195 else 2196 evt_data.rcvd_evt.status = NFA_STATUS_OK; 2197 2198 evt_data.rcvd_evt.p_evt_buf = p_data; 2199 nfa_hci_cb.rsp_buf_size = 0; 2200 nfa_hci_cb.p_rsp_buf = NULL; 2201 2202 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */ 2203 nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner); 2204} 2205 2206