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