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