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