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