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