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