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