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