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