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