bta_jv_act.c revision d9e2d0f1fa19f737632e82c24ba278990b8a7548
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    int ret = 0;
1875    APPL_TRACE_DEBUG("bta_jv_port_data_co_cback, p_cb:%p, p_pcb:%p, len:%d, type:%d",
1876                        p_cb, p_pcb, len, type);
1877    if (p_pcb != NULL)
1878    {
1879        switch(type)
1880        {
1881            case DATA_CO_CALLBACK_TYPE_INCOMING:
1882                bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
1883                ret = bta_co_rfc_data_incoming(p_pcb->user_data, (BT_HDR*)buf);
1884                bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1885                return ret;
1886            case DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE:
1887                return bta_co_rfc_data_outgoing_size(p_pcb->user_data, (int*)buf);
1888            case DATA_CO_CALLBACK_TYPE_OUTGOING:
1889                return bta_co_rfc_data_outgoing(p_pcb->user_data, buf, len);
1890            default:
1891                APPL_TRACE_ERROR("unknown callout type:%d", type);
1892                break;
1893        }
1894    }
1895    return 0;
1896}
1897
1898/*******************************************************************************
1899**
1900** Function     bta_jv_port_mgmt_cl_cback
1901**
1902** Description  callback for port mamangement function of rfcomm
1903**              client connections
1904**
1905** Returns      void
1906**
1907*******************************************************************************/
1908static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle)
1909{
1910    tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1911    tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1912    tBTA_JV evt_data;
1913    BD_ADDR rem_bda;
1914    UINT16 lcid;
1915    tBTA_JV_RFCOMM_CBACK *p_cback;  /* the callback function */
1916
1917    APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle);
1918    if(NULL == p_cb || NULL == p_cb->p_cback)
1919        return;
1920
1921    APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d",
1922        code, port_handle, p_cb->handle);
1923
1924    PORT_CheckConnection(port_handle, rem_bda, &lcid);
1925
1926    if(code == PORT_SUCCESS)
1927    {
1928        evt_data.rfc_open.handle = p_cb->handle;
1929        evt_data.rfc_open.status = BTA_JV_SUCCESS;
1930        bdcpy(evt_data.rfc_open.rem_bda, rem_bda);
1931        p_pcb->state = BTA_JV_ST_CL_OPEN;
1932        p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->user_data);
1933    }
1934    else
1935    {
1936        evt_data.rfc_close.handle = p_cb->handle;
1937        evt_data.rfc_close.status = BTA_JV_FAILURE;
1938        evt_data.rfc_close.port_status = code;
1939        evt_data.rfc_close.async = TRUE;
1940        if (p_pcb->state == BTA_JV_ST_CL_CLOSING)
1941        {
1942            evt_data.rfc_close.async = FALSE;
1943        }
1944        //p_pcb->state = BTA_JV_ST_NONE;
1945        //p_pcb->cong = FALSE;
1946        p_cback = p_cb->p_cback;
1947        p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->user_data);
1948        //bta_jv_free_rfc_cb(p_cb, p_pcb);
1949    }
1950
1951}
1952
1953/*******************************************************************************
1954**
1955** Function     bta_jv_port_event_cl_cback
1956**
1957** Description  Callback for RFCOMM client port events
1958**
1959** Returns      void
1960**
1961*******************************************************************************/
1962static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle)
1963{
1964    tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle);
1965    tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
1966    tBTA_JV evt_data;
1967
1968    APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle);
1969    if(NULL == p_cb || NULL == p_cb->p_cback)
1970        return;
1971
1972    APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback code=x%x port_handle:%d handle:%d",
1973        code, port_handle, p_cb->handle);
1974    if (code & PORT_EV_RXCHAR)
1975    {
1976        evt_data.data_ind.handle = p_cb->handle;
1977        p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, p_pcb->user_data);
1978    }
1979
1980    if (code & PORT_EV_FC)
1981    {
1982        p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
1983        evt_data.rfc_cong.cong = p_pcb->cong;
1984        evt_data.rfc_cong.handle = p_cb->handle;
1985        evt_data.rfc_cong.status = BTA_JV_SUCCESS;
1986        p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, p_pcb->user_data);
1987    }
1988
1989    if (code & PORT_EV_TXEMPTY)
1990    {
1991        bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
1992    }
1993}
1994
1995/*******************************************************************************
1996**
1997** Function     bta_jv_rfcomm_connect
1998**
1999** Description  Client initiates an RFCOMM connection
2000**
2001** Returns      void
2002**
2003*******************************************************************************/
2004void bta_jv_rfcomm_connect(tBTA_JV_MSG *p_data)
2005{
2006    UINT16 handle = 0;
2007    UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2008    tPORT_STATE port_state;
2009    UINT8   sec_id = 0;
2010    tBTA_JV_RFC_CB  *p_cb = NULL;
2011    tBTA_JV_PCB     *p_pcb;
2012    tBTA_JV_API_RFCOMM_CONNECT *cc = &(p_data->rfcomm_connect);
2013    tBTA_JV_RFCOMM_CL_INIT      evt_data = {0};
2014
2015    /* TODO DM role manager
2016    L2CA_SetDesireRole(cc->role);
2017    */
2018
2019    sec_id = bta_jv_alloc_sec_id();
2020    evt_data.sec_id = sec_id;
2021    evt_data.status = BTA_JV_SUCCESS;
2022    if (0 == sec_id ||
2023        BTM_SetSecurityLevel(TRUE, "", sec_id,  cc->sec_mask, BT_PSM_RFCOMM,
2024                BTM_SEC_PROTO_RFCOMM, cc->remote_scn) == FALSE)
2025    {
2026        evt_data.status = BTA_JV_FAILURE;
2027        APPL_TRACE_ERROR("sec_id:%d is zero or BTM_SetSecurityLevel failed, remote_scn:%d", sec_id, cc->remote_scn);
2028    }
2029
2030    if (evt_data.status == BTA_JV_SUCCESS &&
2031        RFCOMM_CreateConnection(UUID_SERVCLASS_SERIAL_PORT, cc->remote_scn, FALSE,
2032        BTA_JV_DEF_RFC_MTU, cc->peer_bd_addr, &handle, bta_jv_port_mgmt_cl_cback) != PORT_SUCCESS)
2033    {
2034        APPL_TRACE_ERROR("bta_jv_rfcomm_connect, RFCOMM_CreateConnection failed");
2035        evt_data.status = BTA_JV_FAILURE;
2036    }
2037    if (evt_data.status == BTA_JV_SUCCESS)
2038    {
2039        p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
2040        if(p_cb)
2041        {
2042            p_cb->p_cback = cc->p_cback;
2043            p_cb->sec_id = sec_id;
2044            p_cb->scn = 0;
2045            p_pcb->state = BTA_JV_ST_CL_OPENING;
2046            p_pcb->user_data = cc->user_data;
2047            evt_data.use_co = TRUE;
2048
2049            PORT_SetEventCallback(handle, bta_jv_port_event_cl_cback);
2050            PORT_SetEventMask(handle, event_mask);
2051            PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
2052
2053            PORT_GetState(handle, &port_state);
2054
2055            port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2056
2057            /* coverity[uninit_use_in_call]
2058               FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2059            PORT_SetState(handle, &port_state);
2060
2061            evt_data.handle = p_cb->handle;
2062        }
2063        else
2064        {
2065            evt_data.status = BTA_JV_FAILURE;
2066            APPL_TRACE_ERROR("run out of rfc control block");
2067        }
2068    }
2069    cc->p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, (tBTA_JV *)&evt_data, cc->user_data);
2070    if(evt_data.status == BTA_JV_FAILURE)
2071    {
2072        if(sec_id)
2073            bta_jv_free_sec_id(&sec_id);
2074        if(handle)
2075            RFCOMM_RemoveConnection(handle);
2076    }
2077 }
2078
2079static int find_rfc_pcb(void* user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb)
2080{
2081    *cb = NULL;
2082    *pcb = NULL;
2083    int i;
2084    for (i = 0; i < MAX_RFC_PORTS; i++)
2085    {
2086        UINT32 rfc_handle = bta_jv_cb.port_cb[i].handle & BTA_JV_RFC_HDL_MASK;
2087        rfc_handle &= ~BTA_JV_RFCOMM_MASK;
2088        if (rfc_handle && bta_jv_cb.port_cb[i].user_data == user_data)
2089        {
2090            *pcb = &bta_jv_cb.port_cb[i];
2091            *cb = &bta_jv_cb.rfc_cb[rfc_handle - 1];
2092            APPL_TRACE_DEBUG("find_rfc_pcb(): FOUND rfc_cb_handle 0x%x, port.jv_handle:"
2093                    " 0x%x, state: %d, rfc_cb->handle: 0x%x", rfc_handle, (*pcb)->handle,
2094                    (*pcb)->state, (*cb)->handle);
2095            return 1;
2096        }
2097    }
2098    APPL_TRACE_DEBUG("find_rfc_pcb: cannot find rfc_cb from user data:%d", (UINT32)user_data);
2099    return 0;
2100}
2101
2102/*******************************************************************************
2103**
2104** Function     bta_jv_rfcomm_close
2105**
2106** Description  Close an RFCOMM connection
2107**
2108** Returns      void
2109**
2110*******************************************************************************/
2111void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
2112{
2113    tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close);
2114    tBTA_JV_RFC_CB           *p_cb = NULL;
2115    tBTA_JV_PCB              *p_pcb = NULL;
2116    APPL_TRACE_DEBUG("bta_jv_rfcomm_close, rfc handle:%d", cc->handle);
2117    if (!cc->handle)
2118    {
2119        APPL_TRACE_ERROR("bta_jv_rfcomm_close, rfc handle is null");
2120        return;
2121    }
2122
2123    void* user_data = cc->user_data;
2124    if (!find_rfc_pcb(user_data, &p_cb, &p_pcb))
2125        return;
2126    bta_jv_free_rfc_cb(p_cb, p_pcb);
2127    APPL_TRACE_DEBUG("bta_jv_rfcomm_close: sec id in use:%d, rfc_cb in use:%d",
2128                get_sec_id_used(), get_rfc_cb_used());
2129}
2130
2131/*******************************************************************************
2132**
2133** Function     bta_jv_port_mgmt_sr_cback
2134**
2135** Description  callback for port mamangement function of rfcomm
2136**              server connections
2137**
2138** Returns      void
2139**
2140*******************************************************************************/
2141static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle)
2142{
2143    tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
2144    tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle);
2145    tBTA_JV evt_data;
2146    BD_ADDR rem_bda;
2147    UINT16 lcid;
2148    UINT8  num;
2149    UINT32  si;
2150    APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:%d, port_handle:%d", code, port_handle);
2151    if(NULL == p_cb || NULL == p_cb->p_cback)
2152    {
2153        APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p",
2154                p_cb, p_cb ? p_cb->p_cback : NULL);
2155        return;
2156    }
2157    void *user_data = p_pcb->user_data;
2158    APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%d port_handle:0x%x handle:0x%x, p_pcb:%p, user:%d",
2159        code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data);
2160
2161    PORT_CheckConnection(port_handle, rem_bda, &lcid);
2162    int failed = TRUE;
2163    if (code == PORT_SUCCESS)
2164    {
2165        evt_data.rfc_srv_open.handle = p_pcb->handle;
2166        evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
2167        bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
2168        tBTA_JV_PCB *p_pcb_new_listen  = bta_jv_add_rfc_port(p_cb, p_pcb);
2169        if (p_pcb_new_listen)
2170        {
2171            evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle;
2172            p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
2173            APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess);
2174            failed = FALSE;
2175        }
2176        else
2177            APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port");
2178    }
2179    if (failed)
2180    {
2181        evt_data.rfc_close.handle = p_cb->handle;
2182        evt_data.rfc_close.status = BTA_JV_FAILURE;
2183        evt_data.rfc_close.async = TRUE;
2184        evt_data.rfc_close.port_status = code;
2185        p_pcb->cong = FALSE;
2186
2187        tBTA_JV_RFCOMM_CBACK    *p_cback = p_cb->p_cback;
2188        APPL_TRACE_DEBUG("PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
2189                            p_cb->curr_sess, p_cb->max_sess);
2190        if(BTA_JV_ST_SR_CLOSING == p_pcb->state)
2191        {
2192            evt_data.rfc_close.async = FALSE;
2193            evt_data.rfc_close.status = BTA_JV_SUCCESS;
2194        }
2195        //p_pcb->state = BTA_JV_ST_NONE;
2196        p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
2197        //bta_jv_free_rfc_cb(p_cb, p_pcb);
2198
2199        APPL_TRACE_DEBUG("PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
2200                p_cb->curr_sess, p_cb->max_sess);
2201     }
2202}
2203
2204/*******************************************************************************
2205**
2206** Function     bta_jv_port_event_sr_cback
2207**
2208** Description  Callback for RFCOMM server port events
2209**
2210** Returns      void
2211**
2212*******************************************************************************/
2213static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle)
2214{
2215    tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
2216    tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle);
2217    tBTA_JV evt_data;
2218
2219    if(NULL == p_cb || NULL == p_cb->p_cback)
2220        return;
2221
2222    APPL_TRACE_DEBUG( "bta_jv_port_event_sr_cback code=x%x port_handle:%d handle:%d",
2223        code, port_handle, p_cb->handle);
2224
2225    void *user_data = p_pcb->user_data;
2226    if (code & PORT_EV_RXCHAR)
2227    {
2228        evt_data.data_ind.handle = p_cb->handle;
2229        p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, user_data);
2230    }
2231
2232    if (code & PORT_EV_FC)
2233    {
2234        p_pcb->cong = (code & PORT_EV_FCS) ? FALSE : TRUE;
2235        evt_data.rfc_cong.cong = p_pcb->cong;
2236        evt_data.rfc_cong.handle = p_cb->handle;
2237        evt_data.rfc_cong.status = BTA_JV_SUCCESS;
2238        p_cb->p_cback(BTA_JV_RFCOMM_CONG_EVT, &evt_data, user_data);
2239    }
2240
2241    if (code & PORT_EV_TXEMPTY)
2242    {
2243        bta_jv_pm_conn_idle(p_pcb->p_pm_cb);
2244    }
2245}
2246
2247/*******************************************************************************
2248**
2249** Function     bta_jv_add_rfc_port
2250**
2251** Description  add a port for server when the existing posts is open
2252**
2253** Returns   return a pointer to tBTA_JV_PCB just added
2254**
2255*******************************************************************************/
2256static tBTA_JV_PCB * bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb_open)
2257{
2258    UINT8   used = 0, i, listen=0;
2259    UINT32  si = 0;
2260    tPORT_STATE port_state;
2261    UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2262    tBTA_JV_PCB *p_pcb = NULL;
2263    if (p_cb->max_sess > 1)
2264    {
2265        for (i=0; i < p_cb->max_sess; i++)
2266        {
2267            if (p_cb->rfc_hdl[i] != 0)
2268            {
2269                p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1];
2270                if (p_pcb->state == BTA_JV_ST_SR_LISTEN)
2271                {
2272                    listen++;
2273                    if(p_pcb_open == p_pcb)
2274                    {
2275                        APPL_TRACE_DEBUG("bta_jv_add_rfc_port, port_handle:%d, change the listen port to open state",
2276                                              p_pcb->port_handle);
2277                        p_pcb->state = BTA_JV_ST_SR_OPEN;
2278
2279                    }
2280                    else
2281                    {
2282                        APPL_TRACE_ERROR("bta_jv_add_rfc_port, open pcb not matching listen one,"
2283                            "listen count:%d, listen pcb handle:%d, open pcb:%d",
2284                               listen, p_pcb->port_handle, p_pcb_open->handle);
2285                        return NULL;
2286                    }
2287                }
2288                used++;
2289            }
2290            else if (si == 0)
2291            {
2292                si = i + 1;
2293            }
2294        }
2295
2296        APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d",
2297                    p_cb->max_sess, used, p_cb->curr_sess, listen, si);
2298        if (used < p_cb->max_sess && listen == 1 && si)
2299        {
2300            si--;
2301            if (RFCOMM_CreateConnection(p_cb->sec_id, p_cb->scn, TRUE,
2302                BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &(p_cb->rfc_hdl[si]), bta_jv_port_mgmt_sr_cback) == PORT_SUCCESS)
2303            {
2304                p_cb->curr_sess++;
2305                p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[si] - 1];
2306                p_pcb->state = BTA_JV_ST_SR_LISTEN;
2307                p_pcb->port_handle = p_cb->rfc_hdl[si];
2308                p_pcb->user_data = p_pcb_open->user_data;
2309
2310                PORT_ClearKeepHandleFlag(p_pcb->port_handle);
2311                PORT_SetEventCallback(p_pcb->port_handle, bta_jv_port_event_sr_cback);
2312                PORT_SetDataCOCallback (p_pcb->port_handle, bta_jv_port_data_co_cback);
2313                PORT_SetEventMask(p_pcb->port_handle, event_mask);
2314                PORT_GetState(p_pcb->port_handle, &port_state);
2315
2316                port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2317
2318/* coverity[uninit_use_in_call]
2319FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2320                PORT_SetState(p_pcb->port_handle, &port_state);
2321                p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si);
2322                APPL_TRACE_DEBUG("bta_jv_add_rfc_port: p_pcb->handle:0x%x, curr_sess:%d",
2323                                    p_pcb->handle, p_cb->curr_sess);
2324            }
2325        }
2326        else
2327            APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port");
2328    }
2329    APPL_TRACE_DEBUG("bta_jv_add_rfc_port: sec id in use:%d, rfc_cb in use:%d",
2330                get_sec_id_used(), get_rfc_cb_used());
2331    return p_pcb;
2332}
2333
2334/*******************************************************************************
2335**
2336** Function     bta_jv_rfcomm_start_server
2337**
2338** Description  waits for an RFCOMM client to connect
2339**
2340**
2341** Returns      void
2342**
2343*******************************************************************************/
2344void bta_jv_rfcomm_start_server(tBTA_JV_MSG *p_data)
2345{
2346    UINT16 handle = 0;
2347    UINT32 event_mask = BTA_JV_RFC_EV_MASK;
2348    tPORT_STATE port_state;
2349    UINT8   sec_id = 0;
2350    tBTA_JV_RFC_CB  *p_cb = NULL;
2351    tBTA_JV_PCB     *p_pcb;
2352    tBTA_JV_API_RFCOMM_SERVER *rs = &(p_data->rfcomm_server);
2353    tBTA_JV_RFCOMM_START        evt_data = {0};
2354    /* TODO DM role manager
2355    L2CA_SetDesireRole(rs->role);
2356    */
2357    evt_data.status = BTA_JV_FAILURE;
2358    APPL_TRACE_DEBUG("bta_jv_rfcomm_start_server: sec id in use:%d, rfc_cb in use:%d",
2359                get_sec_id_used(), get_rfc_cb_used());
2360
2361    do
2362    {
2363        sec_id = bta_jv_alloc_sec_id();
2364
2365        if (0 == sec_id ||
2366            BTM_SetSecurityLevel(FALSE, "JV PORT", sec_id,  rs->sec_mask,
2367                BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, rs->local_scn) == FALSE)
2368        {
2369            APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of sec_id");
2370            break;
2371        }
2372
2373        if (RFCOMM_CreateConnection(sec_id, rs->local_scn, TRUE,
2374            BTA_JV_DEF_RFC_MTU, (UINT8 *) bd_addr_any, &handle, bta_jv_port_mgmt_sr_cback) != PORT_SUCCESS)
2375        {
2376            APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, RFCOMM_CreateConnection failed");
2377            break;
2378        }
2379
2380
2381        p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb);
2382        if(!p_cb)
2383        {
2384            APPL_TRACE_ERROR("bta_jv_rfcomm_start_server, run out of rfc control block");
2385            break;
2386        }
2387
2388        p_cb->max_sess = rs->max_session;
2389        p_cb->p_cback = rs->p_cback;
2390        p_cb->sec_id = sec_id;
2391        p_cb->scn = rs->local_scn;
2392        p_pcb->state = BTA_JV_ST_SR_LISTEN;
2393        p_pcb->user_data = rs->user_data;
2394        evt_data.status = BTA_JV_SUCCESS;
2395        evt_data.handle = p_cb->handle;
2396        evt_data.sec_id = sec_id;
2397        evt_data.use_co = TRUE; //FALSE;
2398
2399        PORT_ClearKeepHandleFlag(handle);
2400        PORT_SetEventCallback(handle, bta_jv_port_event_sr_cback);
2401        PORT_SetEventMask(handle, event_mask);
2402        PORT_GetState(handle, &port_state);
2403
2404        port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
2405
2406/* coverity[uninit_use_in_call]
2407FALSE-POSITIVE: port_state is initialized at PORT_GetState() */
2408        PORT_SetState(handle, &port_state);
2409    } while (0);
2410    rs->p_cback(BTA_JV_RFCOMM_START_EVT, (tBTA_JV *)&evt_data, rs->user_data);
2411    if(evt_data.status == BTA_JV_SUCCESS)
2412    {
2413        PORT_SetDataCOCallback (handle, bta_jv_port_data_co_cback);
2414    }
2415    else
2416    {
2417        if(sec_id)
2418            bta_jv_free_sec_id(&sec_id);
2419        if(handle)
2420            RFCOMM_RemoveConnection(handle);
2421    }
2422}
2423
2424/*******************************************************************************
2425**
2426** Function     bta_jv_rfcomm_stop_server
2427**
2428** Description  stops an RFCOMM server
2429**
2430** Returns      void
2431**
2432*******************************************************************************/
2433
2434void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data)
2435{
2436    tBTA_JV_API_RFCOMM_SERVER *ls = &(p_data->rfcomm_server);
2437    tBTA_JV_RFC_CB           *p_cb = NULL;
2438    tBTA_JV_PCB              *p_pcb = NULL;
2439    APPL_TRACE_ERROR("bta_jv_rfcomm_stop_server");
2440    if(!ls->handle)
2441    {
2442        APPL_TRACE_ERROR("bta_jv_rfcomm_stop_server, jv handle is null");
2443        return;
2444    }
2445    void* user_data = ls->user_data;
2446    if(!find_rfc_pcb(user_data, &p_cb, &p_pcb))
2447        return;
2448    APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d",
2449                        p_pcb, p_pcb->port_handle);
2450    bta_jv_free_rfc_cb(p_cb, p_pcb);
2451    APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d",
2452                get_sec_id_used(), get_rfc_cb_used());
2453}
2454
2455/*******************************************************************************
2456**
2457** Function     bta_jv_rfcomm_read
2458**
2459** Description  Read data from an RFCOMM connection
2460**
2461** Returns      void
2462**
2463*******************************************************************************/
2464void bta_jv_rfcomm_read(tBTA_JV_MSG *p_data)
2465{
2466    tBTA_JV_API_RFCOMM_READ *rc = &(p_data->rfcomm_read);
2467    tBTA_JV_RFC_CB  *p_cb = rc->p_cb;
2468    tBTA_JV_PCB     *p_pcb = rc->p_pcb;
2469    tBTA_JV_RFCOMM_READ    evt_data;
2470
2471    evt_data.status = BTA_JV_FAILURE;
2472    evt_data.handle = p_cb->handle;
2473    evt_data.req_id = rc->req_id;
2474    evt_data.p_data = rc->p_data;
2475    if (PORT_ReadData(rc->p_pcb->port_handle, (char *)rc->p_data, rc->len, &evt_data.len) ==
2476        PORT_SUCCESS)
2477    {
2478        evt_data.status = BTA_JV_SUCCESS;
2479    }
2480
2481    p_cb->p_cback(BTA_JV_RFCOMM_READ_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2482}
2483
2484/*******************************************************************************
2485**
2486** Function     bta_jv_rfcomm_write
2487**
2488** Description  write data to an RFCOMM connection
2489**
2490** Returns      void
2491**
2492*******************************************************************************/
2493void bta_jv_rfcomm_write(tBTA_JV_MSG *p_data)
2494{
2495    tBTA_JV_API_RFCOMM_WRITE *wc = &(p_data->rfcomm_write);
2496    tBTA_JV_RFC_CB  *p_cb = wc->p_cb;
2497    tBTA_JV_PCB     *p_pcb = wc->p_pcb;
2498    tBTA_JV_RFCOMM_WRITE    evt_data;
2499
2500    evt_data.status = BTA_JV_FAILURE;
2501    evt_data.handle = p_cb->handle;
2502    evt_data.req_id = wc->req_id;
2503    evt_data.cong   = p_pcb->cong;
2504    evt_data.len    = 0;
2505    bta_jv_pm_conn_busy(p_pcb->p_pm_cb);
2506    if (!evt_data.cong &&
2507        PORT_WriteDataCO(p_pcb->port_handle, &evt_data.len) ==
2508        PORT_SUCCESS)
2509    {
2510        evt_data.status = BTA_JV_SUCCESS;
2511    }
2512    //update congestion flag
2513    evt_data.cong   = p_pcb->cong;
2514    if (p_cb->p_cback)
2515    {
2516        p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
2517    }
2518    else
2519    {
2520        APPL_TRACE_ERROR("bta_jv_rfcomm_write :: WARNING ! No JV callback set");
2521    }
2522}
2523
2524/*******************************************************************************
2525 **
2526 ** Function     bta_jv_set_pm_profile
2527 **
2528 ** Description  Set or free power mode profile for a JV application
2529 **
2530 ** Returns      void
2531 **
2532 *******************************************************************************/
2533void bta_jv_set_pm_profile(tBTA_JV_MSG *p_data)
2534{
2535    tBTA_JV_STATUS status;
2536    tBTA_JV_PM_CB *p_cb;
2537
2538    APPL_TRACE_API("bta_jv_set_pm_profile(handle: 0x%x, app_id: %d, init_st: %d)",
2539            p_data->set_pm.handle, p_data->set_pm.app_id, p_data->set_pm.init_st);
2540
2541    /* clear PM control block */
2542    if (p_data->set_pm.app_id == BTA_JV_PM_ID_CLEAR)
2543    {
2544        status = bta_jv_free_set_pm_profile_cb(p_data->set_pm.handle);
2545
2546        if (status != BTA_JV_SUCCESS)
2547        {
2548            APPL_TRACE_WARNING("bta_jv_set_pm_profile() free pm cb failed: reason %d",
2549                    status);
2550        }
2551    }
2552    else /* set PM control block */
2553    {
2554        p_cb = bta_jv_alloc_set_pm_profile_cb(p_data->set_pm.handle,
2555                p_data->set_pm.app_id);
2556
2557        if (NULL != p_cb)
2558            bta_jv_pm_state_change(p_cb, p_data->set_pm.init_st);
2559        else
2560            APPL_TRACE_WARNING("bta_jv_alloc_set_pm_profile_cb() failed");
2561    }
2562}
2563
2564/*******************************************************************************
2565 **
2566 ** Function     bta_jv_change_pm_state
2567 **
2568 ** Description  change jv pm connect state, used internally
2569 **
2570 ** Returns      void
2571 **
2572 *******************************************************************************/
2573void bta_jv_change_pm_state(tBTA_JV_MSG *p_data)
2574{
2575    tBTA_JV_API_PM_STATE_CHANGE *p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)p_data;
2576
2577    if (p_msg->p_cb)
2578        bta_jv_pm_state_change(p_msg->p_cb, p_msg->state);
2579}
2580
2581
2582/*******************************************************************************
2583 **
2584 ** Function    bta_jv_set_pm_conn_state
2585 **
2586 ** Description Send pm event state change to jv state machine to serialize jv pm changes
2587 **             in relation to other jv messages. internal API use mainly.
2588 **
2589 ** Params:     p_cb: jv pm control block, NULL pointer returns failure
2590 **             new_state: new PM connections state, setting is forced by action function
2591 **
2592 ** Returns     BTA_JV_SUCCESS, BTA_JV_FAILURE (buffer allocation, or NULL ptr!)
2593 **
2594 *******************************************************************************/
2595tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE
2596        new_st)
2597{
2598    tBTA_JV_STATUS status = BTA_JV_FAILURE;
2599    tBTA_JV_API_PM_STATE_CHANGE *p_msg;
2600
2601    if (NULL == p_cb)
2602        return status;
2603
2604    APPL_TRACE_API("bta_jv_set_pm_conn_state(handle:0x%x, state: %d)", p_cb->handle,
2605            new_st);
2606    if ((p_msg = (tBTA_JV_API_PM_STATE_CHANGE *)GKI_getbuf(
2607            sizeof(tBTA_JV_API_PM_STATE_CHANGE))) != NULL)
2608    {
2609        p_msg->hdr.event = BTA_JV_API_PM_STATE_CHANGE_EVT;
2610        p_msg->p_cb = p_cb;
2611        p_msg->state = new_st;
2612        bta_sys_sendmsg(p_msg);
2613        status = BTA_JV_SUCCESS;
2614    }
2615    return (status);
2616}
2617
2618/*******************************************************************************
2619 **
2620 ** Function    bta_jv_pm_conn_busy
2621 **
2622 ** Description set pm connection busy state (input param safe)
2623 **
2624 ** Params      p_cb: pm control block of jv connection
2625 **
2626 ** Returns     void
2627 **
2628 *******************************************************************************/
2629static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB *p_cb)
2630{
2631    if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST == p_cb->state))
2632        bta_jv_pm_state_change(p_cb, BTA_JV_CONN_BUSY);
2633}
2634
2635/*******************************************************************************
2636 **
2637 ** Function    bta_jv_pm_conn_busy
2638 **
2639 ** Description set pm connection busy state (input param safe)
2640 **
2641 ** Params      p_cb: pm control block of jv connection
2642 **
2643 ** Returns     void
2644 **
2645 *******************************************************************************/
2646static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb)
2647{
2648    if ((NULL != p_cb) && (BTA_JV_PM_IDLE_ST != p_cb->state))
2649        bta_jv_pm_state_change(p_cb, BTA_JV_CONN_IDLE);
2650}
2651
2652/*******************************************************************************
2653 **
2654 ** Function     bta_jv_pm_state_change
2655 **
2656 ** Description  Notify power manager there is state change
2657 **
2658 ** Params      p_cb: must be NONE NULL
2659 **
2660 ** Returns      void
2661 **
2662 *******************************************************************************/
2663static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state)
2664{
2665    APPL_TRACE_API("bta_jv_pm_state_change(p_cb: 0x%x, handle: 0x%x, busy/idle_state: %d"
2666            ", app_id: %d, conn_state: %d)", p_cb, p_cb->handle, p_cb->state,
2667            p_cb->app_id, state);
2668
2669    switch (state)
2670    {
2671    case BTA_JV_CONN_OPEN:
2672        bta_sys_conn_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2673        break;
2674
2675    case BTA_JV_CONN_CLOSE:
2676        bta_sys_conn_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2677        break;
2678
2679    case BTA_JV_APP_OPEN:
2680        bta_sys_app_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2681        break;
2682
2683    case BTA_JV_APP_CLOSE:
2684        bta_sys_app_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2685        break;
2686
2687    case BTA_JV_SCO_OPEN:
2688        bta_sys_sco_open(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2689        break;
2690
2691    case BTA_JV_SCO_CLOSE:
2692        bta_sys_sco_close(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2693        break;
2694
2695    case BTA_JV_CONN_IDLE:
2696        p_cb->state = BTA_JV_PM_IDLE_ST;
2697        bta_sys_idle(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2698        break;
2699
2700    case BTA_JV_CONN_BUSY:
2701        p_cb->state = BTA_JV_PM_BUSY_ST;
2702        bta_sys_busy(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr);
2703        break;
2704
2705    default:
2706        APPL_TRACE_WARNING("bta_jv_pm_state_change(state: %d): Invalid state", state);
2707        break;
2708    }
2709}
2710