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