1 /******************************************************************************
2 *
3 * Copyright 2003-2016 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 module contains API of the audio/video control transport protocol.
22 *
23 ******************************************************************************/
24
25 #include "avct_api.h"
26
27 #include <bluetooth/log.h>
28 #include <com_android_bluetooth_flags.h>
29 #include <string.h>
30
31 #include <cstdint>
32
33 #include "bta/include/bta_sec_api.h"
34 #include "internal_include/bt_target.h"
35 #include "l2cap_types.h"
36 #include "l2cdefs.h"
37 #include "main/shim/dumpsys.h"
38 #include "osi/include/allocator.h"
39 #include "osi/include/fixed_queue.h"
40 #include "stack/avct/avct_int.h"
41 #include "stack/include/avct_api.h"
42 #include "stack/include/bt_hdr.h"
43 #include "stack/include/bt_psm_types.h"
44 #include "stack/include/l2cap_interface.h"
45 #include "types/raw_address.h"
46
47 using namespace bluetooth;
48
49 /* Control block for AVCT */
50 tAVCT_CB avct_cb;
51
52 /*******************************************************************************
53 *
54 * Function AVCT_Register
55 *
56 * Description This is the system level registration function for the
57 * AVCTP protocol. This function initializes AVCTP and
58 * prepares the protocol stack for its use. This function
59 * must be called once by the system or platform using AVCTP
60 * before the other functions of the API an be used.
61 *
62 *
63 * Returns void
64 *
65 ******************************************************************************/
AVCT_Register()66 void AVCT_Register() {
67 log::verbose("AVCT_Register");
68
69 /* initialize AVCTP data structures */
70 memset(&avct_cb, 0, sizeof(tAVCT_CB));
71
72 uint16_t sec = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT;
73
74 /* register PSM with L2CAP */
75 if (!stack::l2cap::get_interface().L2CA_RegisterWithSecurity(
76 BT_PSM_AVCTP, avct_l2c_appl, true /* enable_snoop */, nullptr, kAvrcMtu, 0, sec)) {
77 log::error("Unable to register with L2CAP AVCT profile psm:{}", bt_psm_text(BT_PSM_AVCTP));
78 }
79
80 /* Include the browsing channel which uses eFCR */
81 tL2CAP_ERTM_INFO ertm_info = {
82 .preferred_mode = L2CAP_FCR_ERTM_MODE,
83 };
84
85 if (!stack::l2cap::get_interface().L2CA_RegisterWithSecurity(
86 BT_PSM_AVCTP_BROWSE, avct_l2c_br_appl, true /*enable_snoop*/, &ertm_info, kAvrcBrMtu,
87 AVCT_MIN_BROWSE_MTU, sec)) {
88 log::error("Unable to register with L2CAP AVCT_BROWSE profile psm:{}",
89 bt_psm_text(BT_PSM_AVCTP_BROWSE));
90 }
91 }
92
93 /*******************************************************************************
94 *
95 * Function AVCT_Deregister
96 *
97 * Description This function is called to deregister use AVCTP protocol.
98 * It is called when AVCTP is no longer being used by any
99 * application in the system. Before this function can be
100 * called, all connections must be removed with
101 * AVCT_RemoveConn().
102 *
103 *
104 * Returns void
105 *
106 ******************************************************************************/
AVCT_Deregister(void)107 void AVCT_Deregister(void) {
108 log::verbose("AVCT_Deregister");
109
110 /* deregister PSM with L2CAP */
111 stack::l2cap::get_interface().L2CA_Deregister(BT_PSM_AVCTP);
112
113 /* deregister AVCT_BR_PSM with L2CAP */
114 stack::l2cap::get_interface().L2CA_Deregister(BT_PSM_AVCTP_BROWSE);
115
116 // Clean up AVCTP data structures
117 for (int i = 0; i < AVCT_NUM_LINKS; i++) {
118 osi_free_and_reset((void**)&(avct_cb.lcb[i].p_rx_msg));
119 fixed_queue_free(avct_cb.lcb[i].tx_q, nullptr);
120 avct_cb.lcb[i].tx_q = nullptr;
121 osi_free_and_reset((void**)&(avct_cb.bcb[i].p_tx_msg));
122 }
123 }
124
125 /*******************************************************************************
126 *
127 * Function AVCT_CreateConn
128 *
129 * Description Create an AVCTP connection. There are two types of
130 * connections, initiator and acceptor, as determined by
131 * the p_cc->role parameter. When this function is called to
132 * create an initiator connection, an AVCTP connection to
133 * the peer device is initiated if one does not already exist.
134 * If an acceptor connection is created, the connection waits
135 * passively for an incoming AVCTP connection from a peer
136 * device.
137 *
138 *
139 * Returns AVCT_SUCCESS if successful, otherwise error.
140 *
141 ******************************************************************************/
AVCT_CreateConn(uint8_t * p_handle,tAVCT_CC * p_cc,const RawAddress & peer_addr)142 uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, const RawAddress& peer_addr) {
143 uint16_t result = AVCT_SUCCESS;
144 tAVCT_CCB* p_ccb;
145 tAVCT_LCB* p_lcb;
146
147 log::verbose("AVCT_CreateConn:{}, control:0x{:x}", avct_role_text(p_cc->role), p_cc->control);
148
149 /* Allocate ccb; if no ccbs, return failure */
150 p_ccb = avct_ccb_alloc(p_cc);
151 if (p_ccb == NULL) {
152 result = AVCT_NO_RESOURCES;
153 } else {
154 /* get handle */
155 *p_handle = avct_ccb_to_idx(p_ccb);
156
157 /* if initiator connection */
158 if (p_cc->role == AVCT_ROLE_INITIATOR) {
159 /* find link; if none allocate a new one */
160 p_lcb = avct_lcb_by_bd(peer_addr);
161 if (p_lcb == NULL) {
162 p_lcb = avct_lcb_alloc(peer_addr);
163 if (p_lcb == NULL) {
164 /* no link resources; free ccb as well */
165 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
166 result = AVCT_NO_RESOURCES;
167 }
168 } else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) {
169 /* check if PID already in use */
170 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
171 result = AVCT_PID_IN_USE;
172 }
173
174 if (result == AVCT_SUCCESS) {
175 /* bind lcb to ccb */
176 p_ccb->p_lcb = p_lcb;
177 log::verbose("ch_state:{}", avct_ch_state_text(p_lcb->ch_state));
178 tAVCT_LCB_EVT avct_lcb_evt = {
179 .p_ccb = p_ccb,
180 };
181 avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
182 }
183 }
184 }
185 return result;
186 }
187
188 /*******************************************************************************
189 *
190 * Function AVCT_RemoveConn
191 *
192 * Description Remove an AVCTP connection. This function is called when
193 * the application is no longer using a connection. If this
194 * is the last connection to a peer the L2CAP channel for AVCTP
195 * will be closed.
196 *
197 *
198 * Returns AVCT_SUCCESS if successful, otherwise error.
199 *
200 ******************************************************************************/
AVCT_RemoveConn(uint8_t handle)201 uint16_t AVCT_RemoveConn(uint8_t handle) {
202 log::verbose("AVCT_RemoveConn");
203
204 /* map handle to ccb */
205 tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
206 if (p_ccb == nullptr) {
207 return AVCT_BAD_HANDLE;
208 }
209
210 /* if connection not bound to lcb, dealloc */
211 if (p_ccb->p_lcb == nullptr) {
212 avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
213 } else {
214 /* send unbind event to lcb */
215 tAVCT_LCB_EVT avct_lcb_evt = {
216 .p_ccb = p_ccb,
217 };
218 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
219 }
220 return AVCT_SUCCESS;
221 }
222
223 /*******************************************************************************
224 *
225 * Function AVCT_CreateBrowse
226 *
227 * Description Create an AVCTP Browse channel. There are two types of
228 * connections, initiator and acceptor, as determined by
229 * the role parameter. When this function is called to
230 * create an initiator connection, the Browse channel to
231 * the peer device is initiated if one does not already exist.
232 * If an acceptor connection is created, the connection waits
233 * passively for an incoming AVCTP connection from a peer
234 * device.
235 *
236 *
237 * Returns AVCT_SUCCESS if successful, otherwise error.
238 *
239 ******************************************************************************/
AVCT_CreateBrowse(uint8_t handle,tAVCT_ROLE role)240 uint16_t AVCT_CreateBrowse(uint8_t handle, tAVCT_ROLE role) {
241 uint16_t result = AVCT_SUCCESS;
242 tAVCT_CCB* p_ccb;
243 tAVCT_BCB* p_bcb;
244 int index;
245
246 log::verbose("AVCT_CreateBrowse: role:{}", avct_role_text(role));
247
248 /* map handle to ccb */
249 p_ccb = avct_ccb_by_idx(handle);
250 if (p_ccb == NULL) {
251 return AVCT_BAD_HANDLE;
252 } else {
253 /* mark this CCB as supporting browsing channel */
254 if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
255 p_ccb->allocated |= AVCT_ALOC_BCB;
256 }
257 }
258
259 /* if initiator connection */
260 if (role == AVCT_ROLE_INITIATOR) {
261 /* the link control block must exist before this function is called as INT.
262 */
263 if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
264 result = AVCT_NOT_OPEN;
265 } else {
266 /* find link; if none allocate a new one */
267 index = p_ccb->p_lcb->allocated;
268 if (index > AVCT_NUM_LINKS) {
269 result = AVCT_BAD_HANDLE;
270 } else {
271 p_bcb = &avct_cb.bcb[index - 1];
272 p_bcb->allocated = index;
273 }
274 }
275
276 if (result == AVCT_SUCCESS) {
277 /* bind bcb to ccb */
278 p_ccb->p_bcb = p_bcb;
279 p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
280 log::verbose("Created BCB ch_state:{}", avct_ch_state_text(p_bcb->ch_state));
281 tAVCT_LCB_EVT avct_lcb_evt;
282 avct_lcb_evt.p_ccb = p_ccb;
283 avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
284 }
285 }
286
287 return result;
288 }
289
290 /*******************************************************************************
291 *
292 * Function AVCT_RemoveBrowse
293 *
294 * Description Remove an AVCTP Browse channel. This function is called
295 * when the application is no longer using a connection. If
296 * this is the last connection to a peer the L2CAP channel for
297 * AVCTP will be closed.
298 *
299 *
300 * Returns AVCT_SUCCESS if successful, otherwise error.
301 *
302 ******************************************************************************/
AVCT_RemoveBrowse(uint8_t handle)303 uint16_t AVCT_RemoveBrowse(uint8_t handle) {
304 log::verbose("AVCT_RemoveBrowse");
305
306 /* map handle to ccb */
307 tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
308 if (p_ccb == nullptr) {
309 return AVCT_BAD_HANDLE;
310 }
311
312 if (p_ccb->p_bcb != nullptr) {
313 /* send unbind event to bcb */
314 tAVCT_LCB_EVT avct_lcb_evt = {
315 .p_ccb = p_ccb,
316 };
317 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
318 }
319 return AVCT_SUCCESS;
320 }
321
322 /*******************************************************************************
323 *
324 * Function AVCT_GetBrowseMtu
325 *
326 * Description Get the peer_mtu for the AVCTP Browse channel of the given
327 * connection.
328 *
329 * Returns the peer browsing channel MTU.
330 *
331 ******************************************************************************/
AVCT_GetBrowseMtu(uint8_t handle)332 uint16_t AVCT_GetBrowseMtu(uint8_t handle) {
333 uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU;
334
335 tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
336
337 if (p_ccb != NULL && p_ccb->p_bcb != NULL) {
338 peer_mtu = p_ccb->p_bcb->peer_mtu;
339 }
340
341 return peer_mtu;
342 }
343
344 /*******************************************************************************
345 *
346 * Function AVCT_GetPeerMtu
347 *
348 * Description Get the peer_mtu for the AVCTP channel of the given
349 * connection.
350 *
351 * Returns the peer MTU size.
352 *
353 ******************************************************************************/
AVCT_GetPeerMtu(uint8_t handle)354 uint16_t AVCT_GetPeerMtu(uint8_t handle) {
355 uint16_t peer_mtu = L2CAP_DEFAULT_MTU;
356 tAVCT_CCB* p_ccb;
357
358 /* map handle to ccb */
359 p_ccb = avct_ccb_by_idx(handle);
360 if (p_ccb != NULL) {
361 if (p_ccb->p_lcb) {
362 peer_mtu = p_ccb->p_lcb->peer_mtu;
363 }
364 }
365
366 return peer_mtu;
367 }
368
369 /*******************************************************************************
370 *
371 * Function AVCT_MsgReq
372 *
373 * Description Send an AVCTP message to a peer device. In calling
374 * AVCT_MsgReq(), the application should keep track of the
375 * congestion state of AVCTP as communicated with events
376 * AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT. If the
377 * application calls AVCT_MsgReq() when AVCTP is congested
378 * the message may be discarded. The application may make its
379 * first call to AVCT_MsgReq() after it receives an
380 * AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control
381 * channel or AVCT_BROWSE_CONN_CFM_EVT or
382 * AVCT_BROWSE_CONN_IND_EVT on browsing channel.
383 *
384 * p_msg->layer_specific must be set to
385 * AVCT_DATA_CTRL for control channel traffic;
386 * AVCT_DATA_BROWSE for for browse channel traffic.
387 *
388 * Returns AVCT_SUCCESS if successful, otherwise error.
389 *
390 ******************************************************************************/
AVCT_MsgReq(uint8_t handle,uint8_t label,uint8_t cr,BT_HDR * p_msg)391 uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
392 uint16_t result = AVCT_SUCCESS;
393 tAVCT_CCB* p_ccb;
394 tAVCT_UL_MSG ul_msg;
395
396 log::verbose("");
397
398 /* verify p_msg parameter */
399 if (p_msg == NULL) {
400 return AVCT_NO_RESOURCES;
401 }
402 log::verbose("msg_len:{} msg_layer_specific:{}", p_msg->len, p_msg->layer_specific);
403
404 /* map handle to ccb */
405 p_ccb = avct_ccb_by_idx(handle);
406 if (p_ccb == NULL) {
407 result = AVCT_BAD_HANDLE;
408 osi_free(p_msg);
409 } else if (p_ccb->p_lcb == NULL) {
410 /* verify channel is bound to link */
411 result = AVCT_NOT_OPEN;
412 osi_free(p_msg);
413 }
414
415 if (result == AVCT_SUCCESS) {
416 ul_msg.p_buf = p_msg;
417 ul_msg.p_ccb = p_ccb;
418 ul_msg.label = label;
419 ul_msg.cr = cr;
420
421 /* send msg event to bcb */
422 if (p_msg->layer_specific == AVCT_DATA_BROWSE) {
423 if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
424 /* BCB channel is not open and not allocated */
425 result = AVCT_BAD_HANDLE;
426 osi_free(p_msg);
427 } else {
428 p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
429 tAVCT_LCB_EVT avct_lcb_evt;
430 avct_lcb_evt.ul_msg = ul_msg;
431 avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
432 }
433 } else {
434 /* send msg event to lcb */
435 tAVCT_LCB_EVT avct_lcb_evt;
436 avct_lcb_evt.ul_msg = ul_msg;
437 avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
438 }
439 }
440 return result;
441 }
442
443 #define DUMPSYS_TAG "stack::avct"
444
AVCT_Dumpsys(int fd)445 void AVCT_Dumpsys(int fd) {
446 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
447 for (int i = 0; i < AVCT_NUM_CONN; i++) {
448 const tAVCT_CCB& ccb = avct_cb.ccb[i];
449 if (!ccb.allocated) {
450 continue;
451 }
452 LOG_DUMPSYS(fd, " Id:%2u profile_uuid:0x%04x role:%s control:0x%2x", i, ccb.cc.pid,
453 avct_role_text(ccb.cc.role).c_str(), ccb.cc.control);
454 if (ccb.p_lcb) { // tAVCT_LCB
455 LOG_DUMPSYS(fd,
456 " Link : peer:%s lcid:0x%04x sm_state:%-24s ch_state:%s conflict_lcid:0x%04x",
457 std::format("{}", ccb.p_lcb->peer_addr).c_str(), ccb.p_lcb->ch_lcid,
458 avct_sm_state_text(ccb.p_lcb->state).c_str(),
459 avct_ch_state_text(ccb.p_lcb->ch_state).c_str(), ccb.p_lcb->conflict_lcid);
460 } else {
461 LOG_DUMPSYS(fd, " Link : No link channel");
462 }
463
464 if (ccb.p_bcb) { // tAVCT_BCB
465 LOG_DUMPSYS(fd,
466 " Browse: peer:%s lcid:0x%04x sm_state:%-24s ch_state:%s conflict_lcid:0x%04x",
467 std::format("{}", ccb.p_bcb->peer_addr).c_str(), ccb.p_bcb->ch_lcid,
468 avct_sm_state_text(ccb.p_bcb->state).c_str(),
469 avct_ch_state_text(ccb.p_bcb->ch_state).c_str(), ccb.p_bcb->conflict_lcid);
470 } else {
471 LOG_DUMPSYS(fd, " Browse: No browse channel");
472 }
473 }
474 }
475 #undef DUMPSYS_TAG
476