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