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