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