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