1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2013 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20 /****************************************************************************** 21 * 22 * This file contains the utility 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_dm_int.h" 31 #include "nfa_hci_api.h" 32 #include "nfa_hci_int.h" 33 #include "nfa_nv_co.h" 34 #include "nfa_mem_co.h" 35 #include "nfa_hci_defs.h" 36 37 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction); 38 BOOLEAN HCI_LOOPBACK_DEBUG = FALSE; 39 40 /******************************************************************************* 41 ** 42 ** Function nfa_hciu_find_pipe_by_pid 43 ** 44 ** Description look for the pipe control block based on pipe id 45 ** 46 ** Returns pointer to the pipe control block, or NULL if not found 47 ** 48 *******************************************************************************/ 49 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id) 50 { 51 tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes; 52 int xx = 0; 53 54 /* Loop through looking for a match */ 55 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 56 { 57 if (pp->pipe_id == pipe_id) 58 return (pp); 59 } 60 61 /* If here, not found */ 62 return (NULL); 63 } 64 65 /******************************************************************************* 66 ** 67 ** Function nfa_hciu_find_gate_by_gid 68 ** 69 ** Description Find the gate control block for the given gate id 70 ** 71 ** Returns pointer to the gate control block, or NULL if not found 72 ** 73 *******************************************************************************/ 74 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id) 75 { 76 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates; 77 int xx = 0; 78 79 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 80 { 81 if (pg->gate_id == gate_id) 82 return (pg); 83 } 84 85 return (NULL); 86 } 87 88 /******************************************************************************* 89 ** 90 ** Function nfa_hciu_find_gate_by_owner 91 ** 92 ** Description Find the the first gate control block for the given owner 93 ** 94 ** Returns pointer to the gate control block, or NULL if not found 95 ** 96 *******************************************************************************/ 97 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle) 98 { 99 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates; 100 int xx = 0; 101 102 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 103 { 104 if (pg->gate_owner == app_handle) 105 return (pg); 106 } 107 108 return (NULL); 109 } 110 111 /******************************************************************************* 112 ** 113 ** Function nfa_hciu_find_gate_with_nopipes_by_owner 114 ** 115 ** Description Find the the first gate control block with no pipes 116 ** for the given owner 117 ** 118 ** Returns pointer to the gate control block, or NULL if not found 119 ** 120 *******************************************************************************/ 121 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle) 122 { 123 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates; 124 int xx = 0; 125 126 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 127 { 128 if ( (pg->gate_owner == app_handle) 129 &&(pg->pipe_inx_mask == 0) ) 130 return (pg); 131 } 132 133 return (NULL); 134 } 135 136 /******************************************************************************* 137 ** 138 ** Function nfa_hciu_count_pipes_on_gate 139 ** 140 ** Description Count the number of pipes on the given gate 141 ** 142 ** Returns the number of pipes on the gate 143 ** 144 *******************************************************************************/ 145 UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate) 146 { 147 int xx = 0; 148 UINT32 mask = 1; 149 UINT8 count = 0; 150 151 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++) 152 { 153 if ( p_gate->pipe_inx_mask & mask ) 154 count++; 155 156 mask = mask << 1; 157 } 158 159 return (count); 160 } 161 162 /******************************************************************************* 163 ** 164 ** Function nfa_hciu_count_open_pipes_on_gate 165 ** 166 ** Description Count the number of opened pipes on the given gate 167 ** 168 ** Returns the number of pipes in OPENED state on the gate 169 ** 170 *******************************************************************************/ 171 UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate) 172 { 173 tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes; 174 int xx = 0; 175 UINT32 mask = 1; 176 UINT8 count = 0; 177 178 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 179 { 180 /* For each pipe on this gate, check if it is open */ 181 if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED)) 182 count++; 183 184 mask = mask << 1; 185 } 186 187 return (count); 188 } 189 190 /******************************************************************************* 191 ** 192 ** Function nfa_hciu_get_gate_owner 193 ** 194 ** Description Find the application that owns a gate 195 ** 196 ** Returns application handle 197 ** 198 *******************************************************************************/ 199 tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id) 200 { 201 tNFA_HCI_DYN_GATE *pg; 202 203 if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL) 204 return (NFA_HANDLE_INVALID); 205 206 return (pg->gate_owner); 207 } 208 209 /******************************************************************************* 210 ** 211 ** Function nfa_hciu_get_pipe_owner 212 ** 213 ** Description Find the application that owns a pipe 214 ** 215 ** Returns application handle 216 ** 217 *******************************************************************************/ 218 tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id) 219 { 220 tNFA_HCI_DYN_PIPE *pp; 221 tNFA_HCI_DYN_GATE *pg; 222 223 if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL) 224 return (NFA_HANDLE_INVALID); 225 226 if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL) 227 return (NFA_HANDLE_INVALID); 228 229 return (pg->gate_owner); 230 } 231 232 233 /******************************************************************************* 234 ** 235 ** Function nfa_hciu_alloc_gate 236 ** 237 ** Description Allocate an gate control block 238 ** 239 ** Returns pointer to the allocated gate, or NULL if cannot allocate 240 ** 241 *******************************************************************************/ 242 tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle) 243 { 244 tNFA_HCI_DYN_GATE *pg; 245 int xx; 246 UINT8 app_inx = app_handle & NFA_HANDLE_MASK; 247 248 249 /* First, check if the application handle is valid */ 250 if ((gate_id != NFA_HCI_CONNECTIVITY_GATE) 251 && 252 ( ((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI) 253 ||(app_inx >= NFA_HCI_MAX_APP_CB) 254 ||(nfa_hci_cb.p_app_cback[app_inx] == NULL) )) 255 { 256 return (NULL); 257 } 258 259 if (gate_id != 0) 260 { 261 if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL) 262 return (pg); 263 } 264 else 265 { 266 /* If gate_id is 0, we need to assign a free one */ 267 /* Loop through all possible gate IDs checking if they are already used */ 268 for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id < NFA_HCI_LAST_PROP_GATE; gate_id++) 269 { 270 /* Skip connectivity gate */ 271 if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++; 272 273 /* Check if the gate is already allocated */ 274 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 275 if (pg->gate_id == gate_id) 276 break; 277 /* If the gate is not allocated, use the gate */ 278 if (xx == NFA_HCI_MAX_GATE_CB) 279 break; 280 } 281 if (gate_id == NFA_HCI_LAST_PROP_GATE) 282 { 283 NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u App Handle: 0x%04x", gate_id, app_handle); 284 return (NULL); 285 } 286 } 287 288 /* Now look for a free control block */ 289 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 290 { 291 if (pg->gate_id == 0) 292 { 293 /* Found a free gate control block */ 294 pg->gate_id = gate_id; 295 pg->gate_owner = app_handle; 296 pg->pipe_inx_mask = 0; 297 298 NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d app_handle: 0x%04x", gate_id, app_handle); 299 300 nfa_hci_cb.nv_write_needed = TRUE; 301 return (pg); 302 } 303 } 304 305 /* If here, no free gate control block */ 306 NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB Gate ID: %u App Handle: 0x%04x", gate_id, app_handle); 307 return (NULL); 308 } 309 310 /******************************************************************************* 311 ** 312 ** Function nfa_hciu_send_msg 313 ** 314 ** Description This function will fragment the given packet, if necessary 315 ** and send it on the given pipe. 316 ** 317 ** Returns status 318 ** 319 *******************************************************************************/ 320 tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg) 321 { 322 BT_HDR *p_buf; 323 UINT8 *p_data; 324 BOOLEAN first_pkt = TRUE; 325 UINT16 data_len; 326 tNFA_STATUS status = NFA_STATUS_OK; 327 UINT16 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE; 328 329 #if (BT_TRACE_VERBOSE == TRUE) 330 NFA_TRACE_DEBUG3 ("nfa_hciu_send_msg pipe_id:%d %s len:%d", 331 pipe_id, nfa_hciu_get_type_inst_names (pipe_id, type, instruction), msg_len); 332 #else 333 NFA_TRACE_DEBUG4 ("nfa_hciu_send_msg pipe_id:%d Type: %u Inst: %u len: %d", 334 pipe_id, type, instruction, msg_len); 335 #endif 336 337 if (instruction == NFA_HCI_ANY_GET_PARAMETER) 338 nfa_hci_cb.param_in_use = *p_msg; 339 340 while ((first_pkt == TRUE) || (msg_len != 0)) 341 { 342 if ((p_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) 343 { 344 p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 345 346 /* First packet has a 2-byte header, subsequent fragments have a 1-byte header */ 347 data_len = first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1); 348 349 p_data = (UINT8 *) (p_buf + 1) + p_buf->offset; 350 351 /* Last or only segment has "no fragmentation" bit set */ 352 if (msg_len > data_len) 353 { 354 *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F); 355 } 356 else 357 { 358 data_len = msg_len; 359 *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F); 360 } 361 362 p_buf->len = 1; 363 364 /* Message header only goes in the first segment */ 365 if (first_pkt) 366 { 367 first_pkt = FALSE; 368 *p_data++ = (type << 6) | instruction; 369 p_buf->len++; 370 } 371 372 if (data_len != 0) 373 { 374 memcpy (p_data, p_msg, data_len); 375 376 p_buf->len += data_len; 377 msg_len -= data_len; 378 if (msg_len > 0) 379 p_msg += data_len; 380 } 381 382 #if (BT_TRACE_PROTOCOL == TRUE) 383 DispHcp (((UINT8 *) (p_buf + 1) + p_buf->offset), p_buf->len, FALSE, (BOOLEAN) ((p_buf->len - data_len) == 2)); 384 #endif 385 386 if (HCI_LOOPBACK_DEBUG) 387 handle_debug_loopback (p_buf, pipe_id, type, instruction); 388 else 389 status = NFC_SendData (nfa_hci_cb.conn_id, p_buf); 390 } 391 else 392 { 393 NFA_TRACE_ERROR0 ("nfa_hciu_send_data_packet no buffers"); 394 status = NFA_STATUS_NO_BUFFERS; 395 break; 396 } 397 } 398 399 /* Start timer if response to wait for a particular time for the response */ 400 if (type == NFA_HCI_COMMAND_TYPE) 401 { 402 nfa_hci_cb.cmd_sent = instruction; 403 404 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) 405 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP; 406 407 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout); 408 } 409 410 return status; 411 } 412 413 /******************************************************************************* 414 ** 415 ** Function nfa_hciu_get_allocated_gate_list 416 ** 417 ** Description fills in a list of allocated gates 418 ** 419 ** Returns the number of gates 420 ** 421 *******************************************************************************/ 422 UINT8 nfa_hciu_get_allocated_gate_list (UINT8 *p_gate_list) 423 { 424 tNFA_HCI_DYN_GATE *p_cb; 425 int xx; 426 UINT8 count = 0; 427 428 for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, p_cb++) 429 { 430 if (p_cb->gate_id != 0) 431 { 432 *p_gate_list++ = p_cb->gate_id; 433 count++; 434 } 435 } 436 437 NFA_TRACE_DEBUG1 ("nfa_hciu_get_allocated_gate_list () returns: %u", count); 438 439 return (count); 440 } 441 442 /******************************************************************************* 443 ** 444 ** Function nfa_hciu_alloc_pipe 445 ** 446 ** Description Allocate a pipe control block 447 ** 448 ** Returns pointer to the pipe control block, or NULL if 449 ** cannot allocate 450 ** 451 *******************************************************************************/ 452 tNFA_HCI_DYN_PIPE *nfa_hciu_alloc_pipe (UINT8 pipe_id) 453 { 454 UINT8 xx; 455 tNFA_HCI_DYN_PIPE *pp; 456 457 /* If we already have a pipe of the same ID, release it first it */ 458 if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL) 459 { 460 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) 461 return pp; 462 nfa_hciu_release_pipe (pipe_id); 463 } 464 465 /* Look for a free pipe control block */ 466 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 467 { 468 if (pp->pipe_id == 0) 469 { 470 NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx); 471 pp->pipe_id = pipe_id; 472 473 nfa_hci_cb.nv_write_needed = TRUE; 474 return (pp); 475 } 476 } 477 478 NFA_TRACE_DEBUG1 ("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id); 479 return (NULL); 480 } 481 482 /******************************************************************************* 483 ** 484 ** Function nfa_hciu_release_gate 485 ** 486 ** Description Remove a generic gate from gate list 487 ** 488 ** Returns none 489 ** 490 *******************************************************************************/ 491 void nfa_hciu_release_gate (UINT8 gate_id) 492 { 493 tNFA_HCI_DYN_GATE *p_gate = nfa_hciu_find_gate_by_gid (gate_id); 494 495 if (p_gate != NULL) 496 { 497 NFA_TRACE_DEBUG3 ("nfa_hciu_release_gate () ID: %d owner: 0x%04x pipe_inx_mask: 0x%04x", 498 gate_id, p_gate->gate_owner, p_gate->pipe_inx_mask); 499 500 p_gate->gate_id = 0; 501 p_gate->gate_owner = 0; 502 p_gate->pipe_inx_mask = 0; 503 504 nfa_hci_cb.nv_write_needed = TRUE; 505 } 506 else 507 { 508 NFA_TRACE_WARNING1 ("nfa_hciu_release_gate () ID: %d NOT FOUND", gate_id); 509 } 510 } 511 512 /******************************************************************************* 513 ** 514 ** Function nfa_hciu_add_pipe_to_gate 515 ** 516 ** Description Add pipe to generic gate 517 ** 518 ** Returns NFA_STATUS_OK, if successfully add the pipe on to the gate 519 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise 520 ** 521 *******************************************************************************/ 522 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate (UINT8 pipe_id, UINT8 local_gate, 523 UINT8 dest_host, UINT8 dest_gate) 524 { 525 tNFA_HCI_DYN_GATE *p_gate; 526 tNFA_HCI_DYN_PIPE *p_pipe; 527 UINT8 pipe_index; 528 529 p_gate = nfa_hciu_find_gate_by_gid (local_gate); 530 531 if (p_gate != NULL) 532 { 533 /* Allocate a pipe control block */ 534 if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL) 535 { 536 p_pipe->pipe_id = pipe_id; 537 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 538 p_pipe->dest_host = dest_host; 539 p_pipe->dest_gate = dest_gate; 540 p_pipe->local_gate = local_gate; 541 542 /* Save the pipe in the gate that it belongs to */ 543 pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes); 544 p_gate->pipe_inx_mask |= (UINT32) (1 << pipe_index); 545 546 NFA_TRACE_DEBUG4 ("nfa_hciu_add_pipe_to_gate Gate ID: 0x%02x Pipe ID: 0x%02x pipe_index: %u App Handle: 0x%08x", 547 local_gate, pipe_id, pipe_index, p_gate->gate_owner); 548 return (NFA_HCI_ANY_OK); 549 } 550 } 551 552 NFA_TRACE_DEBUG1 ("nfa_hciu_add_pipe_to_gate: 0x%02x NOT FOUND", local_gate); 553 554 return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE); 555 } 556 557 /******************************************************************************* 558 ** 559 ** Function nfa_hciu_add_pipe_to_static_gate 560 ** 561 ** Description Add pipe to identity management gate 562 ** 563 ** Returns NFA_HCI_ANY_OK, if successfully add the pipe on to the gate 564 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise 565 ** 566 *******************************************************************************/ 567 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate (UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate) 568 { 569 tNFA_HCI_DYN_PIPE *p_pipe; 570 UINT8 pipe_index; 571 572 NFA_TRACE_EVENT4 ("nfa_hciu_add_pipe_to_static_gate (%u) Pipe: 0x%02x Dest Host: 0x%02x Dest Gate: 0x%02x)", 573 local_gate, pipe_id, dest_host, dest_gate); 574 575 /* Allocate a pipe control block */ 576 if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL) 577 { 578 p_pipe->pipe_id = pipe_id; 579 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED; 580 p_pipe->dest_host = dest_host; 581 p_pipe->dest_gate = dest_gate; 582 p_pipe->local_gate = local_gate; 583 584 /* If this is the ID gate, save the pipe index in the ID gate info */ 585 /* block. Note that for loopback, it is enough to just create the pipe */ 586 if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) 587 { 588 pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes); 589 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (UINT32) (1 << pipe_index); 590 } 591 return NFA_HCI_ANY_OK; 592 } 593 594 return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE; 595 } 596 597 /******************************************************************************* 598 ** 599 ** Function nfa_hciu_find_active_pipe_by_owner 600 ** 601 ** Description Find the first pipe associated with the given app 602 ** 603 ** Returns pointer to pipe, or NULL if none found 604 ** 605 *******************************************************************************/ 606 tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_by_owner (tNFA_HANDLE app_handle) 607 { 608 tNFA_HCI_DYN_GATE *pg; 609 tNFA_HCI_DYN_PIPE *pp; 610 int xx; 611 612 NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle); 613 614 /* Loop through all pipes looking for the owner */ 615 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 616 { 617 if ( (pp->pipe_id != 0) 618 &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) 619 &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) 620 &&(nfa_hciu_is_active_host (pp->dest_host)) ) 621 { 622 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL) 623 &&(pg->gate_owner == app_handle) ) 624 return (pp); 625 } 626 } 627 628 /* If here, not found */ 629 return (NULL); 630 } 631 632 /******************************************************************************* 633 ** 634 ** Function nfa_hciu_find_pipe_by_owner 635 ** 636 ** Description Find the first pipe associated with the given app 637 ** 638 ** Returns pointer to pipe, or NULL if none found 639 ** 640 *******************************************************************************/ 641 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle) 642 { 643 tNFA_HCI_DYN_GATE *pg; 644 tNFA_HCI_DYN_PIPE *pp; 645 int xx; 646 647 NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle); 648 649 /* Loop through all pipes looking for the owner */ 650 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 651 { 652 if (pp->pipe_id != 0) 653 { 654 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL) 655 &&(pg->gate_owner == app_handle) ) 656 return (pp); 657 } 658 } 659 660 /* If here, not found */ 661 return (NULL); 662 } 663 664 /******************************************************************************* 665 ** 666 ** Function nfa_hciu_find_pipe_on_gate 667 ** 668 ** Description Find the first pipe associated with the given gate 669 ** 670 ** Returns pointer to pipe, or NULL if none found 671 ** 672 *******************************************************************************/ 673 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_on_gate (UINT8 gate_id) 674 { 675 tNFA_HCI_DYN_GATE *pg; 676 tNFA_HCI_DYN_PIPE *pp; 677 int xx; 678 679 NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id); 680 681 /* Loop through all pipes looking for the owner */ 682 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 683 { 684 if (pp->pipe_id != 0) 685 { 686 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL) 687 &&(pg->gate_id == gate_id) ) 688 return (pp); 689 } 690 } 691 692 /* If here, not found */ 693 return (NULL); 694 } 695 696 /******************************************************************************* 697 ** 698 ** Function nfa_hciu_is_active_host 699 ** 700 ** Description Check if the host is currently active 701 ** 702 ** Returns TRUE, if the host is active in the host network 703 ** FALSE, if the host is not active in the host network 704 ** 705 *******************************************************************************/ 706 BOOLEAN nfa_hciu_is_active_host (UINT8 host_id) 707 { 708 UINT8 xx; 709 710 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 711 { 712 if (nfa_hci_cb.inactive_host[xx] == host_id) 713 return FALSE; 714 } 715 716 return TRUE; 717 } 718 719 /******************************************************************************* 720 ** 721 ** Function nfa_hciu_is_host_reseting 722 ** 723 ** Description Check if the host is currently reseting 724 ** 725 ** Returns TRUE, if the host is reseting 726 ** FALSE, if the host is not reseting 727 ** 728 *******************************************************************************/ 729 BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id) 730 { 731 UINT8 xx; 732 733 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 734 { 735 if (nfa_hci_cb.reset_host[xx] == host_id) 736 return TRUE; 737 } 738 739 return FALSE; 740 } 741 742 /******************************************************************************* 743 ** 744 ** Function nfa_hciu_is_no_host_resetting 745 ** 746 ** Description Check if no host is reseting 747 ** 748 ** Returns TRUE, if no host is resetting at this time 749 ** FALSE, if one or more host is resetting 750 ** 751 *******************************************************************************/ 752 BOOLEAN nfa_hciu_is_no_host_resetting (void) 753 { 754 UINT8 xx; 755 756 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 757 { 758 if (nfa_hci_cb.reset_host[xx] != 0) 759 return FALSE; 760 } 761 762 return TRUE; 763 } 764 765 /******************************************************************************* 766 ** 767 ** Function nfa_hciu_find_active_pipe_on_gate 768 ** 769 ** Description Find the first active pipe associated with the given gate 770 ** 771 ** Returns pointer to pipe, or NULL if none found 772 ** 773 *******************************************************************************/ 774 tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id) 775 { 776 tNFA_HCI_DYN_GATE *pg; 777 tNFA_HCI_DYN_PIPE *pp; 778 int xx; 779 780 NFA_TRACE_DEBUG1 ("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id); 781 782 /* Loop through all pipes looking for the owner */ 783 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 784 { 785 if ( (pp->pipe_id != 0) 786 &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) 787 &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) 788 &&(nfa_hciu_is_active_host (pp->dest_host)) ) 789 { 790 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL) 791 &&(pg->gate_id == gate_id) ) 792 return (pp); 793 } 794 } 795 796 /* If here, not found */ 797 return (NULL); 798 } 799 800 /******************************************************************************* 801 ** 802 ** Function nfa_hciu_release_pipe 803 ** 804 ** Description remove the specified pipe 805 ** 806 ** Returns NFA_HCI_ANY_OK, if removed 807 ** NFA_HCI_ANY_E_NOK, if otherwise 808 ** 809 *******************************************************************************/ 810 tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id) 811 { 812 tNFA_HCI_DYN_GATE *p_gate; 813 tNFA_HCI_DYN_PIPE *p_pipe; 814 UINT8 pipe_index; 815 816 NFA_TRACE_EVENT1 ("nfa_hciu_release_pipe: %u", pipe_id); 817 818 if ((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL) 819 return (NFA_HCI_ANY_E_NOK); 820 821 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) 822 { 823 NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe_id); 824 return (NFA_HCI_ANY_E_NOK); 825 } 826 827 pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes); 828 829 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) 830 { 831 /* Remove pipe from ID management gate */ 832 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~ (UINT32) (1 << pipe_index); 833 } 834 else 835 { 836 if ((p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate)) == NULL) 837 { 838 /* Mark the pipe control block as free */ 839 p_pipe->pipe_id = 0; 840 return (NFA_HCI_ANY_E_NOK); 841 } 842 843 /* Remove pipe from gate */ 844 p_gate->pipe_inx_mask &= ~ (UINT32) (1 << pipe_index); 845 } 846 847 /* Reset pipe control block */ 848 memset (p_pipe,0,sizeof (tNFA_HCI_DYN_PIPE)); 849 nfa_hci_cb.nv_write_needed = TRUE; 850 return NFA_HCI_ANY_OK; 851 } 852 853 /******************************************************************************* 854 ** 855 ** Function nfa_hciu_remove_all_pipes_from_host 856 ** 857 ** Description remove all the pipes that are connected to a specific host 858 ** 859 ** Returns None 860 ** 861 *******************************************************************************/ 862 void nfa_hciu_remove_all_pipes_from_host (UINT8 host) 863 { 864 tNFA_HCI_DYN_GATE *pg; 865 tNFA_HCI_DYN_PIPE *pp; 866 int xx; 867 tNFA_HCI_EVT_DATA evt_data; 868 869 NFA_TRACE_EVENT1 ("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host); 870 871 /* Remove all pipes from the specified host connected to all generic gates */ 872 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 873 { 874 if ( (pp->pipe_id == 0) 875 || 876 ( (host != 0) 877 &&((pp->dest_host != host) || (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))) ) 878 continue; 879 880 if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL) 881 { 882 evt_data.deleted.status = NFA_STATUS_OK; 883 evt_data.deleted.pipe = pp->pipe_id; 884 885 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner); 886 } 887 nfa_hciu_release_pipe (pp->pipe_id); 888 } 889 } 890 891 /******************************************************************************* 892 ** 893 ** Function nfa_hciu_send_create_pipe_cmd 894 ** 895 ** Description Create dynamic pipe between the specified gates 896 ** 897 ** Returns status 898 ** 899 *******************************************************************************/ 900 tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate) 901 { 902 tNFA_STATUS status; 903 UINT8 data[3]; 904 905 data[0] = source_gate; 906 data[1] = dest_host; 907 data[2] = dest_gate; 908 909 NFA_TRACE_DEBUG3 ("nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, dest_gate:%d", source_gate, dest_host, dest_gate); 910 911 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CREATE_PIPE, 3, data); 912 913 return status; 914 } 915 916 /******************************************************************************* 917 ** 918 ** Function nfa_hciu_send_delete_pipe_cmd 919 ** 920 ** Description Delete the dynamic pipe 921 ** 922 ** Returns None 923 ** 924 *******************************************************************************/ 925 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe) 926 { 927 tNFA_STATUS status; 928 929 NFA_TRACE_DEBUG1 ("nfa_hciu_send_delete_pipe_cmd: %d", pipe); 930 931 if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE) 932 { 933 NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe); 934 return (NFA_HCI_ANY_E_NOK); 935 } 936 nfa_hci_cb.pipe_in_use = pipe; 937 938 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_DELETE_PIPE, 1, &pipe); 939 940 return status; 941 } 942 943 944 /******************************************************************************* 945 ** 946 ** Function nfa_hciu_send_clear_all_pipe_cmd 947 ** 948 ** Description delete all the dynamic pipe connected to device host, 949 ** to close all static pipes connected to device host, 950 ** and to set registry values related to static pipes to 951 ** theri default values. 952 ** 953 ** Returns None 954 ** 955 *******************************************************************************/ 956 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void) 957 { 958 tNFA_STATUS status; 959 UINT16 id_ref_data = 0x0102; 960 961 NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd"); 962 963 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data); 964 965 return status; 966 } 967 968 /******************************************************************************* 969 ** 970 ** Function nfa_hciu_send_open_pipe_cmd 971 ** 972 ** Description Open a closed pipe 973 ** 974 ** Returns status 975 ** 976 *******************************************************************************/ 977 tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe) 978 { 979 tNFA_STATUS status; 980 981 nfa_hci_cb.pipe_in_use = pipe; 982 983 status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE, 0, NULL); 984 985 return status; 986 } 987 988 /******************************************************************************* 989 ** 990 ** Function nfa_hciu_send_close_pipe_cmd 991 ** 992 ** Description Close an opened pipe 993 ** 994 ** Returns status 995 ** 996 *******************************************************************************/ 997 tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe) 998 { 999 tNFA_STATUS status; 1000 1001 nfa_hci_cb.pipe_in_use = pipe; 1002 1003 status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE, 0, NULL); 1004 1005 return status; 1006 } 1007 1008 /******************************************************************************* 1009 ** 1010 ** Function nfa_hciu_send_get_param_cmd 1011 ** 1012 ** Description Read a parameter value from gate registry 1013 ** 1014 ** Returns None 1015 ** 1016 *******************************************************************************/ 1017 tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index) 1018 { 1019 tNFA_STATUS status; 1020 1021 if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_GET_PARAMETER, 1, &index)) == NFC_STATUS_OK) 1022 nfa_hci_cb.param_in_use = index; 1023 1024 return status; 1025 } 1026 1027 /******************************************************************************* 1028 ** 1029 ** Function nfa_hciu_send_set_param_cmd 1030 ** 1031 ** Description Set a parameter value in a gate registry 1032 ** 1033 ** Returns None 1034 ** 1035 *******************************************************************************/ 1036 tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data) 1037 { 1038 tNFA_STATUS status; 1039 UINT8 data[255]; 1040 1041 data[0] = index; 1042 1043 memcpy (&data[1], p_data, length); 1044 1045 if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER, (UINT16) (length + 1), data)) == NFC_STATUS_OK) 1046 nfa_hci_cb.param_in_use = index; 1047 1048 return status; 1049 } 1050 1051 1052 /******************************************************************************* 1053 ** 1054 ** Function nfa_hciu_send_to_app 1055 ** 1056 ** Description Send an event back to an application 1057 ** 1058 ** Returns none 1059 ** 1060 *******************************************************************************/ 1061 void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle) 1062 { 1063 UINT8 app_inx = app_handle & NFA_HANDLE_MASK; 1064 1065 /* First, check if the application handle is valid */ 1066 if ( ((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI) 1067 &&(app_inx < NFA_HCI_MAX_APP_CB) ) 1068 { 1069 if (nfa_hci_cb.p_app_cback[app_inx] != NULL) 1070 { 1071 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt); 1072 return; 1073 } 1074 } 1075 1076 if (app_handle != NFA_HANDLE_INVALID) 1077 { 1078 NFA_TRACE_WARNING2 ("nfa_hciu_send_to_app no callback, event: 0x%04x app_handle: 0x%04x", 1079 event, app_handle); 1080 } 1081 } 1082 1083 /******************************************************************************* 1084 ** 1085 ** Function nfa_hciu_send_to_all_apps 1086 ** 1087 ** Description Send an event back to all applications 1088 ** 1089 ** Returns none 1090 ** 1091 *******************************************************************************/ 1092 void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt) 1093 { 1094 UINT8 app_inx; 1095 1096 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) 1097 { 1098 if (nfa_hci_cb.p_app_cback[app_inx] != NULL) 1099 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt); 1100 } 1101 1102 } 1103 1104 /******************************************************************************* 1105 ** 1106 ** Function nfa_hciu_send_to_apps_handling_connectivity_evts 1107 ** 1108 ** Description Send a connectivity event to all the application interested 1109 ** in connectivity events 1110 ** 1111 ** Returns none 1112 ** 1113 *******************************************************************************/ 1114 void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt) 1115 { 1116 UINT8 app_inx; 1117 1118 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) 1119 { 1120 if ( (nfa_hci_cb.p_app_cback[app_inx] != NULL) 1121 &&(nfa_hci_cb.cfg.b_send_conn_evts[app_inx])) 1122 1123 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt); 1124 } 1125 1126 } 1127 1128 #if (BT_TRACE_VERBOSE == TRUE) 1129 /******************************************************************************* 1130 ** 1131 ** Function nfa_hciu_get_response_name 1132 ** 1133 ** Description This function returns the error code name. 1134 ** 1135 ** NOTE conditionally compiled to save memory. 1136 ** 1137 ** Returns pointer to the name 1138 ** 1139 *******************************************************************************/ 1140 char *nfa_hciu_get_response_name (UINT8 rsp_code) 1141 { 1142 static char unknown[50]; 1143 1144 switch (rsp_code) 1145 { 1146 case NFA_HCI_ANY_OK: 1147 return ("ANY_OK"); 1148 case NFA_HCI_ANY_E_NOT_CONNECTED: 1149 return ("ANY_E_NOT_CONNECTED"); 1150 case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN: 1151 return ("ANY_E_CMD_PAR_UNKNOWN"); 1152 case NFA_HCI_ANY_E_NOK: 1153 return ("ANY_E_NOK"); 1154 case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE: 1155 return ("ADM_E_NO_PIPES_AVAILABLE"); 1156 case NFA_HCI_ANY_E_REG_PAR_UNKNOWN: 1157 return ("ANY_E_REG_PAR_UNKNOWN"); 1158 case NFA_HCI_ANY_E_PIPE_NOT_OPENED: 1159 return ("ANY_E_PIPE_NOT_OPENED"); 1160 case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED: 1161 return ("ANY_E_CMD_NOT_SUPPORTED"); 1162 case NFA_HCI_ANY_E_INHIBITED: 1163 return ("ANY_E_INHIBITED"); 1164 case NFA_HCI_ANY_E_TIMEOUT: 1165 return ("ANY_E_TIMEOUT"); 1166 case NFA_HCI_ANY_E_REG_ACCESS_DENIED: 1167 return ("ANY_E_REG_ACCESS_DENIED"); 1168 case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED: 1169 return ("ANY_E_PIPE_ACCESS_DENIED"); 1170 default: 1171 sprintf (unknown, "?? Unknown: %u ?? ", rsp_code); 1172 return (unknown); 1173 } 1174 } 1175 1176 /******************************************************************************* 1177 ** 1178 ** Function nfa_hciu_type_2_str 1179 ** 1180 ** Description This function returns the type name. 1181 ** 1182 ** Returns pointer to the name 1183 ** 1184 *******************************************************************************/ 1185 char *nfa_hciu_type_2_str(UINT8 type) 1186 { 1187 static char unknown[40]; 1188 1189 switch (type) 1190 { 1191 case NFA_HCI_COMMAND_TYPE: 1192 return ("COMMAND"); 1193 case NFA_HCI_EVENT_TYPE: 1194 return ("EVENT"); 1195 case NFA_HCI_RESPONSE_TYPE: 1196 return ("RESPONSE"); 1197 default: 1198 sprintf (unknown, "?? Unknown: %u ?? ", type); 1199 return (unknown); 1200 } 1201 } 1202 1203 /******************************************************************************* 1204 ** 1205 ** Function nfa_hciu_instr_2_str 1206 ** 1207 ** Description This function returns the instruction name. 1208 ** 1209 ** Returns pointer to the name 1210 ** 1211 *******************************************************************************/ 1212 char *nfa_hciu_instr_2_str (UINT8 instruction) 1213 { 1214 static char unknown[40]; 1215 1216 switch (instruction) 1217 { 1218 case NFA_HCI_ANY_SET_PARAMETER: 1219 return ("ANY_SET_PARAMETER"); 1220 case NFA_HCI_ANY_GET_PARAMETER: 1221 return ("ANY_GET_PARAMETER"); 1222 case NFA_HCI_ANY_OPEN_PIPE: 1223 return ("ANY_OPEN_PIPE"); 1224 case NFA_HCI_ANY_CLOSE_PIPE: 1225 return ("ANY_CLOSE_PIPE"); 1226 case NFA_HCI_ADM_CREATE_PIPE: 1227 return ("ADM_CREATE_PIPE"); 1228 case NFA_HCI_ADM_DELETE_PIPE: 1229 return ("ADM_DELETE_PIPE"); 1230 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED: 1231 return ("ADM_NOTIFY_PIPE_CREATED"); 1232 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED: 1233 return ("ADM_NOTIFY_PIPE_DELETED"); 1234 case NFA_HCI_ADM_CLEAR_ALL_PIPE: 1235 return ("ADM_CLEAR_ALL_PIPE"); 1236 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: 1237 return ("ADM_NOTIFY_ALL_PIPE_CLEARED"); 1238 default: 1239 sprintf (unknown, "?? Unknown: %u ?? ", instruction); 1240 return (unknown); 1241 } 1242 } 1243 1244 1245 /******************************************************************************* 1246 ** 1247 ** Function nfa_hciu_get_event_name 1248 ** 1249 ** Description This function returns the event code name. 1250 ** 1251 ** Returns pointer to the name 1252 ** 1253 *******************************************************************************/ 1254 char *nfa_hciu_get_event_name (UINT16 event) 1255 { 1256 static char unknown[40]; 1257 1258 switch (event) 1259 { 1260 case NFA_HCI_API_REGISTER_APP_EVT: return ("API_REGISTER"); 1261 case NFA_HCI_API_DEREGISTER_APP_EVT: return ("API_DEREGISTER"); 1262 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT: return ("API_GET_GATE_LIST"); 1263 case NFA_HCI_API_ALLOC_GATE_EVT: return ("API_ALLOC_GATE"); 1264 case NFA_HCI_API_DEALLOC_GATE_EVT: return ("API_DEALLOC_GATE"); 1265 case NFA_HCI_API_GET_HOST_LIST_EVT: return ("API_GET_HOST_LIST"); 1266 case NFA_HCI_API_GET_REGISTRY_EVT: return ("API_GET_REG_VALUE"); 1267 case NFA_HCI_API_SET_REGISTRY_EVT: return ("API_SET_REG_VALUE"); 1268 case NFA_HCI_API_CREATE_PIPE_EVT: return ("API_CREATE_PIPE"); 1269 case NFA_HCI_API_OPEN_PIPE_EVT: return ("API_OPEN_PIPE"); 1270 case NFA_HCI_API_CLOSE_PIPE_EVT: return ("API_CLOSE_PIPE"); 1271 case NFA_HCI_API_DELETE_PIPE_EVT: return ("API_DELETE_PIPE"); 1272 case NFA_HCI_API_SEND_CMD_EVT: return ("API_SEND_COMMAND_EVT"); 1273 case NFA_HCI_API_SEND_RSP_EVT: return ("API_SEND_RESPONSE_EVT"); 1274 case NFA_HCI_API_SEND_EVENT_EVT: return ("API_SEND_EVENT_EVT"); 1275 case NFA_HCI_RSP_NV_READ_EVT: return ("NV_READ_EVT"); 1276 case NFA_HCI_RSP_NV_WRITE_EVT: return ("NV_WRITE_EVT"); 1277 case NFA_HCI_RSP_TIMEOUT_EVT: return ("RESPONSE_TIMEOUT_EVT"); 1278 case NFA_HCI_CHECK_QUEUE_EVT: return ("CHECK_QUEUE"); 1279 1280 default: 1281 sprintf (unknown, "?? Unknown: %u ?? ", event); 1282 return (unknown); 1283 } 1284 } 1285 1286 /******************************************************************************* 1287 ** 1288 ** Function nfa_hciu_get_state_name 1289 ** 1290 ** Description This function returns the state name. 1291 ** 1292 ** Returns pointer to the name 1293 ** 1294 *******************************************************************************/ 1295 char *nfa_hciu_get_state_name (UINT8 state) 1296 { 1297 static char unknown[40]; 1298 1299 switch (state) 1300 { 1301 case NFA_HCI_STATE_DISABLED: return ("DISABLED"); 1302 case NFA_HCI_STATE_STARTUP: return ("STARTUP"); 1303 case NFA_HCI_STATE_WAIT_NETWK_ENABLE: return ("WAIT_NETWK_ENABLE"); 1304 case NFA_HCI_STATE_IDLE: return ("IDLE"); 1305 case NFA_HCI_STATE_WAIT_RSP: return ("WAIT_RSP"); 1306 case NFA_HCI_STATE_REMOVE_GATE: return ("REMOVE_GATE"); 1307 case NFA_HCI_STATE_APP_DEREGISTER: return ("APP_DEREGISTER"); 1308 case NFA_HCI_STATE_RESTORE: return ("RESTORE"); 1309 case NFA_HCI_STATE_RESTORE_NETWK_ENABLE: return ("WAIT_NETWK_ENABLE_AFTER_RESTORE"); 1310 1311 default: 1312 sprintf (unknown, "?? Unknown: %u ?? ", state); 1313 return (unknown); 1314 } 1315 } 1316 1317 /******************************************************************************* 1318 ** 1319 ** Function nfa_hciu_get_type_inst_names 1320 ** 1321 ** Description This function returns command/response/event name. 1322 ** 1323 ** Returns pointer to the name 1324 ** 1325 *******************************************************************************/ 1326 char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst) 1327 { 1328 static char buff[100]; 1329 int xx; 1330 1331 xx = sprintf (buff, "Type: %s ", nfa_hciu_type_2_str (type)); 1332 1333 switch (type) 1334 { 1335 case NFA_HCI_COMMAND_TYPE: 1336 sprintf (&buff[xx], "Inst: %s ", nfa_hciu_instr_2_str (inst)); 1337 break; 1338 case NFA_HCI_EVENT_TYPE: 1339 sprintf (&buff[xx], "Evt: %s ", nfa_hciu_evt_2_str (pipe, inst)); 1340 break; 1341 case NFA_HCI_RESPONSE_TYPE: 1342 sprintf (&buff[xx], "Resp: %s ", nfa_hciu_get_response_name (inst)); 1343 break; 1344 default: 1345 sprintf (&buff[xx], "Inst: %u ", inst); 1346 break; 1347 } 1348 return (buff); 1349 } 1350 1351 1352 1353 /******************************************************************************* 1354 ** 1355 ** Function nfa_hciu_instr_2_str 1356 ** 1357 ** Description This function returns the instruction name. 1358 ** 1359 ** Returns pointer to the name 1360 ** 1361 *******************************************************************************/ 1362 char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt) 1363 { 1364 static char unknown[40]; 1365 tNFA_HCI_DYN_PIPE *p_pipe; 1366 1367 if ( (pipe_id != NFA_HCI_ADMIN_PIPE) 1368 &&(pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE) 1369 &&((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL) ) 1370 { 1371 if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) 1372 { 1373 switch (evt) 1374 { 1375 case NFA_HCI_EVT_CONNECTIVITY: 1376 return ("EVT_CONNECTIVITY"); 1377 case NFA_HCI_EVT_TRANSACTION: 1378 return ("EVT_TRANSACTION"); 1379 case NFA_HCI_EVT_OPERATION_ENDED: 1380 return ("EVT_OPERATION_ENDED"); 1381 default: 1382 break; 1383 } 1384 } 1385 } 1386 1387 switch (evt) 1388 { 1389 case NFA_HCI_EVT_HCI_END_OF_OPERATION: 1390 return ("EVT_END_OF_OPERATION"); 1391 case NFA_HCI_EVT_POST_DATA: 1392 return ("EVT_POST_DATA"); 1393 case NFA_HCI_EVT_HOT_PLUG: 1394 return ("EVT_HOT_PLUG"); 1395 default: 1396 sprintf (unknown, "?? Unknown: %u ?? ", evt); 1397 return (unknown); 1398 } 1399 } 1400 #endif 1401 1402 1403 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction) 1404 { 1405 UINT8 *p = (UINT8 *) (p_buf + 1) + p_buf->offset; 1406 static UINT8 next_pipe = 0x10; 1407 1408 if (type == NFA_HCI_COMMAND_TYPE) 1409 { 1410 switch (instruction) 1411 { 1412 case NFA_HCI_ADM_CREATE_PIPE: 1413 p[6] = next_pipe++; 1414 p[5] = p[4]; 1415 p[4] = p[3]; 1416 p[3] = p[2]; 1417 p[2] = 3; 1418 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK; 1419 p_buf->len = p_buf->offset + 7; 1420 break; 1421 1422 case NFA_HCI_ANY_GET_PARAMETER: 1423 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK; 1424 memcpy (&p[2], (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, NFA_HCI_SESSION_ID_LEN); 1425 p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN; 1426 break; 1427 1428 default: 1429 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK; 1430 p_buf->len = p_buf->offset + 2; 1431 break; 1432 } 1433 } 1434 else if (type == NFA_HCI_RESPONSE_TYPE) 1435 { 1436 GKI_freebuf (p_buf); 1437 return; 1438 } 1439 1440 p_buf->event = NFA_HCI_CHECK_QUEUE_EVT; 1441 nfa_sys_sendmsg (p_buf); 1442 } 1443 1444