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