OSDN Git Service

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