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>
33 #include "bta_jv_api.h"
34 #include "bta_jv_int.h"
35 #include "bta_jv_co.h"
48 #define HDL2CB(handle) \
49 UINT32 __hi = ((handle) & BTA_JV_RFC_HDL_MASK) - 1; \
50 UINT32 __si = BTA_JV_RFC_HDL_TO_SIDX(handle); \
51 tBTA_JV_RFC_CB *p_cb = &bta_jv_cb.rfc_cb[__hi]; \
52 tBTA_JV_PCB *p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[__si] - 1]
54 extern void uuid_to_string(bt_uuid_t *p_uuid, char *str);
55 static inline void logu(const char* title, const uint8_t * p_uuid)
58 uuid_to_string((bt_uuid_t*)p_uuid, uuids);
59 APPL_TRACE_DEBUG("%s: %s", title, uuids);
63 static tBTA_JV_PCB * bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb_open);
64 static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(UINT32 jv_handle);
65 static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB *p_cb);
66 static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb);
67 static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state);
68 tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE
71 /*******************************************************************************
73 ** Function bta_jv_get_local_device_addr_cback
75 ** Description Callback from btm after local bdaddr is read
79 *******************************************************************************/
80 static void bta_jv_get_local_device_addr_cback(BD_ADDR bd_addr)
82 if(bta_jv_cb.p_dm_cback)
83 bta_jv_cb.p_dm_cback(BTA_JV_LOCAL_ADDR_EVT, (tBTA_JV *)bd_addr, 0);
86 /*******************************************************************************
88 ** Function bta_jv_get_remote_device_name_cback
90 ** Description Callback from btm after remote name is read
94 *******************************************************************************/
95 static void bta_jv_get_remote_device_name_cback(tBTM_REMOTE_DEV_NAME *p_name)
98 evt_data.p_name = p_name->remote_bd_name;
99 if(bta_jv_cb.p_dm_cback)
100 bta_jv_cb.p_dm_cback(BTA_JV_REMOTE_NAME_EVT, &evt_data, 0);
103 /*******************************************************************************
105 ** Function bta_jv_alloc_sec_id
107 ** Description allocate a security id
111 *******************************************************************************/
112 UINT8 bta_jv_alloc_sec_id(void)
116 for(i=0; i<BTA_JV_NUM_SERVICE_ID; i++)
118 if(0 == bta_jv_cb.sec_id[i])
120 bta_jv_cb.sec_id[i] = BTA_JV_FIRST_SERVICE_ID + i;
121 ret = bta_jv_cb.sec_id[i];
128 static int get_sec_id_used(void)
132 for(i=0; i<BTA_JV_NUM_SERVICE_ID; i++)
134 if(bta_jv_cb.sec_id[i])
137 if (used == BTA_JV_NUM_SERVICE_ID)
138 APPL_TRACE_ERROR("get_sec_id_used, sec id exceeds the limit:%d",
139 BTA_JV_NUM_SERVICE_ID);
142 static int get_rfc_cb_used(void)
146 for(i=0; i<BTA_JV_MAX_RFC_CONN; i++)
148 if(bta_jv_cb.rfc_cb[i].handle )
151 if (used == BTA_JV_MAX_RFC_CONN)
152 APPL_TRACE_ERROR("get_sec_id_used, rfc ctrl block exceeds the limit:%d",
153 BTA_JV_MAX_RFC_CONN);
157 /*******************************************************************************
159 ** Function bta_jv_free_sec_id
161 ** Description free the given security id
165 *******************************************************************************/
166 static void bta_jv_free_sec_id(UINT8 *p_sec_id)
168 UINT8 sec_id = *p_sec_id;
170 if(sec_id >= BTA_JV_FIRST_SERVICE_ID && sec_id <= BTA_JV_LAST_SERVICE_ID)
172 BTM_SecClrService(sec_id);
173 bta_jv_cb.sec_id[sec_id - BTA_JV_FIRST_SERVICE_ID] = 0;
177 /*******************************************************************************
179 ** Function bta_jv_alloc_rfc_cb
181 ** Description allocate a control block for the given port handle
185 *******************************************************************************/
186 tBTA_JV_RFC_CB * bta_jv_alloc_rfc_cb(UINT16 port_handle, tBTA_JV_PCB **pp_pcb)
188 tBTA_JV_RFC_CB *p_cb = NULL;
191 for(i=0; i<BTA_JV_MAX_RFC_CONN; i++)
193 if (0 == bta_jv_cb.rfc_cb[i].handle )
195 p_cb = &bta_jv_cb.rfc_cb[i];
196 /* mask handle to distinguish it with L2CAP handle */
197 p_cb->handle = (i + 1) | BTA_JV_RFCOMM_MASK;
201 for (j = 0; j < BTA_JV_MAX_RFC_SR_SESSION; j++)
202 p_cb->rfc_hdl[j] = 0;
203 p_cb->rfc_hdl[0] = port_handle;
204 APPL_TRACE_DEBUG( "bta_jv_alloc_rfc_cb port_handle:%d handle:0x%2x",
205 port_handle, p_cb->handle);
207 p_pcb = &bta_jv_cb.port_cb[port_handle - 1];
208 p_pcb->handle = p_cb->handle;
209 p_pcb->port_handle = port_handle;
210 p_pcb->p_pm_cb = NULL;
217 APPL_TRACE_ERROR( "bta_jv_alloc_rfc_cb: port_handle:%d, ctrl block exceeds "
218 "limit:%d", port_handle, BTA_JV_MAX_RFC_CONN);
223 /*******************************************************************************
225 ** Function bta_jv_rfc_port_to_pcb
227 ** Description find the port control block associated with the given port handle
231 *******************************************************************************/
232 tBTA_JV_PCB * bta_jv_rfc_port_to_pcb(UINT16 port_handle)
234 tBTA_JV_PCB *p_pcb = NULL;
236 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS)
237 && bta_jv_cb.port_cb[port_handle - 1].handle)
239 p_pcb = &bta_jv_cb.port_cb[port_handle - 1];
245 /*******************************************************************************
247 ** Function bta_jv_rfc_port_to_cb
249 ** Description find the RFCOMM control block associated with the given port handle
253 *******************************************************************************/
254 tBTA_JV_RFC_CB * bta_jv_rfc_port_to_cb(UINT16 port_handle)
256 tBTA_JV_RFC_CB *p_cb = NULL;
259 if ((port_handle > 0) && (port_handle <= MAX_RFC_PORTS)
260 && bta_jv_cb.port_cb[port_handle - 1].handle)
262 handle = bta_jv_cb.port_cb[port_handle - 1].handle;
263 handle &= BTA_JV_RFC_HDL_MASK;
264 handle &= ~BTA_JV_RFCOMM_MASK;
266 p_cb = &bta_jv_cb.rfc_cb[handle - 1];
270 APPL_TRACE_WARNING("bta_jv_rfc_port_to_cb(port_handle:0x%x):jv handle:0x%x not"
271 " FOUND", port_handle, bta_jv_cb.port_cb[port_handle - 1].handle);
276 static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb)
278 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
279 BOOLEAN remove_server = FALSE;
280 int close_pending = 0;
284 APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null");
285 return BTA_JV_FAILURE;
287 APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: max_sess:%d, curr_sess:%d, p_pcb:%p, user:"
288 "%p, state:%d, jv handle: 0x%x" ,p_cb->max_sess, p_cb->curr_sess, p_pcb,
289 p_pcb->user_data, p_pcb->state, p_pcb->handle);
291 if (p_cb->curr_sess <= 0)
292 return BTA_JV_SUCCESS;
294 switch (p_pcb->state)
296 case BTA_JV_ST_CL_CLOSING:
297 case BTA_JV_ST_SR_CLOSING:
298 APPL_TRACE_WARNING("bta_jv_free_sr_rfc_cb: return on closing, port state:%d, "
299 "scn:%d, p_pcb:%p, user_data:%p", p_pcb->state, p_cb->scn, p_pcb,
301 status = BTA_JV_FAILURE;
303 case BTA_JV_ST_CL_OPEN:
304 case BTA_JV_ST_CL_OPENING:
305 APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: state: %d, scn:%d,"
306 " user_data:%p", p_pcb->state, p_cb->scn, p_pcb->user_data);
307 p_pcb->state = BTA_JV_ST_CL_CLOSING;
309 case BTA_JV_ST_SR_LISTEN:
310 p_pcb->state = BTA_JV_ST_SR_CLOSING;
311 remove_server = TRUE;
312 APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: state: BTA_JV_ST_SR_LISTEN, scn:%d,"
313 " user_data:%p", p_cb->scn, p_pcb->user_data);
315 case BTA_JV_ST_SR_OPEN:
316 p_pcb->state = BTA_JV_ST_SR_CLOSING;
317 APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: state: BTA_JV_ST_SR_OPEN, scn:%d,"
318 " user_data:%p", p_cb->scn, p_pcb->user_data);
321 APPL_TRACE_WARNING("bta_jv_free_sr_rfc_cb():failed, ignore port state:%d, scn:"
322 "%d, p_pcb:%p, jv handle: 0x%x, port_handle: %d, user_data:%p",
323 p_pcb->state, p_cb->scn, p_pcb, p_pcb->handle, p_pcb->port_handle,
325 status = BTA_JV_FAILURE;
328 if (BTA_JV_SUCCESS == status)
333 port_status = RFCOMM_RemoveConnection(p_pcb->port_handle);
335 port_status = RFCOMM_RemoveServer(p_pcb->port_handle);
336 if (port_status != PORT_SUCCESS)
338 status = BTA_JV_FAILURE;
339 APPL_TRACE_WARNING("bta_jv_free_rfc_cb(jv handle: 0x%x, state %d)::"
340 "port_status: %d, port_handle: %d, close_pending: %d:Remove",
341 p_pcb->handle, p_pcb->state, port_status, p_pcb->port_handle,
347 p_pcb->port_handle = 0;
348 p_pcb->state = BTA_JV_ST_NONE;
349 bta_jv_free_set_pm_profile_cb(p_pcb->handle);
351 //Initialize congestion flags
353 p_pcb->user_data = 0;
354 int si = BTA_JV_RFC_HDL_TO_SIDX(p_pcb->handle);
355 if (0 <= si && si < BTA_JV_MAX_RFC_SR_SESSION)
356 p_cb->rfc_hdl[si] = 0;
359 if (p_cb->curr_sess == 0)
362 bta_jv_free_sec_id(&p_cb->sec_id);
363 p_cb->p_cback = NULL;
365 p_cb->curr_sess = -1;
371 /*******************************************************************************
373 ** Function bta_jv_free_l2c_cb
375 ** Description free the given L2CAP control block
379 *******************************************************************************/
380 tBTA_JV_STATUS bta_jv_free_l2c_cb(tBTA_JV_L2C_CB *p_cb)
384 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
386 if(BTA_JV_ST_NONE != p_cb->state)
388 #if SDP_FOR_JV_INCLUDED == TRUE
389 if(BTA_JV_L2C_FOR_SDP_HDL == p_cb->handle)
391 bta_jv_cb.sdp_data_size = 0;
392 if(SDP_ConnClose(bta_jv_cb.sdp_for_jv))
394 bta_jv_cb.sdp_for_jv = 0;
397 status = BTA_JV_FAILURE;
402 bta_jv_free_set_pm_profile_cb((UINT32)p_cb->handle);
403 if (GAP_ConnClose(p_cb->handle) != BT_PASS)
404 status = BTA_JV_FAILURE;
408 p_cb->state = BTA_JV_ST_NONE;
409 bta_jv_free_sec_id(&p_cb->sec_id);
410 p_cb->p_cback = NULL;
416 /*******************************************************************************
418 ** Function bta_jv_clear_pm_cb
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
424 ** WARNING: Make sure to clear pointer form port or l2c to this control block too!
426 *******************************************************************************/
427 static void bta_jv_clear_pm_cb(tBTA_JV_PM_CB *p_pm_cb, BOOLEAN close_conn)
429 /* needs to be called if registered with bta pm, otherwise we may run out of dm pm slots! */
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);
438 /*******************************************************************************
440 ** Function bta_jv_free_set_pm_profile_cb
442 ** Description free pm profile control block
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
447 *******************************************************************************/
448 static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(UINT32 jv_handle)
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;
454 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++)
457 if ((bta_jv_cb.pm_cb[i].state != BTA_JV_PM_FREE_ST) &&
458 (jv_handle == bta_jv_cb.pm_cb[i].handle))
460 for (j = 0; j < BTA_JV_PM_MAX_NUM; j++)
462 if (bdcmp(bta_jv_cb.pm_cb[j].peer_bd_addr, bta_jv_cb.pm_cb[i].peer_bd_addr) == 0)
464 if (bta_jv_cb.pm_cb[j].app_id == bta_jv_cb.pm_cb[i].app_id)
468 APPL_TRACE_API("bta_jv_free_set_pm_profile_cb(jv_handle: 0x%2x), idx: %d, "
469 "app_id: 0x%x", jv_handle, i, bta_jv_cb.pm_cb[i].app_id);
470 APPL_TRACE_API("bta_jv_free_set_pm_profile_cb, bd_counter = %d, "
471 "appid_counter = %d", bd_counter, appid_counter);
474 bta_jv_pm_conn_idle(&bta_jv_cb.pm_cb[i]);
477 if (bd_counter <= 1 || (appid_counter <= 1))
479 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], TRUE);
483 bta_jv_clear_pm_cb(&bta_jv_cb.pm_cb[i], FALSE);
486 if (BTA_JV_RFCOMM_MASK & jv_handle)
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])
493 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(bta_jv_cb.rfc_cb[hi].rfc_hdl[si]);
496 if (NULL == p_pcb->p_pm_cb)
497 APPL_TRACE_WARNING("bta_jv_free_set_pm_profile_cb(jv_handle:"
498 " 0x%x):port_handle: 0x%x, p_pm_cb: %d: no link to "
499 "pm_cb?", jv_handle, p_pcb->port_handle, i);
500 p_cb = &p_pcb->p_pm_cb;
506 if (jv_handle < BTA_JV_MAX_L2C_CONN)
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("bta_jv_free_set_pm_profile_cb(jv_handle: "
511 "0x%x): p_pm_cb: %d: no link to pm_cb?", jv_handle, i);
512 p_cb = &p_l2c_cb->p_pm_cb;
518 status = BTA_JV_SUCCESS;
525 /*******************************************************************************
527 ** Function bta_jv_alloc_set_pm_profile_cb
529 ** Description set PM profile control block
531 ** Returns pointer to allocated cb or NULL in case of failure
533 *******************************************************************************/
534 static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_PM_ID app_id)
536 BOOLEAN bRfcHandle = (jv_handle & BTA_JV_RFCOMM_MASK) != 0;
537 BD_ADDR peer_bd_addr;
539 tBTA_JV_PM_CB **pp_cb;
541 for (i = 0; i < BTA_JV_PM_MAX_NUM; i++)
544 if (bta_jv_cb.pm_cb[i].state == BTA_JV_PM_FREE_ST)
546 /* rfc handle bd addr retrieval requires core stack handle */
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++)
553 if (jv_handle == bta_jv_cb.port_cb[j].handle)
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;
565 /* use jv handle for l2cap bd address retrieval */
566 for (j = 0; j < BTA_JV_MAX_L2C_CONN; j++)
568 if (jv_handle == bta_jv_cb.l2c_cb[j].handle)
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);
575 i = BTA_JV_PM_MAX_NUM;
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);
587 if ((i != BTA_JV_PM_MAX_NUM) && (NULL != pp_cb))
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];
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;
601 /*******************************************************************************
603 ** Function bta_jv_alloc_sdp_id
605 ** Description allocate a SDP id for the given SDP record handle
609 *******************************************************************************/
610 UINT32 bta_jv_alloc_sdp_id(UINT32 sdp_handle)
615 /* find a free entry */
616 for (j = 0; j < BTA_JV_MAX_SDP_REC; j++)
618 if (bta_jv_cb.sdp_handle[j] == 0)
620 bta_jv_cb.sdp_handle[j] = sdp_handle;
621 id = (UINT32)(j + 1);
625 /* the SDP record handle reported is the (index + 1) to control block */
629 /*******************************************************************************
631 ** Function bta_jv_free_sdp_id
633 ** Description free the sdp id
637 *******************************************************************************/
638 void bta_jv_free_sdp_id(UINT32 sdp_id)
640 if(sdp_id > 0 && sdp_id <= BTA_JV_MAX_SDP_REC)
642 bta_jv_cb.sdp_handle[sdp_id - 1] = 0;
646 /*******************************************************************************
648 ** Function bta_jv_get_sdp_handle
650 ** Description find the SDP handle associated with the given sdp id
654 *******************************************************************************/
655 UINT32 bta_jv_get_sdp_handle(UINT32 sdp_id)
657 UINT32 sdp_handle = 0;
659 if(sdp_id > 0 && sdp_id <= BTA_JV_MAX_SDP_REC)
661 sdp_handle = bta_jv_cb.sdp_handle[sdp_id - 1];
666 /*******************************************************************************
668 ** Function bta_jv_check_psm
670 ** Description for now use only the legal PSM per JSR82 spec
672 ** Returns TRUE, if allowed
674 *******************************************************************************/
675 BOOLEAN bta_jv_check_psm(UINT16 psm)
679 if(L2C_IS_VALID_PSM(psm) )
683 /* see if this is defined by spec */
686 case SDP_PSM: /* 1 */
687 case BT_PSM_RFCOMM: /* 3 */
688 /* do not allow java app to use these 2 PSMs */
691 case TCS_PSM_INTERCOM: /* 5 */
692 case TCS_PSM_CORDLESS: /* 7 */
693 if( FALSE == bta_sys_is_register(BTA_ID_CT) &&
694 FALSE == bta_sys_is_register(BTA_ID_CG) )
698 case BT_PSM_BNEP: /* F */
699 if(FALSE == bta_sys_is_register(BTA_ID_PAN))
703 case HID_PSM_CONTROL: /* 0x11 */
704 case HID_PSM_INTERRUPT: /* 0x13 */
705 //FIX: allow HID Device and HID Host to coexist
706 if( FALSE == bta_sys_is_register(BTA_ID_HD) ||
707 FALSE == bta_sys_is_register(BTA_ID_HH) )
711 case AVCT_PSM: /* 0x17 */
712 case AVDT_PSM: /* 0x19 */
713 if ((FALSE == bta_sys_is_register(BTA_ID_AV)) &&
714 (FALSE == bta_sys_is_register(BTA_ID_AVK)))
730 /*******************************************************************************
732 ** Function bta_jv_enable
734 ** Description Initialises the JAVA I/F
738 *******************************************************************************/
739 void bta_jv_enable(tBTA_JV_MSG *p_data)
741 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
742 bta_jv_cb.p_dm_cback = p_data->enable.p_cback;
743 bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, (tBTA_JV *)&status, 0);
746 /*******************************************************************************
748 ** Function bta_jv_disable
750 ** Description Disables the BT device manager
751 ** free the resources used by java
755 *******************************************************************************/
756 void bta_jv_disable (tBTA_JV_MSG *p_data)
760 APPL_TRACE_ERROR("bta_jv_disable not used");
764 bta_jv_cb.p_dm_cback = NULL;
765 /* delete the SDP records created by java apps */
766 for(i=0; i<BTA_JV_MAX_SDP_REC; i++)
768 if(bta_jv_cb.sdp_handle[i])
770 APPL_TRACE_DEBUG( "delete SDP record: %d", bta_jv_cb.sdp_handle[i]);
771 SDP_DeleteRecord(bta_jv_cb.sdp_handle[i]);
772 bta_jv_cb.sdp_handle[i] = 0;
776 /* free the SCNs allocated by java apps */
777 for(i=0; i<BTA_JV_MAX_SCN; i++)
781 APPL_TRACE_DEBUG( "free scn: %d", (i+1));
782 BTM_FreeSCN((UINT8)(i+1));
783 bta_jv_cb.scn[i] = FALSE;
787 /* disconnect L2CAP connections */
788 for(i=0; i<BTA_JV_MAX_L2C_CONN; i++)
790 bta_jv_free_l2c_cb(&bta_jv_cb.l2c_cb[i]);
793 /* disconnect RFCOMM connections */
794 for(i=0; i<BTA_JV_MAX_RFC_CONN; i++)
796 bta_jv_free_rfc_cb(&bta_jv_cb.rfc_cb[i]);
799 /* free the service records allocated by java apps */
800 for(i=0; i<BTA_JV_NUM_SERVICE_ID; i++)
802 if(bta_jv_cb.sec_id[i])
804 BTM_SecClrService(bta_jv_cb.sec_id[i]);
805 bta_jv_cb.sec_id[i] = 0;
811 /*******************************************************************************
813 ** Function bta_jv_set_discoverability
815 ** Description Sets discoverability
819 *******************************************************************************/
820 void bta_jv_set_discoverability (tBTA_JV_MSG *p_data)
824 evt_data.set_discover.status = BTA_JV_FAILURE;
825 /* initialize the default value for the event as the current mode */
826 evt_data.set_discover.disc_mode = BTM_ReadDiscoverability(NULL, NULL);
828 if(BTM_SUCCESS == BTM_SetDiscoverability((UINT8)p_data->set_discoverability.disc_mode, 0, 0))
830 evt_data.set_discover.status = BTA_JV_SUCCESS;
831 /* update the mode, after BTM_SetDiscoverability() is successful */
832 evt_data.set_discover.disc_mode = p_data->set_discoverability.disc_mode;
835 if(bta_jv_cb.p_dm_cback)
836 bta_jv_cb.p_dm_cback(BTA_JV_SET_DISCOVER_EVT, &evt_data, 0);
839 /*******************************************************************************
841 ** Function bta_jv_get_local_device_addr
843 ** Description Reads the local Bluetooth device address
847 *******************************************************************************/
848 void bta_jv_get_local_device_addr(tBTA_JV_MSG *p_data)
852 BTM_ReadLocalDeviceAddr((tBTM_CMPL_CB *)bta_jv_get_local_device_addr_cback);
855 /*******************************************************************************
857 ** Function bta_jv_get_local_device_name
859 ** Description Reads the local Bluetooth device name
863 *******************************************************************************/
864 void bta_jv_get_local_device_name(tBTA_JV_MSG *p_data)
870 BTM_ReadLocalDeviceName(&name);
871 evt_data.p_name = (UINT8*)name;
872 if(bta_jv_cb.p_dm_cback)
873 bta_jv_cb.p_dm_cback(BTA_JV_LOCAL_NAME_EVT, &evt_data, 0);
876 /*******************************************************************************
878 ** Function bta_jv_get_remote_device_name
880 ** Description Reads the local Bluetooth device name
884 *******************************************************************************/
885 void bta_jv_get_remote_device_name(tBTA_JV_MSG *p_data)
888 BTM_ReadRemoteDeviceName(p_data->get_rmt_name.bd_addr,
889 (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback, BT_TRANSPORT_BR_EDR);
892 /*******************************************************************************
894 ** Function bta_jv_set_service_class
896 ** Description update the service class field of device class
900 *******************************************************************************/
901 void bta_jv_set_service_class (tBTA_JV_MSG *p_data)
905 /* set class of device */
907 BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the
908 API function as defined in the assigned number page.
909 For example: the object transfer bit is bit 20 of the 24-bit Class of device;
910 the value of this bit is 0x00100000 (value 1)
911 Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 (value 2)
912 This reflects that the service class defined at btm is UINT16,
913 which starts at bit 8 of the 24 bit Class of Device
914 The following statement converts from (value 1) into (value 2)
916 cod.service = (p_data->set_service.service >> 8);
917 utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
920 /*******************************************************************************
922 ** Function bta_jv_sec_cback
924 ** Description callback function to handle set encryption complete event
928 *******************************************************************************/
929 static void bta_jv_sec_cback (BD_ADDR bd_addr, tBTA_TRANSPORT transport,
930 void *p_ref_data, tBTM_STATUS result)
935 tBTA_JV_SET_ENCRYPTION set_enc;
936 if(bta_jv_cb.p_dm_cback)
938 bdcpy(set_enc.bd_addr, bd_addr);
939 set_enc.status = result;
940 if (result > BTA_JV_BUSY)
941 set_enc.status = BTA_JV_FAILURE;
942 bta_jv_cb.p_dm_cback(BTA_JV_SET_ENCRYPTION_EVT, (tBTA_JV *)&set_enc, 0);
946 /*******************************************************************************
948 ** Function bta_jv_set_encryption
950 ** Description Reads the local Bluetooth device name
954 *******************************************************************************/
955 void bta_jv_set_encryption(tBTA_JV_MSG *p_data)
957 BTM_SetEncryption(p_data->set_encrypt.bd_addr, BTA_TRANSPORT_BR_EDR, bta_jv_sec_cback, NULL);
960 /*******************************************************************************
962 ** Function bta_jv_get_scn
964 ** Description obtain a free SCN
968 *******************************************************************************/
969 void bta_jv_get_scn(tBTA_JV_MSG *p_data)
974 scn = BTM_AllocateSCN();
976 bta_jv_cb.scn[scn-1] = TRUE;
977 if(bta_jv_cb.p_dm_cback)
978 bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, (tBTA_JV *)&scn);
982 /*******************************************************************************
984 ** Function bta_jv_free_scn
986 ** Description free a SCN
990 *******************************************************************************/
991 void bta_jv_free_scn(tBTA_JV_MSG *p_data)
993 UINT8 scn = p_data->free_scn.scn;
995 if (scn > 0 && scn <= BTA_JV_MAX_SCN && bta_jv_cb.scn[scn-1])
997 /* this scn is used by JV */
998 bta_jv_cb.scn[scn-1] = FALSE;
1002 static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u)
1004 static uint8_t bt_base_uuid[] =
1005 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
1007 logu("in, uuid:", u->uu.uuid128);
1008 APPL_TRACE_DEBUG("uuid len:%d", u->len);
1011 if(memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) == 0)
1014 memset(&su, 0, sizeof(su));
1015 if(u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0)
1019 memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
1020 su.uu.uuid16 = ntohs(u16);
1021 APPL_TRACE_DEBUG("shorten to 16 bits uuid: %x", su.uu.uuid16);
1027 memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
1028 su.uu.uuid32 = ntohl(u32);
1029 APPL_TRACE_DEBUG("shorten to 32 bits uuid: %x", su.uu.uuid32);
1034 APPL_TRACE_DEBUG("cannot shorten none-reserved 128 bits uuid");
1038 /*******************************************************************************
1040 ** Function bta_jv_start_discovery_cback
1042 ** Description Callback for Start Discovery
1046 *******************************************************************************/
1047 static void bta_jv_start_discovery_cback(UINT16 result, void * user_data)
1049 tBTA_JV_STATUS status;
1050 UINT8 old_sdp_act = bta_jv_cb.sdp_active;
1052 APPL_TRACE_DEBUG("bta_jv_start_discovery_cback res: 0x%x", result);
1054 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
1055 if(bta_jv_cb.p_dm_cback)
1057 if (old_sdp_act == BTA_JV_SDP_ACT_CANCEL)
1059 APPL_TRACE_DEBUG("BTA_JV_SDP_ACT_CANCEL");
1060 status = BTA_JV_SUCCESS;
1061 bta_jv_cb.p_dm_cback(BTA_JV_CANCEL_DISCVRY_EVT, (tBTA_JV *)&status, user_data);
1065 tBTA_JV_DISCOVERY_COMP dcomp;
1067 status = BTA_JV_FAILURE;
1068 if (result == SDP_SUCCESS || result == SDP_DB_FULL)
1070 tSDP_DISC_REC *p_sdp_rec = NULL;
1071 tSDP_PROTOCOL_ELEM pe;
1072 logu("bta_jv_cb.uuid", bta_jv_cb.uuid.uu.uuid128);
1073 tBT_UUID su = shorten_sdp_uuid(&bta_jv_cb.uuid);
1074 logu("shorten uuid:", su.uu.uuid128);
1075 p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db, &su, p_sdp_rec);
1076 APPL_TRACE_DEBUG("p_sdp_rec:%p", p_sdp_rec);
1077 if(p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe))
1079 dcomp.scn = (UINT8) pe.params[0];
1080 status = BTA_JV_SUCCESS;
1084 dcomp.status = status;
1085 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&dcomp, user_data);
1088 //utl_freebuf(&(p_bta_jv_cfg->p_sdp_db));
1092 /*******************************************************************************
1094 ** Function bta_jv_start_discovery
1096 ** Description Discovers services on a remote device
1100 *******************************************************************************/
1101 void bta_jv_start_discovery(tBTA_JV_MSG *p_data)
1103 tBTA_JV_STATUS status = BTA_JV_FAILURE;
1104 APPL_TRACE_DEBUG("bta_jv_start_discovery in, sdp_active:%d", bta_jv_cb.sdp_active);
1105 if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE)
1107 /* SDP is still in progress */
1108 status = BTA_JV_BUSY;
1109 if(bta_jv_cb.p_dm_cback)
1110 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&status, p_data->start_discovery.user_data);
1114 if(p_data->start_discovery.num_uuid == 0)
1116 p_data->start_discovery.num_uuid = 1;
1117 p_data->start_discovery.uuid_list[0].len = 2;
1118 p_data->start_discovery.uuid_list[0].uu.uuid16 = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
1121 /* init the database/set up the filter */
1122 APPL_TRACE_DEBUG("call SDP_InitDiscoveryDb, p_data->start_discovery.num_uuid:%d",
1123 p_data->start_discovery.num_uuid);
1124 SDP_InitDiscoveryDb (p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size,
1125 p_data->start_discovery.num_uuid, p_data->start_discovery.uuid_list, 0, NULL);
1127 /* tell SDP to keep the raw data */
1128 p_bta_jv_cfg->p_sdp_db->raw_data = p_bta_jv_cfg->p_sdp_raw_data;
1129 p_bta_jv_cfg->p_sdp_db->raw_size = p_bta_jv_cfg->sdp_raw_size;
1131 bta_jv_cb.p_sel_raw_data = 0;
1132 bta_jv_cb.uuid = p_data->start_discovery.uuid_list[0];
1134 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_YES;
1135 if (!SDP_ServiceSearchAttributeRequest2(p_data->start_discovery.bd_addr,
1136 p_bta_jv_cfg->p_sdp_db,
1137 bta_jv_start_discovery_cback, p_data->start_discovery.user_data))
1139 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
1140 /* failed to start SDP. report the failure right away */
1141 if(bta_jv_cb.p_dm_cback)
1142 bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV *)&status, p_data->start_discovery.user_data);
1145 else report the result when the cback is called
1149 /*******************************************************************************
1151 ** Function bta_jv_cancel_discovery
1153 ** Description Cancels an active discovery
1157 *******************************************************************************/
1158 void bta_jv_cancel_discovery(tBTA_JV_MSG *p_data)
1160 tBTA_JV_STATUS status = BTA_JV_SUCCESS;
1161 if (bta_jv_cb.sdp_active == BTA_JV_SDP_ACT_YES)
1163 if (SDP_CancelServiceSearch (p_bta_jv_cfg->p_sdp_db))
1165 bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_CANCEL;
1169 if(bta_jv_cb.p_dm_cback)
1170 bta_jv_cb.p_dm_cback(BTA_JV_CANCEL_DISCVRY_EVT, (tBTA_JV *)&status, p_data->cancel_discovery.user_data);
1173 /*******************************************************************************
1175 ** Function bta_jv_get_services_length
1177 ** Description Obtain the length of each record in the SDP DB.
1181 *******************************************************************************/
1182 void bta_jv_get_services_length(tBTA_JV_MSG *p_data)
1186 tBTA_JV_SERVICES_LEN evt_data;
1187 UINT8 *p, *np, *op, type;
1188 UINT32 raw_used, raw_cur;
1191 evt_data.num_services = -1;
1192 evt_data.p_services_len = p_data->get_services_length.p_services_len;
1193 if(p_bta_jv_cfg->p_sdp_db->p_first_rec)
1195 /* the database is valid */
1196 evt_data.num_services = 0;
1197 p = p_bta_jv_cfg->p_sdp_db->raw_data;
1198 raw_used = p_bta_jv_cfg->p_sdp_db->raw_used;
1199 while(raw_used && p)
1203 np = sdpu_get_len_from_type(p, type, &len);
1206 if(raw_used >= raw_cur)
1208 raw_used -= raw_cur;
1212 /* error. can not continue */
1215 if(p_data->get_services_length.inc_hdr)
1217 evt_data.p_services_len[evt_data.num_services++] = len + np - op;
1221 evt_data.p_services_len[evt_data.num_services++] = len;
1223 } /* end of while */
1226 if(bta_jv_cb.p_dm_cback)
1227 bta_jv_cb.p_dm_cback(BTA_JV_SERVICES_LEN_EVT, (tBTA_JV *)&evt_data);
1231 /*******************************************************************************
1233 ** Function bta_jv_service_select
1235 ** Description Obtain the length of given UUID in the SDP DB.
1239 *******************************************************************************/
1240 void bta_jv_service_select(tBTA_JV_MSG *p_data)
1244 tBTA_JV_SERVICE_SEL serv_sel;
1245 tSDP_DISC_REC *p_rec, *p_tmp;
1246 UINT8 *p, *np, *op, type;
1247 UINT32 raw_used, raw_cur;
1250 serv_sel.service_len = 0;
1251 bta_jv_cb.p_sel_raw_data = 0;
1252 p_rec = SDP_FindServiceInDb (p_bta_jv_cfg->p_sdp_db, p_data->service_select.uuid, NULL);
1255 /* found the record in the database */
1256 /* the database must be valid */
1257 p = p_bta_jv_cfg->p_sdp_db->raw_data;
1258 raw_used = p_bta_jv_cfg->p_sdp_db->raw_used;
1259 p_tmp = p_bta_jv_cfg->p_sdp_db->p_first_rec;
1260 while(raw_used && p && p_tmp)
1264 np = sdpu_get_len_from_type(p, type, &len);
1267 bta_jv_cb.p_sel_raw_data = op;
1268 bta_jv_cb.sel_len = len;
1269 serv_sel.service_len = len;
1270 bdcpy(serv_sel.bd_addr, p_rec->remote_bd_addr);
1271 APPL_TRACE_DEBUG( "bta_jv_service_select found uuid: 0x%x",
1272 p_data->service_select.uuid);
1277 if(raw_used >= raw_cur)
1279 raw_used -= raw_cur;
1283 /* error. can not continue */
1286 p_tmp = p_tmp->p_next_rec;
1287 } /* end of while */
1289 APPL_TRACE_DEBUG( "service_len: %d", serv_sel.service_len);
1290 if(bta_jv_cb.p_dm_cback)
1291 bta_jv_cb.p_dm_cback(BTA_JV_SERVICE_SEL_EVT, (tBTA_JV *)&serv_sel);
1295 /*******************************************************************************
1297 ** Function bta_jv_create_record
1299 ** Description Create an SDP record with the given attributes
1303 *******************************************************************************/
1304 void bta_jv_create_record(tBTA_JV_MSG *p_data)
1306 tBTA_JV_API_CREATE_RECORD *cr = &(p_data->create_record);
1307 tBTA_JV_CREATE_RECORD evt_data;
1308 evt_data.status = BTA_JV_SUCCESS;
1309 if(bta_jv_cb.p_dm_cback)
1310 //callback user immediately to create his own sdp record in stack thread context
1311 bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, (tBTA_JV *)&evt_data, cr->user_data);
1314 /*******************************************************************************
1316 ** Function bta_jv_update_record
1318 ** Description Update an SDP record with the given attributes
1322 *******************************************************************************/
1323 void bta_jv_update_record(tBTA_JV_MSG *p_data)
1327 tBTA_JV_API_UPDATE_RECORD *ur = &(p_data->update_record);
1328 tBTA_JV_UPDATE_RECORD evt_data;
1337 evt_data.status = BTA_JV_FAILURE;
1338 evt_data.handle = ur->handle;
1340 handle = bta_jv_get_sdp_handle(ur->handle);
1344 /* this is a record created by JV */
1345 for (i = 0; i < ur->array_len; i++)
1347 ptr = ur->p_values[i];
1348 end = ptr + ur->p_value_sizes[i];
1353 next_ptr = sdpu_get_len_from_type(ptr + 1, *ptr, &len);
1355 if(ATTR_ID_SERVICE_RECORD_HDL != ur->p_ids[i])
1357 if (!SDP_AddAttribute(handle, ur->p_ids[i], (UINT8)((type >> 3) & 0x1f),
1360 /* failed on updating attributes. */
1361 if(bta_jv_cb.p_dm_cback)
1362 bta_jv_cb.p_dm_cback(BTA_JV_UPDATE_RECORD_EVT, (tBTA_JV *)&evt_data);
1367 ptr = next_ptr + len;
1368 } /* end of while */
1370 evt_data.status = BTA_JV_SUCCESS;
1373 if(bta_jv_cb.p_dm_cback)
1374 bta_jv_cb.p_dm_cback(BTA_JV_UPDATE_RECORD_EVT, (tBTA_JV *)&evt_data);
1378 /*******************************************************************************
1380 ** Function bta_jv_add_attribute
1382 ** Description Add an attribute to an SDP record
1386 *******************************************************************************/
1387 void bta_jv_add_attribute(tBTA_JV_MSG *p_data)
1391 tBTA_JV_API_ADD_ATTRIBUTE *aa = &(p_data->add_attr);
1392 tBTA_JV_ADD_ATTR evt_data;
1399 evt_data.status = BTA_JV_FAILURE;
1400 evt_data.handle = aa->handle;
1401 handle = bta_jv_get_sdp_handle(aa->handle);
1405 /* this is a record created by JV */
1408 next_ptr = sdpu_get_len_from_type(ptr + 1, *ptr, &len);
1409 APPL_TRACE_DEBUG( "bta_jv_add_attribute: ptr chg:%d len:%d, size:%d",
1410 (next_ptr - ptr), len, aa->value_size);
1411 if(ATTR_ID_SERVICE_RECORD_HDL != aa->attr_id && /* do not allow the SDP record handle to be updated */
1412 ((INT32)(next_ptr - ptr + len) == aa->value_size) && /* double check data size */
1413 SDP_AddAttribute(handle, aa->attr_id, (UINT8)((type >> 3) & 0x1f),
1416 evt_data.status = BTA_JV_SUCCESS;
1420 if(bta_jv_cb.p_dm_cback)
1421 bta_jv_cb.p_dm_cback(BTA_JV_ADD_ATTR_EVT, (tBTA_JV *)&evt_data);
1425 /*******************************************************************************
1427 ** Function bta_jv_delete_attribute
1429 ** Description Delete an attribute from the given SDP record
1433 *******************************************************************************/
1434 void bta_jv_delete_attribute(tBTA_JV_MSG *p_data)
1438 tBTA_JV_API_ADD_ATTRIBUTE *da = &(p_data->add_attr);
1439 tBTA_JV_DELETE_ATTR evt_data;
1442 evt_data.status = BTA_JV_FAILURE;
1443 evt_data.handle = da->handle;
1444 handle = bta_jv_get_sdp_handle(da->handle);
1448 /* this is a record created by JV */
1449 if(SDP_DeleteAttribute(handle, da->attr_id))
1450 evt_data.status = BTA_JV_SUCCESS;
1453 if(bta_jv_cb.p_dm_cback)
1454 bta_jv_cb.p_dm_cback(BTA_JV_DELETE_ATTR_EVT, (tBTA_JV *)&evt_data);
1458 /*******************************************************************************
1460 ** Function bta_jv_delete_record
1462 ** Description Delete an SDP record
1467 *******************************************************************************/
1468 void bta_jv_delete_record(tBTA_JV_MSG *p_data)
1470 tBTA_JV_API_ADD_ATTRIBUTE *dr = &(p_data->add_attr);
1473 /* this is a record created by btif layer*/
1474 SDP_DeleteRecord(dr->handle);
1478 #if SDP_FOR_JV_INCLUDED == TRUE
1479 /*******************************************************************************
1481 ** Function bta_jv_sdp_res_cback
1483 ** Description Callback for Start Discovery
1487 *******************************************************************************/
1488 void bta_jv_sdp_res_cback (UINT16 event, tSDP_DATA *p_data)
1491 tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[BTA_JV_L2C_FOR_SDP_HDL];
1493 APPL_TRACE_DEBUG( "bta_jv_sdp_res_cback: %d evt:x%x",
1494 bta_jv_cb.sdp_for_jv, event);
1496 if(!bta_jv_cb.sdp_for_jv)
1499 evt_data.l2c_open.status = BTA_JV_SUCCESS;
1500 evt_data.l2c_open.handle = BTA_JV_L2C_FOR_SDP_HDL;
1505 bdcpy(evt_data.l2c_open.rem_bda, p_data->open.peer_addr);
1506 evt_data.l2c_open.tx_mtu = p_data->open.peer_mtu;
1507 p_cb->state = BTA_JV_ST_SR_OPEN;
1508 p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data);
1510 case SDP_EVT_DATA_IND:
1511 evt_data.handle = BTA_JV_L2C_FOR_SDP_HDL;
1512 memcpy(p_bta_jv_cfg->p_sdp_raw_data, p_data->data.p_data, p_data->data.data_len);
1513 APPL_TRACE_DEBUG( "data size: %d/%d ", bta_jv_cb.sdp_data_size, p_data->data.data_len);
1514 bta_jv_cb.sdp_data_size = p_data->data.data_len;
1515 p_cb->p_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data);
1520 /*******************************************************************************
1522 ** Function bta_jv_sdp_cback
1524 ** Description Callback for Start Discovery
1528 *******************************************************************************/
1529 static void bta_jv_sdp_cback(UINT16 result)
1531 tBTA_JV_L2CAP_CLOSE close;
1532 tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[BTA_JV_L2C_FOR_SDP_HDL];
1533 APPL_TRACE_DEBUG( "bta_jv_sdp_cback: result:x%x", result);
1537 close.handle = BTA_JV_L2C_FOR_SDP_HDL;
1538 close.async = FALSE;
1539 close.status = BTA_JV_SUCCESS;
1540 bta_jv_free_sec_id(&p_cb->sec_id);
1541 p_cb->p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&close);
1544 bta_jv_cb.sdp_for_jv = 0;
1545 p_cb->p_cback = NULL;
1550 /*******************************************************************************
1552 ** Function bta_jv_l2cap_connect
1554 ** Description makes an l2cap client connection
1558 *******************************************************************************/
1559 void bta_jv_l2cap_connect(tBTA_JV_MSG *p_data)
1563 tBTA_JV_L2C_CB *p_cb;
1564 tBTA_JV_L2CAP_CL_INIT evt_data;
1565 UINT16 handle=GAP_INVALID_HANDLE;
1567 tL2CAP_CFG_INFO cfg;
1568 tBTA_JV_API_L2CAP_CONNECT *cc = &(p_data->l2cap_connect);
1570 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
1571 cfg.mtu_present = TRUE;
1572 cfg.mtu = cc->rx_mtu;
1573 /* TODO: DM role manager
1574 L2CA_SetDesireRole(cc->role);
1577 sec_id = bta_jv_alloc_sec_id();
1578 evt_data.sec_id = sec_id;
1579 evt_data.status = BTA_JV_FAILURE;
1582 #if SDP_FOR_JV_INCLUDED == TRUE
1583 if(SDP_PSM == cc->remote_psm && 0 == bta_jv_cb.sdp_for_jv)
1585 bta_jv_cb.sdp_for_jv = SDP_ConnOpen(cc->peer_bd_addr,
1586 bta_jv_sdp_res_cback,
1588 if(bta_jv_cb.sdp_for_jv)
1590 bta_jv_cb.sdp_data_size = 0;
1591 handle = BTA_JV_L2C_FOR_SDP_HDL;
1592 evt_data.status = BTA_JV_SUCCESS;
1597 if(bta_jv_check_psm(cc->remote_psm)) /* allowed */
1599 if( (handle = GAP_ConnOpen("", sec_id, 0, cc->peer_bd_addr, cc->remote_psm,
1600 &cfg, cc->sec_mask, GAP_FCR_CHAN_OPT_BASIC,
1601 bta_jv_l2cap_client_cback)) != GAP_INVALID_HANDLE )
1603 evt_data.status = BTA_JV_SUCCESS;
1608 if (evt_data.status == BTA_JV_SUCCESS)
1610 p_cb = &bta_jv_cb.l2c_cb[handle];
1611 p_cb->handle = handle;
1612 p_cb->p_cback = cc->p_cback;
1613 p_cb->psm = 0; /* not a server */
1614 p_cb->sec_id = sec_id;
1615 p_cb->state = BTA_JV_ST_CL_OPENING;
1619 bta_jv_free_sec_id(&sec_id);
1621 evt_data.handle = handle;
1622 cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, (tBTA_JV *)&evt_data);
1626 /*******************************************************************************
1628 ** Function bta_jv_l2cap_close
1630 ** Description Close an L2CAP client connection
1634 *******************************************************************************/
1635 void bta_jv_l2cap_close(tBTA_JV_MSG *p_data)
1639 tBTA_JV_L2CAP_CLOSE evt_data;
1640 tBTA_JV_API_L2CAP_CLOSE *cc = &(p_data->l2cap_close);
1641 tBTA_JV_L2CAP_CBACK *p_cback = cc->p_cb->p_cback;
1643 evt_data.handle = cc->handle;
1644 evt_data.status = bta_jv_free_l2c_cb(cc->p_cb);
1645 evt_data.async = FALSE;
1648 p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data);
1650 APPL_TRACE_ERROR("### NO CALLBACK SET !!! ###");
1654 /*******************************************************************************
1656 ** Function bta_jv_l2cap_start_server
1658 ** Description starts an L2CAP server
1662 *******************************************************************************/
1663 void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
1667 tBTA_JV_L2C_CB *p_cb;
1670 tL2CAP_CFG_INFO cfg;
1671 tBTA_JV_L2CAP_START evt_data;
1672 tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
1674 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
1676 //FIX: MTU=0 means not present
1679 cfg.mtu_present = TRUE;
1680 cfg.mtu = ls->rx_mtu;
1684 cfg.mtu_present = FALSE;
1688 /* TODO DM role manager
1689 L2CA_SetDesireRole(ls->role);
1692 sec_id = bta_jv_alloc_sec_id();
1693 if (0 == sec_id || (FALSE == bta_jv_check_psm(ls->local_psm)) ||
1694 (handle = GAP_ConnOpen("JV L2CAP", sec_id, 1, 0, ls->local_psm, &cfg,
1695 ls->sec_mask, GAP_FCR_CHAN_OPT_BASIC, bta_jv_l2cap_server_cback)) == GAP_INVALID_HANDLE)
1697 bta_jv_free_sec_id(&sec_id);
1698 evt_data.status = BTA_JV_FAILURE;
1702 /* default JV implementation requires explicit call
1703 to allow incoming connections when ready*/
1705 GAP_SetAcceptReady(handle, FALSE);
1707 p_cb = &bta_jv_cb.l2c_cb[handle];
1708 evt_data.status = BTA_JV_SUCCESS;
1709 evt_data.handle = handle;
1710 evt_data.sec_id = sec_id;
1711 p_cb->p_cback = ls->p_cback;
1712 p_cb->handle = handle;
1713 p_cb->sec_id = sec_id;
1714 p_cb->state = BTA_JV_ST_SR_LISTEN;
1715 p_cb->psm = ls->local_psm;
1717 ls->p_cback(BTA_JV_L2CAP_START_EVT, (tBTA_JV *)&evt_data);
1721 /*******************************************************************************
1723 ** Function bta_jv_l2cap_stop_server
1725 ** Description stops an L2CAP server
1729 *******************************************************************************/
1730 void bta_jv_l2cap_stop_server(tBTA_JV_MSG *p_data)
1734 tBTA_JV_L2C_CB *p_cb;
1735 tBTA_JV_L2CAP_CLOSE evt_data;
1736 tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
1737 tBTA_JV_L2CAP_CBACK *p_cback;
1740 for(i=0; i<BTA_JV_MAX_L2C_CONN; i++)
1742 if(bta_jv_cb.l2c_cb[i].psm == ls->local_psm)
1744 p_cb = &bta_jv_cb.l2c_cb[i];
1745 p_cback = p_cb->p_cback;
1746 evt_data.handle = p_cb->handle;
1747 evt_data.status = bta_jv_free_l2c_cb(p_cb);
1748 evt_data.async = FALSE;
1749 p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV *)&evt_data);
1756 /*******************************************************************************
1758 ** Function bta_jv_l2cap_read
1760 ** Description Read data from an L2CAP connection
1764 *******************************************************************************/
1765 void bta_jv_l2cap_read(tBTA_JV_MSG *p_data)
1769 tBTA_JV_L2CAP_READ evt_data;
1770 tBTA_JV_API_L2CAP_READ *rc = &(p_data->l2cap_read);
1772 evt_data.status = BTA_JV_FAILURE;
1773 evt_data.handle = rc->handle;
1774 evt_data.req_id = rc->req_id;
1775 evt_data.p_data = rc->p_data;
1777 #if SDP_FOR_JV_INCLUDED == TRUE
1778 if(BTA_JV_L2C_FOR_SDP_HDL == rc->handle)
1780 evt_data.len = rc->len;
1781 if(evt_data.len > bta_jv_cb.sdp_data_size)
1782 evt_data.len = bta_jv_cb.sdp_data_size;
1784 memcpy(rc->p_data, p_bta_jv_cfg->p_sdp_raw_data, evt_data.len);
1785 bta_jv_cb.sdp_data_size = 0;
1786 evt_data.status = BTA_JV_SUCCESS;
1790 if (BT_PASS == GAP_ConnReadData(rc->handle, rc->p_data, rc->len, &evt_data.len))
1792 evt_data.status = BTA_JV_SUCCESS;
1795 rc->p_cback(BTA_JV_L2CAP_READ_EVT, (tBTA_JV *)&evt_data);
1800 /*******************************************************************************
1802 ** Function bta_jv_l2cap_write
1804 ** Description Write data to an L2CAP connection
1808 *******************************************************************************/
1809 void bta_jv_l2cap_write(tBTA_JV_MSG *p_data)
1813 tBTA_JV_L2CAP_WRITE evt_data;
1814 tBTA_JV_API_L2CAP_WRITE *ls = &(p_data->l2cap_write);
1816 evt_data.status = BTA_JV_FAILURE;
1817 evt_data.handle = ls->handle;
1818 evt_data.req_id = ls->req_id;
1819 evt_data.cong = ls->p_cb->cong;
1821 #if SDP_FOR_JV_INCLUDED == TRUE
1822 if(BTA_JV_L2C_FOR_SDP_HDL == ls->handle)
1825 BT_HDR *p_msg = (BT_HDR *) GKI_getbuf ((UINT16)(ls->len + BT_HDR_SIZE + L2CAP_MIN_OFFSET));
1828 p_msg->offset = L2CAP_MIN_OFFSET;
1829 p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
1830 p_msg->len = ls->len;
1831 memcpy(p, ls->p_data, p_msg->len);
1832 bta_jv_pm_conn_busy(ls->p_cb->p_pm_cb);
1833 if(SDP_WriteData (bta_jv_cb.sdp_for_jv, p_msg))
1835 evt_data.len = ls->len;
1836 evt_data.status = BTA_JV_SUCCESS;
1843 bta_jv_pm_conn_busy(ls->p_cb->p_pm_cb);
1844 if (!evt_data.cong &&
1845 BT_PASS == GAP_ConnWriteData(ls->handle, ls->p_data, ls->len, &evt_data.len))
1847 evt_data.status = BTA_JV_SUCCESS;
1850 ls->p_cb->p_cback(BTA_JV_L2CAP_WRITE_EVT, (tBTA_JV *)&evt_data);
1851 bta_jv_set_pm_conn_state(ls->p_cb->p_pm_cb, BTA_JV_CONN_IDLE);
1855 /*******************************************************************************
1857 ** Function bta_jv_port_data_co_cback
1859 ** Description port data callback function of rfcomm
1864 *******************************************************************************/
1866 #define DATA_CO_CALLBACK_TYPE_INCOMING 1
1867 #define DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE 2
1868 #define DATA_CO_CALLBACK_TYPE_OUTGOING 3
1870 static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type)
1872 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1873 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1875 APPL_TRACE_DEBUG("bta_jv_port_data_co_cback, p_cb:%p, p_pcb:%p, len:%d, type:%d",
1876 p_cb, p_pcb, len, type);
1881 case DATA_CO_CALLBACK_TYPE_INCOMING:
1882 bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
1883 ret = bta_co_rfc_data_incoming(p_pcb->user_data, (BT_HDR*)buf);
1884 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1886 case DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE:
1887 return bta_co_rfc_data_outgoing_size(p_pcb->user_data, (int*)buf);
1888 case DATA_CO_CALLBACK_TYPE_OUTGOING:
1889 return bta_co_rfc_data_outgoing(p_pcb->user_data, buf, len);
1891 APPL_TRACE_ERROR("unknown callout type:%d", type);
1898 /*******************************************************************************
1900 ** Function bta_jv_port_mgmt_cl_cback
1902 ** Description callback for port mamangement function of rfcomm
1903 ** client connections
1907 *******************************************************************************/
1908 static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle)
1910 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1911 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1915 tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
1917 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle);
1918 if(NULL == p_cb || NULL == p_cb->p_cback)
1921 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d",
1922 code, port_handle, p_cb->handle);
1924 PORT_CheckConnection(port_handle, rem_bda, &lcid);
1926 if(code == PORT_SUCCESS)
1928 evt_data.rfc_open.handle = p_cb->handle;
1929 evt_data.rfc_open.status = BTA_JV_SUCCESS;
1930 bdcpy(evt_data.rfc_open.rem_bda, rem_bda);
1931 p_pcb->state = BTA_JV_ST_CL_OPEN;
1932 p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->user_data);
1936 evt_data.rfc_close.handle = p_cb->handle;
1937 evt_data.rfc_close.status = BTA_JV_FAILURE;
1938 evt_data.rfc_close.port_status = code;
1939 evt_data.rfc_close.async = TRUE;
1940 if (p_pcb->state == BTA_JV_ST_CL_CLOSING)
1942 evt_data.rfc_close.async = FALSE;
1944 //p_pcb->state = BTA_JV_ST_NONE;
1945 //p_pcb->cong = FALSE;
1946 p_cback = p_cb->p_cback;
1947 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->user_data);
1948 //bta_jv_free_rfc_cb(p_cb, p_pcb);
1953 /*******************************************************************************
1955 ** Function bta_jv_port_event_cl_cback
1957 ** Description Callback for RFCOMM client port events
1961 *******************************************************************************/
1962 static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle)
1964 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1965 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1968 APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle);
1969 if(NULL == p_cb || NULL == p_cb->p_cback)
1972 APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback code=x%x port_handle:%d handle:%d",
1973 code, port_handle, p_cb->handle);
1974 if (code & PORT_EV_RXCHAR)
1976 evt_data.data_ind.handle = p_cb->handle;
1977 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, p_pcb->user_data);
1980 if (code & PORT_EV_FC)
1982 p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
1983 evt_data.rfc_cong.cong = p_pcb->cong;
1984 evt_data.rfc_cong.handle = p_cb->handle;
1985 evt_data.rfc_cong.status = BTA_JV_SUCCESS;
1986 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, p_pcb->user_data);
1989 if (code & PORT_EV_TXEMPTY)
1991 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1995 /*******************************************************************************
1997 ** Function bta_jv_rfcomm_connect
1999 ** Description Client initiates an RFCOMM connection
2003 *******************************************************************************/
2004 void bta_jv_rfcomm_connect(tBTA_JV_MSG *p_data)
2007 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2008 tPORT_STATE port_state;
2010 tBTA_JV_RFC_CB *p_cb = NULL;
2012 tBTA_JV_API_RFCOMM_CONNECT *cc = &(p_data->rfcomm_connect);
2013 tBTA_JV_RFCOMM_CL_INIT evt_data = {0};
2015 /* TODO DM role manager
2016 L2CA_SetDesireRole(cc->role);
2019 sec_id = bta_jv_alloc_sec_id();
2020 evt_data.sec_id = sec_id;
2021 evt_data.status = BTA_JV_SUCCESS;
2023 BTM_SetSecurityLevel(TRUE, "", sec_id, cc->sec_mask, BT_PSM_RFCOMM,
2024 BTM_SEC_PROTO_RFCOMM, cc->remote_scn) == FALSE)
2026 evt_data.status = BTA_JV_FAILURE;
2027 APPL_TRACE_ERROR("sec_id:%d is zero or BTM_SetSecurityLevel failed, remote_scn:%d", sec_id, cc->remote_scn);
2030 if (evt_data.status == BTA_JV_SUCCESS &&
2031 RFCOMM_CreateConnection(UUID_SERVCLASS_SERIAL_PORT, cc->remote_scn, FALSE,
2032 BTA_JV_DEF_RFC_MTU, cc->peer_bd_addr, &handle, bta_jv_port_mgmt_cl_cback) != PORT_SUCCESS)
2034 APPL_TRACE_ERROR("bta_jv_rfcomm_connect, RFCOMM_CreateConnection failed");
2035 evt_data.status = BTA_JV_FAILURE;
2037 if (evt_data.status == BTA_JV_SUCCESS)
2039 p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
2042 p_cb->p_cback = cc->p_cback;
2043 p_cb->sec_id = sec_id;
2045 p_pcb->state = BTA_JV_ST_CL_OPENING;
2046 p_pcb->user_data = cc->user_data;
2047 evt_data.use_co = TRUE;
2049 PORT_SetEventCallback(handle, bta_jv_port_event_cl_cback);
2050 PORT_SetEventMask(handle, event_mask);
2051 PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
2053 PORT_GetState(handle, &port_state);
2055 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2057 /* coverity[uninit_use_in_call]
2058 FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2059 PORT_SetState(handle, &port_state);
2061 evt_data.handle = p_cb->handle;
2065 evt_data.status = BTA_JV_FAILURE;
2066 APPL_TRACE_ERROR("run out of rfc control block");
2069 cc->p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, (tBTA_JV *)&evt_data, cc->user_data);
2070 if(evt_data.status == BTA_JV_FAILURE)
2073 bta_jv_free_sec_id(&sec_id);
2075 RFCOMM_RemoveConnection(handle);
2079 static int find_rfc_pcb(void* user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb)
2084 for (i = 0; i < MAX_RFC_PORTS; i++)
2086 UINT32 rfc_handle = bta_jv_cb.port_cb[i].handle & BTA_JV_RFC_HDL_MASK;
2087 rfc_handle &= ~BTA_JV_RFCOMM_MASK;
2088 if (rfc_handle && bta_jv_cb.port_cb[i].user_data == user_data)
2090 *pcb = &bta_jv_cb.port_cb[i];
2091 *cb = &bta_jv_cb.rfc_cb[rfc_handle - 1];
2092 APPL_TRACE_DEBUG("find_rfc_pcb(): FOUND rfc_cb_handle 0x%x, port.jv_handle:"
2093 " 0x%x, state: %d, rfc_cb->handle: 0x%x", rfc_handle, (*pcb)->handle,
2094 (*pcb)->state, (*cb)->handle);
2098 APPL_TRACE_DEBUG("find_rfc_pcb: cannot find rfc_cb from user data:%d", (UINT32)user_data);
2102 /*******************************************************************************
2104 ** Function bta_jv_rfcomm_close
2106 ** Description Close an RFCOMM connection
2110 *******************************************************************************/
2111 void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
2113 tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close);
2114 tBTA_JV_RFC_CB *p_cb = NULL;
2115 tBTA_JV_PCB *p_pcb = NULL;
2116 APPL_TRACE_DEBUG("bta_jv_rfcomm_close, rfc handle:%d", cc->handle);
2119 APPL_TRACE_ERROR("bta_jv_rfcomm_close, rfc handle is null");
2123 void* user_data = cc->user_data;
2124 if (!find_rfc_pcb(user_data, &p_cb, &p_pcb))
2126 bta_jv_free_rfc_cb(p_cb, p_pcb);
2127 APPL_TRACE_DEBUG("bta_jv_rfcomm_close: sec id in use:%d, rfc_cb in use:%d",
2128 get_sec_id_used(), get_rfc_cb_used());
2131 /*******************************************************************************
2133 ** Function bta_jv_port_mgmt_sr_cback
2135 ** Description callback for port mamangement function of rfcomm
2136 ** server connections
2140 *******************************************************************************/
2141 static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle)
2143 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
2144 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
2150 APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:%d, port_handle:%d", code, port_handle);
2151 if(NULL == p_cb || NULL == p_cb->p_cback)
2153 APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p",
2154 p_cb, p_cb ? p_cb->p_cback : NULL);
2157 void *user_data = p_pcb->user_data;
2158 APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%d port_handle:0x%x handle:0x%x, p_pcb:%p, user:%d",
2159 code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data);
2161 PORT_CheckConnection(port_handle, rem_bda, &lcid);
2163 if (code == PORT_SUCCESS)
2165 evt_data.rfc_srv_open.handle = p_pcb->handle;
2166 evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
2167 bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
2168 tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb);
2169 if (p_pcb_new_listen)
2171 evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle;
2172 p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
2173 APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess);
2177 APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port");
2181 evt_data.rfc_close.handle = p_cb->handle;
2182 evt_data.rfc_close.status = BTA_JV_FAILURE;
2183 evt_data.rfc_close.async = TRUE;
2184 evt_data.rfc_close.port_status = code;
2185 p_pcb->cong = FALSE;
2187 tBTA_JV_RFCOMM_CBACK *p_cback = p_cb->p_cback;
2188 APPL_TRACE_DEBUG("PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
2189 p_cb->curr_sess, p_cb->max_sess);
2190 if(BTA_JV_ST_SR_CLOSING == p_pcb->state)
2192 evt_data.rfc_close.async = FALSE;
2193 evt_data.rfc_close.status = BTA_JV_SUCCESS;
2195 //p_pcb->state = BTA_JV_ST_NONE;
2196 p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
2197 //bta_jv_free_rfc_cb(p_cb, p_pcb);
2199 APPL_TRACE_DEBUG("PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
2200 p_cb->curr_sess, p_cb->max_sess);
2204 /*******************************************************************************
2206 ** Function bta_jv_port_event_sr_cback
2208 ** Description Callback for RFCOMM server port events
2212 *******************************************************************************/
2213 static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle)
2215 tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
2216 tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
2219 if(NULL == p_cb || NULL == p_cb->p_cback)
2222 APPL_TRACE_DEBUG( "bta_jv_port_event_sr_cback code=x%x port_handle:%d handle:%d",
2223 code, port_handle, p_cb->handle);
2225 void *user_data = p_pcb->user_data;
2226 if (code & PORT_EV_RXCHAR)
2228 evt_data.data_ind.handle = p_cb->handle;
2229 p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, user_data);
2232 if (code & PORT_EV_FC)
2234 p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
2235 evt_data.rfc_cong.cong = p_pcb->cong;
2236 evt_data.rfc_cong.handle = p_cb->handle;
2237 evt_data.rfc_cong.status = BTA_JV_SUCCESS;
2238 p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, user_data);
2241 if (code & PORT_EV_TXEMPTY)
2243 bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
2247 /*******************************************************************************
2249 ** Function bta_jv_add_rfc_port
2251 ** Description add a port for server when the existing posts is open
2253 ** Returns return a pointer to tBTA_JV_PCB just added
2255 *******************************************************************************/
2256 static tBTA_JV_PCB * bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb_open)
2258 UINT8 used = 0, i, listen=0;
2260 tPORT_STATE port_state;
2261 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2262 tBTA_JV_PCB *p_pcb = NULL;
2263 if (p_cb->max_sess > 1)
2265 for (i=0; i < p_cb->max_sess; i++)
2267 if (p_cb->rfc_hdl[i] != 0)
2269 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1];
2270 if (p_pcb->state == BTA_JV_ST_SR_LISTEN)
2273 if(p_pcb_open == p_pcb)
2275 APPL_TRACE_DEBUG("bta_jv_add_rfc_port, port_handle:%d, change the listen port to open state",
2276 p_pcb->port_handle);
2277 p_pcb->state = BTA_JV_ST_SR_OPEN;
2282 APPL_TRACE_ERROR("bta_jv_add_rfc_port, open pcb not matching listen one,"
2283 "listen count:%d, listen pcb handle:%d, open pcb:%d",
2284 listen, p_pcb->port_handle, p_pcb_open->handle);
2296 APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d",
2297 p_cb->max_sess, used, p_cb->curr_sess, listen, si);
2298 if (used < p_cb->max_sess && listen == 1 && si)
2301 if (RFCOMM_CreateConnection(p_cb->sec_id, p_cb->scn, TRUE,
2302 BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &(p_cb->rfc_hdl[si]), bta_jv_port_mgmt_sr_cback) == PORT_SUCCESS)
2305 p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[si] - 1];
2306 p_pcb->state = BTA_JV_ST_SR_LISTEN;
2307 p_pcb->port_handle = p_cb->rfc_hdl[si];
2308 p_pcb->user_data = p_pcb_open->user_data;
2310 PORT_ClearKeepHandleFlag(p_pcb->port_handle);
2311 PORT_SetEventCallback(p_pcb->port_handle, bta_jv_port_event_sr_cback);
2312 PORT_SetDataCOCallback (p_pcb->port_handle, bta_jv_port_data_co_cback);
2313 PORT_SetEventMask(p_pcb->port_handle, event_mask);
2314 PORT_GetState(p_pcb->port_handle, &port_state);
2316 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2318 /* coverity[uninit_use_in_call]
2319 FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2320 PORT_SetState(p_pcb->port_handle, &port_state);
2321 p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si);
2322 APPL_TRACE_DEBUG("bta_jv_add_rfc_port: p_pcb->handle:0x%x, curr_sess:%d",
2323 p_pcb->handle, p_cb->curr_sess);
2327 APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port");
2329 APPL_TRACE_DEBUG("bta_jv_add_rfc_port: sec id in use:%d, rfc_cb in use:%d",
2330 get_sec_id_used(), get_rfc_cb_used());
2334 /*******************************************************************************
2336 ** Function bta_jv_rfcomm_start_server
2338 ** Description waits for an RFCOMM client to connect
2343 *******************************************************************************/
2344 void bta_jv_rfcomm_start_server(tBTA_JV_MSG *p_data)
2347 UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2348 tPORT_STATE port_state;
2350 tBTA_JV_RFC_CB *p_cb = NULL;
2352 tBTA_JV_API_RFCOMM_SERVER *rs = &(p_data->rfcomm_server);
2353 tBTA_JV_RFCOMM_START evt_data = {0};
2354 /* TODO DM role manager
2355 L2CA_SetDesireRole(rs->role);
2357 evt_data.status = BTA_JV_FAILURE;
2358 APPL_TRACE_DEBUG("bta_jv_rfcomm_start_server: sec id in use:%d, rfc_cb in use:%d",
2359 get_sec_id_used(), get_rfc_cb_used());
2363 sec_id = bta_jv_alloc_sec_id();
2366 BTM_SetSecurityLevel(FALSE, "JV PORT", sec_id, rs->sec_mask,
2367 BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, rs->local_scn) == FALSE)
2369 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of sec_id");
2373 if (RFCOMM_CreateConnection(sec_id, rs->local_scn, TRUE,
2374 BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &handle, bta_jv_port_mgmt_sr_cback) != PORT_SUCCESS)
2376 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, RFCOMM_CreateConnection failed");
2381 p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
2384 APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of rfc control block");
2388 p_cb->max_sess = rs->max_session;
2389 p_cb->p_cback = rs->p_cback;
2390 p_cb->sec_id = sec_id;
2391 p_cb->scn = rs->local_scn;
2392 p_pcb->state = BTA_JV_ST_SR_LISTEN;
2393 p_pcb->user_data = rs->user_data;
2394 evt_data.status = BTA_JV_SUCCESS;
2395 evt_data.handle = p_cb->handle;
2396 evt_data.sec_id = sec_id;
2397 evt_data.use_co = TRUE; //FALSE;
2399 PORT_ClearKeepHandleFlag(handle);
2400 PORT_SetEventCallback(handle, bta_jv_port_event_sr_cback);
2401 PORT_SetEventMask(handle, event_mask);
2402 PORT_GetState(handle, &port_state);
2404 port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2406 /* coverity[uninit_use_in_call]
2407 FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2408 PORT_SetState(handle, &port_state);
2410 rs->p_cback(BTA_JV_RFCOMM_START_EVT, (tBTA_JV *)&evt_data, rs->user_data);
2411 if(evt_data.status == BTA_JV_SUCCESS)
2413 PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
2418 bta_jv_free_sec_id(&sec_id);
2420 RFCOMM_RemoveConnection(handle);
2424 /*******************************************************************************
2426 ** Function bta_jv_rfcomm_stop_server
2428 ** Description stops an RFCOMM server
2432 *******************************************************************************/
2434 void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data)
2436 tBTA_JV_API_RFCOMM_SERVER *ls = &(p_data->rfcomm_server);
2437 tBTA_JV_RFC_CB *p_cb = NULL;
2438 tBTA_JV_PCB *p_pcb = NULL;
2439 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server");
2442 APPL_TRACE_ERROR("bta_jv_rfcomm_stop_server, jv handle is null");
2445 void* user_data = ls->user_data;
2446 if(!find_rfc_pcb(user_data, &p_cb, &p_pcb))
2448 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d",
2449 p_pcb, p_pcb->port_handle);
2450 bta_jv_free_rfc_cb(p_cb, p_pcb);
2451 APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d",
2452 get_sec_id_used(), get_rfc_cb_used());
2455 /*******************************************************************************
2457 ** Function bta_jv_rfcomm_read
2459 ** Description Read data from an RFCOMM connection
2463 *******************************************************************************/
2464 void bta_jv_rfcomm_read(tBTA_JV_MSG *p_data)
2466 tBTA_JV_API_RFCOMM_READ *rc = &(p_data->rfcomm_read);
2467 tBTA_JV_RFC_CB *p_cb = rc->p_cb;
2468 tBTA_JV_PCB *p_pcb = rc->p_pcb;
2469 tBTA_JV_RFCOMM_READ evt_data;
2471 evt_data.status = BTA_JV_FAILURE;
2472 evt_data.handle = p_cb->handle;
2473 evt_data.req_id = rc->req_id;
2474 evt_data.p_data = rc->p_data;
2475 if (PORT_ReadData(rc->p_pcb->port_handle, (char *)rc->p_data, rc->len, &evt_data.len) ==
2478 evt_data.status = BTA_JV_SUCCESS;
2481 p_cb->p_cback(BTA_JV_RFCOMM_READ_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2484 /*******************************************************************************
2486 ** Function bta_jv_rfcomm_write
2488 ** Description write data to an RFCOMM connection
2492 *******************************************************************************/
2493 void bta_jv_rfcomm_write(tBTA_JV_MSG *p_data)
2495 tBTA_JV_API_RFCOMM_WRITE *wc = &(p_data->rfcomm_write);
2496 tBTA_JV_RFC_CB *p_cb = wc->p_cb;
2497 tBTA_JV_PCB *p_pcb = wc->p_pcb;
2498 tBTA_JV_RFCOMM_WRITE evt_data;
2500 evt_data.status = BTA_JV_FAILURE;
2501 evt_data.handle = p_cb->handle;
2502 evt_data.req_id = wc->req_id;
2503 evt_data.cong = p_pcb->cong;
2505 bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
2506 if (!evt_data.cong &&
2507 PORT_WriteDataCO(p_pcb->port_handle, &evt_data.len) ==
2510 evt_data.status = BTA_JV_SUCCESS;
2512 //update congestion flag
2513 evt_data.cong = p_pcb->cong;
2516 p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2520 APPL_TRACE_ERROR("bta_jv_rfcomm_write :: WARNING ! No JV callback set");
2524 /*******************************************************************************
2526 ** Function bta_jv_set_pm_profile
2528 ** Description Set or free power mode profile for a JV application
2532 *******************************************************************************/
2533 void bta_jv_set_pm_profile(tBTA_JV_MSG *p_data)
2535 tBTA_JV_STATUS status;
2536 tBTA_JV_PM_CB *p_cb;
2538 APPL_TRACE_API("bta_jv_set_pm_profile(handle: 0x%x, app_id: %d, init_st: %d)",
2539 p_data->set_pm.handle, p_data->set_pm.app_id, p_data->set_pm.init_st);
2541 /* clear PM control block */
2542 if (p_data->set_pm.app_id == BTA_JV_PM_ID_CLEAR)
2544 status = bta_jv_free_set_pm_profile_cb(p_data->set_pm.handle);
2546 if (status != BTA_JV_SUCCESS)
2548 APPL_TRACE_WARNING("bta_jv_set_pm_profile() free pm cb failed: reason %d",
2552 else /* set PM control block */
2554 p_cb = bta_jv_alloc_set_pm_profile_cb(p_data->set_pm.handle,
2555 p_data->set_pm.app_id);
2558 bta_jv_pm_state_change(p_cb, p_data->set_pm.init_st);
2560 APPL_TRACE_WARNING("bta_jv_alloc_set_pm_profile_cb() failed");
2564 /*******************************************************************************
2566 ** Function bta_jv_change_pm_state
2568 ** Description change jv pm connect state, used internally
2572 *******************************************************************************/
2573 void bta_jv_change_pm_state(tBTA_JV_MSG *p_data)
2575 tBTA_JV_API_PM_STATE_CHANGE *p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)p_data;
2578 bta_jv_pm_state_change(p_msg->p_cb, p_msg->state);
2582 /*******************************************************************************
2584 ** Function bta_jv_set_pm_conn_state
2586 ** Description Send pm event state change to jv state machine to serialize jv pm changes
2587 ** in relation to other jv messages. internal API use mainly.
2589 ** Params: p_cb: jv pm control block, NULL pointer returns failure
2590 ** new_state: new PM connections state, setting is forced by action function
2592 ** Returns BTA_JV_SUCCESS, BTA_JV_FAILURE (buffer allocation, or NULL ptr!)
2594 *******************************************************************************/
2595 tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE
2598 tBTA_JV_STATUS status = BTA_JV_FAILURE;
2599 tBTA_JV_API_PM_STATE_CHANGE *p_msg;
2604 APPL_TRACE_API("bta_jv_set_pm_conn_state(handle:0x%x, state: %d)", p_cb->handle,
2606 if ((p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)GKI_getbuf(
2607 sizeof(tBTA_JV_API_PM_STATE_CHANGE))) != NULL)
2609 p_msg->hdr.event = BTA_JV_API_PM_STATE_CHANGE_EVT;
2611 p_msg->state = new_st;
2612 bta_sys_sendmsg(p_msg);
2613 status = BTA_JV_SUCCESS;
2618 /*******************************************************************************
2620 ** Function bta_jv_pm_conn_busy
2622 ** Description set pm connection busy state (input param safe)
2624 ** Params p_cb: pm control block of jv connection
2628 *******************************************************************************/
2629 static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB *p_cb)
2631 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST == p_cb->state))
2632 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_BUSY);
2635 /*******************************************************************************
2637 ** Function bta_jv_pm_conn_busy
2639 ** Description set pm connection busy state (input param safe)
2641 ** Params p_cb: pm control block of jv connection
2645 *******************************************************************************/
2646 static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb)
2648 if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST != p_cb->state))
2649 bta_jv_pm_state_change(p_cb, BTA_JV_CONN_IDLE);
2652 /*******************************************************************************
2654 ** Function bta_jv_pm_state_change
2656 ** Description Notify power manager there is state change
2658 ** Params p_cb: must be NONE NULL
2662 *******************************************************************************/
2663 static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state)
2665 APPL_TRACE_API("bta_jv_pm_state_change(p_cb: 0x%x, handle: 0x%x, busy/idle_state: %d"
2666 ", app_id: %d, conn_state: %d)", p_cb, p_cb->handle, p_cb->state,
2667 p_cb->app_id, state);
2671 case BTA_JV_CONN_OPEN:
2672 bta_sys_conn_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2675 case BTA_JV_CONN_CLOSE:
2676 bta_sys_conn_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2679 case BTA_JV_APP_OPEN:
2680 bta_sys_app_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2683 case BTA_JV_APP_CLOSE:
2684 bta_sys_app_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2687 case BTA_JV_SCO_OPEN:
2688 bta_sys_sco_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2691 case BTA_JV_SCO_CLOSE:
2692 bta_sys_sco_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2695 case BTA_JV_CONN_IDLE:
2696 p_cb->state = BTA_JV_PM_IDLE_ST;
2697 bta_sys_idle(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2700 case BTA_JV_CONN_BUSY:
2701 p_cb->state = BTA_JV_PM_BUSY_ST;
2702 bta_sys_busy(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2706 APPL_TRACE_WARNING("bta_jv_pm_state_change(state: %d): Invalid state", state);