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