1 /****************************************************************************** 2 * 3 * Copyright 2006-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains action functions for BTA JV APIs. 22 * 23 ******************************************************************************/ 24 #include <arpa/inet.h> 25 #include <bluetooth/uuid.h> 26 #include <hardware/bluetooth.h> 27 #include <pthread.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include "avct_api.h" 32 #include "avdt_api.h" 33 #include "bt_common.h" 34 #include "bt_types.h" 35 #include "bta_api.h" 36 #include "bta_jv_api.h" 37 #include "bta_jv_co.h" 38 #include "bta_jv_int.h" 39 #include "bta_sys.h" 40 #include "btm_api.h" 41 #include "btm_int.h" 42 #include "device/include/controller.h" 43 #include "gap_api.h" 44 #include "l2c_api.h" 45 #include "osi/include/allocator.h" 46 #include "port_api.h" 47 #include "rfcdefs.h" 48 #include "sdp_api.h" 49 #include "stack/l2cap/l2c_int.h" 50 #include "utl.h" 51 52 #include "osi/include/osi.h" 53 54 using bluetooth::Uuid; 55 56 tBTA_JV_CB bta_jv_cb; 57 58 /* one of these exists for each client */ 59 struct fc_client { 60 struct fc_client* next_all_list; 61 struct fc_client* next_chan_list; 62 RawAddress remote_addr; 63 uint32_t id; 64 tBTA_JV_L2CAP_CBACK* p_cback; 65 uint32_t l2cap_socket_id; 66 uint16_t handle; 67 uint16_t chan; 68 uint8_t sec_id; 69 unsigned server : 1; 70 unsigned init_called : 1; 71 }; 72 73 /* one of these exists for each channel we're dealing with */ 74 struct fc_channel { 75 struct fc_channel* next; 76 struct fc_client* clients; 77 uint8_t has_server : 1; 78 uint16_t chan; 79 }; 80 81 static struct fc_client* fc_clients; 82 static struct fc_channel* fc_channels; 83 static uint32_t fc_next_id; 84 85 static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr, 86 bool connected, uint16_t reason, 87 tBT_TRANSPORT); 88 static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr, 89 BT_HDR* p_buf); 90 91 static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, 92 tBTA_JV_PCB* p_pcb_open); 93 static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle); 94 static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB* p_cb); 95 static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB* p_cb); 96 static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb, 97 const tBTA_JV_CONN_STATE state); 98 99 /******************************************************************************* 100 * 101 * Function bta_jv_alloc_sec_id 102 * 103 * Description allocate a security id 104 * 105 * Returns 106 * 107 ******************************************************************************/ 108 uint8_t bta_jv_alloc_sec_id(void) { 109 uint8_t ret = 0; 110 int i; 111 for (i = 0; i < BTA_JV_NUM_SERVICE_ID; i++) { 112 if (0 == bta_jv_cb.sec_id[i]) { 113 bta_jv_cb.sec_id[i] = BTA_JV_FIRST_SERVICE_ID + i; 114 ret = bta_jv_cb.sec_id[i]; 115 break; 116 } 117 } 118 return ret; 119 } 120 static int get_sec_id_used(void) { 121 int i; 122 int used = 0; 123 for (i = 0; i < BTA_JV_NUM_SERVICE_ID; i++) { 124 if (bta_jv_cb.sec_id[i]) used++; 125 } 126 if (used == BTA_JV_NUM_SERVICE_ID) 127 LOG(ERROR) << __func__ 128 << ": sec id exceeds the limit=" << BTA_JV_NUM_SERVICE_ID; 129 return used; 130 } 131 static int get_rfc_cb_used(void) { 132 int i; 133 int used = 0; 134 for (i = 0; i < BTA_JV_MAX_RFC_CONN; i++) { 135 if (bta_jv_cb.rfc_cb[i].handle) used++; 136 } 137 if (used == BTA_JV_MAX_RFC_CONN) 138 LOG(ERROR) << __func__ 139 << ": rfc ctrl block exceeds the limit=" << BTA_JV_MAX_RFC_CONN; 140 return used; 141 } 142 143 /******************************************************************************* 144 * 145 * Function bta_jv_free_sec_id 146 * 147 * Description free the given security id 148 * 149 * Returns 150 * 151 ******************************************************************************/ 152 static void bta_jv_free_sec_id(uint8_t* p_sec_id) { 153 uint8_t sec_id = *p_sec_id; 154 *p_sec_id = 0; 155 if (sec_id >= BTA_JV_FIRST_SERVICE_ID && sec_id <= BTA_JV_LAST_SERVICE_ID) { 156 BTM_SecClrService(sec_id); 157 bta_jv_cb.sec_id[sec_id - BTA_JV_FIRST_SERVICE_ID] = 0; 158 } 159 } 160 161 /******************************************************************************* 162 * 163 * Function bta_jv_alloc_rfc_cb 164 * 165 * Description allocate a control block for the given port handle 166 * 167 * Returns 168 * 169 ******************************************************************************/ 170 tBTA_JV_RFC_CB* bta_jv_alloc_rfc_cb(uint16_t port_handle, 171 tBTA_JV_PCB** pp_pcb) { 172 tBTA_JV_RFC_CB* p_cb = NULL; 173 tBTA_JV_PCB* p_pcb; 174 int i, j; 175 for (i = 0; i < BTA_JV_MAX_RFC_CONN; i++) { 176 if (0 == bta_jv_cb.rfc_cb[i].handle) { 177 p_cb = &bta_jv_cb.rfc_cb[i]; 178 /* mask handle to distinguish it with L2CAP handle */ 179 p_cb->handle = (i + 1) | BTA_JV_RFCOMM_MASK; 180 181 p_cb->max_sess = 1; 182 p_cb->curr_sess = 1; 183 for (j = 0; j < BTA_JV_MAX_RFC_SR_SESSION; j++) p_cb->rfc_hdl[j] = 0; 184 p_cb->rfc_hdl[0] = port_handle; 185 VLOG(2) << __func__ << "port_handle=" << +port_handle 186 << ", handle=" << loghex(p_cb->handle); 187 188 p_pcb = &bta_jv_cb.port_cb[port_handle - 1]; 189 p_pcb->handle = p_cb->handle; 190 p_pcb->port_handle = port_handle; 191 p_pcb->p_pm_cb = NULL; 192 *pp_pcb = p_pcb; 193 break; 194 } 195 } 196 if (p_cb == NULL) { 197 LOG(ERROR) << __func__ << "port_handle=" << port_handle 198 << " ctrl block exceeds limit:" << port_handle, 199 BTA_JV_MAX_RFC_CONN; 200 } 201 return p_cb; 202 } 203 204 /******************************************************************************* 205 * 206 * Function bta_jv_rfc_port_to_pcb 207 * 208 * Description find the port control block associated with the given port 209 * handle 210 * 211 * Returns 212 * 213 ******************************************************************************/ 214 tBTA_JV_PCB* bta_jv_rfc_port_to_pcb(uint16_t port_handle) { 215 tBTA_JV_PCB* p_pcb = NULL; 216 217 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS) && 218 bta_jv_cb.port_cb[port_handle - 1].handle) { 219 p_pcb = &bta_jv_cb.port_cb[port_handle - 1]; 220 } 221 222 return p_pcb; 223 } 224 225 /******************************************************************************* 226 * 227 * Function bta_jv_rfc_port_to_cb 228 * 229 * Description find the RFCOMM control block associated with the given port 230 * handle 231 * 232 * Returns 233 * 234 ******************************************************************************/ 235 tBTA_JV_RFC_CB* bta_jv_rfc_port_to_cb(uint16_t port_handle) { 236 tBTA_JV_RFC_CB* p_cb = NULL; 237 uint32_t handle; 238 239 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS) && 240 bta_jv_cb.port_cb[port_handle - 1].handle) { 241 handle = bta_jv_cb.port_cb[port_handle - 1].handle; 242 handle &= BTA_JV_RFC_HDL_MASK; 243 handle &= ~BTA_JV_RFCOMM_MASK; 244 if (handle) p_cb = &bta_jv_cb.rfc_cb[handle - 1]; 245 } else { 246 LOG(WARNING) << __func__ 247 << ": jv handle not found port_handle:" << port_handle; 248 } 249 return p_cb; 250 } 251 252 static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB* p_cb, 253 tBTA_JV_PCB* p_pcb) { 254 tBTA_JV_STATUS status = BTA_JV_SUCCESS; 255 bool remove_server = false; 256 int close_pending = 0; 257 258 if (!p_cb || !p_pcb) { 259 LOG(ERROR) << __func__ << " p_cb or p_pcb cannot be null"; 260 return BTA_JV_FAILURE; 261 } 262 VLOG(2) << __func__ << ": max_sess=" << p_cb->max_sess 263 << ", curr_sess=" << p_cb->curr_sess << ", p_pcb=" << p_pcb 264 << ", user=" << p_pcb->rfcomm_slot_id << ", state=" << p_pcb->state 265 << ", jv handle=" << loghex(p_pcb->handle); 266 267 if (p_cb->curr_sess <= 0) return BTA_JV_SUCCESS; 268 269 switch (p_pcb->state) { 270 case BTA_JV_ST_CL_CLOSING: 271 case BTA_JV_ST_SR_CLOSING: 272 LOG(WARNING) << __func__ 273 << ": return on closing, port state=" << p_pcb->state 274 << ", scn=" << p_cb->scn << ", p_pcb=" << p_pcb 275 << ", user_data=" << p_pcb->rfcomm_slot_id; 276 status = BTA_JV_FAILURE; 277 return status; 278 case BTA_JV_ST_CL_OPEN: 279 case BTA_JV_ST_CL_OPENING: 280 VLOG(2) << __func__ << ": state=" << p_pcb->state << ", scn=" << p_cb->scn 281 << ", user_data=" << p_pcb->rfcomm_slot_id; 282 p_pcb->state = BTA_JV_ST_CL_CLOSING; 283 break; 284 case BTA_JV_ST_SR_LISTEN: 285 p_pcb->state = BTA_JV_ST_SR_CLOSING; 286 remove_server = true; 287 VLOG(2) << __func__ << ": state: BTA_JV_ST_SR_LISTEN, scn=" << p_cb->scn 288 << ", user_data=" << p_pcb->rfcomm_slot_id; 289 break; 290 case BTA_JV_ST_SR_OPEN: 291 p_pcb->state = BTA_JV_ST_SR_CLOSING; 292 VLOG(2) << ": state: BTA_JV_ST_SR_OPEN, scn=" << p_cb->scn 293 << " user_data=" << p_pcb->rfcomm_slot_id; 294 break; 295 default: 296 LOG(WARNING) << __func__ << ":failed, ignore port state= " << p_pcb->state 297 << ", scn=" << p_cb->scn << ", p_pcb= " << p_pcb 298 << ", jv handle=" << loghex(p_pcb->handle) 299 << ", port_handle=" << p_pcb->port_handle 300 << ", user_data=" << p_pcb->rfcomm_slot_id; 301 status = BTA_JV_FAILURE; 302 break; 303 } 304 if (BTA_JV_SUCCESS == status) { 305 int port_status; 306 307 if (!remove_server) 308 port_status = RFCOMM_RemoveConnection(p_pcb->port_handle); 309 else 310 port_status = RFCOMM_RemoveServer(p_pcb->port_handle); 311 if (port_status != PORT_SUCCESS) { 312 status = BTA_JV_FAILURE; 313 LOG(WARNING) << __func__ << ": Remove jv handle=" << loghex(p_pcb->handle) 314 << ", state=" << p_pcb->state 315 << ", port_status=" << port_status 316 << ", port_handle=" << p_pcb->port_handle 317 << ", close_pending=" << close_pending; 318 } 319 } 320 if (!close_pending) { 321 p_pcb->port_handle = 0; 322 p_pcb->state = BTA_JV_ST_NONE; 323 bta_jv_free_set_pm_profile_cb(p_pcb->handle); 324 325 // Initialize congestion flags 326 p_pcb->cong = false; 327 p_pcb->rfcomm_slot_id = 0; 328 int si = BTA_JV_RFC_HDL_TO_SIDX(p_pcb->handle); 329 if (0 <= si && si < BTA_JV_MAX_RFC_SR_SESSION) p_cb->rfc_hdl[si] = 0; 330 p_pcb->handle = 0; 331 p_cb->curr_sess--; 332 if (p_cb->curr_sess == 0) { 333 p_cb->scn = 0; 334 bta_jv_free_sec_id(&p_cb->sec_id); 335 p_cb->p_cback = NULL; 336 p_cb->handle = 0; 337 p_cb->curr_sess = -1; 338 } 339 if (remove_server) { 340 bta_jv_free_sec_id(&p_cb->sec_id); 341 } 342 } 343 return status; 344 } 345 346 /******************************************************************************* 347 * 348 * Function bta_jv_free_l2c_cb 349 * 350 * Description free the given L2CAP control block 351 * 352 * Returns 353 * 354 ******************************************************************************/ 355 tBTA_JV_STATUS bta_jv_free_l2c_cb(tBTA_JV_L2C_CB* p_cb) { 356 tBTA_JV_STATUS status = BTA_JV_SUCCESS; 357 358 if (BTA_JV_ST_NONE != p_cb->state) { 359 bta_jv_free_set_pm_profile_cb((uint32_t)p_cb->handle); 360 if (GAP_ConnClose(p_cb->handle) != BT_PASS) status = BTA_JV_FAILURE; 361 } 362 p_cb->psm = 0; 363 p_cb->state = BTA_JV_ST_NONE; 364 p_cb->cong = false; 365 bta_jv_free_sec_id(&p_cb->sec_id); 366 p_cb->p_cback = NULL; 367 return status; 368 } 369 370 /******************************************************************************* 371 * 372 * 373 * Function bta_jv_clear_pm_cb 374 * 375 * Description clears jv pm control block and optionally calls 376 * bta_sys_conn_close() 377 * In general close_conn should be set to true to remove registering 378 * with dm pm! 379 * 380 * WARNING: Make sure to clear pointer form port or l2c to this control block 381 * too! 382 * 383 ******************************************************************************/ 384 static void bta_jv_clear_pm_cb(tBTA_JV_PM_CB* p_pm_cb, bool close_conn) { 385 /* needs to be called if registered with bta pm, otherwise we may run out of 386 * dm pm slots! */ 387 if (close_conn) 388 bta_sys_conn_close(BTA_ID_JV, p_pm_cb->app_id, p_pm_cb->peer_bd_addr); 389 p_pm_cb->state = BTA_JV_PM_FREE_ST; 390 p_pm_cb->app_id = BTA_JV_PM_ALL; 391 p_pm_cb->handle = BTA_JV_PM_HANDLE_CLEAR; 392 p_pm_cb->peer_bd_addr = RawAddress::kEmpty; 393 } 394 395 /******************************************************************************* 396 * 397 * Function bta_jv_free_set_pm_profile_cb 398 * 399 * Description free pm profile control block 400 * 401 * Returns BTA_JV_SUCCESS if cb has been freed correctly, 402 * BTA_JV_FAILURE in case of no profile has been registered or 403 * already freed 404 * 405 ******************************************************************************/ 406 static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle) { 407 tBTA_JV_STATUS status = BTA_JV_FAILURE; 408 tBTA_JV_PM_CB** p_cb; 409 int i, j, bd_counter = 0, appid_counter = 0; 410 411 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++) { 412 p_cb = NULL; 413 if ((bta_jv_cb.pm_cb[i].state != BTA_JV_PM_FREE_ST) && 414 (jv_handle == bta_jv_cb.pm_cb[i].handle)) { 415 for (j = 0; j < BTA_JV_PM_MAX_NUM; j++) { 416 if (bta_jv_cb.pm_cb[j].peer_bd_addr == bta_jv_cb.pm_cb[i].peer_bd_addr) 417 bd_counter++; 418 if (bta_jv_cb.pm_cb[j].app_id == bta_jv_cb.pm_cb[i].app_id) 419 appid_counter++; 420 } 421 422 VLOG(2) << __func__ << ": jv_handle=" << loghex(jv_handle) 423 << ", idx=" << i << "app_id=" << bta_jv_cb.pm_cb[i].app_id 424 << ", bd_counter=" << bd_counter 425 << ", appid_counter=" << appid_counter; 426 if (bd_counter > 1) { 427 bta_jv_pm_conn_idle(&bta_jv_cb.pm_cb[i]); 428 } 429 430 if (bd_counter <= 1 || (appid_counter <= 1)) { 431 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], true); 432 } else { 433 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], false); 434 } 435 436 if (BTA_JV_RFCOMM_MASK & jv_handle) { 437 uint32_t hi = 438 ((jv_handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1; 439 uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(jv_handle); 440 if (hi < BTA_JV_MAX_RFC_CONN && bta_jv_cb.rfc_cb[hi].p_cback && 441 si < BTA_JV_MAX_RFC_SR_SESSION && 442 bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) { 443 tBTA_JV_PCB* p_pcb = 444 bta_jv_rfc_port_to_pcb(bta_jv_cb.rfc_cb[hi].rfc_hdl[si]); 445 if (p_pcb) { 446 if (NULL == p_pcb->p_pm_cb) 447 LOG(WARNING) << __func__ << ": jv_handle=" << loghex(jv_handle) 448 << ", port_handle=" << p_pcb->port_handle 449 << ", i=" << i << ", no link to pm_cb?"; 450 p_cb = &p_pcb->p_pm_cb; 451 } 452 } 453 } else { 454 if (jv_handle < BTA_JV_MAX_L2C_CONN) { 455 tBTA_JV_L2C_CB* p_l2c_cb = &bta_jv_cb.l2c_cb[jv_handle]; 456 if (NULL == p_l2c_cb->p_pm_cb) 457 LOG(WARNING) << __func__ << ": jv_handle=" << loghex(jv_handle) 458 << ", i=" << i << " no link to pm_cb?"; 459 p_cb = &p_l2c_cb->p_pm_cb; 460 } 461 } 462 if (p_cb) { 463 *p_cb = NULL; 464 status = BTA_JV_SUCCESS; 465 } 466 } 467 } 468 return status; 469 } 470 471 /******************************************************************************* 472 * 473 * Function bta_jv_alloc_set_pm_profile_cb 474 * 475 * Description set PM profile control block 476 * 477 * Returns pointer to allocated cb or NULL in case of failure 478 * 479 ******************************************************************************/ 480 static tBTA_JV_PM_CB* bta_jv_alloc_set_pm_profile_cb(uint32_t jv_handle, 481 tBTA_JV_PM_ID app_id) { 482 bool bRfcHandle = (jv_handle & BTA_JV_RFCOMM_MASK) != 0; 483 RawAddress peer_bd_addr; 484 int i, j; 485 tBTA_JV_PM_CB** pp_cb; 486 487 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++) { 488 pp_cb = NULL; 489 if (bta_jv_cb.pm_cb[i].state == BTA_JV_PM_FREE_ST) { 490 /* rfc handle bd addr retrieval requires core stack handle */ 491 if (bRfcHandle) { 492 for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++) { 493 if (jv_handle == bta_jv_cb.port_cb[j].handle) { 494 pp_cb = &bta_jv_cb.port_cb[j].p_pm_cb; 495 if (PORT_SUCCESS != 496 PORT_CheckConnection(bta_jv_cb.port_cb[j].port_handle, 497 peer_bd_addr, NULL)) 498 i = BTA_JV_PM_MAX_NUM; 499 break; 500 } 501 } 502 } else { 503 /* use jv handle for l2cap bd address retrieval */ 504 for (j = 0; j < BTA_JV_MAX_L2C_CONN; j++) { 505 if (jv_handle == bta_jv_cb.l2c_cb[j].handle) { 506 pp_cb = &bta_jv_cb.l2c_cb[j].p_pm_cb; 507 const RawAddress* p_bd_addr = 508 GAP_ConnGetRemoteAddr((uint16_t)jv_handle); 509 if (p_bd_addr) 510 peer_bd_addr = *p_bd_addr; 511 else 512 i = BTA_JV_PM_MAX_NUM; 513 break; 514 } 515 } 516 } 517 VLOG(2) << __func__ << ": handle=" << loghex(jv_handle) 518 << ", app_id=" << app_id << ", idx=" << i 519 << ", BTA_JV_PM_MAX_NUM=" << BTA_JV_PM_MAX_NUM 520 << ", pp_cb=" << pp_cb; 521 break; 522 } 523 } 524 525 if ((i != BTA_JV_PM_MAX_NUM) && (NULL != pp_cb)) { 526 *pp_cb = &bta_jv_cb.pm_cb[i]; 527 bta_jv_cb.pm_cb[i].handle = jv_handle; 528 bta_jv_cb.pm_cb[i].app_id = app_id; 529 bta_jv_cb.pm_cb[i].peer_bd_addr = peer_bd_addr; 530 bta_jv_cb.pm_cb[i].state = BTA_JV_PM_IDLE_ST; 531 return &bta_jv_cb.pm_cb[i]; 532 } 533 LOG(WARNING) << __func__ << ": handle=" << loghex(jv_handle) 534 << ", app_id=" << app_id << ", return NULL"; 535 return NULL; 536 } 537 538 /******************************************************************************* 539 * 540 * Function bta_jv_check_psm 541 * 542 * Description for now use only the legal PSM per JSR82 spec 543 * 544 * Returns true, if allowed 545 * 546 ******************************************************************************/ 547 bool bta_jv_check_psm(uint16_t psm) { 548 bool ret = false; 549 550 if (L2C_IS_VALID_PSM(psm)) { 551 if (psm < 0x1001) { 552 /* see if this is defined by spec */ 553 switch (psm) { 554 case SDP_PSM: /* 1 */ 555 case BT_PSM_RFCOMM: /* 3 */ 556 /* do not allow java app to use these 2 PSMs */ 557 break; 558 559 case TCS_PSM_INTERCOM: /* 5 */ 560 case TCS_PSM_CORDLESS: /* 7 */ 561 if (!bta_sys_is_register(BTA_ID_CT) && 562 !bta_sys_is_register(BTA_ID_CG)) 563 ret = true; 564 break; 565 566 case BT_PSM_BNEP: /* F */ 567 if (!bta_sys_is_register(BTA_ID_PAN)) ret = true; 568 break; 569 570 case HID_PSM_CONTROL: /* 0x11 */ 571 case HID_PSM_INTERRUPT: /* 0x13 */ 572 // FIX: allow HID Device and HID Host to coexist 573 if (!bta_sys_is_register(BTA_ID_HD) || 574 !bta_sys_is_register(BTA_ID_HH)) 575 ret = true; 576 break; 577 578 case AVCT_PSM: /* 0x17 */ 579 case AVDT_PSM: /* 0x19 */ 580 if ((!bta_sys_is_register(BTA_ID_AV)) && 581 (!bta_sys_is_register(BTA_ID_AVK))) 582 ret = true; 583 break; 584 585 default: 586 ret = true; 587 break; 588 } 589 } else { 590 ret = true; 591 } 592 } 593 return ret; 594 } 595 596 /* Initialises the JAVA I/F */ 597 void bta_jv_enable(tBTA_JV_DM_CBACK* p_cback) { 598 tBTA_JV_STATUS status = BTA_JV_SUCCESS; 599 bta_jv_cb.p_dm_cback = p_cback; 600 tBTA_JV bta_jv; 601 bta_jv.status = status; 602 bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, &bta_jv, 0); 603 memset(bta_jv_cb.free_psm_list, 0, sizeof(bta_jv_cb.free_psm_list)); 604 } 605 606 /** Disables the BT device manager free the resources used by java */ 607 void bta_jv_disable() { LOG(ERROR) << __func__; } 608 609 /** 610 * We keep a list of PSM's that have been freed from JAVA, for reuse. 611 * This function will return a free PSM, and delete it from the free 612 * list. 613 * If no free PSMs exist, 0 will be returned. 614 */ 615 static uint16_t bta_jv_get_free_psm() { 616 const int cnt = 617 sizeof(bta_jv_cb.free_psm_list) / sizeof(bta_jv_cb.free_psm_list[0]); 618 for (int i = 0; i < cnt; i++) { 619 uint16_t psm = bta_jv_cb.free_psm_list[i]; 620 if (psm != 0) { 621 VLOG(2) << __func__ << ": Reusing PSM=" << loghex(psm); 622 bta_jv_cb.free_psm_list[i] = 0; 623 return psm; 624 } 625 } 626 return 0; 627 } 628 629 static void bta_jv_set_free_psm(uint16_t psm) { 630 int free_index = -1; 631 const int cnt = 632 sizeof(bta_jv_cb.free_psm_list) / sizeof(bta_jv_cb.free_psm_list[0]); 633 for (int i = 0; i < cnt; i++) { 634 if (bta_jv_cb.free_psm_list[i] == 0) { 635 free_index = i; 636 } else if (psm == bta_jv_cb.free_psm_list[i]) { 637 return; // PSM already freed? 638 } 639 } 640 if (free_index != -1) { 641 bta_jv_cb.free_psm_list[free_index] = psm; 642 VLOG(2) << __func__ << ": Recycling PSM=" << loghex(psm); 643 } else { 644 LOG(ERROR) << __func__ << ": unable to free psm=" << loghex(psm) 645 << " no more free slots"; 646 } 647 } 648 649 /** Obtain a free SCN (Server Channel Number) (RFCOMM channel or L2CAP PSM) */ 650 void bta_jv_get_channel_id( 651 int32_t type /* One of BTA_JV_CONN_TYPE_ */, 652 int32_t channel /* optionally request a specific channel */, 653 uint32_t l2cap_socket_id, uint32_t rfcomm_slot_id) { 654 uint16_t psm = 0; 655 656 switch (type) { 657 case BTA_JV_CONN_TYPE_RFCOMM: { 658 uint8_t scn = 0; 659 if (channel > 0) { 660 if (!BTM_TryAllocateSCN(channel)) { 661 LOG(ERROR) << "rfc channel=" << channel 662 << " already in use or invalid"; 663 channel = 0; 664 } 665 } else { 666 channel = BTM_AllocateSCN(); 667 if (channel == 0) { 668 LOG(ERROR) << "run out of rfc channels"; 669 channel = 0; 670 } 671 } 672 if (channel != 0) { 673 bta_jv_cb.scn[channel - 1] = true; 674 scn = (uint8_t)channel; 675 } 676 if (bta_jv_cb.p_dm_cback) { 677 tBTA_JV bta_jv; 678 bta_jv.scn = scn; 679 bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, &bta_jv, rfcomm_slot_id); 680 } 681 return; 682 } 683 case BTA_JV_CONN_TYPE_L2CAP: 684 psm = bta_jv_get_free_psm(); 685 if (psm == 0) { 686 psm = L2CA_AllocatePSM(); 687 VLOG(2) << __func__ << ": returned PSM=" << loghex(psm); 688 } 689 break; 690 case BTA_JV_CONN_TYPE_L2CAP_LE: 691 psm = L2CA_AllocateLePSM(); 692 if (psm == 0) { 693 LOG(ERROR) << __func__ << ": Error: No free LE PSM available"; 694 } 695 break; 696 default: 697 break; 698 } 699 700 if (bta_jv_cb.p_dm_cback) { 701 tBTA_JV bta_jv; 702 bta_jv.psm = psm; 703 bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, &bta_jv, l2cap_socket_id); 704 } 705 } 706 707 /** free a SCN */ 708 void bta_jv_free_scn(int32_t type /* One of BTA_JV_CONN_TYPE_ */, 709 uint16_t scn) { 710 switch (type) { 711 case BTA_JV_CONN_TYPE_RFCOMM: { 712 if (scn > 0 && scn <= BTA_JV_MAX_SCN && bta_jv_cb.scn[scn - 1]) { 713 /* this scn is used by JV */ 714 bta_jv_cb.scn[scn - 1] = false; 715 BTM_FreeSCN(scn); 716 } 717 break; 718 } 719 case BTA_JV_CONN_TYPE_L2CAP: 720 bta_jv_set_free_psm(scn); 721 break; 722 case BTA_JV_CONN_TYPE_L2CAP_LE: 723 VLOG(2) << __func__ << ": type=BTA_JV_CONN_TYPE_L2CAP_LE. psm=" << scn; 724 L2CA_FreeLePSM(scn); 725 break; 726 default: 727 break; 728 } 729 } 730 731 /******************************************************************************* 732 * 733 * Function bta_jv_start_discovery_cback 734 * 735 * Description Callback for Start Discovery 736 * 737 * Returns void 738 * 739 ******************************************************************************/ 740 static void bta_jv_start_discovery_cback(uint16_t result, void* user_data) { 741 tBTA_JV_STATUS status; 742 uint32_t* p_rfcomm_slot_id = static_cast<uint32_t*>(user_data); 743 744 VLOG(2) << __func__ << ": res=" << loghex(result); 745 746 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE; 747 if (bta_jv_cb.p_dm_cback) { 748 tBTA_JV_DISCOVERY_COMP dcomp; 749 dcomp.scn = 0; 750 status = BTA_JV_FAILURE; 751 if (result == SDP_SUCCESS || result == SDP_DB_FULL) { 752 tSDP_DISC_REC* p_sdp_rec = NULL; 753 tSDP_PROTOCOL_ELEM pe; 754 VLOG(2) << __func__ << ": bta_jv_cb.uuid=" << bta_jv_cb.uuid; 755 p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db, 756 bta_jv_cb.uuid, p_sdp_rec); 757 VLOG(2) << __func__ << ": p_sdp_rec=" << p_sdp_rec; 758 if (p_sdp_rec && 759 SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 760 dcomp.scn = (uint8_t)pe.params[0]; 761 status = BTA_JV_SUCCESS; 762 } 763 } 764 765 dcomp.status = status; 766 tBTA_JV bta_jv; 767 bta_jv.disc_comp = dcomp; 768 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv, *p_rfcomm_slot_id); 769 osi_free(p_rfcomm_slot_id); 770 } 771 } 772 773 /* Discovers services on a remote device */ 774 void bta_jv_start_discovery(const RawAddress& bd_addr, uint16_t num_uuid, 775 bluetooth::Uuid* uuid_list, 776 uint32_t rfcomm_slot_id) { 777 tBTA_JV_STATUS status = BTA_JV_FAILURE; 778 VLOG(2) << __func__ << ": in, sdp_active=" << bta_jv_cb.sdp_active; 779 if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE) { 780 /* SDP is still in progress */ 781 status = BTA_JV_BUSY; 782 if (bta_jv_cb.p_dm_cback) { 783 tBTA_JV bta_jv; 784 bta_jv.status = status; 785 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv, rfcomm_slot_id); 786 } 787 return; 788 } 789 790 /* init the database/set up the filter */ 791 VLOG(2) << __func__ << ": call SDP_InitDiscoveryDb, num_uuid=", num_uuid; 792 SDP_InitDiscoveryDb(p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size, 793 num_uuid, uuid_list, 0, NULL); 794 795 /* tell SDP to keep the raw data */ 796 p_bta_jv_cfg->p_sdp_db->raw_data = p_bta_jv_cfg->p_sdp_raw_data; 797 p_bta_jv_cfg->p_sdp_db->raw_size = p_bta_jv_cfg->sdp_raw_size; 798 799 bta_jv_cb.p_sel_raw_data = 0; 800 bta_jv_cb.uuid = uuid_list[0]; 801 802 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_YES; 803 804 uint32_t* rfcomm_slot_id_copy = (uint32_t*)osi_malloc(sizeof(uint32_t)); 805 *rfcomm_slot_id_copy = rfcomm_slot_id; 806 807 if (!SDP_ServiceSearchAttributeRequest2(bd_addr, p_bta_jv_cfg->p_sdp_db, 808 bta_jv_start_discovery_cback, 809 (void*)rfcomm_slot_id_copy)) { 810 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE; 811 /* failed to start SDP. report the failure right away */ 812 if (bta_jv_cb.p_dm_cback) { 813 tBTA_JV bta_jv; 814 bta_jv.status = status; 815 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv, rfcomm_slot_id); 816 } 817 } 818 /* 819 else report the result when the cback is called 820 */ 821 } 822 823 /* Create an SDP record with the given attributes */ 824 void bta_jv_create_record(uint32_t rfcomm_slot_id) { 825 tBTA_JV_CREATE_RECORD evt_data; 826 evt_data.status = BTA_JV_SUCCESS; 827 if (bta_jv_cb.p_dm_cback) { 828 // callback immediately to create the sdp record in stack thread context 829 tBTA_JV bta_jv; 830 bta_jv.create_rec = evt_data; 831 bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, &bta_jv, rfcomm_slot_id); 832 } 833 } 834 835 /* Delete an SDP record */ 836 void bta_jv_delete_record(uint32_t handle) { 837 if (handle) { 838 /* this is a record created by btif layer*/ 839 SDP_DeleteRecord(handle); 840 } 841 } 842 843 /******************************************************************************* 844 * 845 * Function bta_jv_l2cap_client_cback 846 * 847 * Description handles the l2cap client events 848 * 849 * Returns void 850 * 851 ******************************************************************************/ 852 static void bta_jv_l2cap_client_cback(uint16_t gap_handle, uint16_t event, 853 tGAP_CB_DATA* data) { 854 tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[gap_handle]; 855 tBTA_JV evt_data; 856 857 if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) return; 858 859 VLOG(2) << __func__ << ": gap_handle=" << gap_handle 860 << ", evt=" << loghex(event); 861 evt_data.l2c_open.status = BTA_JV_SUCCESS; 862 evt_data.l2c_open.handle = gap_handle; 863 864 switch (event) { 865 case GAP_EVT_CONN_OPENED: 866 evt_data.l2c_open.rem_bda = *GAP_ConnGetRemoteAddr(gap_handle); 867 evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle); 868 p_cb->state = BTA_JV_ST_CL_OPEN; 869 p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->l2cap_socket_id); 870 break; 871 872 case GAP_EVT_CONN_CLOSED: 873 p_cb->state = BTA_JV_ST_NONE; 874 bta_jv_free_sec_id(&p_cb->sec_id); 875 evt_data.l2c_close.async = true; 876 p_cb->p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt_data, p_cb->l2cap_socket_id); 877 p_cb->p_cback = NULL; 878 break; 879 880 case GAP_EVT_CONN_DATA_AVAIL: 881 evt_data.data_ind.handle = gap_handle; 882 /* Reset idle timer to avoid requesting sniff mode while receiving data */ 883 bta_jv_pm_conn_busy(p_cb->p_pm_cb); 884 p_cb->p_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, 885 p_cb->l2cap_socket_id); 886 bta_jv_pm_conn_idle(p_cb->p_pm_cb); 887 break; 888 889 case GAP_EVT_TX_EMPTY: 890 bta_jv_pm_conn_idle(p_cb->p_pm_cb); 891 break; 892 893 case GAP_EVT_CONN_CONGESTED: 894 case GAP_EVT_CONN_UNCONGESTED: 895 p_cb->cong = (event == GAP_EVT_CONN_CONGESTED) ? true : false; 896 evt_data.l2c_cong.cong = p_cb->cong; 897 p_cb->p_cback(BTA_JV_L2CAP_CONG_EVT, &evt_data, p_cb->l2cap_socket_id); 898 break; 899 900 default: 901 break; 902 } 903 } 904 905 /* makes an l2cap client connection */ 906 void bta_jv_l2cap_connect(int32_t type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, 907 uint16_t remote_psm, uint16_t rx_mtu, 908 const RawAddress& peer_bd_addr, 909 std::unique_ptr<tL2CAP_CFG_INFO> cfg_param, 910 std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info, 911 tBTA_JV_L2CAP_CBACK* p_cback, 912 uint32_t l2cap_socket_id) { 913 uint16_t handle = GAP_INVALID_HANDLE; 914 uint8_t chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC; 915 916 tL2CAP_CFG_INFO cfg; 917 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); 918 if (cfg_param) { 919 cfg = *cfg_param; 920 if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) { 921 chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM; 922 } 923 } 924 925 /* We need to use this value for MTU to be able to handle cases where cfg is 926 * not set in req. */ 927 cfg.mtu_present = true; 928 cfg.mtu = rx_mtu; 929 930 /* TODO: DM role manager 931 L2CA_SetDesireRole(role); 932 */ 933 934 uint8_t sec_id = bta_jv_alloc_sec_id(); 935 tBTA_JV_L2CAP_CL_INIT evt_data; 936 evt_data.sec_id = sec_id; 937 evt_data.status = BTA_JV_FAILURE; 938 939 if (sec_id) { 940 /* PSM checking is not required for LE COC */ 941 if ((type != BTA_JV_CONN_TYPE_L2CAP) || 942 (bta_jv_check_psm(remote_psm))) /* allowed */ 943 { 944 uint16_t max_mps = 0xffff; // Let GAP_ConnOpen set the max_mps. 945 handle = GAP_ConnOpen("", sec_id, 0, &peer_bd_addr, remote_psm, max_mps, 946 &cfg, ertm_info.get(), sec_mask, chan_mode_mask, 947 bta_jv_l2cap_client_cback, type); 948 if (handle != GAP_INVALID_HANDLE) { 949 evt_data.status = BTA_JV_SUCCESS; 950 } 951 } 952 } 953 954 if (evt_data.status == BTA_JV_SUCCESS) { 955 tBTA_JV_L2C_CB* p_cb; 956 p_cb = &bta_jv_cb.l2c_cb[handle]; 957 p_cb->handle = handle; 958 p_cb->p_cback = p_cback; 959 p_cb->l2cap_socket_id = l2cap_socket_id; 960 p_cb->psm = 0; /* not a server */ 961 p_cb->sec_id = sec_id; 962 p_cb->state = BTA_JV_ST_CL_OPENING; 963 } else { 964 bta_jv_free_sec_id(&sec_id); 965 } 966 967 evt_data.handle = handle; 968 if (p_cback) { 969 tBTA_JV bta_jv; 970 bta_jv.l2c_cl_init = evt_data; 971 p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &bta_jv, l2cap_socket_id); 972 } 973 } 974 975 /** Close an L2CAP client connection */ 976 void bta_jv_l2cap_close(uint32_t handle, tBTA_JV_L2C_CB* p_cb) { 977 tBTA_JV_L2CAP_CLOSE evt_data; 978 tBTA_JV_L2CAP_CBACK* p_cback = p_cb->p_cback; 979 uint32_t l2cap_socket_id = p_cb->l2cap_socket_id; 980 981 evt_data.handle = handle; 982 evt_data.status = bta_jv_free_l2c_cb(p_cb); 983 evt_data.async = false; 984 985 if (p_cback) { 986 tBTA_JV bta_jv; 987 bta_jv.l2c_close = evt_data; 988 p_cback(BTA_JV_L2CAP_CLOSE_EVT, &bta_jv, l2cap_socket_id); 989 } 990 } 991 992 /******************************************************************************* 993 * 994 * Function bta_jv_l2cap_server_cback 995 * 996 * Description handles the l2cap server callback 997 * 998 * Returns void 999 * 1000 ******************************************************************************/ 1001 static void bta_jv_l2cap_server_cback(uint16_t gap_handle, uint16_t event, 1002 tGAP_CB_DATA* data) { 1003 tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[gap_handle]; 1004 tBTA_JV evt_data; 1005 tBTA_JV_L2CAP_CBACK* p_cback; 1006 uint32_t socket_id; 1007 1008 if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) return; 1009 1010 VLOG(2) << __func__ << ": gap_handle=" << gap_handle 1011 << ", evt=" << loghex(event); 1012 evt_data.l2c_open.status = BTA_JV_SUCCESS; 1013 evt_data.l2c_open.handle = gap_handle; 1014 1015 switch (event) { 1016 case GAP_EVT_CONN_OPENED: 1017 evt_data.l2c_open.rem_bda = *GAP_ConnGetRemoteAddr(gap_handle); 1018 evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle); 1019 p_cb->state = BTA_JV_ST_SR_OPEN; 1020 p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->l2cap_socket_id); 1021 break; 1022 1023 case GAP_EVT_CONN_CLOSED: 1024 evt_data.l2c_close.async = true; 1025 evt_data.l2c_close.handle = p_cb->handle; 1026 p_cback = p_cb->p_cback; 1027 socket_id = p_cb->l2cap_socket_id; 1028 evt_data.l2c_close.status = bta_jv_free_l2c_cb(p_cb); 1029 p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt_data, socket_id); 1030 break; 1031 1032 case GAP_EVT_CONN_DATA_AVAIL: 1033 evt_data.data_ind.handle = gap_handle; 1034 /* Reset idle timer to avoid requesting sniff mode while receiving data */ 1035 bta_jv_pm_conn_busy(p_cb->p_pm_cb); 1036 p_cb->p_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, 1037 p_cb->l2cap_socket_id); 1038 bta_jv_pm_conn_idle(p_cb->p_pm_cb); 1039 break; 1040 1041 case GAP_EVT_TX_EMPTY: 1042 bta_jv_pm_conn_idle(p_cb->p_pm_cb); 1043 break; 1044 1045 case GAP_EVT_CONN_CONGESTED: 1046 case GAP_EVT_CONN_UNCONGESTED: 1047 p_cb->cong = (event == GAP_EVT_CONN_CONGESTED) ? true : false; 1048 evt_data.l2c_cong.cong = p_cb->cong; 1049 p_cb->p_cback(BTA_JV_L2CAP_CONG_EVT, &evt_data, p_cb->l2cap_socket_id); 1050 break; 1051 1052 default: 1053 break; 1054 } 1055 } 1056 1057 /** starts an L2CAP server */ 1058 void bta_jv_l2cap_start_server(int32_t type, tBTA_SEC sec_mask, 1059 tBTA_JV_ROLE role, uint16_t local_psm, 1060 uint16_t rx_mtu, 1061 std::unique_ptr<tL2CAP_CFG_INFO> cfg_param, 1062 std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info, 1063 tBTA_JV_L2CAP_CBACK* p_cback, 1064 uint32_t l2cap_socket_id) { 1065 uint16_t handle; 1066 tBTA_JV_L2CAP_START evt_data; 1067 uint8_t chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC; 1068 1069 tL2CAP_CFG_INFO cfg; 1070 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); 1071 if (cfg_param) { 1072 cfg = *cfg_param; 1073 if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) { 1074 chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM; 1075 } 1076 } 1077 1078 // FIX: MTU=0 means not present 1079 if (rx_mtu > 0) { 1080 cfg.mtu_present = true; 1081 cfg.mtu = rx_mtu; 1082 } else { 1083 cfg.mtu_present = false; 1084 cfg.mtu = 0; 1085 } 1086 1087 /* TODO DM role manager 1088 L2CA_SetDesireRole(role); 1089 */ 1090 1091 uint8_t sec_id = bta_jv_alloc_sec_id(); 1092 uint16_t max_mps = 0xffff; // Let GAP_ConnOpen set the max_mps. 1093 /* PSM checking is not required for LE COC */ 1094 if (0 == sec_id || 1095 ((type == BTA_JV_CONN_TYPE_L2CAP) && (!bta_jv_check_psm(local_psm))) || 1096 (handle = GAP_ConnOpen("JV L2CAP", sec_id, 1, nullptr, local_psm, max_mps, 1097 &cfg, ertm_info.get(), sec_mask, chan_mode_mask, 1098 bta_jv_l2cap_server_cback, type)) == 1099 GAP_INVALID_HANDLE) { 1100 bta_jv_free_sec_id(&sec_id); 1101 evt_data.status = BTA_JV_FAILURE; 1102 } else { 1103 tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[handle]; 1104 evt_data.status = BTA_JV_SUCCESS; 1105 evt_data.handle = handle; 1106 evt_data.sec_id = sec_id; 1107 p_cb->p_cback = p_cback; 1108 p_cb->l2cap_socket_id = l2cap_socket_id; 1109 p_cb->handle = handle; 1110 p_cb->sec_id = sec_id; 1111 p_cb->state = BTA_JV_ST_SR_LISTEN; 1112 p_cb->psm = local_psm; 1113 } 1114 1115 if (p_cback) { 1116 tBTA_JV bta_jv; 1117 bta_jv.l2c_start = evt_data; 1118 p_cback(BTA_JV_L2CAP_START_EVT, &bta_jv, l2cap_socket_id); 1119 } 1120 } 1121 1122 /* stops an L2CAP server */ 1123 void bta_jv_l2cap_stop_server(uint16_t local_psm, uint32_t l2cap_socket_id) { 1124 for (int i = 0; i < BTA_JV_MAX_L2C_CONN; i++) { 1125 if (bta_jv_cb.l2c_cb[i].psm == local_psm) { 1126 tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[i]; 1127 tBTA_JV_L2CAP_CBACK* p_cback = p_cb->p_cback; 1128 tBTA_JV_L2CAP_CLOSE evt_data; 1129 evt_data.handle = p_cb->handle; 1130 evt_data.status = bta_jv_free_l2c_cb(p_cb); 1131 evt_data.async = false; 1132 if (p_cback) { 1133 tBTA_JV bta_jv; 1134 bta_jv.l2c_close = evt_data; 1135 p_cback(BTA_JV_L2CAP_CLOSE_EVT, &bta_jv, l2cap_socket_id); 1136 } 1137 break; 1138 } 1139 } 1140 } 1141 1142 /* Write data to an L2CAP connection */ 1143 void bta_jv_l2cap_write(uint32_t handle, uint32_t req_id, BT_HDR* msg, 1144 uint32_t user_id, tBTA_JV_L2C_CB* p_cb) { 1145 /* As we check this callback exists before the tBTA_JV_API_L2CAP_WRITE can be 1146 * send through the API this check should not be needed. But the API is not 1147 * designed to be used (safely at least) in a multi-threaded scheduler, hence 1148 * if the peer device disconnects the l2cap link after the API is called, but 1149 * before this message is handled, the ->p_cback will be cleared at this 1150 * point. At first glanch this seems highly unlikely, but for all 1151 * obex-profiles with two channels connected - e.g. MAP, this happens around 1 1152 * of 4 disconnects, as a disconnect on the server channel causes a disconnect 1153 * to be send on the client (notification) channel, but at the peer typically 1154 * disconnects both the OBEX disconnect request crosses the incoming l2cap 1155 * disconnect. If p_cback is cleared, we simply discard the data. RISK: The 1156 * caller must handle any cleanup based on another signal than 1157 * BTA_JV_L2CAP_WRITE_EVT, which is typically not possible, as the pointer to 1158 * the allocated buffer is stored in this message, and can therefore not be 1159 * freed, hence we have a mem-leak-by-design.*/ 1160 if (!p_cb->p_cback) { 1161 /* As this pointer is checked in the API function, this occurs only when the 1162 * channel is disconnected after the API function is called, but before the 1163 * message is handled. */ 1164 LOG(ERROR) << __func__ << ": p_cb->p_cback == NULL"; 1165 osi_free(msg); 1166 return; 1167 } 1168 1169 tBTA_JV_L2CAP_WRITE evt_data; 1170 evt_data.status = BTA_JV_FAILURE; 1171 evt_data.handle = handle; 1172 evt_data.req_id = req_id; 1173 evt_data.cong = p_cb->cong; 1174 evt_data.len = msg->len; 1175 1176 bta_jv_pm_conn_busy(p_cb->p_pm_cb); 1177 1178 // TODO: this was set only for non-fixed channel packets. Is that needed ? 1179 msg->event = BT_EVT_TO_BTU_SP_DATA; 1180 1181 if (evt_data.cong) { 1182 osi_free(msg); 1183 } else { 1184 if (GAP_ConnWriteData(handle, msg) == BT_PASS) 1185 evt_data.status = BTA_JV_SUCCESS; 1186 } 1187 1188 tBTA_JV bta_jv; 1189 bta_jv.l2c_write = evt_data; 1190 p_cb->p_cback(BTA_JV_L2CAP_WRITE_EVT, &bta_jv, user_id); 1191 } 1192 1193 /* Write data to an L2CAP connection using Fixed channels */ 1194 void bta_jv_l2cap_write_fixed(uint16_t channel, const RawAddress& addr, 1195 uint32_t req_id, BT_HDR* msg, uint32_t user_id, 1196 tBTA_JV_L2CAP_CBACK* p_cback) { 1197 tBTA_JV_L2CAP_WRITE_FIXED evt_data; 1198 evt_data.status = BTA_JV_FAILURE; 1199 evt_data.channel = channel; 1200 evt_data.addr = addr; 1201 evt_data.req_id = req_id; 1202 evt_data.len = 0; 1203 1204 L2CA_SendFixedChnlData(channel, addr, msg); 1205 1206 tBTA_JV bta_jv; 1207 bta_jv.l2c_write_fixed = evt_data; 1208 p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, &bta_jv, user_id); 1209 } 1210 1211 /******************************************************************************* 1212 * 1213 * Function bta_jv_port_data_co_cback 1214 * 1215 * Description port data callback function of rfcomm 1216 * connections 1217 * 1218 * Returns void 1219 * 1220 ******************************************************************************/ 1221 static int bta_jv_port_data_co_cback(uint16_t port_handle, uint8_t* buf, 1222 uint16_t len, int type) { 1223 tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); 1224 tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); 1225 VLOG(2) << __func__ << ": p_cb=" << p_cb << ", p_pcb=" << p_pcb 1226 << ", len=" << len << ", type=" << type; 1227 if (p_pcb != NULL) { 1228 switch (type) { 1229 case DATA_CO_CALLBACK_TYPE_INCOMING: 1230 return bta_co_rfc_data_incoming(p_pcb->rfcomm_slot_id, (BT_HDR*)buf); 1231 case DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE: 1232 return bta_co_rfc_data_outgoing_size(p_pcb->rfcomm_slot_id, (int*)buf); 1233 case DATA_CO_CALLBACK_TYPE_OUTGOING: 1234 return bta_co_rfc_data_outgoing(p_pcb->rfcomm_slot_id, buf, len); 1235 default: 1236 LOG(ERROR) << __func__ << ": unknown callout type=" << type; 1237 break; 1238 } 1239 } 1240 return 0; 1241 } 1242 1243 /******************************************************************************* 1244 * 1245 * Function bta_jv_port_mgmt_cl_cback 1246 * 1247 * Description callback for port mamangement function of rfcomm 1248 * client connections 1249 * 1250 * Returns void 1251 * 1252 ******************************************************************************/ 1253 static void bta_jv_port_mgmt_cl_cback(uint32_t code, uint16_t port_handle) { 1254 tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); 1255 tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); 1256 tBTA_JV evt_data; 1257 RawAddress rem_bda; 1258 uint16_t lcid; 1259 tBTA_JV_RFCOMM_CBACK* p_cback; /* the callback function */ 1260 1261 VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle; 1262 if (NULL == p_cb || NULL == p_cb->p_cback) return; 1263 1264 VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle 1265 << ", handle=" << p_cb->handle; 1266 1267 PORT_CheckConnection(port_handle, rem_bda, &lcid); 1268 1269 if (code == PORT_SUCCESS) { 1270 evt_data.rfc_open.handle = p_cb->handle; 1271 evt_data.rfc_open.status = BTA_JV_SUCCESS; 1272 evt_data.rfc_open.rem_bda = rem_bda; 1273 p_pcb->state = BTA_JV_ST_CL_OPEN; 1274 p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->rfcomm_slot_id); 1275 } else { 1276 evt_data.rfc_close.handle = p_cb->handle; 1277 evt_data.rfc_close.status = BTA_JV_FAILURE; 1278 evt_data.rfc_close.port_status = code; 1279 evt_data.rfc_close.async = true; 1280 if (p_pcb->state == BTA_JV_ST_CL_CLOSING) { 1281 evt_data.rfc_close.async = false; 1282 } 1283 // p_pcb->state = BTA_JV_ST_NONE; 1284 // p_pcb->cong = false; 1285 p_cback = p_cb->p_cback; 1286 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->rfcomm_slot_id); 1287 // bta_jv_free_rfc_cb(p_cb, p_pcb); 1288 } 1289 } 1290 1291 /******************************************************************************* 1292 * 1293 * Function bta_jv_port_event_cl_cback 1294 * 1295 * Description Callback for RFCOMM client port events 1296 * 1297 * Returns void 1298 * 1299 ******************************************************************************/ 1300 static void bta_jv_port_event_cl_cback(uint32_t code, uint16_t port_handle) { 1301 tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); 1302 tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); 1303 tBTA_JV evt_data; 1304 1305 VLOG(2) << __func__ << ": port_handle=" << port_handle; 1306 if (NULL == p_cb || NULL == p_cb->p_cback) return; 1307 1308 VLOG(2) << __func__ << ": code=" << loghex(code) 1309 << ", port_handle=" << port_handle << ", handle=" << p_cb->handle; 1310 if (code & PORT_EV_RXCHAR) { 1311 evt_data.data_ind.handle = p_cb->handle; 1312 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, p_pcb->rfcomm_slot_id); 1313 } 1314 1315 if (code & PORT_EV_FC) { 1316 p_pcb->cong = (code & PORT_EV_FCS) ? false : true; 1317 evt_data.rfc_cong.cong = p_pcb->cong; 1318 evt_data.rfc_cong.handle = p_cb->handle; 1319 evt_data.rfc_cong.status = BTA_JV_SUCCESS; 1320 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, p_pcb->rfcomm_slot_id); 1321 } 1322 1323 if (code & PORT_EV_TXEMPTY) { 1324 bta_jv_pm_conn_idle(p_pcb->p_pm_cb); 1325 } 1326 } 1327 1328 /* Client initiates an RFCOMM connection */ 1329 void bta_jv_rfcomm_connect(tBTA_SEC sec_mask, tBTA_JV_ROLE role, 1330 uint8_t remote_scn, const RawAddress& peer_bd_addr, 1331 tBTA_JV_RFCOMM_CBACK* p_cback, 1332 uint32_t rfcomm_slot_id) { 1333 uint16_t handle = 0; 1334 uint32_t event_mask = BTA_JV_RFC_EV_MASK; 1335 tPORT_STATE port_state; 1336 1337 /* TODO DM role manager 1338 L2CA_SetDesireRole(role); 1339 */ 1340 1341 uint8_t sec_id = bta_jv_alloc_sec_id(); 1342 1343 tBTA_JV_RFCOMM_CL_INIT evt_data; 1344 memset(&evt_data, 0, sizeof(evt_data)); 1345 evt_data.sec_id = sec_id; 1346 evt_data.status = BTA_JV_SUCCESS; 1347 if (0 == sec_id || 1348 !BTM_SetSecurityLevel(true, "", sec_id, sec_mask, BT_PSM_RFCOMM, 1349 BTM_SEC_PROTO_RFCOMM, remote_scn)) { 1350 evt_data.status = BTA_JV_FAILURE; 1351 LOG(ERROR) << __func__ << ": sec_id=" << +sec_id 1352 << " is zero or BTM_SetSecurityLevel failed, remote_scn:" 1353 << +remote_scn; 1354 } 1355 1356 if (evt_data.status == BTA_JV_SUCCESS && 1357 RFCOMM_CreateConnection(UUID_SERVCLASS_SERIAL_PORT, remote_scn, false, 1358 BTA_JV_DEF_RFC_MTU, peer_bd_addr, &handle, 1359 bta_jv_port_mgmt_cl_cback) != PORT_SUCCESS) { 1360 LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection failed"; 1361 evt_data.status = BTA_JV_FAILURE; 1362 } 1363 if (evt_data.status == BTA_JV_SUCCESS) { 1364 tBTA_JV_PCB* p_pcb; 1365 tBTA_JV_RFC_CB* p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb); 1366 if (p_cb) { 1367 p_cb->p_cback = p_cback; 1368 p_cb->sec_id = sec_id; 1369 p_cb->scn = 0; 1370 p_pcb->state = BTA_JV_ST_CL_OPENING; 1371 p_pcb->rfcomm_slot_id = rfcomm_slot_id; 1372 evt_data.use_co = true; 1373 1374 PORT_SetEventCallback(handle, bta_jv_port_event_cl_cback); 1375 PORT_SetEventMask(handle, event_mask); 1376 PORT_SetDataCOCallback(handle, bta_jv_port_data_co_cback); 1377 1378 PORT_GetState(handle, &port_state); 1379 1380 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT); 1381 1382 PORT_SetState(handle, &port_state); 1383 1384 evt_data.handle = p_cb->handle; 1385 } else { 1386 evt_data.status = BTA_JV_FAILURE; 1387 LOG(ERROR) << __func__ << ": run out of rfc control block"; 1388 } 1389 } 1390 tBTA_JV bta_jv; 1391 bta_jv.rfc_cl_init = evt_data; 1392 p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, &bta_jv, rfcomm_slot_id); 1393 if (bta_jv.rfc_cl_init.status == BTA_JV_FAILURE) { 1394 if (sec_id) bta_jv_free_sec_id(&sec_id); 1395 if (handle) RFCOMM_RemoveConnection(handle); 1396 } 1397 } 1398 1399 static int find_rfc_pcb(uint32_t rfcomm_slot_id, tBTA_JV_RFC_CB** cb, 1400 tBTA_JV_PCB** pcb) { 1401 *cb = NULL; 1402 *pcb = NULL; 1403 int i; 1404 for (i = 0; i < MAX_RFC_PORTS; i++) { 1405 uint32_t rfc_handle = bta_jv_cb.port_cb[i].handle & BTA_JV_RFC_HDL_MASK; 1406 rfc_handle &= ~BTA_JV_RFCOMM_MASK; 1407 if (rfc_handle && bta_jv_cb.port_cb[i].rfcomm_slot_id == rfcomm_slot_id) { 1408 *pcb = &bta_jv_cb.port_cb[i]; 1409 *cb = &bta_jv_cb.rfc_cb[rfc_handle - 1]; 1410 VLOG(2) << __func__ << ": FOUND rfc_cb_handle=" << loghex(rfc_handle) 1411 << ", port.jv_handle=" << loghex((*pcb)->handle) 1412 << ", state=" << (*pcb)->state 1413 << ", rfc_cb->handle=" << loghex((*cb)->handle); 1414 return 1; 1415 } 1416 } 1417 VLOG(2) << __func__ 1418 << ": cannot find rfc_cb from user data:" << rfcomm_slot_id; 1419 return 0; 1420 } 1421 1422 /* Close an RFCOMM connection */ 1423 void bta_jv_rfcomm_close(uint32_t handle, uint32_t rfcomm_slot_id) { 1424 if (!handle) { 1425 LOG(ERROR) << __func__ << ": rfc handle is null"; 1426 return; 1427 } 1428 1429 VLOG(2) << __func__ << ": rfc handle=" << handle; 1430 1431 tBTA_JV_RFC_CB* p_cb = NULL; 1432 tBTA_JV_PCB* p_pcb = NULL; 1433 1434 if (!find_rfc_pcb(rfcomm_slot_id, &p_cb, &p_pcb)) return; 1435 bta_jv_free_rfc_cb(p_cb, p_pcb); 1436 VLOG(2) << __func__ << ": sec id in use=" << get_sec_id_used() 1437 << ", rfc_cb in use=" << get_rfc_cb_used(); 1438 } 1439 1440 /******************************************************************************* 1441 * 1442 * Function bta_jv_port_mgmt_sr_cback 1443 * 1444 * Description callback for port mamangement function of rfcomm 1445 * server connections 1446 * 1447 * Returns void 1448 * 1449 ******************************************************************************/ 1450 static void bta_jv_port_mgmt_sr_cback(uint32_t code, uint16_t port_handle) { 1451 tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); 1452 tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); 1453 tBTA_JV evt_data; 1454 RawAddress rem_bda; 1455 uint16_t lcid; 1456 VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle; 1457 if (NULL == p_cb || NULL == p_cb->p_cback) { 1458 LOG(ERROR) << __func__ << ": p_cb=" << p_cb 1459 << ", p_cb->p_cback=" << (p_cb ? p_cb->p_cback : 0); 1460 return; 1461 } 1462 uint32_t rfcomm_slot_id = p_pcb->rfcomm_slot_id; 1463 VLOG(2) << __func__ << ": code=" << code 1464 << ", port_handle=" << loghex(port_handle) 1465 << ", handle=" << loghex(p_cb->handle) << ", p_pcb" << p_pcb 1466 << ", user=" << p_pcb->rfcomm_slot_id; 1467 1468 PORT_CheckConnection(port_handle, rem_bda, &lcid); 1469 int failed = true; 1470 if (code == PORT_SUCCESS) { 1471 evt_data.rfc_srv_open.handle = p_pcb->handle; 1472 evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; 1473 evt_data.rfc_srv_open.rem_bda = rem_bda; 1474 tBTA_JV_PCB* p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb); 1475 if (p_pcb_new_listen) { 1476 evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle; 1477 p_pcb_new_listen->rfcomm_slot_id = 1478 p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, rfcomm_slot_id); 1479 VLOG(2) << __func__ << ": curr_sess=" << p_cb->curr_sess 1480 << ", max_sess=" << p_cb->max_sess; 1481 failed = false; 1482 } else 1483 LOG(ERROR) << __func__ << ": failed to create new listen port"; 1484 } 1485 if (failed) { 1486 evt_data.rfc_close.handle = p_cb->handle; 1487 evt_data.rfc_close.status = BTA_JV_FAILURE; 1488 evt_data.rfc_close.async = true; 1489 evt_data.rfc_close.port_status = code; 1490 p_pcb->cong = false; 1491 1492 tBTA_JV_RFCOMM_CBACK* p_cback = p_cb->p_cback; 1493 VLOG(2) << __func__ 1494 << ": PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess=" 1495 << p_cb->curr_sess << ", max_sess=" << p_cb->max_sess; 1496 if (BTA_JV_ST_SR_CLOSING == p_pcb->state) { 1497 evt_data.rfc_close.async = false; 1498 evt_data.rfc_close.status = BTA_JV_SUCCESS; 1499 } 1500 // p_pcb->state = BTA_JV_ST_NONE; 1501 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, rfcomm_slot_id); 1502 // bta_jv_free_rfc_cb(p_cb, p_pcb); 1503 1504 VLOG(2) << __func__ 1505 << ": PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess=" 1506 << p_cb->curr_sess << ", max_sess=" << p_cb->max_sess; 1507 } 1508 } 1509 1510 /******************************************************************************* 1511 * 1512 * Function bta_jv_port_event_sr_cback 1513 * 1514 * Description Callback for RFCOMM server port events 1515 * 1516 * Returns void 1517 * 1518 ******************************************************************************/ 1519 static void bta_jv_port_event_sr_cback(uint32_t code, uint16_t port_handle) { 1520 tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); 1521 tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); 1522 tBTA_JV evt_data; 1523 1524 if (NULL == p_cb || NULL == p_cb->p_cback) return; 1525 1526 VLOG(2) << __func__ << ": code=" << loghex(code) 1527 << ", port_handle=" << port_handle << ", handle=" << p_cb->handle; 1528 1529 uint32_t user_data = p_pcb->rfcomm_slot_id; 1530 if (code & PORT_EV_RXCHAR) { 1531 evt_data.data_ind.handle = p_cb->handle; 1532 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, user_data); 1533 } 1534 1535 if (code & PORT_EV_FC) { 1536 p_pcb->cong = (code & PORT_EV_FCS) ? false : true; 1537 evt_data.rfc_cong.cong = p_pcb->cong; 1538 evt_data.rfc_cong.handle = p_cb->handle; 1539 evt_data.rfc_cong.status = BTA_JV_SUCCESS; 1540 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, user_data); 1541 } 1542 1543 if (code & PORT_EV_TXEMPTY) { 1544 bta_jv_pm_conn_idle(p_pcb->p_pm_cb); 1545 } 1546 } 1547 1548 /******************************************************************************* 1549 * 1550 * Function bta_jv_add_rfc_port 1551 * 1552 * Description add a port for server when the existing posts is open 1553 * 1554 * Returns return a pointer to tBTA_JV_PCB just added 1555 * 1556 ******************************************************************************/ 1557 static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, 1558 tBTA_JV_PCB* p_pcb_open) { 1559 uint8_t used = 0, i, listen = 0; 1560 uint32_t si = 0; 1561 tPORT_STATE port_state; 1562 uint32_t event_mask = BTA_JV_RFC_EV_MASK; 1563 tBTA_JV_PCB* p_pcb = NULL; 1564 if (p_cb->max_sess > 1) { 1565 for (i = 0; i < p_cb->max_sess; i++) { 1566 if (p_cb->rfc_hdl[i] != 0) { 1567 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1]; 1568 if (p_pcb->state == BTA_JV_ST_SR_LISTEN) { 1569 listen++; 1570 if (p_pcb_open == p_pcb) { 1571 VLOG(2) << __func__ << ": port_handle=" << p_pcb->port_handle 1572 << ", change the listen port to open state"; 1573 p_pcb->state = BTA_JV_ST_SR_OPEN; 1574 1575 } else { 1576 LOG(ERROR) << __func__ 1577 << ": open pcb not matching listen one, count=" << listen 1578 << ", listen pcb handle=" << p_pcb->port_handle 1579 << ", open pcb=" << p_pcb_open->handle; 1580 return NULL; 1581 } 1582 } 1583 used++; 1584 } else if (si == 0) { 1585 si = i + 1; 1586 } 1587 } 1588 1589 VLOG(2) << __func__ << ": max_sess=" << p_cb->max_sess << ", used=" << used 1590 << ", curr_sess=" << p_cb->curr_sess << ", listen=" << listen 1591 << ", si=" << si; 1592 if (used < p_cb->max_sess && listen == 1 && si) { 1593 si--; 1594 if (RFCOMM_CreateConnection(p_cb->sec_id, p_cb->scn, true, 1595 BTA_JV_DEF_RFC_MTU, RawAddress::kAny, 1596 &(p_cb->rfc_hdl[si]), 1597 bta_jv_port_mgmt_sr_cback) == PORT_SUCCESS) { 1598 p_cb->curr_sess++; 1599 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[si] - 1]; 1600 p_pcb->state = BTA_JV_ST_SR_LISTEN; 1601 p_pcb->port_handle = p_cb->rfc_hdl[si]; 1602 p_pcb->rfcomm_slot_id = p_pcb_open->rfcomm_slot_id; 1603 1604 PORT_ClearKeepHandleFlag(p_pcb->port_handle); 1605 PORT_SetEventCallback(p_pcb->port_handle, bta_jv_port_event_sr_cback); 1606 PORT_SetDataCOCallback(p_pcb->port_handle, bta_jv_port_data_co_cback); 1607 PORT_SetEventMask(p_pcb->port_handle, event_mask); 1608 PORT_GetState(p_pcb->port_handle, &port_state); 1609 1610 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT); 1611 1612 PORT_SetState(p_pcb->port_handle, &port_state); 1613 p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si); 1614 VLOG(2) << __func__ << ": p_pcb->handle=" << loghex(p_pcb->handle) 1615 << ", curr_sess=" << p_cb->curr_sess; 1616 } 1617 } else { 1618 LOG(ERROR) << __func__ << ": cannot create new rfc listen port"; 1619 return NULL; 1620 } 1621 } 1622 VLOG(2) << __func__ << ": sec id in use=" << get_sec_id_used() 1623 << ", rfc_cb in use=" << get_rfc_cb_used(); 1624 return p_pcb; 1625 } 1626 1627 /* waits for an RFCOMM client to connect */ 1628 void bta_jv_rfcomm_start_server(tBTA_SEC sec_mask, tBTA_JV_ROLE role, 1629 uint8_t local_scn, uint8_t max_session, 1630 tBTA_JV_RFCOMM_CBACK* p_cback, 1631 uint32_t rfcomm_slot_id) { 1632 uint16_t handle = 0; 1633 uint32_t event_mask = BTA_JV_RFC_EV_MASK; 1634 tPORT_STATE port_state; 1635 uint8_t sec_id = 0; 1636 tBTA_JV_RFC_CB* p_cb = NULL; 1637 tBTA_JV_PCB* p_pcb; 1638 tBTA_JV_RFCOMM_START evt_data; 1639 1640 /* TODO DM role manager 1641 L2CA_SetDesireRole(role); 1642 */ 1643 memset(&evt_data, 0, sizeof(evt_data)); 1644 evt_data.status = BTA_JV_FAILURE; 1645 VLOG(2) << __func__ << ": sec id in use=" << get_sec_id_used() 1646 << ", rfc_cb in use=" << get_rfc_cb_used(); 1647 1648 do { 1649 sec_id = bta_jv_alloc_sec_id(); 1650 1651 if (0 == sec_id || 1652 !BTM_SetSecurityLevel(false, "JV PORT", sec_id, sec_mask, BT_PSM_RFCOMM, 1653 BTM_SEC_PROTO_RFCOMM, local_scn)) { 1654 LOG(ERROR) << __func__ << ": run out of sec_id"; 1655 break; 1656 } 1657 1658 if (RFCOMM_CreateConnection(sec_id, local_scn, true, BTA_JV_DEF_RFC_MTU, 1659 RawAddress::kAny, &handle, 1660 bta_jv_port_mgmt_sr_cback) != PORT_SUCCESS) { 1661 LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection failed"; 1662 break; 1663 } 1664 1665 p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb); 1666 if (!p_cb) { 1667 LOG(ERROR) << __func__ << ": run out of rfc control block"; 1668 break; 1669 } 1670 1671 p_cb->max_sess = max_session; 1672 p_cb->p_cback = p_cback; 1673 p_cb->sec_id = sec_id; 1674 p_cb->scn = local_scn; 1675 p_pcb->state = BTA_JV_ST_SR_LISTEN; 1676 p_pcb->rfcomm_slot_id = rfcomm_slot_id; 1677 evt_data.status = BTA_JV_SUCCESS; 1678 evt_data.handle = p_cb->handle; 1679 evt_data.sec_id = sec_id; 1680 evt_data.use_co = true; 1681 1682 PORT_ClearKeepHandleFlag(handle); 1683 PORT_SetEventCallback(handle, bta_jv_port_event_sr_cback); 1684 PORT_SetEventMask(handle, event_mask); 1685 PORT_GetState(handle, &port_state); 1686 1687 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT); 1688 1689 PORT_SetState(handle, &port_state); 1690 } while (0); 1691 1692 tBTA_JV bta_jv; 1693 bta_jv.rfc_start = evt_data; 1694 p_cback(BTA_JV_RFCOMM_START_EVT, &bta_jv, rfcomm_slot_id); 1695 if (bta_jv.rfc_start.status == BTA_JV_SUCCESS) { 1696 PORT_SetDataCOCallback(handle, bta_jv_port_data_co_cback); 1697 } else { 1698 if (sec_id) bta_jv_free_sec_id(&sec_id); 1699 if (handle) RFCOMM_RemoveConnection(handle); 1700 } 1701 } 1702 1703 /* stops an RFCOMM server */ 1704 void bta_jv_rfcomm_stop_server(uint32_t handle, uint32_t rfcomm_slot_id) { 1705 if (!handle) { 1706 LOG(ERROR) << __func__ << ": jv handle is null"; 1707 return; 1708 } 1709 1710 VLOG(2) << __func__; 1711 tBTA_JV_RFC_CB* p_cb = NULL; 1712 tBTA_JV_PCB* p_pcb = NULL; 1713 1714 if (!find_rfc_pcb(rfcomm_slot_id, &p_cb, &p_pcb)) return; 1715 VLOG(2) << __func__ << ": p_pcb=" << p_pcb 1716 << ", p_pcb->port_handle=" << p_pcb->port_handle; 1717 bta_jv_free_rfc_cb(p_cb, p_pcb); 1718 VLOG(2) << __func__ << ": sec id in use=" << get_sec_id_used() 1719 << ", rfc_cb in use=" << get_rfc_cb_used(); 1720 } 1721 1722 /* write data to an RFCOMM connection */ 1723 void bta_jv_rfcomm_write(uint32_t handle, uint32_t req_id, tBTA_JV_RFC_CB* p_cb, 1724 tBTA_JV_PCB* p_pcb) { 1725 if (p_pcb->state == BTA_JV_ST_NONE) { 1726 LOG(ERROR) << __func__ << ": in state BTA_JV_ST_NONE - cannot write"; 1727 return; 1728 } 1729 1730 tBTA_JV_RFCOMM_WRITE evt_data; 1731 evt_data.status = BTA_JV_FAILURE; 1732 evt_data.handle = handle; 1733 evt_data.req_id = req_id; 1734 evt_data.cong = p_pcb->cong; 1735 evt_data.len = 0; 1736 1737 bta_jv_pm_conn_busy(p_pcb->p_pm_cb); 1738 1739 if (!evt_data.cong && 1740 PORT_WriteDataCO(p_pcb->port_handle, &evt_data.len) == PORT_SUCCESS) { 1741 evt_data.status = BTA_JV_SUCCESS; 1742 } 1743 1744 // Update congestion flag 1745 evt_data.cong = p_pcb->cong; 1746 1747 if (!p_cb->p_cback) { 1748 LOG(ERROR) << __func__ << ": No JV callback set"; 1749 return; 1750 } 1751 1752 tBTA_JV bta_jv; 1753 bta_jv.rfc_write = evt_data; 1754 p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, &bta_jv, p_pcb->rfcomm_slot_id); 1755 } 1756 1757 /* Set or free power mode profile for a JV application */ 1758 void bta_jv_set_pm_profile(uint32_t handle, tBTA_JV_PM_ID app_id, 1759 tBTA_JV_CONN_STATE init_st) { 1760 tBTA_JV_STATUS status; 1761 tBTA_JV_PM_CB* p_cb; 1762 1763 VLOG(2) << __func__ << " handle=" << loghex(handle) << ", app_id=" << app_id 1764 << ", init_st=" << +init_st; 1765 1766 /* clear PM control block */ 1767 if (app_id == BTA_JV_PM_ID_CLEAR) { 1768 status = bta_jv_free_set_pm_profile_cb(handle); 1769 1770 if (status != BTA_JV_SUCCESS) { 1771 LOG(WARNING) << __func__ << ": free pm cb failed: reason=" << +status; 1772 } 1773 } else /* set PM control block */ 1774 { 1775 p_cb = bta_jv_alloc_set_pm_profile_cb(handle, app_id); 1776 1777 if (NULL != p_cb) 1778 bta_jv_pm_state_change(p_cb, init_st); 1779 else 1780 LOG(WARNING) << __func__ << ": failed"; 1781 } 1782 } 1783 1784 /******************************************************************************* 1785 * 1786 * Function bta_jv_pm_conn_busy 1787 * 1788 * Description set pm connection busy state (input param safe) 1789 * 1790 * Params p_cb: pm control block of jv connection 1791 * 1792 * Returns void 1793 * 1794 ******************************************************************************/ 1795 static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB* p_cb) { 1796 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST == p_cb->state)) 1797 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_BUSY); 1798 } 1799 1800 /******************************************************************************* 1801 * 1802 * Function bta_jv_pm_conn_busy 1803 * 1804 * Description set pm connection busy state (input param safe) 1805 * 1806 * Params p_cb: pm control block of jv connection 1807 * 1808 * Returns void 1809 * 1810 ******************************************************************************/ 1811 static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB* p_cb) { 1812 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST != p_cb->state)) 1813 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_IDLE); 1814 } 1815 1816 /******************************************************************************* 1817 * 1818 * Function bta_jv_pm_state_change 1819 * 1820 * Description Notify power manager there is state change 1821 * 1822 * Params p_cb: must be NONE NULL 1823 * 1824 * Returns void 1825 * 1826 ******************************************************************************/ 1827 static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb, 1828 const tBTA_JV_CONN_STATE state) { 1829 VLOG(2) << __func__ << ": p_cb=" << p_cb 1830 << ", handle=" << loghex(p_cb->handle) 1831 << ", busy/idle_state=" << p_cb->state << ", app_id=" << p_cb->app_id 1832 << ", conn_state=" << state; 1833 1834 switch (state) { 1835 case BTA_JV_CONN_OPEN: 1836 bta_sys_conn_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1837 break; 1838 1839 case BTA_JV_CONN_CLOSE: 1840 bta_sys_conn_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1841 break; 1842 1843 case BTA_JV_APP_OPEN: 1844 bta_sys_app_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1845 break; 1846 1847 case BTA_JV_APP_CLOSE: 1848 bta_sys_app_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1849 break; 1850 1851 case BTA_JV_SCO_OPEN: 1852 bta_sys_sco_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1853 break; 1854 1855 case BTA_JV_SCO_CLOSE: 1856 bta_sys_sco_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1857 break; 1858 1859 case BTA_JV_CONN_IDLE: 1860 p_cb->state = BTA_JV_PM_IDLE_ST; 1861 bta_sys_idle(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1862 break; 1863 1864 case BTA_JV_CONN_BUSY: 1865 p_cb->state = BTA_JV_PM_BUSY_ST; 1866 bta_sys_busy(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); 1867 break; 1868 1869 default: 1870 LOG(WARNING) << __func__ << ": Invalid state=" << +state; 1871 break; 1872 } 1873 } 1874 /******************************************************************************/ 1875 1876 static struct fc_channel* fcchan_get(uint16_t chan, char create) { 1877 struct fc_channel* t = fc_channels; 1878 static tL2CAP_FIXED_CHNL_REG fcr = { 1879 .pL2CA_FixedConn_Cb = fcchan_conn_chng_cbk, 1880 .pL2CA_FixedData_Cb = fcchan_data_cbk, 1881 .default_idle_tout = 0xffff, 1882 .fixed_chnl_opts = 1883 { 1884 .mode = L2CAP_FCR_BASIC_MODE, 1885 .max_transmit = 0xFF, 1886 .rtrans_tout = 2000, 1887 .mon_tout = 12000, 1888 .mps = 670, 1889 .tx_win_sz = 1, 1890 }, 1891 }; 1892 1893 while (t && t->chan != chan) t = t->next; 1894 1895 if (t) 1896 return t; 1897 else if (!create) 1898 return NULL; /* we cannot alloc a struct if not asked to */ 1899 1900 t = static_cast<struct fc_channel*>(osi_calloc(sizeof(*t))); 1901 t->chan = chan; 1902 1903 if (!L2CA_RegisterFixedChannel(chan, &fcr)) { 1904 osi_free(t); 1905 return NULL; 1906 } 1907 1908 // link it in 1909 t->next = fc_channels; 1910 fc_channels = t; 1911 1912 return t; 1913 } 1914 1915 /* pass NULL to find servers */ 1916 static struct fc_client* fcclient_find_by_addr(struct fc_client* start, 1917 const RawAddress* addr) { 1918 struct fc_client* t = start; 1919 1920 while (t) { 1921 /* match client if have addr */ 1922 if (addr && addr == &t->remote_addr) break; 1923 1924 /* match server if do not have addr */ 1925 if (!addr && t->server) break; 1926 1927 t = t->next_all_list; 1928 } 1929 1930 return t; 1931 } 1932 1933 static struct fc_client* fcclient_find_by_id(uint32_t id) { 1934 struct fc_client* t = fc_clients; 1935 1936 while (t && t->id != id) t = t->next_all_list; 1937 1938 return t; 1939 } 1940 1941 static struct fc_client* fcclient_alloc(uint16_t chan, char server, 1942 const uint8_t* sec_id_to_use) { 1943 struct fc_channel* fc = fcchan_get(chan, true); 1944 struct fc_client* t; 1945 uint8_t sec_id; 1946 1947 if (!fc) return NULL; 1948 1949 if (fc->has_server && server) 1950 return NULL; /* no way to have multiple servers on same channel */ 1951 1952 if (sec_id_to_use) 1953 sec_id = *sec_id_to_use; 1954 else 1955 sec_id = bta_jv_alloc_sec_id(); 1956 1957 t = static_cast<fc_client*>(osi_calloc(sizeof(*t))); 1958 // Allocate it a unique ID 1959 do { 1960 t->id = ++fc_next_id; 1961 } while (!t->id || fcclient_find_by_id(t->id)); 1962 1963 // Populate some params 1964 t->chan = chan; 1965 t->server = server; 1966 1967 // Get a security id 1968 t->sec_id = sec_id; 1969 1970 // Link it in to global list 1971 t->next_all_list = fc_clients; 1972 fc_clients = t; 1973 1974 // Link it in to channel list 1975 t->next_chan_list = fc->clients; 1976 fc->clients = t; 1977 1978 // Update channel if needed 1979 if (server) fc->has_server = true; 1980 1981 return t; 1982 } 1983 1984 static void fcclient_free(struct fc_client* fc) { 1985 struct fc_client* t = fc_clients; 1986 struct fc_channel* tc = fcchan_get(fc->chan, false); 1987 1988 // remove from global list 1989 while (t && t->next_all_list != fc) t = t->next_all_list; 1990 1991 if (!t && fc != fc_clients) return; /* prevent double-free */ 1992 1993 if (t) 1994 t->next_all_list = fc->next_all_list; 1995 else 1996 fc_clients = fc->next_all_list; 1997 1998 // remove from channel list 1999 if (tc) { 2000 t = tc->clients; 2001 2002 while (t && t->next_chan_list != fc) t = t->next_chan_list; 2003 2004 if (t) 2005 t->next_chan_list = fc->next_chan_list; 2006 else 2007 tc->clients = fc->next_chan_list; 2008 2009 // if was server then channel no longer has a server 2010 if (fc->server) tc->has_server = false; 2011 } 2012 2013 // free security id 2014 bta_jv_free_sec_id(&fc->sec_id); 2015 2016 osi_free(fc); 2017 } 2018 2019 static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr, 2020 bool connected, uint16_t reason, 2021 tBT_TRANSPORT transport) { 2022 tBTA_JV init_evt; 2023 tBTA_JV open_evt; 2024 struct fc_channel* tc; 2025 struct fc_client *t = NULL, *new_conn; 2026 tBTA_JV_L2CAP_CBACK* p_cback = NULL; 2027 char call_init = false; 2028 uint32_t l2cap_socket_id; 2029 2030 tc = fcchan_get(chan, false); 2031 if (tc) { 2032 t = fcclient_find_by_addr( 2033 tc->clients, 2034 &bd_addr); // try to find an open socked for that addr 2035 if (t) { 2036 p_cback = t->p_cback; 2037 l2cap_socket_id = t->l2cap_socket_id; 2038 } else { 2039 t = fcclient_find_by_addr( 2040 tc->clients, 2041 NULL); // try to find a listening socked for that channel 2042 if (t) { 2043 // found: create a normal connection socket and assign the connection to 2044 // it 2045 new_conn = fcclient_alloc(chan, false, &t->sec_id); 2046 if (new_conn) { 2047 new_conn->remote_addr = bd_addr; 2048 new_conn->p_cback = NULL; // for now 2049 new_conn->init_called = true; /*nop need to do it again */ 2050 2051 p_cback = t->p_cback; 2052 l2cap_socket_id = t->l2cap_socket_id; 2053 2054 t = new_conn; 2055 } 2056 } else { 2057 // drop it 2058 return; 2059 } 2060 } 2061 } 2062 2063 if (t) { 2064 if (!t->init_called) { 2065 call_init = true; 2066 t->init_called = true; 2067 2068 init_evt.l2c_cl_init.handle = t->id; 2069 init_evt.l2c_cl_init.status = BTA_JV_SUCCESS; 2070 init_evt.l2c_cl_init.sec_id = t->sec_id; 2071 } 2072 2073 open_evt.l2c_open.handle = t->id; 2074 open_evt.l2c_open.tx_mtu = 23; /* 23, why not ?*/ 2075 memcpy(&open_evt.l2c_le_open.rem_bda, &t->remote_addr, 2076 sizeof(open_evt.l2c_le_open.rem_bda)); 2077 // TODO: (apanicke) Change the way these functions work so that casting 2078 // isn't needed 2079 open_evt.l2c_le_open.p_p_cback = (void**)&t->p_cback; 2080 open_evt.l2c_le_open.p_user_data = (void**)&t->l2cap_socket_id; 2081 open_evt.l2c_le_open.status = BTA_JV_SUCCESS; 2082 2083 if (connected) { 2084 open_evt.l2c_open.status = BTA_JV_SUCCESS; 2085 } else { 2086 fcclient_free(t); 2087 open_evt.l2c_open.status = BTA_JV_FAILURE; 2088 } 2089 } 2090 2091 if (call_init) p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &init_evt, l2cap_socket_id); 2092 2093 // call this with lock taken so socket does not disappear from under us */ 2094 if (p_cback) { 2095 p_cback(BTA_JV_L2CAP_OPEN_EVT, &open_evt, l2cap_socket_id); 2096 if (!t->p_cback) /* no callback set, means they do not want this one... */ 2097 fcclient_free(t); 2098 } 2099 } 2100 2101 static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr, 2102 BT_HDR* p_buf) { 2103 tBTA_JV evt_data; 2104 struct fc_channel* tc; 2105 struct fc_client* t = NULL; 2106 tBTA_JV_L2CAP_CBACK* sock_cback = NULL; 2107 uint32_t sock_id; 2108 2109 tc = fcchan_get(chan, false); 2110 if (tc) { 2111 // try to find an open socked for that addr and channel 2112 t = fcclient_find_by_addr(tc->clients, &bd_addr); 2113 if (!t) { 2114 // no socket -> drop it 2115 return; 2116 } 2117 } 2118 2119 sock_cback = t->p_cback; 2120 sock_id = t->l2cap_socket_id; 2121 evt_data.le_data_ind.handle = t->id; 2122 evt_data.le_data_ind.p_buf = p_buf; 2123 2124 if (sock_cback) sock_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, sock_id); 2125 } 2126 2127 /** makes an le l2cap client connection */ 2128 void bta_jv_l2cap_connect_le(uint16_t remote_chan, 2129 const RawAddress& peer_bd_addr, 2130 tBTA_JV_L2CAP_CBACK* p_cback, 2131 uint32_t l2cap_socket_id) { 2132 tBTA_JV evt; 2133 uint32_t id; 2134 char call_init_f = true; 2135 struct fc_client* t; 2136 2137 evt.l2c_cl_init.handle = GAP_INVALID_HANDLE; 2138 evt.l2c_cl_init.status = BTA_JV_FAILURE; 2139 2140 t = fcclient_alloc(remote_chan, false, NULL); 2141 if (!t) { 2142 p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, l2cap_socket_id); 2143 return; 2144 } 2145 2146 t->p_cback = p_cback; 2147 t->l2cap_socket_id = l2cap_socket_id; 2148 t->remote_addr = peer_bd_addr; 2149 id = t->id; 2150 t->init_called = false; 2151 2152 if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr)) { 2153 evt.l2c_cl_init.status = BTA_JV_SUCCESS; 2154 evt.l2c_cl_init.handle = id; 2155 } 2156 2157 // it could have been deleted/moved from under us, so re-find it */ 2158 t = fcclient_find_by_id(id); 2159 if (t) { 2160 if (evt.l2c_cl_init.status == BTA_JV_SUCCESS) 2161 call_init_f = !t->init_called; 2162 else 2163 fcclient_free(t); 2164 } 2165 if (call_init_f) p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, l2cap_socket_id); 2166 t->init_called = true; 2167 } 2168 2169 /* stops an LE L2CAP server */ 2170 void bta_jv_l2cap_stop_server_le(uint16_t local_chan) { 2171 struct fc_client* fcclient; 2172 2173 tBTA_JV evt; 2174 evt.l2c_close.status = BTA_JV_FAILURE; 2175 evt.l2c_close.async = false; 2176 evt.l2c_close.handle = GAP_INVALID_HANDLE; 2177 2178 struct fc_channel* fcchan = fcchan_get(local_chan, false); 2179 if (fcchan) { 2180 while ((fcclient = fcchan->clients)) { 2181 tBTA_JV_L2CAP_CBACK* p_cback = fcclient->p_cback; 2182 uint32_t l2cap_socket_id = fcclient->l2cap_socket_id; 2183 2184 evt.l2c_close.handle = fcclient->id; 2185 evt.l2c_close.status = BTA_JV_SUCCESS; 2186 evt.l2c_close.async = false; 2187 2188 fcclient_free(fcclient); 2189 2190 if (p_cback) p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt, l2cap_socket_id); 2191 } 2192 } 2193 } 2194 2195 /** starts an LE L2CAP server */ 2196 void bta_jv_l2cap_start_server_le(uint16_t local_chan, 2197 tBTA_JV_L2CAP_CBACK* p_cback, 2198 uint32_t l2cap_socket_id) { 2199 tBTA_JV_L2CAP_START evt_data; 2200 evt_data.handle = GAP_INVALID_HANDLE; 2201 evt_data.status = BTA_JV_FAILURE; 2202 2203 struct fc_client* t = fcclient_alloc(local_chan, true, NULL); 2204 if (!t) goto out; 2205 2206 t->p_cback = p_cback; 2207 t->l2cap_socket_id = l2cap_socket_id; 2208 2209 // if we got here, we're registered... 2210 evt_data.status = BTA_JV_SUCCESS; 2211 evt_data.handle = t->id; 2212 evt_data.sec_id = t->sec_id; 2213 2214 out: 2215 tBTA_JV bta_jv; 2216 bta_jv.l2c_start = evt_data; 2217 p_cback(BTA_JV_L2CAP_START_EVT, &bta_jv, l2cap_socket_id); 2218 } 2219 2220 /* close a fixed channel connection. calls no callbacks. idempotent */ 2221 extern void bta_jv_l2cap_close_fixed(uint32_t handle) { 2222 struct fc_client* t = fcclient_find_by_id(handle); 2223 if (t) fcclient_free(t); 2224 } 2225