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