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