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