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