1 /******************************************************************************
2  *
3  *  Copyright 2002-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 AVDTP adaption layer module interfaces to L2CAP
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bluetooth-a2dp"
26 
27 #include <bluetooth/log.h>
28 
29 #include "avdt_int.h"
30 #include "bta/include/bta_av_api.h"
31 #include "device/include/interop.h"
32 #include "l2c_api.h"
33 #include "l2cdefs.h"
34 #include "osi/include/allocator.h"
35 #include "osi/include/osi.h"
36 #include "stack/include/acl_api.h"
37 #include "stack/include/bt_hdr.h"
38 #include "types/raw_address.h"
39 
40 using namespace bluetooth;
41 
42 /* callback function declarations */
43 void avdt_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
44                                 uint16_t psm, uint8_t id);
45 void avdt_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result);
46 void avdt_l2c_config_cfm_cback(uint16_t lcid, uint16_t result,
47                                tL2CAP_CFG_INFO* p_cfg);
48 void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
49 void avdt_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
50 void avdt_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested);
51 void avdt_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
52 static void avdt_on_l2cap_error(uint16_t lcid, uint16_t result);
53 
54 /* L2CAP callback function structure */
55 const tL2CAP_APPL_INFO avdt_l2c_appl = {avdt_l2c_connect_ind_cback,
56                                         avdt_l2c_connect_cfm_cback,
57                                         avdt_l2c_config_ind_cback,
58                                         avdt_l2c_config_cfm_cback,
59                                         avdt_l2c_disconnect_ind_cback,
60                                         NULL,
61                                         avdt_l2c_data_ind_cback,
62                                         avdt_l2c_congestion_ind_cback,
63                                         NULL,
64                                         avdt_on_l2cap_error,
65                                         NULL,
66                                         NULL,
67                                         NULL,
68                                         NULL};
69 
70 /*******************************************************************************
71  *
72  * Function         avdt_sec_check_complete_term
73  *
74  * Description      The function called when Security Manager finishes
75  *                  verification of the service side connection
76  *
77  * Returns          void
78  *
79  ******************************************************************************/
avdt_sec_check_complete_term(const RawAddress * bd_addr,tBT_TRANSPORT transport,void * p_ref_data)80 static void avdt_sec_check_complete_term(const RawAddress* bd_addr,
81                                          tBT_TRANSPORT transport,
82                                          void* p_ref_data) {
83   AvdtpCcb* p_ccb = NULL;
84   AvdtpTransportChannel* p_tbl;
85 
86   p_ccb = avdt_ccb_by_bd(*bd_addr);
87 
88   p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_ACP);
89   if (p_tbl == NULL) return;
90 
91   /* store idx in LCID table, store LCID in routing table */
92   avdtp_cb.ad.lcid_tbl[p_tbl->lcid] = avdt_ad_tc_tbl_to_idx(p_tbl);
93   avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = p_tbl->lcid;
94 
95   /* transition to configuration state */
96   p_tbl->state = AVDT_AD_ST_CFG;
97 }
98 
99 /*******************************************************************************
100  *
101  * Function         avdt_sec_check_complete_orig
102  *
103  * Description      The function called when Security Manager finishes
104  *                  verification of the service side connection
105  *
106  * Returns          void
107  *
108  ******************************************************************************/
avdt_sec_check_complete_orig(const RawAddress * bd_addr,tBT_TRANSPORT trasnport,void *,uint8_t res)109 static void avdt_sec_check_complete_orig(const RawAddress* bd_addr,
110                                          tBT_TRANSPORT trasnport,
111                                          void* /* p_ref_data */, uint8_t res) {
112   AvdtpCcb* p_ccb = NULL;
113   AvdtpTransportChannel* p_tbl;
114 
115   log::verbose("avdt_sec_check_complete_orig res: {}", res);
116   if (bd_addr) p_ccb = avdt_ccb_by_bd(*bd_addr);
117   p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_INT);
118   if (p_tbl == NULL) return;
119 
120   if (res == BTM_SUCCESS) {
121     /* set channel state */
122     p_tbl->state = AVDT_AD_ST_CFG;
123   } else {
124     avdt_l2c_disconnect(p_tbl->lcid);
125     avdt_ad_tc_close_ind(p_tbl);
126   }
127 }
128 /*******************************************************************************
129  *
130  * Function         avdt_l2c_connect_ind_cback
131  *
132  * Description      This is the L2CAP connect indication callback function.
133  *
134  *
135  * Returns          void
136  *
137  ******************************************************************************/
avdt_l2c_connect_ind_cback(const RawAddress & bd_addr,uint16_t lcid,uint16_t,uint8_t id)138 void avdt_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
139                                 uint16_t /* psm */, uint8_t id) {
140   AvdtpCcb* p_ccb;
141   AvdtpTransportChannel* p_tbl = NULL;
142   uint16_t result;
143 
144   /* do we already have a control channel for this peer? */
145   p_ccb = avdt_ccb_by_bd(bd_addr);
146   if (p_ccb == NULL) {
147     /* no, allocate ccb */
148     int channel_index = BTA_AvObtainPeerChannelIndex(bd_addr);
149     if (channel_index >= 0) {
150       p_ccb = avdt_ccb_alloc_by_channel_index(bd_addr, channel_index);
151     }
152     if (p_ccb == nullptr) {
153       p_ccb = avdt_ccb_alloc(bd_addr);
154     }
155     if (p_ccb == NULL) {
156       /* no ccb available, reject L2CAP connection */
157       result = L2CAP_CONN_NO_RESOURCES;
158     } else {
159       /* allocate and set up entry; first channel is always signaling */
160       p_tbl = avdt_ad_tc_tbl_alloc(p_ccb);
161       p_tbl->my_mtu = kAvdtpMtu;
162       p_tbl->tcid = AVDT_CHAN_SIG;
163       p_tbl->lcid = lcid;
164       p_tbl->state = AVDT_AD_ST_SEC_ACP;
165       p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_ACP;
166 
167       if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY, &bd_addr)) {
168         // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
169         btm_set_packet_types_from_address(
170             bd_addr,
171             (acl_get_supported_packet_types() | HCI_PKT_TYPES_MASK_NO_3_DH1 |
172              HCI_PKT_TYPES_MASK_NO_3_DH3 | HCI_PKT_TYPES_MASK_NO_3_DH5));
173       }
174       /* Assume security check is complete */
175       avdt_sec_check_complete_term(&p_ccb->peer_addr, BT_TRANSPORT_BR_EDR,
176                                    nullptr);
177       return;
178     }
179   } else {
180     /* deal with simultaneous control channel connect case */
181     p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_CONN);
182     if (p_tbl != NULL) {
183       /* reject their connection */
184       result = L2CAP_CONN_NO_RESOURCES;
185     } else {
186       /* This must be a traffic channel; are we accepting a traffic channel
187        * for this ccb?
188        */
189       p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_MEDIA, p_ccb, AVDT_AD_ST_ACP);
190       if (p_tbl != NULL) {
191         /* yes; proceed with connection */
192         result = L2CAP_CONN_OK;
193       } else {
194         /* this must be a reporting channel; are we accepting a reporting
195          * channel for this ccb?
196          */
197         p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_REPORT, p_ccb, AVDT_AD_ST_ACP);
198         if (p_tbl != NULL) {
199           /* yes; proceed with connection */
200           result = L2CAP_CONN_OK;
201         } else {
202           /* else we're not listening for traffic channel; reject */
203           result = L2CAP_CONN_NO_PSM;
204         }
205       }
206     }
207   }
208 
209   /* If we reject the connection, send DisconnectReq */
210   if (result != L2CAP_CONN_OK) {
211     if (!L2CA_DisconnectReq(lcid)) {
212       log::warn("Unable to disconnect L2CAP cid:{}", lcid);
213     }
214     return;
215   }
216 
217   /* if result ok, proceed with connection */
218   /* store idx in LCID table, store LCID in routing table */
219   avdtp_cb.ad.lcid_tbl[lcid] = avdt_ad_tc_tbl_to_idx(p_tbl);
220   avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
221 
222   /* transition to configuration state */
223   p_tbl->state = AVDT_AD_ST_CFG;
224 }
225 
avdt_on_l2cap_error(uint16_t lcid,uint16_t result)226 static void avdt_on_l2cap_error(uint16_t lcid, uint16_t result) {
227   avdt_l2c_disconnect(lcid);
228 }
229 
230 /*******************************************************************************
231  *
232  * Function         avdt_l2c_connect_cfm_cback
233  *
234  * Description      This is the L2CAP connect confirm callback function.
235  *
236  *
237  * Returns          void
238  *
239  ******************************************************************************/
avdt_l2c_connect_cfm_cback(uint16_t lcid,uint16_t result)240 void avdt_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) {
241   AvdtpTransportChannel* p_tbl;
242   AvdtpCcb* p_ccb;
243 
244   log::verbose("avdt_l2c_connect_cfm_cback lcid: {}, result: {}", lcid, result);
245   /* look up info for this channel */
246   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
247   if (p_tbl != NULL) {
248     /* if in correct state */
249     if (p_tbl->state == AVDT_AD_ST_CONN) {
250       /* if result successful */
251       if (result == L2CAP_CONN_OK) {
252         if (p_tbl->tcid != AVDT_CHAN_SIG) {
253           /* set channel state */
254           p_tbl->state = AVDT_AD_ST_CFG;
255         } else {
256           p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
257           if (p_ccb == NULL) {
258             result = L2CAP_CONN_NO_RESOURCES;
259           } else {
260             /* set channel state */
261             p_tbl->state = AVDT_AD_ST_SEC_INT;
262             p_tbl->lcid = lcid;
263             p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_INT;
264 
265             if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY,
266                                    (const RawAddress*)&p_ccb->peer_addr)) {
267               // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
268               btm_set_packet_types_from_address(
269                   p_ccb->peer_addr,
270                   (acl_get_supported_packet_types() |
271                    HCI_PKT_TYPES_MASK_NO_3_DH1 | HCI_PKT_TYPES_MASK_NO_3_DH3 |
272                    HCI_PKT_TYPES_MASK_NO_3_DH5));
273             }
274 
275             /* Assume security check is complete */
276             avdt_sec_check_complete_orig(&p_ccb->peer_addr, BT_TRANSPORT_BR_EDR,
277                                          nullptr, BTM_SUCCESS);
278           }
279         }
280       }
281 
282       /* failure; notify adaption that channel closed */
283       if (result != L2CAP_CONN_OK) {
284         log::error("invoked with non OK status");
285       }
286     }
287   }
288 }
289 
290 /*******************************************************************************
291  *
292  * Function         avdt_l2c_config_cfm_cback
293  *
294  * Description      This is the L2CAP config confirm callback function.
295  *
296  *
297  * Returns          void
298  *
299  ******************************************************************************/
avdt_l2c_config_cfm_cback(uint16_t lcid,uint16_t initiator,tL2CAP_CFG_INFO * p_cfg)300 void avdt_l2c_config_cfm_cback(uint16_t lcid, uint16_t initiator,
301                                tL2CAP_CFG_INFO* p_cfg) {
302   avdt_l2c_config_ind_cback(lcid, p_cfg);
303 
304   AvdtpTransportChannel* p_tbl;
305 
306   log::verbose("lcid: {}", lcid);
307 
308   /* look up info for this channel */
309   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
310   if (p_tbl != NULL) {
311     p_tbl->lcid = lcid;
312 
313     /* if in correct state */
314     if (p_tbl->state == AVDT_AD_ST_CFG) {
315       avdt_ad_tc_open_ind(p_tbl);
316     }
317   }
318 }
319 
320 /*******************************************************************************
321  *
322  * Function         avdt_l2c_config_ind_cback
323  *
324  * Description      This is the L2CAP config indication callback function.
325  *
326  *
327  * Returns          void
328  *
329  ******************************************************************************/
avdt_l2c_config_ind_cback(uint16_t lcid,tL2CAP_CFG_INFO * p_cfg)330 void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
331   AvdtpTransportChannel* p_tbl;
332 
333   log::verbose("lcid: {}", lcid);
334 
335   /* look up info for this channel */
336   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
337   if (p_tbl != NULL) {
338     /* store the mtu in tbl */
339     if (p_cfg->mtu_present) {
340       p_tbl->peer_mtu = p_cfg->mtu;
341     } else {
342       p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
343     }
344     log::verbose("peer_mtu: {}, lcid: {}", p_tbl->peer_mtu, lcid);
345   }
346 }
347 
348 /*******************************************************************************
349  *
350  * Function         avdt_l2c_disconnect_ind_cback
351  *
352  * Description      This is the L2CAP disconnect indication callback function.
353  *
354  *
355  * Returns          void
356  *
357  ******************************************************************************/
avdt_l2c_disconnect_ind_cback(uint16_t lcid,bool ack_needed)358 void avdt_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed) {
359   AvdtpTransportChannel* p_tbl;
360 
361   log::verbose("avdt_l2c_disconnect_ind_cback lcid: {}, ack_needed: {}", lcid,
362                ack_needed);
363   /* look up info for this channel */
364   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
365   if (p_tbl != NULL) {
366     avdt_ad_tc_close_ind(p_tbl);
367   }
368 }
369 
avdt_l2c_disconnect(uint16_t lcid)370 void avdt_l2c_disconnect(uint16_t lcid) {
371   if (!L2CA_DisconnectReq(lcid)) {
372     log::warn("Unable to disconnect L2CAP cid:{}", lcid);
373   }
374 
375   AvdtpTransportChannel* p_tbl;
376 
377   log::verbose("avdt_l2c_disconnect_cfm_cback lcid: {}", lcid);
378   /* look up info for this channel */
379   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
380   if (p_tbl != NULL) {
381     avdt_ad_tc_close_ind(p_tbl);
382   }
383 }
384 
385 /*******************************************************************************
386  *
387  * Function         avdt_l2c_congestion_ind_cback
388  *
389  * Description      This is the L2CAP congestion indication callback function.
390  *
391  *
392  * Returns          void
393  *
394  ******************************************************************************/
avdt_l2c_congestion_ind_cback(uint16_t lcid,bool is_congested)395 void avdt_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested) {
396   AvdtpTransportChannel* p_tbl;
397 
398   /* look up info for this channel */
399   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
400   if (p_tbl != NULL) {
401     avdt_ad_tc_cong_ind(p_tbl, is_congested);
402   }
403 }
404 
405 /*******************************************************************************
406  *
407  * Function         avdt_l2c_data_ind_cback
408  *
409  * Description      This is the L2CAP data indication callback function.
410  *
411  *
412  * Returns          void
413  *
414  ******************************************************************************/
avdt_l2c_data_ind_cback(uint16_t lcid,BT_HDR * p_buf)415 void avdt_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) {
416   AvdtpTransportChannel* p_tbl;
417 
418   /* look up info for this channel */
419   p_tbl = avdt_ad_tc_tbl_by_lcid(lcid);
420   if (p_tbl != NULL) {
421     avdt_ad_tc_data_ind(p_tbl, p_buf);
422   } else /* prevent buffer leak */
423     osi_free(p_buf);
424 }
425