1 /******************************************************************************
2  *
3  *  Copyright 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 is the implementation of the JAVA API for Bluetooth Wireless
22  *  Technology (JABWT) as specified by the JSR82 specificiation
23  *
24  ******************************************************************************/
25 
26 #include <base/functional/bind.h>
27 #include <base/location.h>
28 #include <bluetooth/log.h>
29 
30 #include <cstdint>
31 #include <memory>
32 
33 #include "bta/jv/bta_jv_int.h"
34 #include "internal_include/bt_target.h"
35 #include "internal_include/bt_trace.h"
36 #include "osi/include/allocator.h"
37 #include "stack/include/bt_hdr.h"
38 #include "stack/include/gap_api.h"
39 #include "stack/include/main_thread.h"
40 #include "types/bluetooth/uuid.h"
41 #include "types/raw_address.h"
42 
43 using base::Bind;
44 using bluetooth::Uuid;
45 using namespace bluetooth;
46 
47 namespace {
48 bool bta_jv_enabled = false;
49 }
50 
51 /*******************************************************************************
52  *
53  * Function         BTA_JvEnable
54  *
55  * Description      Enable the Java I/F service. When the enable
56  *                  operation is complete the callback function will be
57  *                  called with a BTA_JV_ENABLE_EVT. This function must
58  *                  be called before other function in the JV API are
59  *                  called.
60  *
61  * Returns          tBTA_JV_STATUS::SUCCESS if successful.
62  *                  tBTA_JV_STATUS::FAILURE if internal failure.
63  *
64  ******************************************************************************/
BTA_JvEnable(tBTA_JV_DM_CBACK * p_cback)65 tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK* p_cback) {
66   log::verbose("");
67   if (!p_cback || bta_jv_enabled) {
68     log::error("failure");
69     return tBTA_JV_STATUS::FAILURE;
70   }
71 
72   memset(&bta_jv_cb, 0, sizeof(tBTA_JV_CB));
73   /* set handle to invalid value by default */
74   for (int i = 0; i < BTA_JV_PM_MAX_NUM; i++) {
75     bta_jv_cb.pm_cb[i].handle = BTA_JV_PM_HANDLE_CLEAR;
76   }
77   bta_jv_cb.dyn_psm = 0xfff;
78   used_l2cap_classic_dynamic_psm = {};
79 
80   bta_jv_enabled = true;
81 
82   do_in_main_thread(Bind(&bta_jv_enable, p_cback));
83   return tBTA_JV_STATUS::SUCCESS;
84 }
85 
86 /** Disable the Java I/F */
BTA_JvDisable(void)87 void BTA_JvDisable(void) {
88   log::verbose("");
89 
90   bta_jv_enabled = false;
91 
92   do_in_main_thread(Bind(&bta_jv_disable));
93 }
94 
95 /*******************************************************************************
96  *
97  * Function         BTA_JvGetChannelId
98  *
99  * Description      This function reserves a SCN (server channel number) for
100  *                  applications running over RFCOMM, L2CAP of L2CAP_LE.
101  *                  It is primarily called by server profiles/applications to
102  *                  register their SCN into the SDP database. The SCN is
103  *                  reported by the tBTA_JV_DM_CBACK callback with a
104  *                  BTA_JV_GET_SCN_EVT for RFCOMM channels and
105  *                  BTA_JV_GET_PSM_EVT for L2CAP and LE.
106  *                  If the SCN/PSM reported is 0, that means all resources are
107  *                  exhausted.
108  * Parameters
109  *   conn_type      one of BTA_JV_CONN_TYPE
110  *   user_data      Any uservalue - will be returned in the resulting event.
111  *   channel        Only used for RFCOMM - to try to allocate a specific RFCOMM
112  *                  channel.
113  *
114  * Returns          void
115  *
116  ******************************************************************************/
BTA_JvGetChannelId(tBTA_JV_CONN_TYPE conn_type,uint32_t id,int32_t channel)117 void BTA_JvGetChannelId(tBTA_JV_CONN_TYPE conn_type, uint32_t id, int32_t channel) {
118   log::verbose("conn_type:{}, id:{}, channel:{}", bta_jv_conn_type_text(conn_type), id, channel);
119 
120   do_in_main_thread(Bind(&bta_jv_get_channel_id, conn_type, channel, id, id));
121 }
122 
123 /*******************************************************************************
124  *
125  * Function         BTA_JvFreeChannel
126  *
127  * Description      This function frees a server channel number that was used
128  *                  by an application running over RFCOMM.
129  * Parameters
130  *   channel        The channel to free
131  *   conn_type      one of BTA_JV_CONN_TYPE
132  *
133  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
134  *                  tBTA_JV_STATUS::FAILURE, otherwise.
135  *
136  ******************************************************************************/
BTA_JvFreeChannel(uint16_t channel,tBTA_JV_CONN_TYPE conn_type)137 tBTA_JV_STATUS BTA_JvFreeChannel(uint16_t channel, tBTA_JV_CONN_TYPE conn_type) {
138   log::verbose("channel:{}, conn_type:{}", channel, bta_jv_conn_type_text(conn_type));
139 
140   do_in_main_thread(Bind(&bta_jv_free_scn, conn_type, channel));
141   return tBTA_JV_STATUS::SUCCESS;
142 }
143 
144 /*******************************************************************************
145  *
146  * Function         BTA_JvStartDiscovery
147  *
148  * Description      This function performs service discovery for the services
149  *                  provided by the given peer device. When the operation is
150  *                  complete the tBTA_JV_DM_CBACK callback function will be
151  *                  called with a BTA_JV_DISCOVERY_COMP_EVT.
152  *
153  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
154  *                  tBTA_JV_STATUS::FAILURE, otherwise.
155  *
156  ******************************************************************************/
BTA_JvStartDiscovery(const RawAddress & bd_addr,uint16_t num_uuid,const Uuid * p_uuid_list,uint32_t rfcomm_slot_id)157 tBTA_JV_STATUS BTA_JvStartDiscovery(const RawAddress& bd_addr, uint16_t num_uuid,
158                                     const Uuid* p_uuid_list, uint32_t rfcomm_slot_id) {
159   log::verbose("bd_addr:{}, rfcomm_slot_id:{}, num_uuid:{}", bd_addr, rfcomm_slot_id, num_uuid);
160 
161   Uuid* uuid_list_copy = new Uuid[num_uuid];
162   memcpy(uuid_list_copy, p_uuid_list, num_uuid * sizeof(Uuid));
163 
164   do_in_main_thread(Bind(&bta_jv_start_discovery, bd_addr, num_uuid, base::Owned(uuid_list_copy),
165                          rfcomm_slot_id));
166   return tBTA_JV_STATUS::SUCCESS;
167 }
168 
169 /*******************************************************************************
170  *
171  * Function         BTA_JvCancelDiscovery
172  *
173  * Description      This function cancels the ongoing service discovery and make
174  *                  sure the tBTA_JV_DM_CBACK callback function will be called
175  *                  with a BTA_JV_DISCOVERY_COMP_EVT.
176  *
177  * Returns          void
178  *
179  ******************************************************************************/
BTA_JvCancelDiscovery(uint32_t rfcomm_slot_id)180 void BTA_JvCancelDiscovery(uint32_t rfcomm_slot_id) {
181   log::verbose("rfcomm_slot_id:{}", rfcomm_slot_id);
182   do_in_main_thread(Bind(&bta_jv_cancel_discovery, rfcomm_slot_id));
183 }
184 
185 /*******************************************************************************
186  *
187  * Function         BTA_JvCreateRecord
188  *
189  * Description      Create a service record in the local SDP database.
190  *                  When the operation is complete the tBTA_JV_DM_CBACK callback
191  *                  function will be called with a BTA_JV_CREATE_RECORD_EVT.
192  *
193  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
194  *                  tBTA_JV_STATUS::FAILURE, otherwise.
195  *
196  ******************************************************************************/
BTA_JvCreateRecordByUser(uint32_t rfcomm_slot_id)197 tBTA_JV_STATUS BTA_JvCreateRecordByUser(uint32_t rfcomm_slot_id) {
198   log::verbose("rfcomm_slot_id: {}", rfcomm_slot_id);
199 
200   do_in_main_thread(Bind(&bta_jv_create_record, rfcomm_slot_id));
201   return tBTA_JV_STATUS::SUCCESS;
202 }
203 
204 /*******************************************************************************
205  *
206  * Function         BTA_JvDeleteRecord
207  *
208  * Description      Delete a service record in the local SDP database.
209  *
210  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
211  *                  tBTA_JV_STATUS::FAILURE, otherwise.
212  *
213  ******************************************************************************/
BTA_JvDeleteRecord(uint32_t handle)214 tBTA_JV_STATUS BTA_JvDeleteRecord(uint32_t handle) {
215   log::verbose("handle:{}", handle);
216 
217   do_in_main_thread(Bind(&bta_jv_delete_record, handle));
218   return tBTA_JV_STATUS::SUCCESS;
219 }
220 
221 /*******************************************************************************
222  *
223  * Function         BTA_JvL2capConnect
224  *
225  * Description      Initiate a connection as a L2CAP client to the given BD
226  *                  Address.
227  *                  When the connection is initiated or failed to initiate,
228  *                  tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_CL_INIT_EVT
229  *                  When the connection is established or failed,
230  *                  tBTA_JV_L2CAP_CBACK is called with BTA_JV_L2CAP_OPEN_EVT
231  *
232  ******************************************************************************/
BTA_JvL2capConnect(tBTA_JV_CONN_TYPE conn_type,tBTA_SEC sec_mask,std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info,uint16_t remote_psm,uint16_t rx_mtu,std::unique_ptr<tL2CAP_CFG_INFO> cfg,const RawAddress & peer_bd_addr,tBTA_JV_L2CAP_CBACK * p_cback,uint32_t l2cap_socket_id)233 void BTA_JvL2capConnect(tBTA_JV_CONN_TYPE conn_type, tBTA_SEC sec_mask,
234                         std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info, uint16_t remote_psm,
235                         uint16_t rx_mtu, std::unique_ptr<tL2CAP_CFG_INFO> cfg,
236                         const RawAddress& peer_bd_addr, tBTA_JV_L2CAP_CBACK* p_cback,
237                         uint32_t l2cap_socket_id) {
238   log::verbose("conn_type:{}, remote_psm:{}, peer_bd_addr:{}, l2cap_socket_id:{}",
239                bta_jv_conn_type_text(conn_type), remote_psm, peer_bd_addr, l2cap_socket_id);
240   log::assert_that(p_cback != nullptr, "assert failed: p_cback != nullptr");
241 
242   do_in_main_thread(Bind(&bta_jv_l2cap_connect, conn_type, sec_mask, remote_psm, rx_mtu,
243                          peer_bd_addr, base::Passed(&cfg), base::Passed(&ertm_info), p_cback,
244                          l2cap_socket_id));
245 }
246 
247 /*******************************************************************************
248  *
249  * Function         BTA_JvL2capClose
250  *
251  * Description      This function closes an L2CAP client connection
252  *
253  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
254  *                  tBTA_JV_STATUS::FAILURE, otherwise.
255  *
256  ******************************************************************************/
BTA_JvL2capClose(uint32_t handle)257 tBTA_JV_STATUS BTA_JvL2capClose(uint32_t handle) {
258   log::verbose("handle:{}", handle);
259 
260   if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) {
261     return tBTA_JV_STATUS::FAILURE;
262   }
263 
264   do_in_main_thread(Bind(&bta_jv_l2cap_close, handle, &bta_jv_cb.l2c_cb[handle]));
265   return tBTA_JV_STATUS::SUCCESS;
266 }
267 
268 /*******************************************************************************
269  *
270  * Function         BTA_JvL2capStartServer
271  *
272  * Description      This function starts an L2CAP server and listens for an
273  *                  L2CAP connection from a remote Bluetooth device.  When the
274  *                  server is started successfully, tBTA_JV_L2CAP_CBACK is
275  *                  called with BTA_JV_L2CAP_START_EVT.  When the connection is
276  *                  established tBTA_JV_L2CAP_CBACK is called with
277  *                  BTA_JV_L2CAP_OPEN_EVT.
278  *
279  * Returns          void
280  *
281  ******************************************************************************/
BTA_JvL2capStartServer(tBTA_JV_CONN_TYPE conn_type,tBTA_SEC sec_mask,std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info,uint16_t local_psm,uint16_t rx_mtu,std::unique_ptr<tL2CAP_CFG_INFO> cfg,tBTA_JV_L2CAP_CBACK * p_cback,uint32_t l2cap_socket_id)282 void BTA_JvL2capStartServer(tBTA_JV_CONN_TYPE conn_type, tBTA_SEC sec_mask,
283                             std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info, uint16_t local_psm,
284                             uint16_t rx_mtu, std::unique_ptr<tL2CAP_CFG_INFO> cfg,
285                             tBTA_JV_L2CAP_CBACK* p_cback, uint32_t l2cap_socket_id) {
286   log::verbose("conn_type:{}, local_psm:{}, l2cap_socket_id:{}", bta_jv_conn_type_text(conn_type),
287                local_psm, l2cap_socket_id);
288   CHECK(p_cback);
289 
290   do_in_main_thread(Bind(&bta_jv_l2cap_start_server, conn_type, sec_mask, local_psm, rx_mtu,
291                          base::Passed(&cfg), base::Passed(&ertm_info), p_cback, l2cap_socket_id));
292 }
293 
294 /*******************************************************************************
295  *
296  * Function         BTA_JvL2capStopServer
297  *
298  * Description      This function stops the L2CAP server. If the server has an
299  *                  active connection, it would be closed.
300  *
301  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
302  *                  tBTA_JV_STATUS::FAILURE, otherwise.
303  *
304  ******************************************************************************/
BTA_JvL2capStopServer(uint16_t local_psm,uint32_t l2cap_socket_id)305 tBTA_JV_STATUS BTA_JvL2capStopServer(uint16_t local_psm, uint32_t l2cap_socket_id) {
306   log::verbose("local_psm:{}, l2cap_socket_id:{}", local_psm, l2cap_socket_id);
307 
308   do_in_main_thread(Bind(&bta_jv_l2cap_stop_server, local_psm, l2cap_socket_id));
309   return tBTA_JV_STATUS::SUCCESS;
310 }
311 
312 /*******************************************************************************
313  *
314  * Function         BTA_JvL2capRead
315  *
316  * Description      This function reads data from an L2CAP connection
317  *                  When the operation is complete, tBTA_JV_L2CAP_CBACK is
318  *                  called with BTA_JV_L2CAP_READ_EVT.
319  *
320  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
321  *                  tBTA_JV_STATUS::FAILURE, otherwise.
322  *
323  ******************************************************************************/
BTA_JvL2capRead(uint32_t handle,uint32_t req_id,uint8_t * p_data,uint16_t len)324 tBTA_JV_STATUS BTA_JvL2capRead(uint32_t handle, uint32_t req_id, uint8_t* p_data, uint16_t len) {
325   log::verbose("handle:{}, req_id:{}, len:{}", handle, req_id, len);
326 
327   if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) {
328     return tBTA_JV_STATUS::FAILURE;
329   }
330 
331   tBTA_JV_L2CAP_READ evt_data;
332   evt_data.status = tBTA_JV_STATUS::FAILURE;
333   evt_data.handle = handle;
334   evt_data.req_id = req_id;
335   evt_data.p_data = p_data;
336   evt_data.len = 0;
337 
338   if (BT_PASS == GAP_ConnReadData((uint16_t)handle, p_data, len, &evt_data.len)) {
339     evt_data.status = tBTA_JV_STATUS::SUCCESS;
340   }
341   bta_jv_cb.l2c_cb[handle].p_cback(BTA_JV_L2CAP_READ_EVT, (tBTA_JV*)&evt_data,
342                                    bta_jv_cb.l2c_cb[handle].l2cap_socket_id);
343   return tBTA_JV_STATUS::SUCCESS;
344 }
345 
346 /*******************************************************************************
347  *
348  * Function         BTA_JvL2capReady
349  *
350  * Description      This function determined if there is data to read from
351  *                    an L2CAP connection
352  *
353  * Returns          tBTA_JV_STATUS::SUCCESS, if data queue size is in
354  *                  *p_data_size.
355  *                  tBTA_JV_STATUS::FAILURE, if error.
356  *
357  ******************************************************************************/
BTA_JvL2capReady(uint32_t handle,uint32_t * p_data_size)358 tBTA_JV_STATUS BTA_JvL2capReady(uint32_t handle, uint32_t* p_data_size) {
359   tBTA_JV_STATUS status = tBTA_JV_STATUS::FAILURE;
360 
361   log::verbose("handle:{}", handle);
362   if (p_data_size && handle < BTA_JV_MAX_L2C_CONN && bta_jv_cb.l2c_cb[handle].p_cback) {
363     *p_data_size = 0;
364     if (BT_PASS == GAP_GetRxQueueCnt((uint16_t)handle, p_data_size)) {
365       status = tBTA_JV_STATUS::SUCCESS;
366     }
367   }
368 
369   return status;
370 }
371 
372 /*******************************************************************************
373  *
374  * Function         BTA_JvL2capWrite
375  *
376  * Description      This function writes data to an L2CAP connection
377  *                  When the operation is complete, tBTA_JV_L2CAP_CBACK is
378  *                  called with BTA_JV_L2CAP_WRITE_EVT. Works for
379  *                  PSM-based connections. This function takes ownership of
380  *                  p_data, and will osi_free it. Data length must be smaller
381  *                  than remote maximum SDU size.
382  *
383  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
384  *                  tBTA_JV_STATUS::FAILURE, otherwise.
385  *
386  ******************************************************************************/
BTA_JvL2capWrite(uint32_t handle,uint32_t req_id,BT_HDR * msg,uint32_t user_id)387 tBTA_JV_STATUS BTA_JvL2capWrite(uint32_t handle, uint32_t req_id, BT_HDR* msg, uint32_t user_id) {
388   log::verbose("handle:{}, user_id:{}", handle, user_id);
389 
390   if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) {
391     osi_free(msg);
392     return tBTA_JV_STATUS::FAILURE;
393   }
394 
395   do_in_main_thread(
396           Bind(&bta_jv_l2cap_write, handle, req_id, msg, user_id, &bta_jv_cb.l2c_cb[handle]));
397   return tBTA_JV_STATUS::SUCCESS;
398 }
399 
400 /*******************************************************************************
401  *
402  * Function         BTA_JvRfcommConnect
403  *
404  * Description      This function makes an RFCOMM conection to a remote BD
405  *                  Address.
406  *                  When the connection is initiated or failed to initiate,
407  *                  tBTA_JV_RFCOMM_CBACK is called with
408  *                  BTA_JV_RFCOMM_CL_INIT_EVT
409  *                  When the connection is established or failed,
410  *                  tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_OPEN_EVT
411  *
412  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
413  *                  tBTA_JV_STATUS::FAILURE, otherwise.
414  *
415  ******************************************************************************/
BTA_JvRfcommConnect(tBTA_SEC sec_mask,uint8_t remote_scn,const RawAddress & peer_bd_addr,tBTA_JV_RFCOMM_CBACK * p_cback,uint32_t rfcomm_slot_id)416 tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, uint8_t remote_scn,
417                                    const RawAddress& peer_bd_addr, tBTA_JV_RFCOMM_CBACK* p_cback,
418                                    uint32_t rfcomm_slot_id) {
419   log::verbose("remote_scn:{}, peer_bd_addr:{}, rfcomm_slot_id:{}", remote_scn, peer_bd_addr,
420                rfcomm_slot_id);
421 
422   if (!p_cback) {
423     return tBTA_JV_STATUS::FAILURE; /* Nothing to do */
424   }
425 
426   do_in_main_thread(Bind(&bta_jv_rfcomm_connect, sec_mask, remote_scn, peer_bd_addr, p_cback,
427                          rfcomm_slot_id));
428   return tBTA_JV_STATUS::SUCCESS;
429 }
430 
431 /*******************************************************************************
432  *
433  * Function         BTA_JvRfcommClose
434  *
435  * Description      This function closes an RFCOMM connection
436  *
437  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
438  *                  tBTA_JV_STATUS::FAILURE, otherwise.
439  *
440  ******************************************************************************/
BTA_JvRfcommClose(uint32_t handle,uint32_t rfcomm_slot_id)441 tBTA_JV_STATUS BTA_JvRfcommClose(uint32_t handle, uint32_t rfcomm_slot_id) {
442   uint32_t hi = ((handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1;
443   uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(handle);
444 
445   log::verbose("handle:{}, rfcomm_slot_id:{}", handle, rfcomm_slot_id);
446 
447   if (hi >= BTA_JV_MAX_RFC_CONN || !bta_jv_cb.rfc_cb[hi].p_cback ||
448       si >= BTA_JV_MAX_RFC_SR_SESSION || !bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) {
449     return tBTA_JV_STATUS::FAILURE;
450   }
451 
452   do_in_main_thread(Bind(&bta_jv_rfcomm_close, handle, rfcomm_slot_id));
453   return tBTA_JV_STATUS::SUCCESS;
454 }
455 
456 /*******************************************************************************
457  *
458  * Function         BTA_JvRfcommStartServer
459  *
460  * Description      This function starts listening for an RFCOMM connection
461  *                  request from a remote Bluetooth device.  When the server is
462  *                  started successfully, tBTA_JV_RFCOMM_CBACK is called
463  *                  with BTA_JV_RFCOMM_START_EVT.
464  *                  When the connection is established, tBTA_JV_RFCOMM_CBACK
465  *                  is called with BTA_JV_RFCOMM_OPEN_EVT.
466  *
467  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
468  *                  tBTA_JV_STATUS::FAILURE, otherwise.
469  *
470  ******************************************************************************/
BTA_JvRfcommStartServer(tBTA_SEC sec_mask,uint8_t local_scn,uint8_t max_session,tBTA_JV_RFCOMM_CBACK * p_cback,uint32_t rfcomm_slot_id)471 tBTA_JV_STATUS BTA_JvRfcommStartServer(tBTA_SEC sec_mask, uint8_t local_scn, uint8_t max_session,
472                                        tBTA_JV_RFCOMM_CBACK* p_cback, uint32_t rfcomm_slot_id) {
473   log::verbose("local_scn:{}, rfcomm_slot_id:{}", local_scn, rfcomm_slot_id);
474 
475   if (p_cback == NULL) {
476     return tBTA_JV_STATUS::FAILURE; /* Nothing to do */
477   }
478 
479   if (max_session == 0) {
480     max_session = 1;
481   }
482   if (max_session > BTA_JV_MAX_RFC_SR_SESSION) {
483     log::info("max_session is too big. use max {}", BTA_JV_MAX_RFC_SR_SESSION);
484     max_session = BTA_JV_MAX_RFC_SR_SESSION;
485   }
486 
487   do_in_main_thread(Bind(&bta_jv_rfcomm_start_server, sec_mask, local_scn, max_session, p_cback,
488                          rfcomm_slot_id));
489   return tBTA_JV_STATUS::SUCCESS;
490 }
491 
492 /*******************************************************************************
493  *
494  * Function         BTA_JvRfcommStopServer
495  *
496  * Description      This function stops the RFCOMM server. If the server has an
497  *                  active connection, it would be closed.
498  *
499  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
500  *                  tBTA_JV_STATUS::FAILURE, otherwise.
501  *
502  ******************************************************************************/
BTA_JvRfcommStopServer(uint32_t handle,uint32_t rfcomm_slot_id)503 tBTA_JV_STATUS BTA_JvRfcommStopServer(uint32_t handle, uint32_t rfcomm_slot_id) {
504   log::verbose("handle:{}, rfcomm_slot_id:{}", handle, rfcomm_slot_id);
505 
506   do_in_main_thread(Bind(&bta_jv_rfcomm_stop_server, handle, rfcomm_slot_id));
507   return tBTA_JV_STATUS::SUCCESS;
508 }
509 
510 /*******************************************************************************
511  *
512  * Function         BTA_JvRfcommGetPortHdl
513  *
514  * Description      This function fetches the rfcomm port handle
515  *
516  * Returns
517  *
518  ******************************************************************************/
BTA_JvRfcommGetPortHdl(uint32_t handle)519 uint16_t BTA_JvRfcommGetPortHdl(uint32_t handle) {
520   uint32_t hi = ((handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1;
521   uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(handle);
522 
523   if (hi < BTA_JV_MAX_RFC_CONN && si < BTA_JV_MAX_RFC_SR_SESSION &&
524       bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) {
525     return bta_jv_cb.port_cb[bta_jv_cb.rfc_cb[hi].rfc_hdl[si] - 1].port_handle;
526   } else {
527     return 0xffff;
528   }
529 }
530 
531 /*******************************************************************************
532  *
533  * Function         BTA_JvRfcommWrite
534  *
535  * Description      This function writes data to an RFCOMM connection
536  *
537  * Returns          tBTA_JV_STATUS::SUCCESS, if the request is being processed.
538  *                  tBTA_JV_STATUS::FAILURE, otherwise.
539  *
540  ******************************************************************************/
BTA_JvRfcommWrite(uint32_t handle,uint32_t req_id)541 tBTA_JV_STATUS BTA_JvRfcommWrite(uint32_t handle, uint32_t req_id) {
542   uint32_t hi = ((handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1;
543   uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(handle);
544 
545   log::verbose("handle:{}, req_id:{}, hi:{}, si:{}", handle, req_id, hi, si);
546   if (hi >= BTA_JV_MAX_RFC_CONN || !bta_jv_cb.rfc_cb[hi].p_cback ||
547       si >= BTA_JV_MAX_RFC_SR_SESSION || !bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) {
548     return tBTA_JV_STATUS::FAILURE;
549   }
550 
551   log::verbose("write ok");
552 
553   tBTA_JV_RFC_CB* p_cb = &bta_jv_cb.rfc_cb[hi];
554   do_in_main_thread(Bind(&bta_jv_rfcomm_write, handle, req_id, p_cb,
555                          &bta_jv_cb.port_cb[p_cb->rfc_hdl[si] - 1]));
556   return tBTA_JV_STATUS::SUCCESS;
557 }
558 
559 /*******************************************************************************
560  *
561  * Function    BTA_JVSetPmProfile
562  *
563  * Description: This function set or free power mode profile for different JV
564  *              application.
565  *
566  * Parameters:  handle,  JV handle from RFCOMM or L2CAP
567  *              app_id:  app specific pm ID, can be BTA_JV_PM_ALL, see
568  *                       bta_dm_cfg.c for details
569  *              BTA_JV_PM_ID_CLEAR: removes pm management on the handle. init_st
570  *              is ignored and BTA_JV_CONN_CLOSE is called implicitly
571  *              init_st:  state after calling this API. typically it should be
572  *                        BTA_JV_CONN_OPEN
573  *
574  * Returns      tBTA_JV_STATUS::SUCCESS, if the request is being processed.
575  *              tBTA_JV_STATUS::FAILURE, otherwise.
576  *
577  * NOTE:        BTA_JV_PM_ID_CLEAR: In general no need to be called as jv pm
578  *                                  calls automatically
579  *              BTA_JV_CONN_CLOSE to remove in case of connection close!
580  *
581  ******************************************************************************/
BTA_JvSetPmProfile(uint32_t handle,tBTA_JV_PM_ID app_id,tBTA_JV_CONN_STATE init_st)582 tBTA_JV_STATUS BTA_JvSetPmProfile(uint32_t handle, tBTA_JV_PM_ID app_id,
583                                   tBTA_JV_CONN_STATE init_st) {
584   log::verbose("handle:{}, app_id:{}, init_st:{}", handle, app_id, handle);
585 
586   do_in_main_thread(Bind(&bta_jv_set_pm_profile, handle, app_id, init_st));
587   return tBTA_JV_STATUS::SUCCESS;
588 }
589