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