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