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