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