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