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