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