1 /******************************************************************************
3 * Copyright (C) 2006-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains action functions for BTA JV APIs.
23 ******************************************************************************/
24 #include <hardware/bluetooth.h>
25 #include <arpa/inet.h>
30 #include "osi/include/allocator.h"
36 #include "bta_jv_api.h"
37 #include "bta_jv_int.h"
38 #include "bta_jv_co.h"
50 #include "osi/include/osi.h"
53 /* one of these exists for each client */
55 struct fc_client *next_all_list;
56 struct fc_client *next_chan_list;
59 tBTA_JV_L2CAP_CBACK *p_cback;
65 unsigned init_called : 1;
68 /* one of these exists for each channel we're dealing with */
70 struct fc_channel *next;
71 struct fc_client *clients;
72 uint8_t has_server : 1;
77 static struct fc_client *fc_clients;
78 static struct fc_channel *fc_channels;
79 static uint32_t fc_next_id;
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);
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)
91 uuid_to_string_legacy((bt_uuid_t*)p_uuid, uuids);
92 APPL_TRACE_DEBUG("%s: %s", title, uuids);
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
104 /*******************************************************************************
106 ** Function bta_jv_alloc_sec_id
108 ** Description allocate a security id
112 *******************************************************************************/
113 UINT8 bta_jv_alloc_sec_id(void)
117 for(i=0; i<BTA_JV_NUM_SERVICE_ID; i++)
119 if(0 == bta_jv_cb.sec_id[i])
121 bta_jv_cb.sec_id[i] = BTA_JV_FIRST_SERVICE_ID + i;
122 ret = bta_jv_cb.sec_id[i];
129 static int get_sec_id_used(void)
133 for(i=0; i<BTA_JV_NUM_SERVICE_ID; i++)
135 if(bta_jv_cb.sec_id[i])
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);
143 static int get_rfc_cb_used(void)
147 for(i=0; i<BTA_JV_MAX_RFC_CONN; i++)
149 if(bta_jv_cb.rfc_cb[i].handle )
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);
158 /*******************************************************************************
160 ** Function bta_jv_free_sec_id
162 ** Description free the given security id
166 *******************************************************************************/
167 static void bta_jv_free_sec_id(UINT8 *p_sec_id)
169 UINT8 sec_id = *p_sec_id;
171 if(sec_id >= BTA_JV_FIRST_SERVICE_ID && sec_id <= BTA_JV_LAST_SERVICE_ID)
173 BTM_SecClrService(sec_id);
174 bta_jv_cb.sec_id[sec_id - BTA_JV_FIRST_SERVICE_ID] = 0;
178 /*******************************************************************************
180 ** Function bta_jv_alloc_rfc_cb
182 ** Description allocate a control block for the given port handle
186 *******************************************************************************/
187 tBTA_JV_RFC_CB * bta_jv_alloc_rfc_cb(UINT16 port_handle, tBTA_JV_PCB **pp_pcb)
189 tBTA_JV_RFC_CB *p_cb = NULL;
192 for(i=0; i<BTA_JV_MAX_RFC_CONN; i++)
194 if (0 == bta_jv_cb.rfc_cb[i].handle )
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;
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);
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;
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);
224 /*******************************************************************************
226 ** Function bta_jv_rfc_port_to_pcb
228 ** Description find the port control block associated with the given port handle
232 *******************************************************************************/
233 tBTA_JV_PCB * bta_jv_rfc_port_to_pcb(UINT16 port_handle)
235 tBTA_JV_PCB *p_pcb = NULL;
237 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS)
238 && bta_jv_cb.port_cb[port_handle - 1].handle)
240 p_pcb = &bta_jv_cb.port_cb[port_handle - 1];
246 /*******************************************************************************
248 ** Function bta_jv_rfc_port_to_cb
250 ** Description find the RFCOMM control block associated with the given port handle
254 *******************************************************************************/
255 tBTA_JV_RFC_CB * bta_jv_rfc_port_to_cb(UINT16 port_handle)
257 tBTA_JV_RFC_CB *p_cb = NULL;
260 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS)
261 && bta_jv_cb.port_cb[port_handle - 1].handle)
263 handle = bta_jv_cb.port_cb[port_handle - 1].handle;
264 handle &= BTA_JV_RFC_HDL_MASK;
265 handle &= ~BTA_JV_RFCOMM_MASK;
267 p_cb = &bta_jv_cb.rfc_cb[handle - 1];
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);
277 static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb)
279 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
280 BOOLEAN remove_server = FALSE;
281 int close_pending = 0;
285 APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null");
286 return BTA_JV_FAILURE;
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);
292 if (p_cb->curr_sess <= 0)
293 return BTA_JV_SUCCESS;
295 switch (p_pcb->state)
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,
302 status = BTA_JV_FAILURE;
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;
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);
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);
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,
326 status = BTA_JV_FAILURE;
329 if (BTA_JV_SUCCESS == status)
334 port_status = RFCOMM_RemoveConnection(p_pcb->port_handle);
336 port_status = RFCOMM_RemoveServer(p_pcb->port_handle);
337 if (port_status != PORT_SUCCESS)
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,
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);
352 //Initialize congestion flags
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;
360 if (p_cb->curr_sess == 0)
363 bta_jv_free_sec_id(&p_cb->sec_id);
364 p_cb->p_cback = NULL;
366 p_cb->curr_sess = -1;
369 bta_jv_free_sec_id(&p_cb->sec_id);
375 /*******************************************************************************
377 ** Function bta_jv_free_l2c_cb
379 ** Description free the given L2CAP control block
383 *******************************************************************************/
384 tBTA_JV_STATUS bta_jv_free_l2c_cb(tBTA_JV_L2C_CB *p_cb)
386 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
388 if(BTA_JV_ST_NONE != p_cb->state)
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;
395 p_cb->state = BTA_JV_ST_NONE;
396 bta_jv_free_sec_id(&p_cb->sec_id);
397 p_cb->p_cback = NULL;
401 /*******************************************************************************
404 ** Function bta_jv_clear_pm_cb
406 ** Description clears jv pm control block and optionally calls bta_sys_conn_close()
407 ** In general close_conn should be set to TRUE to remove registering with
410 ** WARNING: Make sure to clear pointer form port or l2c to this control block too!
412 *******************************************************************************/
413 static void bta_jv_clear_pm_cb(tBTA_JV_PM_CB *p_pm_cb, BOOLEAN close_conn)
415 /* needs to be called if registered with bta pm, otherwise we may run out of dm pm slots! */
417 bta_sys_conn_close(BTA_ID_JV, p_pm_cb->app_id, p_pm_cb->peer_bd_addr);
418 p_pm_cb->state = BTA_JV_PM_FREE_ST;
419 p_pm_cb->app_id = BTA_JV_PM_ALL;
420 p_pm_cb->handle = BTA_JV_PM_HANDLE_CLEAR;
421 bdcpy(p_pm_cb->peer_bd_addr, bd_addr_null);
424 /*******************************************************************************
426 ** Function bta_jv_free_set_pm_profile_cb
428 ** Description free pm profile control block
430 ** Returns BTA_JV_SUCCESS if cb has been freed correctly,
431 ** BTA_JV_FAILURE in case of no profile has been registered or already freed
433 *******************************************************************************/
434 static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(UINT32 jv_handle)
436 tBTA_JV_STATUS status = BTA_JV_FAILURE;
437 tBTA_JV_PM_CB **p_cb;
438 int i, j, bd_counter = 0, appid_counter = 0;
440 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++)
443 if ((bta_jv_cb.pm_cb[i].state != BTA_JV_PM_FREE_ST) &&
444 (jv_handle == bta_jv_cb.pm_cb[i].handle))
446 for (j = 0; j < BTA_JV_PM_MAX_NUM; j++)
448 if (bdcmp(bta_jv_cb.pm_cb[j].peer_bd_addr, bta_jv_cb.pm_cb[i].peer_bd_addr) == 0)
450 if (bta_jv_cb.pm_cb[j].app_id == bta_jv_cb.pm_cb[i].app_id)
454 APPL_TRACE_API("%s(jv_handle: 0x%2x), idx: %d, "
455 "app_id: 0x%x",__func__, jv_handle, i, bta_jv_cb.pm_cb[i].app_id);
456 APPL_TRACE_API("%s, bd_counter = %d, "
457 "appid_counter = %d", __func__, bd_counter, appid_counter);
460 bta_jv_pm_conn_idle(&bta_jv_cb.pm_cb[i]);
463 if (bd_counter <= 1 || (appid_counter <= 1))
465 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], TRUE);
469 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], FALSE);
472 if (BTA_JV_RFCOMM_MASK & jv_handle)
474 UINT32 hi = ((jv_handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1;
475 UINT32 si = BTA_JV_RFC_HDL_TO_SIDX(jv_handle);
476 if (hi < BTA_JV_MAX_RFC_CONN && bta_jv_cb.rfc_cb[hi].p_cback && si
477 < BTA_JV_MAX_RFC_SR_SESSION && bta_jv_cb.rfc_cb[hi].rfc_hdl[si])
479 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(bta_jv_cb.rfc_cb[hi].rfc_hdl[si]);
482 if (NULL == p_pcb->p_pm_cb)
483 APPL_TRACE_WARNING("%s(jv_handle:"
484 " 0x%x):port_handle: 0x%x, p_pm_cb: %d: no link to "
485 "pm_cb?", __func__, jv_handle, p_pcb->port_handle, i);
486 p_cb = &p_pcb->p_pm_cb;
492 if (jv_handle < BTA_JV_MAX_L2C_CONN)
494 tBTA_JV_L2C_CB *p_l2c_cb = &bta_jv_cb.l2c_cb[jv_handle];
495 if (NULL == p_l2c_cb->p_pm_cb)
496 APPL_TRACE_WARNING("%s(jv_handle: "
497 "0x%x): p_pm_cb: %d: no link to pm_cb?", __func__, jv_handle, i);
498 p_cb = &p_l2c_cb->p_pm_cb;
504 status = BTA_JV_SUCCESS;
511 /*******************************************************************************
513 ** Function bta_jv_alloc_set_pm_profile_cb
515 ** Description set PM profile control block
517 ** Returns pointer to allocated cb or NULL in case of failure
519 *******************************************************************************/
520 static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_PM_ID app_id)
522 BOOLEAN bRfcHandle = (jv_handle & BTA_JV_RFCOMM_MASK) != 0;
523 BD_ADDR peer_bd_addr;
525 tBTA_JV_PM_CB **pp_cb;
527 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++)
530 if (bta_jv_cb.pm_cb[i].state == BTA_JV_PM_FREE_ST)
532 /* rfc handle bd addr retrieval requires core stack handle */
535 for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++)
537 if (jv_handle == bta_jv_cb.port_cb[j].handle)
539 pp_cb = &bta_jv_cb.port_cb[j].p_pm_cb;
540 if (PORT_SUCCESS != PORT_CheckConnection(
541 bta_jv_cb.port_cb[j].port_handle, peer_bd_addr, NULL))
542 i = BTA_JV_PM_MAX_NUM;
549 /* use jv handle for l2cap bd address retrieval */
550 for (j = 0; j < BTA_JV_MAX_L2C_CONN; j++)
552 if (jv_handle == bta_jv_cb.l2c_cb[j].handle)
554 pp_cb = &bta_jv_cb.l2c_cb[j].p_pm_cb;
555 UINT8 *p_bd_addr = GAP_ConnGetRemoteAddr((UINT16)jv_handle);
556 if (NULL != p_bd_addr)
557 bdcpy(peer_bd_addr, p_bd_addr);
559 i = BTA_JV_PM_MAX_NUM;
564 APPL_TRACE_API("bta_jv_alloc_set_pm_profile_cb(handle 0x%2x, app_id %d): "
565 "idx: %d, (BTA_JV_PM_MAX_NUM: %d), pp_cb: 0x%x", jv_handle, app_id,
566 i, BTA_JV_PM_MAX_NUM, pp_cb);
571 if ((i != BTA_JV_PM_MAX_NUM) && (NULL != pp_cb))
573 *pp_cb = &bta_jv_cb.pm_cb[i];
574 bta_jv_cb.pm_cb[i].handle = jv_handle;
575 bta_jv_cb.pm_cb[i].app_id = app_id;
576 bdcpy(bta_jv_cb.pm_cb[i].peer_bd_addr, peer_bd_addr);
577 bta_jv_cb.pm_cb[i].state = BTA_JV_PM_IDLE_ST;
578 return &bta_jv_cb.pm_cb[i];
580 APPL_TRACE_WARNING("bta_jv_alloc_set_pm_profile_cb(jv_handle: 0x%x, app_id: %d) "
581 "return NULL", jv_handle, app_id);
582 return (tBTA_JV_PM_CB *)NULL;
585 /*******************************************************************************
587 ** Function bta_jv_check_psm
589 ** Description for now use only the legal PSM per JSR82 spec
591 ** Returns TRUE, if allowed
593 *******************************************************************************/
594 BOOLEAN bta_jv_check_psm(UINT16 psm)
598 if (L2C_IS_VALID_PSM(psm))
602 /* see if this is defined by spec */
605 case SDP_PSM: /* 1 */
606 case BT_PSM_RFCOMM: /* 3 */
607 /* do not allow java app to use these 2 PSMs */
610 case TCS_PSM_INTERCOM: /* 5 */
611 case TCS_PSM_CORDLESS: /* 7 */
612 if( FALSE == bta_sys_is_register(BTA_ID_CT) &&
613 FALSE == bta_sys_is_register(BTA_ID_CG) )
617 case BT_PSM_BNEP: /* F */
618 if(FALSE == bta_sys_is_register(BTA_ID_PAN))
622 case HID_PSM_CONTROL: /* 0x11 */
623 case HID_PSM_INTERRUPT: /* 0x13 */
624 //FIX: allow HID Device and HID Host to coexist
625 if( FALSE == bta_sys_is_register(BTA_ID_HD) ||
626 FALSE == bta_sys_is_register(BTA_ID_HH) )
630 case AVCT_PSM: /* 0x17 */
631 case AVDT_PSM: /* 0x19 */
632 if ((FALSE == bta_sys_is_register(BTA_ID_AV)) &&
633 (FALSE == bta_sys_is_register(BTA_ID_AVK)))
651 /*******************************************************************************
653 ** Function bta_jv_enable
655 ** Description Initialises the JAVA I/F
659 *******************************************************************************/
660 void bta_jv_enable(tBTA_JV_MSG *p_data)
662 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
663 bta_jv_cb.p_dm_cback = p_data->enable.p_cback;
664 bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, (tBTA_JV *)&status, 0);
665 memset(bta_jv_cb.free_psm_list,0,sizeof(bta_jv_cb.free_psm_list));
668 /*******************************************************************************
670 ** Function bta_jv_disable
672 ** Description Disables the BT device manager
673 ** free the resources used by java
677 *******************************************************************************/
678 void bta_jv_disable (tBTA_JV_MSG *p_data)
682 APPL_TRACE_ERROR("%s",__func__);
687 * We keep a list of PSM's that have been freed from JAVA, for reuse.
688 * This function will return a free PSM, and delete it from the free
690 * If no free PSMs exist, 0 will be returned.
692 static UINT16 bta_jv_get_free_psm() {
693 const int cnt = sizeof(bta_jv_cb.free_psm_list)/sizeof(bta_jv_cb.free_psm_list[0]);
694 for (int i = 0; i < cnt; i++) {
695 UINT16 psm = bta_jv_cb.free_psm_list[i];
697 APPL_TRACE_DEBUG("%s(): Reusing PSM: 0x%04d", __func__, psm)
698 bta_jv_cb.free_psm_list[i] = 0;
705 static void bta_jv_set_free_psm(UINT16 psm) {
707 const int cnt = sizeof(bta_jv_cb.free_psm_list)/sizeof(bta_jv_cb.free_psm_list[0]);
708 for (int i = 0; i < cnt; i++) {
709 if (bta_jv_cb.free_psm_list[i] == 0) {
711 } else if (psm == bta_jv_cb.free_psm_list[i]) {
712 return; // PSM already freed?
715 if (free_index != -1) {
716 bta_jv_cb.free_psm_list[free_index] = psm;
717 APPL_TRACE_DEBUG("%s(): Recycling PSM: 0x%04d", __func__, psm)
719 APPL_TRACE_ERROR("%s unable to free psm 0x%x no more free slots",__func__, psm);
723 /*******************************************************************************
725 ** Function bta_jv_get_channel_id
727 ** Description Obtain a free SCN (Server Channel Number)
728 ** (RFCOMM channel or L2CAP PSM)
732 *******************************************************************************/
733 void bta_jv_get_channel_id(tBTA_JV_MSG *p_data)
737 switch (p_data->alloc_channel.type) {
738 case BTA_JV_CONN_TYPE_RFCOMM: {
739 INT32 channel = p_data->alloc_channel.channel;
743 if (BTM_TryAllocateSCN(channel) == FALSE)
745 APPL_TRACE_ERROR("rfc channel:%d already in use or invalid", channel);
748 } else if ((channel = BTM_AllocateSCN()) == 0) {
749 APPL_TRACE_ERROR("run out of rfc channels");
753 bta_jv_cb.scn[channel-1] = TRUE;
754 scn = (UINT8) channel;
756 if (bta_jv_cb.p_dm_cback)
757 bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, (tBTA_JV *)&scn,
758 p_data->alloc_channel.user_data);
761 case BTA_JV_CONN_TYPE_L2CAP:
762 psm = bta_jv_get_free_psm();
764 psm = L2CA_AllocatePSM();
765 APPL_TRACE_DEBUG("%s() returned PSM: 0x%04x", __func__, psm);
768 case BTA_JV_CONN_TYPE_L2CAP_LE:
774 if (bta_jv_cb.p_dm_cback)
775 bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, (tBTA_JV *)&psm, p_data->alloc_channel.user_data);
778 /*******************************************************************************
780 ** Function bta_jv_free_scn
782 ** Description free a SCN
786 *******************************************************************************/
787 void bta_jv_free_scn(tBTA_JV_MSG *p_data)
789 UINT16 scn = p_data->free_channel.scn;
791 switch (p_data->free_channel.type) {
792 case BTA_JV_CONN_TYPE_RFCOMM: {
793 if (scn > 0 && scn <= BTA_JV_MAX_SCN && bta_jv_cb.scn[scn-1])
795 /* this scn is used by JV */
796 bta_jv_cb.scn[scn-1] = FALSE;
801 case BTA_JV_CONN_TYPE_L2CAP:
802 bta_jv_set_free_psm(scn);
804 case BTA_JV_CONN_TYPE_L2CAP_LE:
805 // TODO: Not yet implemented...
811 static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u)
813 static uint8_t bt_base_uuid[] =
814 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
816 logu("in, uuid:", u->uu.uuid128);
817 APPL_TRACE_DEBUG("uuid len:%d", u->len);
820 if(memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) == 0)
823 memset(&su, 0, sizeof(su));
824 if(u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0)
828 memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
829 su.uu.uuid16 = ntohs(u16);
830 APPL_TRACE_DEBUG("shorten to 16 bits uuid: %x", su.uu.uuid16);
836 memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
837 su.uu.uuid32 = ntohl(u32);
838 APPL_TRACE_DEBUG("shorten to 32 bits uuid: %x", su.uu.uuid32);
843 APPL_TRACE_DEBUG("cannot shorten none-reserved 128 bits uuid");
847 /*******************************************************************************
849 ** Function bta_jv_start_discovery_cback
851 ** Description Callback for Start Discovery
855 *******************************************************************************/
856 static void bta_jv_start_discovery_cback(UINT16 result, void * user_data)
858 tBTA_JV_STATUS status;
860 APPL_TRACE_DEBUG("bta_jv_start_discovery_cback res: 0x%x", result);
862 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
863 if(bta_jv_cb.p_dm_cback)
865 tBTA_JV_DISCOVERY_COMP dcomp;
867 status = BTA_JV_FAILURE;
868 if (result == SDP_SUCCESS || result == SDP_DB_FULL)
870 tSDP_DISC_REC *p_sdp_rec = NULL;
871 tSDP_PROTOCOL_ELEM pe;
872 logu("bta_jv_cb.uuid", bta_jv_cb.uuid.uu.uuid128);
873 tBT_UUID su = shorten_sdp_uuid(&bta_jv_cb.uuid);
874 logu("shorten uuid:", su.uu.uuid128);
875 p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db, &su, p_sdp_rec);
876 APPL_TRACE_DEBUG("p_sdp_rec:%p", p_sdp_rec);
877 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe))
879 dcomp.scn = (UINT8) pe.params[0];
880 status = BTA_JV_SUCCESS;
884 dcomp.status = status;
885 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&dcomp, user_data);
889 /*******************************************************************************
891 ** Function bta_jv_start_discovery
893 ** Description Discovers services on a remote device
897 *******************************************************************************/
898 void bta_jv_start_discovery(tBTA_JV_MSG *p_data)
900 tBTA_JV_STATUS status = BTA_JV_FAILURE;
901 APPL_TRACE_DEBUG("bta_jv_start_discovery in, sdp_active:%d", bta_jv_cb.sdp_active);
902 if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE)
904 /* SDP is still in progress */
905 status = BTA_JV_BUSY;
906 if(bta_jv_cb.p_dm_cback)
907 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&status, p_data->start_discovery.user_data);
911 /* init the database/set up the filter */
912 APPL_TRACE_DEBUG("call SDP_InitDiscoveryDb, p_data->start_discovery.num_uuid:%d",
913 p_data->start_discovery.num_uuid);
914 SDP_InitDiscoveryDb (p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size,
915 p_data->start_discovery.num_uuid, p_data->start_discovery.uuid_list, 0, NULL);
917 /* tell SDP to keep the raw data */
918 p_bta_jv_cfg->p_sdp_db->raw_data = p_bta_jv_cfg->p_sdp_raw_data;
919 p_bta_jv_cfg->p_sdp_db->raw_size = p_bta_jv_cfg->sdp_raw_size;
921 bta_jv_cb.p_sel_raw_data = 0;
922 bta_jv_cb.uuid = p_data->start_discovery.uuid_list[0];
924 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_YES;
925 if (!SDP_ServiceSearchAttributeRequest2(p_data->start_discovery.bd_addr,
926 p_bta_jv_cfg->p_sdp_db,
927 bta_jv_start_discovery_cback, p_data->start_discovery.user_data))
929 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
930 /* failed to start SDP. report the failure right away */
931 if(bta_jv_cb.p_dm_cback)
932 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&status, p_data->start_discovery.user_data);
935 else report the result when the cback is called
939 /*******************************************************************************
941 ** Function bta_jv_create_record
943 ** Description Create an SDP record with the given attributes
947 *******************************************************************************/
948 void bta_jv_create_record(tBTA_JV_MSG *p_data)
950 tBTA_JV_API_CREATE_RECORD *cr = &(p_data->create_record);
951 tBTA_JV_CREATE_RECORD evt_data;
952 evt_data.status = BTA_JV_SUCCESS;
953 if(bta_jv_cb.p_dm_cback)
954 //callback user immediately to create his own sdp record in stack thread context
955 bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, (tBTA_JV *)&evt_data, cr->user_data);
958 /*******************************************************************************
960 ** Function bta_jv_delete_record
962 ** Description Delete an SDP record
967 *******************************************************************************/
968 void bta_jv_delete_record(tBTA_JV_MSG *p_data)
970 tBTA_JV_API_ADD_ATTRIBUTE *dr = &(p_data->add_attr);
973 /* this is a record created by btif layer*/
974 SDP_DeleteRecord(dr->handle);
978 /*******************************************************************************
980 ** Function bta_jv_l2cap_client_cback
982 ** Description handles the l2cap client events
986 *******************************************************************************/
987 static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event)
989 tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle];
992 if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback)
995 APPL_TRACE_DEBUG( "%s: %d evt:x%x",__func__, gap_handle, event);
996 evt_data.l2c_open.status = BTA_JV_SUCCESS;
997 evt_data.l2c_open.handle = gap_handle;
1001 case GAP_EVT_CONN_OPENED:
1002 bdcpy(evt_data.l2c_open.rem_bda, GAP_ConnGetRemoteAddr(gap_handle));
1003 evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
1004 p_cb->state = BTA_JV_ST_CL_OPEN;
1005 p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->user_data);
1008 case GAP_EVT_CONN_CLOSED:
1009 p_cb->state = BTA_JV_ST_NONE;
1010 bta_jv_free_sec_id(&p_cb->sec_id);
1011 evt_data.l2c_close.async = TRUE;
1012 p_cb->p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt_data, p_cb->user_data);
1013 p_cb->p_cback = NULL;
1016 case GAP_EVT_CONN_DATA_AVAIL:
1017 evt_data.data_ind.handle = gap_handle;
1018 /* Reset idle timer to avoid requesting sniff mode while receiving data */
1019 bta_jv_pm_conn_busy(p_cb->p_pm_cb);
1020 p_cb->p_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, p_cb->user_data);
1021 bta_jv_pm_conn_idle(p_cb->p_pm_cb);
1024 case GAP_EVT_CONN_CONGESTED:
1025 case GAP_EVT_CONN_UNCONGESTED:
1026 p_cb->cong = (event == GAP_EVT_CONN_CONGESTED) ? TRUE : FALSE;
1027 evt_data.l2c_cong.cong = p_cb->cong;
1028 p_cb->p_cback(BTA_JV_L2CAP_CONG_EVT, &evt_data, p_cb->user_data);
1036 /*******************************************************************************
1038 ** Function bta_jv_l2cap_connect
1040 ** Description makes an l2cap client connection
1044 *******************************************************************************/
1045 void bta_jv_l2cap_connect(tBTA_JV_MSG *p_data)
1047 tBTA_JV_L2C_CB *p_cb;
1048 tBTA_JV_L2CAP_CL_INIT evt_data;
1049 UINT16 handle=GAP_INVALID_HANDLE;
1051 tL2CAP_CFG_INFO cfg;
1052 tBTA_JV_API_L2CAP_CONNECT *cc = &(p_data->l2cap_connect);
1053 UINT8 chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC;
1054 tL2CAP_ERTM_INFO *ertm_info = NULL;
1056 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
1058 if (cc->has_cfg == TRUE)
1061 if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
1062 chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM;
1066 if (cc->has_ertm_info == TRUE)
1068 ertm_info = &(cc->ertm_info);
1071 /* We need to use this value for MTU to be able to handle cases where cfg is not set in req. */
1072 cfg.mtu_present = TRUE;
1073 cfg.mtu = cc->rx_mtu;
1075 /* TODO: DM role manager
1076 L2CA_SetDesireRole(cc->role);
1079 sec_id = bta_jv_alloc_sec_id();
1080 evt_data.sec_id = sec_id;
1081 evt_data.status = BTA_JV_FAILURE;
1085 if (bta_jv_check_psm(cc->remote_psm)) /* allowed */
1087 if ((handle = GAP_ConnOpen("", sec_id, 0, cc->peer_bd_addr, cc->remote_psm,
1088 &cfg, ertm_info, cc->sec_mask, chan_mode_mask,
1089 bta_jv_l2cap_client_cback)) != GAP_INVALID_HANDLE )
1091 evt_data.status = BTA_JV_SUCCESS;
1096 if (evt_data.status == BTA_JV_SUCCESS)
1098 p_cb = &bta_jv_cb.l2c_cb[handle];
1099 p_cb->handle = handle;
1100 p_cb->p_cback = cc->p_cback;
1101 p_cb->user_data = cc->user_data;
1102 p_cb->psm = 0; /* not a server */
1103 p_cb->sec_id = sec_id;
1104 p_cb->state = BTA_JV_ST_CL_OPENING;
1108 bta_jv_free_sec_id(&sec_id);
1111 evt_data.handle = handle;
1112 cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, (tBTA_JV *)&evt_data, cc->user_data);
1116 /*******************************************************************************
1118 ** Function bta_jv_l2cap_close
1120 ** Description Close an L2CAP client connection
1124 *******************************************************************************/
1125 void bta_jv_l2cap_close(tBTA_JV_MSG *p_data)
1127 tBTA_JV_L2CAP_CLOSE evt_data;
1128 tBTA_JV_API_L2CAP_CLOSE *cc = &(p_data->l2cap_close);
1129 tBTA_JV_L2CAP_CBACK *p_cback = cc->p_cb->p_cback;
1130 void *user_data = cc->p_cb->user_data;
1132 evt_data.handle = cc->handle;
1133 evt_data.status = bta_jv_free_l2c_cb(cc->p_cb);
1134 evt_data.async = FALSE;
1137 p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
1140 /*******************************************************************************
1142 ** Function bta_jv_l2cap_server_cback
1144 ** Description handles the l2cap server callback
1148 *******************************************************************************/
1149 static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event)
1151 tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle];
1153 tBTA_JV_L2CAP_CBACK *p_cback;
1156 if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback)
1159 APPL_TRACE_DEBUG( "%s: %d evt:x%x", __func__, gap_handle, event);
1160 evt_data.l2c_open.status = BTA_JV_SUCCESS;
1161 evt_data.l2c_open.handle = gap_handle;
1165 case GAP_EVT_CONN_OPENED:
1166 bdcpy(evt_data.l2c_open.rem_bda, GAP_ConnGetRemoteAddr(gap_handle));
1167 evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
1168 p_cb->state = BTA_JV_ST_SR_OPEN;
1169 p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->user_data);
1172 case GAP_EVT_CONN_CLOSED:
1173 evt_data.l2c_close.async = TRUE;
1174 evt_data.l2c_close.handle = p_cb->handle;
1175 p_cback = p_cb->p_cback;
1176 user_data = p_cb->user_data;
1177 evt_data.l2c_close.status = bta_jv_free_l2c_cb(p_cb);
1178 p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt_data, user_data);
1181 case GAP_EVT_CONN_DATA_AVAIL:
1182 evt_data.data_ind.handle = gap_handle;
1183 /* Reset idle timer to avoid requesting sniff mode while receiving data */
1184 bta_jv_pm_conn_busy(p_cb->p_pm_cb);
1185 p_cb->p_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, p_cb->user_data);
1186 bta_jv_pm_conn_idle(p_cb->p_pm_cb);
1189 case GAP_EVT_CONN_CONGESTED:
1190 case GAP_EVT_CONN_UNCONGESTED:
1191 p_cb->cong = (event == GAP_EVT_CONN_CONGESTED) ? TRUE : FALSE;
1192 evt_data.l2c_cong.cong = p_cb->cong;
1193 p_cb->p_cback(BTA_JV_L2CAP_CONG_EVT, &evt_data, p_cb->user_data);
1201 /*******************************************************************************
1203 ** Function bta_jv_l2cap_start_server
1205 ** Description starts an L2CAP server
1209 *******************************************************************************/
1210 void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
1212 tBTA_JV_L2C_CB *p_cb;
1215 tL2CAP_CFG_INFO cfg;
1216 tBTA_JV_L2CAP_START evt_data;
1217 tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
1218 UINT8 chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC;
1219 tL2CAP_ERTM_INFO *ertm_info = NULL;
1221 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
1223 if (ls->has_cfg == TRUE) {
1225 if (cfg.fcr_present && cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
1226 chan_mode_mask = GAP_FCR_CHAN_OPT_ERTM;
1230 if (ls->has_ertm_info == TRUE) {
1231 ertm_info = &(ls->ertm_info);
1234 //FIX: MTU=0 means not present
1237 cfg.mtu_present = TRUE;
1238 cfg.mtu = ls->rx_mtu;
1242 cfg.mtu_present = FALSE;
1246 /* TODO DM role manager
1247 L2CA_SetDesireRole(ls->role);
1250 sec_id = bta_jv_alloc_sec_id();
1251 if (0 == sec_id || (FALSE == bta_jv_check_psm(ls->local_psm)) ||
1252 (handle = GAP_ConnOpen("JV L2CAP", sec_id, 1, 0, ls->local_psm, &cfg, ertm_info,
1253 ls->sec_mask, chan_mode_mask, bta_jv_l2cap_server_cback)) == GAP_INVALID_HANDLE)
1255 bta_jv_free_sec_id(&sec_id);
1256 evt_data.status = BTA_JV_FAILURE;
1260 p_cb = &bta_jv_cb.l2c_cb[handle];
1261 evt_data.status = BTA_JV_SUCCESS;
1262 evt_data.handle = handle;
1263 evt_data.sec_id = sec_id;
1264 p_cb->p_cback = ls->p_cback;
1265 p_cb->user_data = ls->user_data;
1266 p_cb->handle = handle;
1267 p_cb->sec_id = sec_id;
1268 p_cb->state = BTA_JV_ST_SR_LISTEN;
1269 p_cb->psm = ls->local_psm;
1272 ls->p_cback(BTA_JV_L2CAP_START_EVT, (tBTA_JV *)&evt_data, ls->user_data);
1275 /*******************************************************************************
1277 ** Function bta_jv_l2cap_stop_server
1279 ** Description stops an L2CAP server
1283 *******************************************************************************/
1284 void bta_jv_l2cap_stop_server(tBTA_JV_MSG *p_data)
1286 tBTA_JV_L2C_CB *p_cb;
1287 tBTA_JV_L2CAP_CLOSE evt_data;
1288 tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
1289 tBTA_JV_L2CAP_CBACK *p_cback;
1291 for (int i = 0; i < BTA_JV_MAX_L2C_CONN; i++)
1293 if (bta_jv_cb.l2c_cb[i].psm == ls->local_psm)
1295 p_cb = &bta_jv_cb.l2c_cb[i];
1296 p_cback = p_cb->p_cback;
1297 user_data = p_cb->user_data;
1298 evt_data.handle = p_cb->handle;
1299 evt_data.status = bta_jv_free_l2c_cb(p_cb);
1300 evt_data.async = FALSE;
1301 p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
1309 /*******************************************************************************
1311 ** Function bta_jv_l2cap_read
1313 ** Description Read data from an L2CAP connection
1317 *******************************************************************************/
1318 void bta_jv_l2cap_read(tBTA_JV_MSG *p_data)
1320 tBTA_JV_L2CAP_READ evt_data;
1321 tBTA_JV_API_L2CAP_READ *rc = &(p_data->l2cap_read);
1323 evt_data.status = BTA_JV_FAILURE;
1324 evt_data.handle = rc->handle;
1325 evt_data.req_id = rc->req_id;
1326 evt_data.p_data = rc->p_data;
1329 if (BT_PASS == GAP_ConnReadData(rc->handle, rc->p_data, rc->len, &evt_data.len))
1331 evt_data.status = BTA_JV_SUCCESS;
1334 rc->p_cback(BTA_JV_L2CAP_READ_EVT, (tBTA_JV *)&evt_data, rc->user_data);
1338 /*******************************************************************************
1340 ** Function bta_jv_l2cap_write
1342 ** Description Write data to an L2CAP connection
1346 *******************************************************************************/
1347 void bta_jv_l2cap_write(tBTA_JV_MSG *p_data)
1349 tBTA_JV_L2CAP_WRITE evt_data;
1350 tBTA_JV_API_L2CAP_WRITE *ls = &(p_data->l2cap_write);
1352 /* As we check this callback exists before the tBTA_JV_API_L2CAP_WRITE can be send through the
1353 * API this check should not be needed.
1354 * But the API is not designed to be used (safely at least) in a multi-threaded scheduler, hence
1355 * if the peer device disconnects the l2cap link after the API is called, but before this
1356 * message is handled, the ->p_cback will be cleared at this point. At first glanch this seems
1357 * highly unlikely, but for all obex-profiles with two channels connected - e.g. MAP, this
1358 * happens around 1 of 4 disconnects, as a disconnect on the server channel causes a disconnect
1359 * to be send on the client (notification) channel, but at the peer typically disconnects both
1360 * the OBEX disconnect request crosses the incoming l2cap disconnect.
1361 * If p_cback is cleared, we simply discard the data.
1362 * RISK: The caller must handle any cleanup based on another signal than BTA_JV_L2CAP_WRITE_EVT,
1363 * which is typically not possible, as the pointer to the allocated buffer is stored
1364 * in this message, and can therefore not be freed, hence we have a mem-leak-by-design.*/
1365 if (ls->p_cb->p_cback != NULL) {
1366 evt_data.status = BTA_JV_FAILURE;
1367 evt_data.handle = ls->handle;
1368 evt_data.req_id = ls->req_id;
1369 evt_data.cong = ls->p_cb->cong;
1371 bta_jv_pm_conn_busy(ls->p_cb->p_pm_cb);
1372 if (!evt_data.cong &&
1373 BT_PASS == GAP_ConnWriteData(ls->handle, ls->p_data, ls->len, &evt_data.len))
1375 evt_data.status = BTA_JV_SUCCESS;
1377 ls->p_cb->p_cback(BTA_JV_L2CAP_WRITE_EVT, (tBTA_JV *)&evt_data, ls->user_data);
1378 bta_jv_set_pm_conn_state(ls->p_cb->p_pm_cb, BTA_JV_CONN_IDLE);
1380 /* As this pointer is checked in the API function, this occurs only when the channel is
1381 * disconnected after the API function is called, but before the message is handled. */
1382 APPL_TRACE_ERROR("%s() ls->p_cb->p_cback == NULL", __func__);
1386 /*******************************************************************************
1388 ** Function bta_jv_l2cap_write_fixed
1390 ** Description Write data to an L2CAP connection using Fixed channels
1394 *******************************************************************************/
1395 void bta_jv_l2cap_write_fixed(tBTA_JV_MSG *p_data)
1397 tBTA_JV_L2CAP_WRITE_FIXED evt_data;
1398 tBTA_JV_API_L2CAP_WRITE_FIXED *ls = &(p_data->l2cap_write_fixed);
1399 BT_HDR *msg = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + ls->len + L2CAP_MIN_OFFSET);
1402 APPL_TRACE_ERROR("%s() could not allocate msg buffer",__func__);
1405 evt_data.status = BTA_JV_FAILURE;
1406 evt_data.channel = ls->channel;
1407 memcpy(evt_data.addr, ls->addr, sizeof(evt_data.addr));
1408 evt_data.req_id = ls->req_id;
1412 memcpy(((uint8_t*)(msg + 1)) + L2CAP_MIN_OFFSET, ls->p_data, ls->len);
1414 msg->offset = L2CAP_MIN_OFFSET;
1416 L2CA_SendFixedChnlData(ls->channel, ls->addr, msg);
1418 ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, (tBTA_JV *)&evt_data, ls->user_data);
1421 /*******************************************************************************
1423 ** Function bta_jv_port_data_co_cback
1425 ** Description port data callback function of rfcomm
1430 *******************************************************************************/
1431 static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type)
1433 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1434 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1436 APPL_TRACE_DEBUG("%s, p_cb:%p, p_pcb:%p, len:%d, type:%d", __func__, p_cb, p_pcb, len, type);
1441 case DATA_CO_CALLBACK_TYPE_INCOMING:
1442 bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
1443 ret = bta_co_rfc_data_incoming(p_pcb->user_data, (BT_HDR*)buf);
1444 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1446 case DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE:
1447 return bta_co_rfc_data_outgoing_size(p_pcb->user_data, (int*)buf);
1448 case DATA_CO_CALLBACK_TYPE_OUTGOING:
1449 return bta_co_rfc_data_outgoing(p_pcb->user_data, buf, len);
1451 APPL_TRACE_ERROR("unknown callout type:%d", type);
1458 /*******************************************************************************
1460 ** Function bta_jv_port_mgmt_cl_cback
1462 ** Description callback for port mamangement function of rfcomm
1463 ** client connections
1467 *******************************************************************************/
1468 static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle)
1470 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1471 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1475 tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
1477 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle);
1478 if(NULL == p_cb || NULL == p_cb->p_cback)
1481 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d",
1482 code, port_handle, p_cb->handle);
1484 PORT_CheckConnection(port_handle, rem_bda, &lcid);
1486 if(code == PORT_SUCCESS)
1488 evt_data.rfc_open.handle = p_cb->handle;
1489 evt_data.rfc_open.status = BTA_JV_SUCCESS;
1490 bdcpy(evt_data.rfc_open.rem_bda, rem_bda);
1491 p_pcb->state = BTA_JV_ST_CL_OPEN;
1492 p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->user_data);
1496 evt_data.rfc_close.handle = p_cb->handle;
1497 evt_data.rfc_close.status = BTA_JV_FAILURE;
1498 evt_data.rfc_close.port_status = code;
1499 evt_data.rfc_close.async = TRUE;
1500 if (p_pcb->state == BTA_JV_ST_CL_CLOSING)
1502 evt_data.rfc_close.async = FALSE;
1504 //p_pcb->state = BTA_JV_ST_NONE;
1505 //p_pcb->cong = FALSE;
1506 p_cback = p_cb->p_cback;
1507 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->user_data);
1508 //bta_jv_free_rfc_cb(p_cb, p_pcb);
1513 /*******************************************************************************
1515 ** Function bta_jv_port_event_cl_cback
1517 ** Description Callback for RFCOMM client port events
1521 *******************************************************************************/
1522 static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle)
1524 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1525 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1528 APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle);
1529 if (NULL == p_cb || NULL == p_cb->p_cback)
1532 APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback code=x%x port_handle:%d handle:%d",
1533 code, port_handle, p_cb->handle);
1534 if (code & PORT_EV_RXCHAR)
1536 evt_data.data_ind.handle = p_cb->handle;
1537 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, p_pcb->user_data);
1540 if (code & PORT_EV_FC)
1542 p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
1543 evt_data.rfc_cong.cong = p_pcb->cong;
1544 evt_data.rfc_cong.handle = p_cb->handle;
1545 evt_data.rfc_cong.status = BTA_JV_SUCCESS;
1546 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, p_pcb->user_data);
1549 if (code & PORT_EV_TXEMPTY)
1551 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1555 /*******************************************************************************
1557 ** Function bta_jv_rfcomm_connect
1559 ** Description Client initiates an RFCOMM connection
1563 *******************************************************************************/
1564 void bta_jv_rfcomm_connect(tBTA_JV_MSG *p_data)
1567 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
1568 tPORT_STATE port_state;
1570 tBTA_JV_RFC_CB *p_cb = NULL;
1572 tBTA_JV_API_RFCOMM_CONNECT *cc = &(p_data->rfcomm_connect);
1573 tBTA_JV_RFCOMM_CL_INIT evt_data = {0};
1575 /* TODO DM role manager
1576 L2CA_SetDesireRole(cc->role);
1579 sec_id = bta_jv_alloc_sec_id();
1580 evt_data.sec_id = sec_id;
1581 evt_data.status = BTA_JV_SUCCESS;
1583 BTM_SetSecurityLevel(TRUE, "", sec_id, cc->sec_mask, BT_PSM_RFCOMM,
1584 BTM_SEC_PROTO_RFCOMM, cc->remote_scn) == FALSE)
1586 evt_data.status = BTA_JV_FAILURE;
1587 APPL_TRACE_ERROR("sec_id:%d is zero or BTM_SetSecurityLevel failed, remote_scn:%d", sec_id, cc->remote_scn);
1590 if (evt_data.status == BTA_JV_SUCCESS &&
1591 RFCOMM_CreateConnection(UUID_SERVCLASS_SERIAL_PORT, cc->remote_scn, FALSE,
1592 BTA_JV_DEF_RFC_MTU, cc->peer_bd_addr, &handle, bta_jv_port_mgmt_cl_cback) != PORT_SUCCESS)
1594 APPL_TRACE_ERROR("bta_jv_rfcomm_connect, RFCOMM_CreateConnection failed");
1595 evt_data.status = BTA_JV_FAILURE;
1597 if (evt_data.status == BTA_JV_SUCCESS)
1599 p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
1602 p_cb->p_cback = cc->p_cback;
1603 p_cb->sec_id = sec_id;
1605 p_pcb->state = BTA_JV_ST_CL_OPENING;
1606 p_pcb->user_data = cc->user_data;
1607 evt_data.use_co = TRUE;
1609 PORT_SetEventCallback(handle, bta_jv_port_event_cl_cback);
1610 PORT_SetEventMask(handle, event_mask);
1611 PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
1613 PORT_GetState(handle, &port_state);
1615 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
1617 /* coverity[uninit_use_in_call]
1618 FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
1619 PORT_SetState(handle, &port_state);
1621 evt_data.handle = p_cb->handle;
1625 evt_data.status = BTA_JV_FAILURE;
1626 APPL_TRACE_ERROR("run out of rfc control block");
1629 cc->p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, (tBTA_JV *)&evt_data, cc->user_data);
1630 if(evt_data.status == BTA_JV_FAILURE)
1633 bta_jv_free_sec_id(&sec_id);
1635 RFCOMM_RemoveConnection(handle);
1639 static int find_rfc_pcb(void* user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb)
1644 for (i = 0; i < MAX_RFC_PORTS; i++)
1646 UINT32 rfc_handle = bta_jv_cb.port_cb[i].handle & BTA_JV_RFC_HDL_MASK;
1647 rfc_handle &= ~BTA_JV_RFCOMM_MASK;
1648 if (rfc_handle && bta_jv_cb.port_cb[i].user_data == user_data)
1650 *pcb = &bta_jv_cb.port_cb[i];
1651 *cb = &bta_jv_cb.rfc_cb[rfc_handle - 1];
1652 APPL_TRACE_DEBUG("find_rfc_pcb(): FOUND rfc_cb_handle 0x%x, port.jv_handle:"
1653 " 0x%x, state: %d, rfc_cb->handle: 0x%x", rfc_handle, (*pcb)->handle,
1654 (*pcb)->state, (*cb)->handle);
1658 APPL_TRACE_DEBUG("find_rfc_pcb: cannot find rfc_cb from user data: %u", PTR_TO_UINT(user_data));
1662 /*******************************************************************************
1664 ** Function bta_jv_rfcomm_close
1666 ** Description Close an RFCOMM connection
1670 *******************************************************************************/
1671 void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
1673 tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close);
1674 tBTA_JV_RFC_CB *p_cb = NULL;
1675 tBTA_JV_PCB *p_pcb = NULL;
1676 APPL_TRACE_DEBUG("bta_jv_rfcomm_close, rfc handle:%d", cc->handle);
1679 APPL_TRACE_ERROR("bta_jv_rfcomm_close, rfc handle is null");
1683 void* user_data = cc->user_data;
1684 if (!find_rfc_pcb(user_data, &p_cb, &p_pcb))
1686 bta_jv_free_rfc_cb(p_cb, p_pcb);
1687 APPL_TRACE_DEBUG("bta_jv_rfcomm_close: sec id in use:%d, rfc_cb in use:%d",
1688 get_sec_id_used(), get_rfc_cb_used());
1691 /*******************************************************************************
1693 ** Function bta_jv_port_mgmt_sr_cback
1695 ** Description callback for port mamangement function of rfcomm
1696 ** server connections
1700 *******************************************************************************/
1701 static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle)
1703 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1704 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1708 APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:%d, port_handle:%d", code, port_handle);
1709 if (NULL == p_cb || NULL == p_cb->p_cback)
1711 APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p",
1712 p_cb, p_cb ? p_cb->p_cback : NULL);
1715 void *user_data = p_pcb->user_data;
1716 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%d port_handle:0x%x handle:0x%x, p_pcb:%p, user:%d",
1717 code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data);
1719 PORT_CheckConnection(port_handle, rem_bda, &lcid);
1721 if (code == PORT_SUCCESS)
1723 evt_data.rfc_srv_open.handle = p_pcb->handle;
1724 evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
1725 bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
1726 tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb);
1727 if (p_pcb_new_listen)
1729 evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle;
1730 p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
1731 APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess);
1735 APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port");
1739 evt_data.rfc_close.handle = p_cb->handle;
1740 evt_data.rfc_close.status = BTA_JV_FAILURE;
1741 evt_data.rfc_close.async = TRUE;
1742 evt_data.rfc_close.port_status = code;
1743 p_pcb->cong = FALSE;
1745 tBTA_JV_RFCOMM_CBACK *p_cback = p_cb->p_cback;
1746 APPL_TRACE_DEBUG("PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
1747 p_cb->curr_sess, p_cb->max_sess);
1748 if (BTA_JV_ST_SR_CLOSING == p_pcb->state)
1750 evt_data.rfc_close.async = FALSE;
1751 evt_data.rfc_close.status = BTA_JV_SUCCESS;
1753 //p_pcb->state = BTA_JV_ST_NONE;
1754 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
1755 //bta_jv_free_rfc_cb(p_cb, p_pcb);
1757 APPL_TRACE_DEBUG("PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
1758 p_cb->curr_sess, p_cb->max_sess);
1762 /*******************************************************************************
1764 ** Function bta_jv_port_event_sr_cback
1766 ** Description Callback for RFCOMM server port events
1770 *******************************************************************************/
1771 static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle)
1773 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1774 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1777 if (NULL == p_cb || NULL == p_cb->p_cback)
1780 APPL_TRACE_DEBUG( "bta_jv_port_event_sr_cback code=x%x port_handle:%d handle:%d",
1781 code, port_handle, p_cb->handle);
1783 void *user_data = p_pcb->user_data;
1784 if (code & PORT_EV_RXCHAR)
1786 evt_data.data_ind.handle = p_cb->handle;
1787 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, user_data);
1790 if (code & PORT_EV_FC)
1792 p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
1793 evt_data.rfc_cong.cong = p_pcb->cong;
1794 evt_data.rfc_cong.handle = p_cb->handle;
1795 evt_data.rfc_cong.status = BTA_JV_SUCCESS;
1796 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, user_data);
1799 if (code & PORT_EV_TXEMPTY)
1801 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1805 /*******************************************************************************
1807 ** Function bta_jv_add_rfc_port
1809 ** Description add a port for server when the existing posts is open
1811 ** Returns return a pointer to tBTA_JV_PCB just added
1813 *******************************************************************************/
1814 static tBTA_JV_PCB * bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb_open)
1816 UINT8 used = 0, i, listen=0;
1818 tPORT_STATE port_state;
1819 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
1820 tBTA_JV_PCB *p_pcb = NULL;
1821 if (p_cb->max_sess > 1)
1823 for (i=0; i < p_cb->max_sess; i++)
1825 if (p_cb->rfc_hdl[i] != 0)
1827 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1];
1828 if (p_pcb->state == BTA_JV_ST_SR_LISTEN)
1831 if (p_pcb_open == p_pcb)
1833 APPL_TRACE_DEBUG("bta_jv_add_rfc_port, port_handle:%d, change the listen port to open state",
1834 p_pcb->port_handle);
1835 p_pcb->state = BTA_JV_ST_SR_OPEN;
1840 APPL_TRACE_ERROR("bta_jv_add_rfc_port, open pcb not matching listen one,"
1841 "listen count:%d, listen pcb handle:%d, open pcb:%d",
1842 listen, p_pcb->port_handle, p_pcb_open->handle);
1854 APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d",
1855 p_cb->max_sess, used, p_cb->curr_sess, listen, si);
1856 if (used < p_cb->max_sess && listen == 1 && si)
1859 if (RFCOMM_CreateConnection(p_cb->sec_id, p_cb->scn, TRUE,
1860 BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &(p_cb->rfc_hdl[si]), bta_jv_port_mgmt_sr_cback) == PORT_SUCCESS)
1863 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[si] - 1];
1864 p_pcb->state = BTA_JV_ST_SR_LISTEN;
1865 p_pcb->port_handle = p_cb->rfc_hdl[si];
1866 p_pcb->user_data = p_pcb_open->user_data;
1868 PORT_ClearKeepHandleFlag(p_pcb->port_handle);
1869 PORT_SetEventCallback(p_pcb->port_handle, bta_jv_port_event_sr_cback);
1870 PORT_SetDataCOCallback (p_pcb->port_handle, bta_jv_port_data_co_cback);
1871 PORT_SetEventMask(p_pcb->port_handle, event_mask);
1872 PORT_GetState(p_pcb->port_handle, &port_state);
1874 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
1876 PORT_SetState(p_pcb->port_handle, &port_state);
1877 p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si);
1878 APPL_TRACE_DEBUG("bta_jv_add_rfc_port: p_pcb->handle:0x%x, curr_sess:%d",
1879 p_pcb->handle, p_cb->curr_sess);
1883 APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port");
1885 APPL_TRACE_DEBUG("bta_jv_add_rfc_port: sec id in use:%d, rfc_cb in use:%d",
1886 get_sec_id_used(), get_rfc_cb_used());
1890 /*******************************************************************************
1892 ** Function bta_jv_rfcomm_start_server
1894 ** Description waits for an RFCOMM client to connect
1899 *******************************************************************************/
1900 void bta_jv_rfcomm_start_server(tBTA_JV_MSG *p_data)
1903 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
1904 tPORT_STATE port_state;
1906 tBTA_JV_RFC_CB *p_cb = NULL;
1908 tBTA_JV_API_RFCOMM_SERVER *rs = &(p_data->rfcomm_server);
1909 tBTA_JV_RFCOMM_START evt_data = {0};
1910 /* TODO DM role manager
1911 L2CA_SetDesireRole(rs->role);
1913 evt_data.status = BTA_JV_FAILURE;
1914 APPL_TRACE_DEBUG("bta_jv_rfcomm_start_server: sec id in use:%d, rfc_cb in use:%d",
1915 get_sec_id_used(), get_rfc_cb_used());
1919 sec_id = bta_jv_alloc_sec_id();
1922 BTM_SetSecurityLevel(FALSE, "JV PORT", sec_id, rs->sec_mask,
1923 BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, rs->local_scn) == FALSE)
1925 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of sec_id");
1929 if (RFCOMM_CreateConnection(sec_id, rs->local_scn, TRUE,
1930 BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &handle, bta_jv_port_mgmt_sr_cback) != PORT_SUCCESS)
1932 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, RFCOMM_CreateConnection failed");
1937 p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
1940 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of rfc control block");
1944 p_cb->max_sess = rs->max_session;
1945 p_cb->p_cback = rs->p_cback;
1946 p_cb->sec_id = sec_id;
1947 p_cb->scn = rs->local_scn;
1948 p_pcb->state = BTA_JV_ST_SR_LISTEN;
1949 p_pcb->user_data = rs->user_data;
1950 evt_data.status = BTA_JV_SUCCESS;
1951 evt_data.handle = p_cb->handle;
1952 evt_data.sec_id = sec_id;
1953 evt_data.use_co = TRUE;
1955 PORT_ClearKeepHandleFlag(handle);
1956 PORT_SetEventCallback(handle, bta_jv_port_event_sr_cback);
1957 PORT_SetEventMask(handle, event_mask);
1958 PORT_GetState(handle, &port_state);
1960 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
1962 PORT_SetState(handle, &port_state);
1965 rs->p_cback(BTA_JV_RFCOMM_START_EVT, (tBTA_JV *)&evt_data, rs->user_data);
1966 if (evt_data.status == BTA_JV_SUCCESS)
1968 PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
1973 bta_jv_free_sec_id(&sec_id);
1975 RFCOMM_RemoveConnection(handle);
1979 /*******************************************************************************
1981 ** Function bta_jv_rfcomm_stop_server
1983 ** Description stops an RFCOMM server
1987 *******************************************************************************/
1989 void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data)
1991 tBTA_JV_API_RFCOMM_SERVER *ls = &(p_data->rfcomm_server);
1992 tBTA_JV_RFC_CB *p_cb = NULL;
1993 tBTA_JV_PCB *p_pcb = NULL;
1994 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server");
1997 APPL_TRACE_ERROR("bta_jv_rfcomm_stop_server, jv handle is null");
2000 void* user_data = ls->user_data;
2001 if (!find_rfc_pcb(user_data, &p_cb, &p_pcb))
2003 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d",
2004 p_pcb, p_pcb->port_handle);
2005 bta_jv_free_rfc_cb(p_cb, p_pcb);
2006 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d",
2007 get_sec_id_used(), get_rfc_cb_used());
2010 /*******************************************************************************
2012 ** Function bta_jv_rfcomm_read
2014 ** Description Read data from an RFCOMM connection
2018 *******************************************************************************/
2019 void bta_jv_rfcomm_read(tBTA_JV_MSG *p_data)
2021 tBTA_JV_API_RFCOMM_READ *rc = &(p_data->rfcomm_read);
2022 tBTA_JV_RFC_CB *p_cb = rc->p_cb;
2023 tBTA_JV_PCB *p_pcb = rc->p_pcb;
2024 tBTA_JV_RFCOMM_READ evt_data;
2026 evt_data.status = BTA_JV_FAILURE;
2027 evt_data.handle = p_cb->handle;
2028 evt_data.req_id = rc->req_id;
2029 evt_data.p_data = rc->p_data;
2030 if (PORT_ReadData(rc->p_pcb->port_handle, (char *)rc->p_data, rc->len, &evt_data.len) ==
2033 evt_data.status = BTA_JV_SUCCESS;
2036 p_cb->p_cback(BTA_JV_RFCOMM_READ_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2039 /*******************************************************************************
2041 ** Function bta_jv_rfcomm_write
2043 ** Description write data to an RFCOMM connection
2047 *******************************************************************************/
2048 void bta_jv_rfcomm_write(tBTA_JV_MSG *p_data)
2050 tBTA_JV_API_RFCOMM_WRITE *wc = &(p_data->rfcomm_write);
2051 tBTA_JV_RFC_CB *p_cb = wc->p_cb;
2052 tBTA_JV_PCB *p_pcb = wc->p_pcb;
2053 tBTA_JV_RFCOMM_WRITE evt_data;
2055 evt_data.status = BTA_JV_FAILURE;
2056 evt_data.handle = p_cb->handle;
2057 evt_data.req_id = wc->req_id;
2058 evt_data.cong = p_pcb->cong;
2060 bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
2061 if (!evt_data.cong &&
2062 PORT_WriteDataCO(p_pcb->port_handle, &evt_data.len) ==
2065 evt_data.status = BTA_JV_SUCCESS;
2067 //update congestion flag
2068 evt_data.cong = p_pcb->cong;
2071 p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2075 APPL_TRACE_ERROR("bta_jv_rfcomm_write :: WARNING ! No JV callback set");
2079 /*******************************************************************************
2081 ** Function bta_jv_set_pm_profile
2083 ** Description Set or free power mode profile for a JV application
2087 *******************************************************************************/
2088 void bta_jv_set_pm_profile(tBTA_JV_MSG *p_data)
2090 tBTA_JV_STATUS status;
2091 tBTA_JV_PM_CB *p_cb;
2093 APPL_TRACE_API("bta_jv_set_pm_profile(handle: 0x%x, app_id: %d, init_st: %d)",
2094 p_data->set_pm.handle, p_data->set_pm.app_id, p_data->set_pm.init_st);
2096 /* clear PM control block */
2097 if (p_data->set_pm.app_id == BTA_JV_PM_ID_CLEAR)
2099 status = bta_jv_free_set_pm_profile_cb(p_data->set_pm.handle);
2101 if (status != BTA_JV_SUCCESS)
2103 APPL_TRACE_WARNING("bta_jv_set_pm_profile() free pm cb failed: reason %d",
2107 else /* set PM control block */
2109 p_cb = bta_jv_alloc_set_pm_profile_cb(p_data->set_pm.handle,
2110 p_data->set_pm.app_id);
2113 bta_jv_pm_state_change(p_cb, p_data->set_pm.init_st);
2115 APPL_TRACE_WARNING("bta_jv_alloc_set_pm_profile_cb() failed");
2119 /*******************************************************************************
2121 ** Function bta_jv_change_pm_state
2123 ** Description change jv pm connect state, used internally
2127 *******************************************************************************/
2128 void bta_jv_change_pm_state(tBTA_JV_MSG *p_data)
2130 tBTA_JV_API_PM_STATE_CHANGE *p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)p_data;
2133 bta_jv_pm_state_change(p_msg->p_cb, p_msg->state);
2137 /*******************************************************************************
2139 ** Function bta_jv_set_pm_conn_state
2141 ** Description Send pm event state change to jv state machine to serialize jv pm changes
2142 ** in relation to other jv messages. internal API use mainly.
2144 ** Params: p_cb: jv pm control block, NULL pointer returns failure
2145 ** new_state: new PM connections state, setting is forced by action function
2147 ** Returns BTA_JV_SUCCESS, BTA_JV_FAILURE (buffer allocation, or NULL ptr!)
2149 *******************************************************************************/
2150 tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE
2153 tBTA_JV_STATUS status = BTA_JV_FAILURE;
2154 tBTA_JV_API_PM_STATE_CHANGE *p_msg;
2159 APPL_TRACE_API("bta_jv_set_pm_conn_state(handle:0x%x, state: %d)", p_cb->handle,
2161 if ((p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)GKI_getbuf(
2162 sizeof(tBTA_JV_API_PM_STATE_CHANGE))) != NULL)
2164 p_msg->hdr.event = BTA_JV_API_PM_STATE_CHANGE_EVT;
2166 p_msg->state = new_st;
2167 bta_sys_sendmsg(p_msg);
2168 status = BTA_JV_SUCCESS;
2173 /*******************************************************************************
2175 ** Function bta_jv_pm_conn_busy
2177 ** Description set pm connection busy state (input param safe)
2179 ** Params p_cb: pm control block of jv connection
2183 *******************************************************************************/
2184 static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB *p_cb)
2186 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST == p_cb->state))
2187 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_BUSY);
2190 /*******************************************************************************
2192 ** Function bta_jv_pm_conn_busy
2194 ** Description set pm connection busy state (input param safe)
2196 ** Params p_cb: pm control block of jv connection
2200 *******************************************************************************/
2201 static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb)
2203 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST != p_cb->state))
2204 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_IDLE);
2207 /*******************************************************************************
2209 ** Function bta_jv_pm_state_change
2211 ** Description Notify power manager there is state change
2213 ** Params p_cb: must be NONE NULL
2217 *******************************************************************************/
2218 static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state)
2220 APPL_TRACE_API("bta_jv_pm_state_change(p_cb: 0x%x, handle: 0x%x, busy/idle_state: %d"
2221 ", app_id: %d, conn_state: %d)", p_cb, p_cb->handle, p_cb->state,
2222 p_cb->app_id, state);
2226 case BTA_JV_CONN_OPEN:
2227 bta_sys_conn_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2230 case BTA_JV_CONN_CLOSE:
2231 bta_sys_conn_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2234 case BTA_JV_APP_OPEN:
2235 bta_sys_app_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2238 case BTA_JV_APP_CLOSE:
2239 bta_sys_app_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2242 case BTA_JV_SCO_OPEN:
2243 bta_sys_sco_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2246 case BTA_JV_SCO_CLOSE:
2247 bta_sys_sco_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2250 case BTA_JV_CONN_IDLE:
2251 p_cb->state = BTA_JV_PM_IDLE_ST;
2252 bta_sys_idle(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2255 case BTA_JV_CONN_BUSY:
2256 p_cb->state = BTA_JV_PM_BUSY_ST;
2257 bta_sys_busy(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2261 APPL_TRACE_WARNING("bta_jv_pm_state_change(state: %d): Invalid state", state);
2265 /**********************************************************************************************/
2268 static struct fc_channel *fcchan_get(uint16_t chan, char create)
2270 struct fc_channel *t = fc_channels;
2271 static tL2CAP_FIXED_CHNL_REG fcr = {
2272 .pL2CA_FixedConn_Cb = fcchan_conn_chng_cbk,
2273 .pL2CA_FixedData_Cb = fcchan_data_cbk,
2274 .default_idle_tout = 0xffff,
2275 .fixed_chnl_opts = {
2276 .mode = L2CAP_FCR_BASIC_MODE,
2277 .max_transmit = 0xFF,
2278 .rtrans_tout = 2000,
2285 while (t && t->chan != chan)
2291 return NULL; /* we cannot alloc a struct if not asked to */
2293 t = osi_calloc(sizeof(*t));
2299 if (!L2CA_RegisterFixedChannel(chan, &fcr)) {
2305 t->next = fc_channels;
2311 /* pass NULL to find servers */
2312 static struct fc_client *fcclient_find_by_addr(struct fc_client *start, BD_ADDR addr)
2314 struct fc_client *t = start;
2318 /* match client if have addr */
2319 if (addr && !memcmp(addr, &t->remote_addr, sizeof(t->remote_addr)))
2322 /* match server if do not have addr */
2323 if (!addr && t->server)
2326 t = t->next_all_list;
2332 static struct fc_client *fcclient_find_by_id(uint32_t id)
2334 struct fc_client *t = fc_clients;
2336 while (t && t->id != id)
2337 t = t->next_all_list;
2342 static struct fc_client *fcclient_alloc(uint16_t chan, char server, const uint8_t *sec_id_to_use)
2344 struct fc_channel *fc = fcchan_get(chan, TRUE);
2345 struct fc_client *t;
2351 if (fc->has_server && server)
2352 return NULL; /* no way to have multiple servers on same channel */
2355 sec_id = *sec_id_to_use;
2357 sec_id = bta_jv_alloc_sec_id();
2359 t = osi_calloc(sizeof(*t));
2361 //allocate it a unique ID
2363 t->id = ++fc_next_id;
2364 } while (!t->id || fcclient_find_by_id(t->id));
2366 //populate some params
2373 //link it in to global list
2374 t->next_all_list = fc_clients;
2377 //link it in to channel list
2378 t->next_chan_list = fc->clients;
2381 //update channel if needed
2383 fc->has_server = TRUE;
2384 } else if (!sec_id_to_use)
2385 bta_jv_free_sec_id(&sec_id);
2390 static void fcclient_free(struct fc_client *fc)
2392 struct fc_client *t = fc_clients;
2393 struct fc_channel *tc = fcchan_get(fc->chan, FALSE);
2395 //remove from global list
2396 while (t && t->next_all_list != fc)
2397 t = t->next_all_list;
2399 if (!t && fc != fc_clients)
2400 return; /* prevent double-free */
2403 t->next_all_list = fc->next_all_list;
2405 fc_clients = fc->next_all_list;
2407 //remove from channel list
2411 while (t && t->next_chan_list != fc)
2412 t = t->next_chan_list;
2415 t->next_chan_list = fc->next_chan_list;
2417 tc->clients = fc->next_chan_list;
2419 //if was server then channel no longer has a server
2421 tc->has_server = FALSE;
2425 bta_jv_free_sec_id(&fc->sec_id);
2430 static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport)
2434 struct fc_channel *tc;
2435 struct fc_client *t = NULL, *new_conn;
2436 tBTA_JV_L2CAP_CBACK *p_cback = NULL;
2437 char call_init = FALSE;
2438 void *user_data = NULL;
2441 tc = fcchan_get(chan, FALSE);
2443 t = fcclient_find_by_addr(tc->clients, bd_addr); // try to find an open socked for that addr
2445 p_cback = t->p_cback;
2446 user_data = t->user_data;
2448 t = fcclient_find_by_addr(tc->clients, NULL); // try to find a listening socked for that channel
2450 //found: create a normal connection socket and assign the connection to it
2451 new_conn = fcclient_alloc(chan, FALSE, &t->sec_id);
2454 memcpy(&new_conn->remote_addr, bd_addr, sizeof(new_conn->remote_addr));
2455 new_conn->p_cback = NULL; //for now
2456 new_conn->init_called = TRUE; /*nop need to do it again */
2458 p_cback = t->p_cback;
2459 user_data = t->user_data;
2472 if (!t->init_called) {
2475 t->init_called = TRUE;
2477 init_evt.l2c_cl_init.handle = t->id;
2478 init_evt.l2c_cl_init.status = BTA_JV_SUCCESS;
2479 init_evt.l2c_cl_init.sec_id = t->sec_id;
2482 open_evt.l2c_open.handle = t->id;
2483 open_evt.l2c_open.tx_mtu = 23; /* 23, why not ?*/
2484 memcpy(&open_evt.l2c_le_open.rem_bda, &t->remote_addr, sizeof(open_evt.l2c_le_open.rem_bda));
2485 open_evt.l2c_le_open.p_p_cback = (void**)&t->p_cback;
2486 open_evt.l2c_le_open.p_user_data = &t->user_data;
2487 open_evt.l2c_le_open.status = BTA_JV_SUCCESS;
2490 open_evt.l2c_open.status = BTA_JV_SUCCESS;
2493 open_evt.l2c_open.status = BTA_JV_FAILURE;
2498 p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &init_evt, user_data);
2500 //call this with lock taken so socket does not disappear from under us */
2502 p_cback(BTA_JV_L2CAP_OPEN_EVT, &open_evt, user_data);
2503 if (!t->p_cback) /* no callback set, means they do not want this one... */
2508 static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
2511 struct fc_channel *tc;
2512 struct fc_client *t = NULL;
2513 tBTA_JV_L2CAP_CBACK *sock_cback = NULL;
2514 void *sock_user_data;
2516 tc = fcchan_get(chan, FALSE);
2518 t = fcclient_find_by_addr(tc->clients, bd_addr); // try to find an open socked for that addr and channel
2520 //no socket -> drop it
2525 sock_cback = t->p_cback;
2526 sock_user_data = t->user_data;
2527 evt_data.le_data_ind.handle = t->id;
2528 evt_data.le_data_ind.p_buf = p_buf;
2531 sock_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, sock_user_data);
2535 /*******************************************************************************
2537 ** Function bta_jv_l2cap_connect_le
2539 ** Description makes an le l2cap client connection
2543 *******************************************************************************/
2544 void bta_jv_l2cap_connect_le(tBTA_JV_MSG *p_data)
2546 tBTA_JV_API_L2CAP_CONNECT *cc = &(p_data->l2cap_connect);
2549 char call_init_f = TRUE;
2550 struct fc_client *t;
2552 evt.l2c_cl_init.handle = GAP_INVALID_HANDLE;
2553 evt.l2c_cl_init.status = BTA_JV_FAILURE;
2555 t = fcclient_alloc(cc->remote_chan, FALSE, NULL);
2557 cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, cc->user_data);
2561 t->p_cback = cc->p_cback;
2562 t->user_data = cc->user_data;
2563 memcpy(&t->remote_addr, &cc->peer_bd_addr, sizeof(t->remote_addr));
2565 t->init_called = FALSE;
2567 if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr)) {
2569 evt.l2c_cl_init.status = BTA_JV_SUCCESS;
2570 evt.l2c_cl_init.handle = id;
2573 //it could have been deleted/moved from under us, so re-find it */
2574 t = fcclient_find_by_id(id);
2576 if (evt.l2c_cl_init.status == BTA_JV_SUCCESS)
2577 call_init_f = !t->init_called;
2582 cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, cc->user_data);
2583 t->init_called = TRUE;
2587 /*******************************************************************************
2589 ** Function bta_jv_l2cap_stop_server_le
2591 ** Description stops an LE L2CAP server
2595 *******************************************************************************/
2596 void bta_jv_l2cap_stop_server_le(tBTA_JV_MSG *p_data)
2599 tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
2600 tBTA_JV_L2CAP_CBACK *p_cback = NULL;
2601 struct fc_channel *fcchan;
2602 struct fc_client *fcclient;
2605 evt.l2c_close.status = BTA_JV_FAILURE;
2606 evt.l2c_close.async = FALSE;
2607 evt.l2c_close.handle = GAP_INVALID_HANDLE;
2609 fcchan = fcchan_get(ls->local_chan, FALSE);
2611 while((fcclient = fcchan->clients)) {
2612 p_cback = fcclient->p_cback;
2613 user_data = fcclient->user_data;
2615 evt.l2c_close.handle = fcclient->id;
2616 evt.l2c_close.status = BTA_JV_SUCCESS;
2617 evt.l2c_close.async = FALSE;
2619 fcclient_free(fcclient);
2622 p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt, user_data);
2627 /*******************************************************************************
2629 ** Function bta_jv_l2cap_start_server_le
2631 ** Description starts an LE L2CAP server
2635 *******************************************************************************/
2636 void bta_jv_l2cap_start_server_le(tBTA_JV_MSG *p_data)
2638 tBTA_JV_API_L2CAP_SERVER *ss = &(p_data->l2cap_server);
2639 tBTA_JV_L2CAP_START evt_data;
2640 struct fc_client *t;
2642 evt_data.handle = GAP_INVALID_HANDLE;
2643 evt_data.status = BTA_JV_FAILURE;
2646 t = fcclient_alloc(ss->local_chan, TRUE, NULL);
2650 t->p_cback = ss->p_cback;
2651 t->user_data = ss->user_data;
2653 //if we got here, we're registered...
2654 evt_data.status = BTA_JV_SUCCESS;
2655 evt_data.handle = t->id;
2656 evt_data.sec_id = t->sec_id;
2659 ss->p_cback(BTA_JV_L2CAP_START_EVT, (tBTA_JV *)&evt_data, ss->user_data);
2662 /*******************************************************************************
2664 ** Function bta_jv_l2cap_close_fixed
2666 ** Description close a fixed channel connection. calls no callbacks. idempotent
2670 *******************************************************************************/
2671 extern void bta_jv_l2cap_close_fixed (tBTA_JV_MSG *p_data)
2673 tBTA_JV_API_L2CAP_CLOSE *cc = &(p_data->l2cap_close);
2674 struct fc_client *t;
2676 t = fcclient_find_by_id(cc->handle);