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