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