OSDN Git Service

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