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 * 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 the gate if any specified or an 201 ** available generic gate for the app to provide an entry point 202 ** for a particular service to other host or to establish 203 ** communication with other host. When the gate is 204 ** allocated (or if an error occurs), the app will be notified 205 ** with NFA_HCI_ALLOCATE_GATE_EVT with the gate id. The allocated 206 ** Gate information will be stored in 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, UINT8 gate) 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 if ( (gate) 223 &&((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (gate > NFA_HCI_LAST_PROP_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE)) ) 224 { 225 NFA_TRACE_API1 ("NFA_HciAllocGate (): Cannot allocate gate:0x%02x", gate); 226 return (NFA_STATUS_FAILED); 227 } 228 229 NFA_TRACE_API2 ("NFA_HciAllocGate (): hci_handle:0x%04x, Gate:0x%02x", hci_handle, gate); 230 231 /* Request HCI to allocate gate to the application */ 232 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 233 &&((p_msg = (tNFA_HCI_API_ALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_ALLOC_GATE))) != NULL) ) 234 { 235 p_msg->hdr.event = NFA_HCI_API_ALLOC_GATE_EVT; 236 p_msg->hci_handle = hci_handle; 237 p_msg->gate = gate; 238 239 nfa_sys_sendmsg (p_msg); 240 return (NFA_STATUS_OK); 241 } 242 return (NFA_STATUS_FAILED); 243 } 244 245 /******************************************************************************* 246 ** 247 ** Function NFA_HciDeallocGate 248 ** 249 ** Description This function will release the specified gate that was 250 ** previously allocated to the application. When the generic 251 ** gate is released (or if an error occurs), the app will be 252 ** notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id. 253 ** 254 ** Returns NFA_STATUS_OK if successfully initiated 255 ** NFA_STATUS_FAILED otherwise 256 ** 257 *******************************************************************************/ 258 tNFA_STATUS NFA_HciDeallocGate (tNFA_HANDLE hci_handle, UINT8 gate) 259 { 260 tNFA_HCI_API_DEALLOC_GATE *p_msg; 261 262 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 263 { 264 NFA_TRACE_API1 ("NFA_HciDeallocGate (): Invalid hci_handle:0x%04x", hci_handle); 265 return (NFA_STATUS_FAILED); 266 } 267 268 if ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (gate > NFA_HCI_LAST_PROP_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE)) 269 { 270 NFA_TRACE_API1 ("NFA_HciDeallocGate (): Cannot deallocate the gate:0x%02x", gate); 271 return (NFA_STATUS_FAILED); 272 } 273 274 NFA_TRACE_API2 ("NFA_HciDeallocGate (): hci_handle:0x%04x, gate:0x%02X", hci_handle, gate); 275 276 /* Request HCI to deallocate the gate that was previously allocated to the application */ 277 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 278 &&((p_msg = (tNFA_HCI_API_DEALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_DEALLOC_GATE))) != NULL) ) 279 { 280 p_msg->hdr.event = NFA_HCI_API_DEALLOC_GATE_EVT; 281 p_msg->hci_handle = hci_handle; 282 p_msg->gate = gate; 283 284 nfa_sys_sendmsg (p_msg); 285 return (NFA_STATUS_OK); 286 } 287 return (NFA_STATUS_FAILED); 288 } 289 290 /******************************************************************************* 291 ** 292 ** Function NFA_HciGetHostList 293 ** 294 ** Description This function will request the host controller to return the 295 ** list of hosts that are present in the host network. When 296 ** host controller responds with the host list (or if an error 297 ** occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT 298 ** 299 ** Returns NFA_STATUS_OK if successfully initiated 300 ** NFA_STATUS_FAILED otherwise 301 ** 302 *******************************************************************************/ 303 tNFA_STATUS NFA_HciGetHostList (tNFA_HANDLE hci_handle) 304 { 305 tNFA_HCI_API_GET_HOST_LIST *p_msg; 306 307 308 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 309 { 310 NFA_TRACE_API1 ("NFA_HciGetHostList (): Invalid hci_handle:0x%04x", hci_handle); 311 return (NFA_STATUS_FAILED); 312 } 313 314 NFA_TRACE_API1 ("NFA_HciGetHostList (): hci_handle:0x%04x",hci_handle); 315 316 /* Request HCI to get list of host in the hci network */ 317 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 318 &&((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL) ) 319 { 320 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT; 321 p_msg->hci_handle = hci_handle; 322 323 nfa_sys_sendmsg (p_msg); 324 return (NFA_STATUS_OK); 325 } 326 327 return (NFA_STATUS_FAILED); 328 } 329 330 /******************************************************************************* 331 ** 332 ** Function NFA_HciCreatePipe 333 ** 334 ** Description This function is called to create a dynamic pipe with the 335 ** specified host. When the dynamic pipe is created (or 336 ** if an error occurs), the app will be notified with 337 ** NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists 338 ** between the two gates passed as argument and if it was 339 ** created earlier by the calling application then the pipe 340 ** id of the existing pipe will be returned and a new pipe 341 ** will not be created. After successful creation of pipe, 342 ** registry entry will be created for the dynamic pipe and 343 ** all information related to the pipe will be stored in non 344 ** volatile memory. 345 ** 346 ** Returns NFA_STATUS_OK if successfully initiated 347 ** NFA_STATUS_FAILED otherwise 348 ** 349 *******************************************************************************/ 350 tNFA_STATUS NFA_HciCreatePipe (tNFA_HANDLE hci_handle, 351 UINT8 source_gate_id, 352 UINT8 dest_host, 353 UINT8 dest_gate) 354 { 355 tNFA_HCI_API_CREATE_PIPE_EVT *p_msg; 356 UINT8 xx; 357 358 NFA_TRACE_API4 ("NFA_HciCreatePipe (): hci_handle:0x%04x, source gate:0x%02X, destination host:0x%02X , destination gate:0x%02X", 359 hci_handle, source_gate_id, dest_host, dest_gate); 360 361 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 362 { 363 NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid hci_handle:0x%04x", hci_handle); 364 return (NFA_STATUS_FAILED); 365 } 366 367 if ((source_gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (source_gate_id > NFA_HCI_LAST_PROP_GATE)) 368 { 369 NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid local Gate:0x%02x", source_gate_id); 370 return (NFA_STATUS_FAILED); 371 } 372 373 if ( ((dest_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) && (dest_gate != NFA_HCI_LOOP_BACK_GATE) && (dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) 374 ||(dest_gate > NFA_HCI_LAST_PROP_GATE)) 375 { 376 NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid Destination Gate:0x%02x", dest_gate); 377 return (NFA_STATUS_FAILED); 378 } 379 380 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 381 if (nfa_hci_cb.inactive_host[xx] == dest_host) 382 break; 383 384 if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) 385 { 386 NFA_TRACE_API1 ("NFA_HciCreatePipe (): Host not active:0x%02x", dest_host); 387 return (NFA_STATUS_FAILED); 388 } 389 390 /* Request HCI to create a pipe between two specified gates */ 391 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 392 &&(!nfa_hci_cb.b_low_power_mode) 393 &&((p_msg = (tNFA_HCI_API_CREATE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CREATE_PIPE_EVT))) != NULL) ) 394 { 395 p_msg->hdr.event = NFA_HCI_API_CREATE_PIPE_EVT; 396 p_msg->hci_handle = hci_handle; 397 p_msg->source_gate = source_gate_id; 398 p_msg->dest_host = dest_host; /* Host id of the destination host */ 399 p_msg->dest_gate = dest_gate; /* Gate id of the destination gate */ 400 401 nfa_sys_sendmsg (p_msg); 402 return (NFA_STATUS_OK); 403 } 404 return (NFA_STATUS_FAILED); 405 } 406 407 /******************************************************************************* 408 ** 409 ** Function NFA_HciOpenPipe 410 ** 411 ** Description This function is called to open a dynamic pipe. 412 ** When the dynamic pipe is opened (or 413 ** if an error occurs), the app will be notified with 414 ** NFA_HCI_OPEN_PIPE_EVT with the pipe id. 415 ** 416 ** Returns NFA_STATUS_OK if successfully initiated 417 ** NFA_STATUS_FAILED otherwise 418 ** 419 *******************************************************************************/ 420 tNFA_STATUS NFA_HciOpenPipe (tNFA_HANDLE hci_handle, UINT8 pipe) 421 { 422 tNFA_HCI_API_OPEN_PIPE_EVT *p_msg; 423 424 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 425 { 426 NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid hci_handle:0x%04x", hci_handle); 427 return (NFA_STATUS_FAILED); 428 } 429 430 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) 431 { 432 NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid Pipe:0x%02x", pipe); 433 return (NFA_STATUS_FAILED); 434 } 435 436 437 NFA_TRACE_API2 ("NFA_HciOpenPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 438 439 /* Request HCI to open a pipe if it is in closed state */ 440 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 441 &&(!nfa_hci_cb.b_low_power_mode) 442 &&((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL) ) 443 { 444 p_msg->hdr.event = NFA_HCI_API_OPEN_PIPE_EVT; 445 p_msg->hci_handle = hci_handle; 446 p_msg->pipe = pipe; /* Pipe ID of the pipe to open */ 447 448 nfa_sys_sendmsg (p_msg); 449 return (NFA_STATUS_OK); 450 } 451 return (NFA_STATUS_FAILED); 452 } 453 454 /******************************************************************************* 455 ** 456 ** Function NFA_HciGetRegistry 457 ** 458 ** Description This function requests a peer host to return the desired 459 ** registry field value for the gate that the pipe is on. 460 ** 461 ** When the peer host responds,the app is notified with 462 ** NFA_HCI_GET_REG_RSP_EVT or 463 ** if an error occurs in sending the command the app will be 464 ** notified by NFA_HCI_CMD_SENT_EVT 465 ** 466 ** Returns NFA_STATUS_OK if successfully initiated 467 ** NFA_STATUS_FAILED otherwise 468 ** 469 *******************************************************************************/ 470 tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx) 471 { 472 tNFA_HCI_API_GET_REGISTRY *p_msg; 473 474 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 475 { 476 NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid hci_handle:0x%04x", hci_handle); 477 return (NFA_STATUS_FAILED); 478 } 479 480 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) 481 { 482 NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid Pipe:0x%02x", pipe); 483 return (NFA_STATUS_FAILED); 484 } 485 486 NFA_TRACE_API2 ("NFA_HciGetRegistry (): hci_handle:0x%04x Pipe: 0x%02x", hci_handle, pipe); 487 488 /* Request HCI to get list of gates supported by the specified host */ 489 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 490 &&((p_msg = (tNFA_HCI_API_GET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_REGISTRY))) != NULL) ) 491 { 492 p_msg->hdr.event = NFA_HCI_API_GET_REGISTRY_EVT; 493 p_msg->hci_handle = hci_handle; 494 p_msg->pipe = pipe; 495 p_msg->reg_inx = reg_inx; 496 497 nfa_sys_sendmsg (p_msg); 498 return (NFA_STATUS_OK); 499 } 500 501 return (NFA_STATUS_FAILED); 502 } 503 504 /******************************************************************************* 505 ** 506 ** Function NFA_HciSetRegistry 507 ** 508 ** Description This function requests a peer host to set the desired 509 ** registry field value for the gate that the pipe is on. 510 ** 511 ** When the peer host responds,the app is notified with 512 ** NFA_HCI_SET_REG_RSP_EVT or 513 ** if an error occurs in sending the command the app will be 514 ** notified by NFA_HCI_CMD_SENT_EVT 515 ** 516 ** Returns NFA_STATUS_OK if successfully initiated 517 ** NFA_STATUS_FAILED otherwise 518 ** 519 *******************************************************************************/ 520 NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE hci_handle, 521 UINT8 pipe, 522 UINT8 reg_inx, 523 UINT8 data_size, 524 UINT8 *p_data) 525 { 526 tNFA_HCI_API_SET_REGISTRY *p_msg; 527 528 529 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 530 { 531 NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid hci_handle:0x%04x", hci_handle); 532 return (NFA_STATUS_FAILED); 533 } 534 535 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) 536 { 537 NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid Pipe:0x%02x", pipe); 538 return (NFA_STATUS_FAILED); 539 } 540 541 if ((data_size == 0) || (p_data == NULL) || (data_size > NFA_MAX_HCI_CMD_LEN)) 542 { 543 NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid data size:0x%02x", data_size); 544 return (NFA_STATUS_FAILED); 545 } 546 547 NFA_TRACE_API2 ("NFA_HciSetRegistry (): hci_handle:0x%04x Pipe: 0x%02x", hci_handle, pipe); 548 549 /* Request HCI to get list of gates supported by the specified host */ 550 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 551 &&((p_msg = (tNFA_HCI_API_SET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_SET_REGISTRY))) != NULL) ) 552 { 553 p_msg->hdr.event = NFA_HCI_API_SET_REGISTRY_EVT; 554 p_msg->hci_handle = hci_handle; 555 p_msg->pipe = pipe; 556 p_msg->reg_inx = reg_inx; 557 p_msg->size = data_size; 558 559 memcpy (p_msg->data, p_data, data_size); 560 nfa_sys_sendmsg (p_msg); 561 return (NFA_STATUS_OK); 562 } 563 564 return (NFA_STATUS_FAILED); 565 } 566 567 /******************************************************************************* 568 ** 569 ** Function NFA_HciSendCommand 570 ** 571 ** Description This function is called to send a command on a pipe created 572 ** by the application. 573 ** The app will be notified by NFA_HCI_CMD_SENT_EVT if an error 574 ** occurs. 575 ** When the peer host responds,the app is notified with 576 ** NFA_HCI_RSP_RCVD_EVT 577 ** 578 ** Returns NFA_STATUS_OK if successfully initiated 579 ** NFA_STATUS_FAILED otherwise 580 ** 581 *******************************************************************************/ 582 tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE hci_handle, 583 UINT8 pipe, 584 UINT8 cmd_code, 585 UINT16 cmd_size, 586 UINT8 *p_data) 587 { 588 tNFA_HCI_API_SEND_CMD_EVT *p_msg; 589 590 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 591 { 592 NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid hci_handle:0x%04x", hci_handle); 593 return (NFA_STATUS_FAILED); 594 } 595 596 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) 597 { 598 NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid Pipe:0x%02x", pipe); 599 return (NFA_STATUS_FAILED); 600 } 601 602 if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN)) 603 { 604 NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid cmd size:0x%02x", cmd_size); 605 return (NFA_STATUS_FAILED); 606 } 607 608 NFA_TRACE_API3 ("NFA_HciSendCommand (): hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", hci_handle, pipe, cmd_code); 609 610 /* Request HCI to post event data on a particular pipe */ 611 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 612 &&((p_msg = (tNFA_HCI_API_SEND_CMD_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_CMD_EVT))) != NULL) ) 613 { 614 p_msg->hdr.event = NFA_HCI_API_SEND_CMD_EVT; 615 p_msg->hci_handle = hci_handle; 616 p_msg->pipe = pipe; 617 p_msg->cmd_code = cmd_code; 618 p_msg->cmd_len = cmd_size; 619 620 if (cmd_size) 621 memcpy (p_msg->data, p_data, cmd_size); 622 623 nfa_sys_sendmsg (p_msg); 624 return (NFA_STATUS_OK); 625 } 626 627 return (NFA_STATUS_FAILED); 628 } 629 630 /******************************************************************************* 631 ** 632 ** Function NFA_HciSendResponse 633 ** 634 ** Description This function is called to send a response on a pipe created 635 ** by the application. 636 ** The app will be notified by NFA_HCI_RSP_SENT_EVT if an error 637 ** occurs. 638 ** 639 ** Returns NFA_STATUS_OK if successfully initiated 640 ** NFA_STATUS_FAILED otherwise 641 ** 642 *******************************************************************************/ 643 NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE hci_handle, 644 UINT8 pipe, 645 UINT8 response, 646 UINT8 data_size, 647 UINT8 *p_data) 648 { 649 tNFA_HCI_API_SEND_RSP_EVT *p_msg; 650 651 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 652 { 653 NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid hci_handle:0x%04x", hci_handle); 654 return (NFA_STATUS_FAILED); 655 } 656 657 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) 658 { 659 NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid Pipe:0x%02x", pipe); 660 return (NFA_STATUS_FAILED); 661 } 662 663 if ((data_size && (p_data == NULL)) || (data_size > NFA_MAX_HCI_RSP_LEN)) 664 { 665 NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid data size:0x%02x", data_size); 666 return (NFA_STATUS_FAILED); 667 } 668 669 NFA_TRACE_API3 ("NFA_HciSendResponse (): hci_handle:0x%04x Pipe: 0x%02x Response: 0x%02x", hci_handle, pipe, response); 670 671 /* Request HCI to get list of gates supported by the specified host */ 672 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 673 &&((p_msg = (tNFA_HCI_API_SEND_RSP_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_RSP_EVT))) != NULL) ) 674 { 675 p_msg->hdr.event = NFA_HCI_API_SEND_RSP_EVT; 676 p_msg->hci_handle = hci_handle; 677 p_msg->response = response; 678 p_msg->size = data_size; 679 680 if (data_size) 681 memcpy (p_msg->data, p_data, data_size); 682 683 nfa_sys_sendmsg (p_msg); 684 return (NFA_STATUS_OK); 685 } 686 687 return (NFA_STATUS_FAILED); 688 } 689 690 /******************************************************************************* 691 ** 692 ** Function NFA_HciSendEvent 693 ** 694 ** Description This function is called to send any event on a pipe created 695 ** by the application. 696 ** The app will be notified by NFA_HCI_EVENT_SENT_EVT 697 ** after successfully sending the event on the specified pipe 698 ** or if an error occurs. The application should wait for this 699 ** event before releasing event buffer passed as argument. 700 ** If the app is expecting a response to the event then it can 701 ** provide response buffer for collecting the response. If it 702 ** provides a response buffer it can also provide response 703 ** timeout indicating maximum timeout for the response. 704 ** Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received 705 ** using internal buffer if no response buffer is provided by 706 ** the application. The app will be notified by 707 ** NFA_HCI_EVENT_RCVD_EVT after receiving the response event 708 ** or on timeout if app provided response buffer and response 709 ** timeout. If response buffer and response timeout is provided 710 ** by the application, it should wait for this event before 711 ** releasing the response buffer. If the application did not 712 ** provide response timeout then it should not release the 713 ** response buffer until it receives NFA_HCI_EVENT_RCVD_EVT or 714 ** after timeout it sends next event on the same pipe 715 ** and receives NFA_HCI_EVENT_SENT_EVT for that event. 716 ** 717 ** Returns NFA_STATUS_OK if successfully initiated 718 ** NFA_STATUS_FAILED otherwise 719 ** 720 *******************************************************************************/ 721 tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE hci_handle, 722 UINT8 pipe, 723 UINT8 evt_code, 724 UINT16 evt_size, 725 UINT8 *p_data, 726 UINT16 rsp_size, 727 UINT8 *p_rsp_buf, 728 UINT16 rsp_timeout) 729 { 730 tNFA_HCI_API_SEND_EVENT_EVT *p_msg; 731 732 NFA_TRACE_API3 ("NFA_HciSendEvent(): hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", hci_handle, pipe, evt_code); 733 734 735 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 736 { 737 NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid hci_handle:0x%04x", hci_handle); 738 return (NFA_STATUS_FAILED); 739 } 740 741 if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) 742 { 743 NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Pipe:0x%02x", pipe); 744 return (NFA_STATUS_FAILED); 745 } 746 747 if (evt_size && (p_data == NULL)) 748 { 749 NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Event size:0x%02x", evt_size); 750 return (NFA_STATUS_FAILED); 751 } 752 753 if (rsp_size && (p_rsp_buf == NULL)) 754 { 755 NFA_TRACE_API1 ("NFA_HciSendEvent (): No Event buffer, but invalid event buffer size :%u", rsp_size); 756 return (NFA_STATUS_FAILED); 757 } 758 759 /* Request HCI to post event data on a particular pipe */ 760 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 761 &&((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_EVENT_EVT))) != NULL) ) 762 { 763 p_msg->hdr.event = NFA_HCI_API_SEND_EVENT_EVT; 764 p_msg->hci_handle = hci_handle; 765 p_msg->pipe = pipe; 766 p_msg->evt_code = evt_code; 767 p_msg->evt_len = evt_size; 768 p_msg->p_evt_buf = p_data; 769 p_msg->rsp_len = rsp_size; 770 p_msg->p_rsp_buf = p_rsp_buf; 771 p_msg->rsp_timeout = rsp_timeout; 772 773 nfa_sys_sendmsg (p_msg); 774 return (NFA_STATUS_OK); 775 } 776 777 return (NFA_STATUS_FAILED); 778 } 779 780 /******************************************************************************* 781 ** 782 ** Function NFA_HciClosePipe 783 ** 784 ** Description This function is called to close a dynamic pipe. 785 ** When the dynamic pipe is closed (or 786 ** if an error occurs), the app will be notified with 787 ** NFA_HCI_CLOSE_PIPE_EVT with the pipe id. 788 ** 789 ** Returns NFA_STATUS_OK if successfully initiated 790 ** NFA_STATUS_FAILED otherwise 791 ** 792 *******************************************************************************/ 793 tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE hci_handle, UINT8 pipe) 794 { 795 tNFA_HCI_API_CLOSE_PIPE_EVT *p_msg; 796 797 NFA_TRACE_API2 ("NFA_HciClosePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 798 799 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 800 { 801 NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid hci_handle:0x%04x", hci_handle); 802 return (NFA_STATUS_FAILED); 803 } 804 805 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) 806 { 807 NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid Pipe:0x%02x", pipe); 808 return (NFA_STATUS_FAILED); 809 } 810 811 /* Request HCI to close a pipe if it is in opened state */ 812 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 813 &&(!nfa_hci_cb.b_low_power_mode) 814 &&((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL) ) 815 { 816 p_msg->hdr.event = NFA_HCI_API_CLOSE_PIPE_EVT; 817 p_msg->hci_handle = hci_handle; 818 p_msg->pipe = pipe; 819 820 nfa_sys_sendmsg (p_msg); 821 return (NFA_STATUS_OK); 822 } 823 return (NFA_STATUS_FAILED); 824 } 825 826 /******************************************************************************* 827 ** 828 ** Function NFA_HciDeletePipe 829 ** 830 ** Description This function is called to delete a particular dynamic pipe. 831 ** When the dynamic pipe is deleted (or if an error occurs), 832 ** the app will be notified with NFA_HCI_DELETE_PIPE_EVT with 833 ** the pipe id. After successful deletion of pipe, registry 834 ** entry will be deleted for the dynamic pipe and all 835 ** information related to the pipe will be deleted from non 836 ** volatile memory. 837 ** 838 ** Returns NFA_STATUS_OK if successfully initiated 839 ** NFA_STATUS_FAILED otherwise 840 ** 841 *******************************************************************************/ 842 tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE hci_handle, UINT8 pipe) 843 { 844 tNFA_HCI_API_DELETE_PIPE_EVT *p_msg; 845 846 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 847 { 848 NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid hci_handle:0x%04x", hci_handle); 849 return (NFA_STATUS_FAILED); 850 } 851 852 if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) 853 { 854 NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid Pipe:0x%02x", pipe); 855 return (NFA_STATUS_FAILED); 856 } 857 858 NFA_TRACE_API2 ("NFA_HciDeletePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 859 860 /* Request HCI to delete a pipe created by the application identified by hci handle */ 861 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 862 &&(!nfa_hci_cb.b_low_power_mode) 863 &&((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL) ) 864 { 865 p_msg->hdr.event = NFA_HCI_API_DELETE_PIPE_EVT; 866 p_msg->hci_handle = hci_handle; 867 p_msg->pipe = pipe; 868 869 nfa_sys_sendmsg (p_msg); 870 return (NFA_STATUS_OK); 871 } 872 return (NFA_STATUS_FAILED); 873 } 874 875 876 /******************************************************************************* 877 ** 878 ** Function NFA_HciAddStaticPipe 879 ** 880 ** Description This function is called to add a static pipe for sending 881 ** 7816 APDUs. When the static pipe is added (or if an error occurs), 882 ** the app will be notified with NFA_HCI_ADD_STATIC_PIPE_EVT with 883 ** the status. 884 ** Returns NFA_STATUS_OK if successfully initiated 885 ** NFA_STATUS_FAILED otherwise 886 ** 887 *******************************************************************************/ 888 tNFA_STATUS NFA_HciAddStaticPipe (tNFA_HANDLE hci_handle, UINT8 host, UINT8 gate, UINT8 pipe) 889 { 890 tNFA_HCI_API_ADD_STATIC_PIPE_EVT *p_msg; 891 UINT8 xx; 892 893 if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) 894 { 895 NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid hci_handle:0x%04x", hci_handle); 896 return (NFA_STATUS_FAILED); 897 } 898 899 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) 900 if (nfa_hci_cb.inactive_host[xx] == host) 901 break; 902 903 if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) 904 { 905 NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Host not active:0x%02x", host); 906 return (NFA_STATUS_FAILED); 907 } 908 909 if (gate <= NFA_HCI_LAST_HOST_SPECIFIC_GATE) 910 { 911 NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid Gate:0x%02x", gate); 912 return (NFA_STATUS_FAILED); 913 } 914 915 if (pipe <= NFA_HCI_LAST_DYNAMIC_PIPE) 916 { 917 NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid Pipe:0x%02x", pipe); 918 return (NFA_STATUS_FAILED); 919 } 920 921 NFA_TRACE_API2 ("NFA_HciAddStaticPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe); 922 923 /* Request HCI to delete a pipe created by the application identified by hci handle */ 924 if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) 925 &&((p_msg = (tNFA_HCI_API_ADD_STATIC_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_ADD_STATIC_PIPE_EVT))) != NULL) ) 926 { 927 p_msg->hdr.event = NFA_HCI_API_ADD_STATIC_PIPE_EVT; 928 p_msg->hci_handle = hci_handle; 929 p_msg->host = host; 930 p_msg->gate = gate; 931 p_msg->pipe = pipe; 932 933 nfa_sys_sendmsg (p_msg); 934 return (NFA_STATUS_OK); 935 } 936 /* Unable to add static pipe */ 937 return (NFA_STATUS_FAILED); 938 } 939 940 /******************************************************************************* 941 ** 942 ** Function NFA_HciDebug 943 ** 944 ** Description Debug function. 945 ** 946 *******************************************************************************/ 947 void NFA_HciDebug (UINT8 action, UINT8 size, UINT8 *p_data) 948 { 949 int xx; 950 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates; 951 tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes; 952 BT_HDR *p_msg; 953 UINT8 *p; 954 955 switch (action) 956 { 957 case NFA_HCI_DEBUG_DISPLAY_CB: 958 NFA_TRACE_API0 ("NFA_HciDebug Host List:"); 959 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) 960 { 961 if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) 962 { 963 NFA_TRACE_API2 (" Host Inx: %u Name: %s", xx, &nfa_hci_cb.cfg.reg_app_names[xx][0]); 964 } 965 } 966 967 NFA_TRACE_API0 ("NFA_HciDebug Gate List:"); 968 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) 969 { 970 if (pg->gate_id != 0) 971 { 972 NFA_TRACE_API4 (" Gate Inx: %x ID: 0x%02x Owner: 0x%04x PipeInxMask: 0x%08x", 973 xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask); 974 } 975 } 976 977 NFA_TRACE_API0 ("NFA_HciDebug Pipe List:"); 978 for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) 979 { 980 if (pp->pipe_id != 0) 981 { 982 NFA_TRACE_API6 (" Pipe Inx: %x ID: 0x%02x State: %u LocalGate: 0x%02x Dest Gate: 0x%02x Host: 0x%02x", 983 xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate, pp->dest_host); 984 } 985 } 986 break; 987 988 case NFA_HCI_DEBUG_SIM_HCI_EVENT: 989 if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) 990 { 991 p = (UINT8 *) (p_msg + 1); 992 993 p_msg->event = NFA_HCI_CHECK_QUEUE_EVT; 994 p_msg->len = size; 995 p_msg->offset = 0; 996 997 memcpy (p, p_data, size); 998 999 nfa_sys_sendmsg (p_msg); 1000 } 1001 break; 1002 1003 case NFA_HCI_DEBUG_ENABLE_LOOPBACK: 1004 NFA_TRACE_API0 ("NFA_HciDebug HCI_LOOPBACK_DEBUG = TRUE"); 1005 HCI_LOOPBACK_DEBUG = TRUE; 1006 break; 1007 1008 case NFA_HCI_DEBUG_DISABLE_LOOPBACK: 1009 NFA_TRACE_API0 ("NFA_HciDebug HCI_LOOPBACK_DEBUG = FALSE"); 1010 HCI_LOOPBACK_DEBUG = FALSE; 1011 break; 1012 } 1013 } 1014