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 * NFA interface to HCI 22 * 23 ******************************************************************************/ 24#include <android-base/stringprintf.h> 25#include <base/logging.h> 26 27#include "nfa_hci_api.h" 28#include "nfa_hci_defs.h" 29#include "nfa_hci_int.h" 30 31using android::base::StringPrintf; 32 33extern bool nfc_debug_enabled; 34 35/******************************************************************************* 36** 37** Function NFA_HciRegister 38** 39** Description This function will register an application with hci and 40** returns an application handle and provides a mechanism to 41** register a callback with HCI to receive NFA HCI event 42** notification. When the application is registered (or if an 43** error occurs), the app will be notified with 44** NFA_HCI_REGISTER_EVT. Previous session information including 45** allocated gates, created pipes and pipes states will be 46** returned as part of tNFA_HCI_REGISTER data. 47** 48** Returns NFA_STATUS_OK if successfully initiated 49** NFA_STATUS_FAILED otherwise 50** 51*******************************************************************************/ 52tNFA_STATUS NFA_HciRegister(char* p_app_name, tNFA_HCI_CBACK* p_cback, 53 bool b_send_conn_evts) { 54 tNFA_HCI_API_REGISTER_APP* p_msg; 55 uint8_t app_name_len; 56 57 if (p_app_name == NULL) { 58 DLOG_IF(INFO, nfc_debug_enabled) 59 << StringPrintf("Invalid Application name"); 60 return (NFA_STATUS_FAILED); 61 } 62 63 if (p_cback == NULL) { 64 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 65 "Application should provide callback function to " 66 "register!"); 67 return (NFA_STATUS_FAILED); 68 } 69 70 DLOG_IF(INFO, nfc_debug_enabled) 71 << StringPrintf("Application Name: %s", p_app_name); 72 73 app_name_len = (uint8_t)strlen(p_app_name); 74 75 /* Register the application with HCI */ 76 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 77 (p_app_name != NULL) && (app_name_len <= NFA_MAX_HCI_APP_NAME_LEN) && 78 ((p_msg = (tNFA_HCI_API_REGISTER_APP*)GKI_getbuf( 79 sizeof(tNFA_HCI_API_REGISTER_APP))) != NULL)) { 80 p_msg->hdr.event = NFA_HCI_API_REGISTER_APP_EVT; 81 82 /* Save application name and callback */ 83 memset(p_msg->app_name, 0, sizeof(p_msg->app_name)); 84 strncpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN); 85 p_msg->p_cback = p_cback; 86 p_msg->b_send_conn_evts = b_send_conn_evts; 87 88 nfa_sys_sendmsg(p_msg); 89 return (NFA_STATUS_OK); 90 } 91 92 return (NFA_STATUS_FAILED); 93} 94 95/******************************************************************************* 96** 97** Function NFA_HciGetGateAndPipeList 98** 99** Description This function will get the list of gates allocated to the 100** application and list of dynamic pipes created by the 101** application. The app will be notified with 102** NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic 103** gates to the application and list of pipes created by the 104** application will be returned as part of 105** tNFA_HCI_GET_GATE_PIPE_LIST data. 106** 107** Returns NFA_STATUS_OK if successfully initiated 108** NFA_STATUS_FAILED otherwise 109** 110*******************************************************************************/ 111tNFA_STATUS NFA_HciGetGateAndPipeList(tNFA_HANDLE hci_handle) { 112 tNFA_HCI_API_GET_APP_GATE_PIPE* p_msg; 113 114 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 115 DLOG_IF(INFO, nfc_debug_enabled) 116 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 117 return (NFA_STATUS_FAILED); 118 } 119 120 DLOG_IF(INFO, nfc_debug_enabled) 121 << StringPrintf("hci_handle:0x%04x", hci_handle); 122 123 /* Register the application with HCI */ 124 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 125 ((p_msg = (tNFA_HCI_API_GET_APP_GATE_PIPE*)GKI_getbuf( 126 sizeof(tNFA_HCI_API_GET_APP_GATE_PIPE))) != NULL)) { 127 p_msg->hdr.event = NFA_HCI_API_GET_APP_GATE_PIPE_EVT; 128 p_msg->hci_handle = hci_handle; 129 130 nfa_sys_sendmsg(p_msg); 131 return (NFA_STATUS_OK); 132 } 133 134 return (NFA_STATUS_FAILED); 135} 136 137/******************************************************************************* 138** 139** Function NFA_HciDeregister 140** 141** Description This function is called to deregister an application 142** from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT 143** after deleting all the pipes owned by the app and 144** deallocating all the gates allocated to the app or if an 145** error occurs. Even if deregistration fails, the app has to 146** register again to provide a new cback function. 147** 148** Returns NFA_STATUS_OK if the application is deregistered 149** successfully 150** NFA_STATUS_FAILED otherwise 151 152*******************************************************************************/ 153tNFA_STATUS NFA_HciDeregister(char* p_app_name) { 154 tNFA_HCI_API_DEREGISTER_APP* p_msg; 155 int xx; 156 uint8_t app_name_len; 157 158 if (p_app_name == NULL) { 159 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Invalid Application"); 160 return (NFA_STATUS_FAILED); 161 } 162 163 DLOG_IF(INFO, nfc_debug_enabled) 164 << StringPrintf("Application Name: %s", p_app_name); 165 app_name_len = (uint8_t)strlen(p_app_name); 166 167 if (app_name_len > NFA_MAX_HCI_APP_NAME_LEN) return (NFA_STATUS_FAILED); 168 169 /* Find the application registration */ 170 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 171 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) && 172 (!strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], 173 app_name_len))) 174 break; 175 } 176 177 if (xx == NFA_HCI_MAX_APP_CB) { 178 LOG(ERROR) << StringPrintf("Application Name: %s NOT FOUND", p_app_name); 179 return (NFA_STATUS_FAILED); 180 } 181 182 /* Deregister the application with HCI */ 183 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 184 ((p_msg = (tNFA_HCI_API_DEREGISTER_APP*)GKI_getbuf( 185 sizeof(tNFA_HCI_API_DEREGISTER_APP))) != NULL)) { 186 p_msg->hdr.event = NFA_HCI_API_DEREGISTER_APP_EVT; 187 188 memset(p_msg->app_name, 0, sizeof(p_msg->app_name)); 189 strncpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN); 190 191 nfa_sys_sendmsg(p_msg); 192 return (NFA_STATUS_OK); 193 } 194 195 return (NFA_STATUS_FAILED); 196} 197 198/******************************************************************************* 199** 200** Function NFA_HciAllocGate 201** 202** Description This function will allocate the gate if any specified or an 203** available generic gate for the app to provide an entry point 204** for a particular service to other host or to establish 205** communication with other host. When the gate is 206** allocated (or if an error occurs), the app will be notified 207** with NFA_HCI_ALLOCATE_GATE_EVT with the gate id. The 208** allocated Gate information will be stored in non volatile 209** memory. 210** 211** Returns NFA_STATUS_OK if this API started 212** NFA_STATUS_FAILED if no generic gate is available 213** 214*******************************************************************************/ 215tNFA_STATUS NFA_HciAllocGate(tNFA_HANDLE hci_handle, uint8_t gate) { 216 tNFA_HCI_API_ALLOC_GATE* p_msg; 217 218 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 219 DLOG_IF(INFO, nfc_debug_enabled) 220 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 221 return (NFA_STATUS_FAILED); 222 } 223 224 if ((gate) && ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || 225 (gate > NFA_HCI_LAST_PROP_GATE) || 226 (gate == NFA_HCI_CONNECTIVITY_GATE))) { 227 DLOG_IF(INFO, nfc_debug_enabled) 228 << StringPrintf("Cannot allocate gate:0x%02x", gate); 229 return (NFA_STATUS_FAILED); 230 } 231 232 DLOG_IF(INFO, nfc_debug_enabled) 233 << StringPrintf("hci_handle:0x%04x, Gate:0x%02x", hci_handle, gate); 234 235 /* Request HCI to allocate gate to the application */ 236 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 237 ((p_msg = (tNFA_HCI_API_ALLOC_GATE*)GKI_getbuf( 238 sizeof(tNFA_HCI_API_ALLOC_GATE))) != NULL)) { 239 p_msg->hdr.event = NFA_HCI_API_ALLOC_GATE_EVT; 240 p_msg->hci_handle = hci_handle; 241 p_msg->gate = gate; 242 243 nfa_sys_sendmsg(p_msg); 244 return (NFA_STATUS_OK); 245 } 246 return (NFA_STATUS_FAILED); 247} 248 249/******************************************************************************* 250** 251** Function NFA_HciDeallocGate 252** 253** Description This function will release the specified gate that was 254** previously allocated to the application. When the generic 255** gate is released (or if an error occurs), the app will be 256** notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id. 257** 258** Returns NFA_STATUS_OK if successfully initiated 259** NFA_STATUS_FAILED otherwise 260** 261*******************************************************************************/ 262tNFA_STATUS NFA_HciDeallocGate(tNFA_HANDLE hci_handle, uint8_t gate) { 263 tNFA_HCI_API_DEALLOC_GATE* p_msg; 264 265 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 266 DLOG_IF(INFO, nfc_debug_enabled) 267 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 268 return (NFA_STATUS_FAILED); 269 } 270 271 if ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || 272 (gate > NFA_HCI_LAST_PROP_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE)) { 273 DLOG_IF(INFO, nfc_debug_enabled) 274 << StringPrintf("Cannot deallocate the gate:0x%02x", gate); 275 return (NFA_STATUS_FAILED); 276 } 277 278 DLOG_IF(INFO, nfc_debug_enabled) 279 << StringPrintf("hci_handle:0x%04x, gate:0x%02X", hci_handle, gate); 280 281 /* Request HCI to deallocate the gate that was previously allocated to the 282 * application */ 283 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 284 ((p_msg = (tNFA_HCI_API_DEALLOC_GATE*)GKI_getbuf( 285 sizeof(tNFA_HCI_API_DEALLOC_GATE))) != NULL)) { 286 p_msg->hdr.event = NFA_HCI_API_DEALLOC_GATE_EVT; 287 p_msg->hci_handle = hci_handle; 288 p_msg->gate = gate; 289 290 nfa_sys_sendmsg(p_msg); 291 return (NFA_STATUS_OK); 292 } 293 return (NFA_STATUS_FAILED); 294} 295 296/******************************************************************************* 297** 298** Function NFA_HciGetHostList 299** 300** Description This function will request the host controller to return the 301** list of hosts that are present in the host network. When 302** host controller responds with the host list (or if an error 303** occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT 304** 305** Returns NFA_STATUS_OK if successfully initiated 306** NFA_STATUS_FAILED otherwise 307** 308*******************************************************************************/ 309tNFA_STATUS NFA_HciGetHostList(tNFA_HANDLE hci_handle) { 310 tNFA_HCI_API_GET_HOST_LIST* p_msg; 311 312 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 313 DLOG_IF(INFO, nfc_debug_enabled) 314 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 315 return (NFA_STATUS_FAILED); 316 } 317 318 DLOG_IF(INFO, nfc_debug_enabled) 319 << StringPrintf("hci_handle:0x%04x", hci_handle); 320 321 /* Request HCI to get list of host in the hci network */ 322 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 323 ((p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf( 324 sizeof(tNFA_HCI_API_GET_HOST_LIST))) != NULL)) { 325 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT; 326 p_msg->hci_handle = hci_handle; 327 328 nfa_sys_sendmsg(p_msg); 329 return (NFA_STATUS_OK); 330 } 331 332 return (NFA_STATUS_FAILED); 333} 334 335/******************************************************************************* 336** 337** Function NFA_HciCreatePipe 338** 339** Description This function is called to create a dynamic pipe with the 340** specified host. When the dynamic pipe is created (or 341** if an error occurs), the app will be notified with 342** NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists 343** between the two gates passed as argument and if it was 344** created earlier by the calling application then the pipe 345** id of the existing pipe will be returned and a new pipe 346** will not be created. After successful creation of pipe, 347** registry entry will be created for the dynamic pipe and 348** all information related to the pipe will be stored in non 349** volatile memory. 350** 351** Returns NFA_STATUS_OK if successfully initiated 352** NFA_STATUS_FAILED otherwise 353** 354*******************************************************************************/ 355tNFA_STATUS NFA_HciCreatePipe(tNFA_HANDLE hci_handle, uint8_t source_gate_id, 356 uint8_t dest_host, uint8_t dest_gate) { 357 tNFA_HCI_API_CREATE_PIPE_EVT* p_msg; 358 uint8_t xx; 359 360 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 361 "hci_handle:0x%04x, source gate:0x%02X, " 362 "destination host:0x%02X , destination gate:0x%02X", 363 hci_handle, source_gate_id, dest_host, dest_gate); 364 365 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 366 DLOG_IF(INFO, nfc_debug_enabled) 367 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 368 return (NFA_STATUS_FAILED); 369 } 370 371 if ((source_gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || 372 (source_gate_id > NFA_HCI_LAST_PROP_GATE)) { 373 DLOG_IF(INFO, nfc_debug_enabled) 374 << StringPrintf("Invalid local Gate:0x%02x", source_gate_id); 375 return (NFA_STATUS_FAILED); 376 } 377 378 if (((dest_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) && 379 (dest_gate != NFA_HCI_LOOP_BACK_GATE) && 380 (dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) || 381 (dest_gate > NFA_HCI_LAST_PROP_GATE)) { 382 DLOG_IF(INFO, nfc_debug_enabled) 383 << StringPrintf("Invalid Destination Gate:0x%02x", dest_gate); 384 return (NFA_STATUS_FAILED); 385 } 386 387 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 388 if (nfa_hci_cb.inactive_host[xx] == dest_host) break; 389 390 if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) { 391 DLOG_IF(INFO, nfc_debug_enabled) 392 << StringPrintf("Host not active:0x%02x", dest_host); 393 return (NFA_STATUS_FAILED); 394 } 395 396 /* Request HCI to create a pipe between two specified gates */ 397 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 398 (!nfa_hci_cb.b_low_power_mode) && 399 ((p_msg = (tNFA_HCI_API_CREATE_PIPE_EVT*)GKI_getbuf( 400 sizeof(tNFA_HCI_API_CREATE_PIPE_EVT))) != NULL)) { 401 p_msg->hdr.event = NFA_HCI_API_CREATE_PIPE_EVT; 402 p_msg->hci_handle = hci_handle; 403 p_msg->source_gate = source_gate_id; 404 p_msg->dest_host = dest_host; /* Host id of the destination host */ 405 p_msg->dest_gate = dest_gate; /* Gate id of the destination gate */ 406 407 nfa_sys_sendmsg(p_msg); 408 return (NFA_STATUS_OK); 409 } 410 return (NFA_STATUS_FAILED); 411} 412 413/******************************************************************************* 414** 415** Function NFA_HciOpenPipe 416** 417** Description This function is called to open a dynamic pipe. 418** When the dynamic pipe is opened (or 419** if an error occurs), the app will be notified with 420** NFA_HCI_OPEN_PIPE_EVT with the pipe id. 421** 422** Returns NFA_STATUS_OK if successfully initiated 423** NFA_STATUS_FAILED otherwise 424** 425*******************************************************************************/ 426tNFA_STATUS NFA_HciOpenPipe(tNFA_HANDLE hci_handle, uint8_t pipe) { 427 tNFA_HCI_API_OPEN_PIPE_EVT* p_msg; 428 429 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 430 DLOG_IF(INFO, nfc_debug_enabled) 431 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 432 return (NFA_STATUS_FAILED); 433 } 434 435 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || 436 (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) { 437 DLOG_IF(INFO, nfc_debug_enabled) 438 << StringPrintf("Invalid Pipe:0x%02x", pipe); 439 return (NFA_STATUS_FAILED); 440 } 441 442 DLOG_IF(INFO, nfc_debug_enabled) 443 << StringPrintf("hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 444 445 /* Request HCI to open a pipe if it is in closed state */ 446 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 447 (!nfa_hci_cb.b_low_power_mode) && 448 ((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT*)GKI_getbuf( 449 sizeof(tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL)) { 450 p_msg->hdr.event = NFA_HCI_API_OPEN_PIPE_EVT; 451 p_msg->hci_handle = hci_handle; 452 p_msg->pipe = pipe; /* Pipe ID of the pipe to open */ 453 454 nfa_sys_sendmsg(p_msg); 455 return (NFA_STATUS_OK); 456 } 457 return (NFA_STATUS_FAILED); 458} 459 460/******************************************************************************* 461** 462** Function NFA_HciGetRegistry 463** 464** Description This function requests a peer host to return the desired 465** registry field value for the gate that the pipe is on. 466** 467** When the peer host responds,the app is notified with 468** NFA_HCI_GET_REG_RSP_EVT or 469** if an error occurs in sending the command the app will be 470** notified by NFA_HCI_CMD_SENT_EVT 471** 472** Returns NFA_STATUS_OK if successfully initiated 473** NFA_STATUS_FAILED otherwise 474** 475*******************************************************************************/ 476tNFA_STATUS NFA_HciGetRegistry(tNFA_HANDLE hci_handle, uint8_t pipe, 477 uint8_t reg_inx) { 478 tNFA_HCI_API_GET_REGISTRY* p_msg; 479 480 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 481 DLOG_IF(INFO, nfc_debug_enabled) 482 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 483 return (NFA_STATUS_FAILED); 484 } 485 486 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) { 487 DLOG_IF(INFO, nfc_debug_enabled) 488 << StringPrintf("Invalid Pipe:0x%02x", pipe); 489 return (NFA_STATUS_FAILED); 490 } 491 492 DLOG_IF(INFO, nfc_debug_enabled) 493 << StringPrintf("hci_handle:0x%04x Pipe: 0x%02x", hci_handle, pipe); 494 495 /* Request HCI to get list of gates supported by the specified host */ 496 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 497 ((p_msg = (tNFA_HCI_API_GET_REGISTRY*)GKI_getbuf( 498 sizeof(tNFA_HCI_API_GET_REGISTRY))) != NULL)) { 499 p_msg->hdr.event = NFA_HCI_API_GET_REGISTRY_EVT; 500 p_msg->hci_handle = hci_handle; 501 p_msg->pipe = pipe; 502 p_msg->reg_inx = reg_inx; 503 504 nfa_sys_sendmsg(p_msg); 505 return (NFA_STATUS_OK); 506 } 507 508 return (NFA_STATUS_FAILED); 509} 510 511/******************************************************************************* 512** 513** Function NFA_HciSendCommand 514** 515** Description This function is called to send a command on a pipe created 516** by the application. 517** The app will be notified by NFA_HCI_CMD_SENT_EVT if an error 518** occurs. 519** When the peer host responds,the app is notified with 520** NFA_HCI_RSP_RCVD_EVT 521** 522** Returns NFA_STATUS_OK if successfully initiated 523** NFA_STATUS_FAILED otherwise 524** 525*******************************************************************************/ 526tNFA_STATUS NFA_HciSendCommand(tNFA_HANDLE hci_handle, uint8_t pipe, 527 uint8_t cmd_code, uint16_t cmd_size, 528 uint8_t* p_data) { 529 tNFA_HCI_API_SEND_CMD_EVT* p_msg; 530 531 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 532 DLOG_IF(INFO, nfc_debug_enabled) 533 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 534 return (NFA_STATUS_FAILED); 535 } 536 537 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) { 538 DLOG_IF(INFO, nfc_debug_enabled) 539 << StringPrintf("Invalid Pipe:0x%02x", pipe); 540 return (NFA_STATUS_FAILED); 541 } 542 543 if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN)) { 544 DLOG_IF(INFO, nfc_debug_enabled) 545 << StringPrintf("Invalid cmd size:0x%02x", cmd_size); 546 return (NFA_STATUS_FAILED); 547 } 548 549 DLOG_IF(INFO, nfc_debug_enabled) 550 << StringPrintf("hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", 551 hci_handle, pipe, cmd_code); 552 553 /* Request HCI to post event data on a particular pipe */ 554 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 555 ((p_msg = (tNFA_HCI_API_SEND_CMD_EVT*)GKI_getbuf( 556 sizeof(tNFA_HCI_API_SEND_CMD_EVT))) != NULL)) { 557 p_msg->hdr.event = NFA_HCI_API_SEND_CMD_EVT; 558 p_msg->hci_handle = hci_handle; 559 p_msg->pipe = pipe; 560 p_msg->cmd_code = cmd_code; 561 p_msg->cmd_len = cmd_size; 562 563 if (cmd_size) memcpy(p_msg->data, p_data, cmd_size); 564 565 nfa_sys_sendmsg(p_msg); 566 return (NFA_STATUS_OK); 567 } 568 569 return (NFA_STATUS_FAILED); 570} 571 572/******************************************************************************* 573** 574** Function NFA_HciSendEvent 575** 576** Description This function is called to send any event on a pipe created 577** by the application. 578** The app will be notified by NFA_HCI_EVENT_SENT_EVT 579** after successfully sending the event on the specified pipe 580** or if an error occurs. The application should wait for this 581** event before releasing event buffer passed as argument. 582** If the app is expecting a response to the event then it can 583** provide response buffer for collecting the response. If it 584** provides a response buffer it can also provide response 585** timeout indicating maximum timeout for the response. 586** Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received 587** using internal buffer if no response buffer is provided by 588** the application. The app will be notified by 589** NFA_HCI_EVENT_RCVD_EVT after receiving the response event 590** or on timeout if app provided response buffer and response 591** timeout. If response buffer and response timeout is provided 592** by the application, it should wait for this event before 593** releasing the response buffer. If the application did not 594** provide response timeout then it should not release the 595** response buffer until it receives NFA_HCI_EVENT_RCVD_EVT or 596** after timeout it sends next event on the same pipe 597** and receives NFA_HCI_EVENT_SENT_EVT for that event. 598** 599** Returns NFA_STATUS_OK if successfully initiated 600** NFA_STATUS_FAILED otherwise 601** 602*******************************************************************************/ 603tNFA_STATUS NFA_HciSendEvent(tNFA_HANDLE hci_handle, uint8_t pipe, 604 uint8_t evt_code, uint16_t evt_size, 605 uint8_t* p_data, uint16_t rsp_size, 606 uint8_t* p_rsp_buf, uint16_t rsp_timeout) { 607 tNFA_HCI_API_SEND_EVENT_EVT* p_msg; 608 609 DLOG_IF(INFO, nfc_debug_enabled) 610 << StringPrintf("hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", 611 hci_handle, pipe, evt_code); 612 613 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 614 DLOG_IF(INFO, nfc_debug_enabled) 615 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 616 return (NFA_STATUS_FAILED); 617 } 618 619 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) { 620 DLOG_IF(INFO, nfc_debug_enabled) 621 << StringPrintf("Invalid Pipe:0x%02x", pipe); 622 return (NFA_STATUS_FAILED); 623 } 624 625 if (evt_size && (p_data == NULL)) { 626 DLOG_IF(INFO, nfc_debug_enabled) 627 << StringPrintf("Invalid Event size:0x%02x", evt_size); 628 return (NFA_STATUS_FAILED); 629 } 630 631 if (rsp_size && (p_rsp_buf == NULL)) { 632 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 633 "No Event buffer, but invalid event buffer size " 634 ":%u", 635 rsp_size); 636 return (NFA_STATUS_FAILED); 637 } 638 639 /* Request HCI to post event data on a particular pipe */ 640 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 641 ((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT*)GKI_getbuf( 642 sizeof(tNFA_HCI_API_SEND_EVENT_EVT))) != NULL)) { 643 p_msg->hdr.event = NFA_HCI_API_SEND_EVENT_EVT; 644 p_msg->hci_handle = hci_handle; 645 p_msg->pipe = pipe; 646 p_msg->evt_code = evt_code; 647 p_msg->evt_len = evt_size; 648 p_msg->p_evt_buf = p_data; 649 p_msg->rsp_len = rsp_size; 650 p_msg->p_rsp_buf = p_rsp_buf; 651 p_msg->rsp_timeout = rsp_timeout; 652 653 nfa_sys_sendmsg(p_msg); 654 return (NFA_STATUS_OK); 655 } 656 657 return (NFA_STATUS_FAILED); 658} 659 660/******************************************************************************* 661** 662** Function NFA_HciClosePipe 663** 664** Description This function is called to close a dynamic pipe. 665** When the dynamic pipe is closed (or 666** if an error occurs), the app will be notified with 667** NFA_HCI_CLOSE_PIPE_EVT with the pipe id. 668** 669** Returns NFA_STATUS_OK if successfully initiated 670** NFA_STATUS_FAILED otherwise 671** 672*******************************************************************************/ 673tNFA_STATUS NFA_HciClosePipe(tNFA_HANDLE hci_handle, uint8_t pipe) { 674 tNFA_HCI_API_CLOSE_PIPE_EVT* p_msg; 675 676 DLOG_IF(INFO, nfc_debug_enabled) 677 << StringPrintf("hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 678 679 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 680 DLOG_IF(INFO, nfc_debug_enabled) 681 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 682 return (NFA_STATUS_FAILED); 683 } 684 685 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || 686 (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) { 687 DLOG_IF(INFO, nfc_debug_enabled) 688 << StringPrintf("Invalid Pipe:0x%02x", pipe); 689 return (NFA_STATUS_FAILED); 690 } 691 692 /* Request HCI to close a pipe if it is in opened state */ 693 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 694 (!nfa_hci_cb.b_low_power_mode) && 695 ((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT*)GKI_getbuf( 696 sizeof(tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL)) { 697 p_msg->hdr.event = NFA_HCI_API_CLOSE_PIPE_EVT; 698 p_msg->hci_handle = hci_handle; 699 p_msg->pipe = pipe; 700 701 nfa_sys_sendmsg(p_msg); 702 return (NFA_STATUS_OK); 703 } 704 return (NFA_STATUS_FAILED); 705} 706 707/******************************************************************************* 708** 709** Function NFA_HciDeletePipe 710** 711** Description This function is called to delete a particular dynamic pipe. 712** When the dynamic pipe is deleted (or if an error occurs), 713** the app will be notified with NFA_HCI_DELETE_PIPE_EVT with 714** the pipe id. After successful deletion of pipe, registry 715** entry will be deleted for the dynamic pipe and all 716** information related to the pipe will be deleted from non 717** volatile memory. 718** 719** Returns NFA_STATUS_OK if successfully initiated 720** NFA_STATUS_FAILED otherwise 721** 722*******************************************************************************/ 723tNFA_STATUS NFA_HciDeletePipe(tNFA_HANDLE hci_handle, uint8_t pipe) { 724 tNFA_HCI_API_DELETE_PIPE_EVT* p_msg; 725 726 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 727 DLOG_IF(INFO, nfc_debug_enabled) 728 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 729 return (NFA_STATUS_FAILED); 730 } 731 732 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || 733 (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) { 734 DLOG_IF(INFO, nfc_debug_enabled) 735 << StringPrintf("Invalid Pipe:0x%02x", pipe); 736 return (NFA_STATUS_FAILED); 737 } 738 739 DLOG_IF(INFO, nfc_debug_enabled) 740 << StringPrintf("hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 741 742 /* Request HCI to delete a pipe created by the application identified by hci 743 * handle */ 744 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 745 (!nfa_hci_cb.b_low_power_mode) && 746 ((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT*)GKI_getbuf( 747 sizeof(tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL)) { 748 p_msg->hdr.event = NFA_HCI_API_DELETE_PIPE_EVT; 749 p_msg->hci_handle = hci_handle; 750 p_msg->pipe = pipe; 751 752 nfa_sys_sendmsg(p_msg); 753 return (NFA_STATUS_OK); 754 } 755 return (NFA_STATUS_FAILED); 756} 757 758/******************************************************************************* 759** 760** Function NFA_HciAddStaticPipe 761** 762** Description This function is called to add a static pipe for sending 763** 7816 APDUs. When the static pipe is added (or if an error 764** occurs), the app will be notified with 765** NFA_HCI_ADD_STATIC_PIPE_EVT with the status. 766** 767** Returns NFA_STATUS_OK if successfully initiated 768** NFA_STATUS_FAILED otherwise 769** 770*******************************************************************************/ 771tNFA_STATUS NFA_HciAddStaticPipe(tNFA_HANDLE hci_handle, uint8_t host, 772 uint8_t gate, uint8_t pipe) { 773 tNFA_HCI_API_ADD_STATIC_PIPE_EVT* p_msg; 774 uint8_t xx; 775 776 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) { 777 DLOG_IF(INFO, nfc_debug_enabled) 778 << StringPrintf("Invalid hci_handle:0x%04x", hci_handle); 779 return (NFA_STATUS_FAILED); 780 } 781 782 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 783 if (nfa_hci_cb.inactive_host[xx] == host) break; 784 785 if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) { 786 DLOG_IF(INFO, nfc_debug_enabled) 787 << StringPrintf("Host not active:0x%02x", host); 788 return (NFA_STATUS_FAILED); 789 } 790 791 if (gate <= NFA_HCI_LAST_HOST_SPECIFIC_GATE) { 792 DLOG_IF(INFO, nfc_debug_enabled) 793 << StringPrintf("Invalid Gate:0x%02x", gate); 794 return (NFA_STATUS_FAILED); 795 } 796 797 if (pipe <= NFA_HCI_LAST_DYNAMIC_PIPE) { 798 DLOG_IF(INFO, nfc_debug_enabled) 799 << StringPrintf("Invalid Pipe:0x%02x", pipe); 800 return (NFA_STATUS_FAILED); 801 } 802 803 DLOG_IF(INFO, nfc_debug_enabled) 804 << StringPrintf("hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 805 806 /* Request HCI to delete a pipe created by the application identified by hci 807 * handle */ 808 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) && 809 ((p_msg = (tNFA_HCI_API_ADD_STATIC_PIPE_EVT*)GKI_getbuf( 810 sizeof(tNFA_HCI_API_ADD_STATIC_PIPE_EVT))) != NULL)) { 811 p_msg->hdr.event = NFA_HCI_API_ADD_STATIC_PIPE_EVT; 812 p_msg->hci_handle = hci_handle; 813 p_msg->host = host; 814 p_msg->gate = gate; 815 p_msg->pipe = pipe; 816 817 nfa_sys_sendmsg(p_msg); 818 return (NFA_STATUS_OK); 819 } 820 /* Unable to add static pipe */ 821 return (NFA_STATUS_FAILED); 822} 823 824/******************************************************************************* 825** 826** Function NFA_HciDebug 827** 828** Description Debug function. 829** 830*******************************************************************************/ 831void NFA_HciDebug(uint8_t action, uint8_t size, uint8_t* p_data) { 832 int xx; 833 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates; 834 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes; 835 NFC_HDR* p_msg; 836 uint8_t* p; 837 838 switch (action) { 839 case NFA_HCI_DEBUG_DISPLAY_CB: 840 DLOG_IF(INFO, nfc_debug_enabled) 841 << StringPrintf("NFA_HciDebug Host List:"); 842 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) { 843 if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) { 844 DLOG_IF(INFO, nfc_debug_enabled) 845 << StringPrintf(" Host Inx: %u Name: %s", xx, 846 &nfa_hci_cb.cfg.reg_app_names[xx][0]); 847 } 848 } 849 850 DLOG_IF(INFO, nfc_debug_enabled) 851 << StringPrintf("NFA_HciDebug Gate List:"); 852 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) { 853 if (pg->gate_id != 0) { 854 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 855 " Gate Inx: %x ID: 0x%02x Owner: 0x%04x " 856 "PipeInxMask: 0x%08x", 857 xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask); 858 } 859 } 860 861 DLOG_IF(INFO, nfc_debug_enabled) 862 << StringPrintf("NFA_HciDebug Pipe List:"); 863 for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) { 864 if (pp->pipe_id != 0) { 865 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 866 " Pipe Inx: %x ID: 0x%02x State: %u " 867 "LocalGate: " 868 "0x%02x Dest Gate: 0x%02x Host: 0x%02x", 869 xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate, 870 pp->dest_host); 871 } 872 } 873 break; 874 875 case NFA_HCI_DEBUG_SIM_HCI_EVENT: 876 p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 877 if (p_msg != NULL) { 878 p = (uint8_t*)(p_msg + 1); 879 880 p_msg->event = NFA_HCI_CHECK_QUEUE_EVT; 881 p_msg->len = size; 882 p_msg->offset = 0; 883 884 memcpy(p, p_data, size); 885 886 nfa_sys_sendmsg(p_msg); 887 } 888 break; 889 890 case NFA_HCI_DEBUG_ENABLE_LOOPBACK: 891 DLOG_IF(INFO, nfc_debug_enabled) 892 << StringPrintf("NFA_HciDebug HCI_LOOPBACK_DEBUG = TRUE"); 893 HCI_LOOPBACK_DEBUG = NFA_HCI_DEBUG_ON; 894 break; 895 896 case NFA_HCI_DEBUG_DISABLE_LOOPBACK: 897 DLOG_IF(INFO, nfc_debug_enabled) 898 << StringPrintf("NFA_HciDebug HCI_LOOPBACK_DEBUG = FALSE"); 899 HCI_LOOPBACK_DEBUG = NFA_HCI_DEBUG_OFF; 900 break; 901 } 902} 903