1 /******************************************************************************
2 *
3 * Copyright (C) 2002-2012 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 distribution transport
22 * protocol.
23 *
24 ******************************************************************************/
25
26 #include "avdt_api.h"
27 #include <string.h>
28 #include "avdt_int.h"
29 #include "avdtc_api.h"
30 #include "bt_target.h"
31 #include "bt_types.h"
32 #include "btm_api.h"
33 #include "btu.h"
34 #include "l2c_api.h"
35
36 /* Control block for AVDT */
37 tAVDT_CB avdt_cb;
38
avdt_ccb_idle_ccb_timer_timeout(void * data)39 void avdt_ccb_idle_ccb_timer_timeout(void* data) {
40 tAVDT_CCB* p_ccb = (tAVDT_CCB*)data;
41 uint8_t avdt_event = AVDT_CCB_IDLE_TOUT_EVT;
42 uint8_t err_code = AVDT_ERR_TIMEOUT;
43
44 avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
45 }
46
avdt_ccb_ret_ccb_timer_timeout(void * data)47 void avdt_ccb_ret_ccb_timer_timeout(void* data) {
48 tAVDT_CCB* p_ccb = (tAVDT_CCB*)data;
49 uint8_t avdt_event = AVDT_CCB_RET_TOUT_EVT;
50 uint8_t err_code = AVDT_ERR_TIMEOUT;
51
52 avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
53 }
54
avdt_ccb_rsp_ccb_timer_timeout(void * data)55 void avdt_ccb_rsp_ccb_timer_timeout(void* data) {
56 tAVDT_CCB* p_ccb = (tAVDT_CCB*)data;
57 uint8_t avdt_event = AVDT_CCB_RSP_TOUT_EVT;
58 uint8_t err_code = AVDT_ERR_TIMEOUT;
59
60 avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
61 }
62
avdt_scb_transport_channel_timer_timeout(void * data)63 void avdt_scb_transport_channel_timer_timeout(void* data) {
64 tAVDT_SCB* p_scb = (tAVDT_SCB*)data;
65 uint8_t avdt_event = AVDT_SCB_TC_TOUT_EVT;
66
67 avdt_scb_event(p_scb, avdt_event, NULL);
68 }
69
70 /*******************************************************************************
71 *
72 * Function AVDT_Register
73 *
74 * Description This is the system level registration function for the
75 * AVDTP protocol. This function initializes AVDTP and
76 * prepares the protocol stack for its use. This function
77 * must be called once by the system or platform using AVDTP
78 * before the other functions of the API an be used.
79 *
80 *
81 * Returns void
82 *
83 ******************************************************************************/
AVDT_Register(tAVDT_REG * p_reg,tAVDT_CTRL_CBACK * p_cback)84 void AVDT_Register(tAVDT_REG* p_reg, tAVDT_CTRL_CBACK* p_cback) {
85 /* register PSM with L2CAP */
86 L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO*)&avdt_l2c_appl);
87
88 /* set security level */
89 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
90 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
91 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
92 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
93
94 /* do not use security on the media channel */
95 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
96 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
97 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
98 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
99
100 #if (AVDT_REPORTING == TRUE)
101 /* do not use security on the reporting channel */
102 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
103 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
104 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
105 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
106 #endif
107
108 /* initialize AVDTP data structures */
109 avdt_scb_init();
110 avdt_ccb_init();
111 avdt_ad_init();
112
113 /* copy registration struct */
114 memcpy(&avdt_cb.rcb, p_reg, sizeof(tAVDT_REG));
115 avdt_cb.p_conn_cback = p_cback;
116 }
117
118 /*******************************************************************************
119 *
120 * Function AVDT_Deregister
121 *
122 * Description This function is called to deregister use AVDTP protocol.
123 * It is called when AVDTP is no longer being used by any
124 * application in the system. Before this function can be
125 * called, all streams must be removed with
126 * AVDT_RemoveStream().
127 *
128 *
129 * Returns void
130 *
131 ******************************************************************************/
AVDT_Deregister(void)132 void AVDT_Deregister(void) {
133 /* deregister PSM with L2CAP */
134 L2CA_Deregister(AVDT_PSM);
135 }
136
AVDT_AbortReq(uint8_t handle)137 void AVDT_AbortReq(uint8_t handle) {
138 AVDT_TRACE_ERROR("%s", __func__);
139
140 tAVDT_SCB* p_scb = avdt_scb_by_hdl(handle);
141 if (p_scb != NULL) {
142 avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_REQ_EVT, NULL);
143 } else {
144 AVDT_TRACE_ERROR("%s Improper SCB, can not abort the stream", __func__);
145 }
146 }
147
148 /*******************************************************************************
149 *
150 * Function AVDT_CreateStream
151 *
152 * Description Create a stream endpoint. After a stream endpoint is
153 * created an application can initiate a connection between
154 * this endpoint and an endpoint on a peer device. In
155 * addition, a peer device can discover, get the capabilities,
156 * and connect to this endpoint.
157 *
158 *
159 * Returns AVDT_SUCCESS if successful, otherwise error.
160 *
161 ******************************************************************************/
AVDT_CreateStream(uint8_t * p_handle,tAVDT_CS * p_cs)162 uint16_t AVDT_CreateStream(uint8_t* p_handle, tAVDT_CS* p_cs) {
163 uint16_t result = AVDT_SUCCESS;
164 tAVDT_SCB* p_scb;
165
166 /* Verify parameters; if invalid, return failure */
167 if (((p_cs->cfg.psc_mask & (~AVDT_PSC)) != 0) ||
168 (p_cs->p_ctrl_cback == NULL)) {
169 result = AVDT_BAD_PARAMS;
170 }
171 /* Allocate scb; if no scbs, return failure */
172 else {
173 p_scb = avdt_scb_alloc(p_cs);
174 if (p_scb == NULL) {
175 result = AVDT_NO_RESOURCES;
176 } else {
177 *p_handle = avdt_scb_to_hdl(p_scb);
178 }
179 }
180 return result;
181 }
182
183 /*******************************************************************************
184 *
185 * Function AVDT_RemoveStream
186 *
187 * Description Remove a stream endpoint. This function is called when
188 * the application is no longer using a stream endpoint.
189 * If this function is called when the endpoint is connected
190 * the connection is closed and then the stream endpoint
191 * is removed.
192 *
193 *
194 * Returns AVDT_SUCCESS if successful, otherwise error.
195 *
196 ******************************************************************************/
AVDT_RemoveStream(uint8_t handle)197 uint16_t AVDT_RemoveStream(uint8_t handle) {
198 uint16_t result = AVDT_SUCCESS;
199 tAVDT_SCB* p_scb;
200
201 /* look up scb */
202 p_scb = avdt_scb_by_hdl(handle);
203 if (p_scb == NULL) {
204 result = AVDT_BAD_HANDLE;
205 } else {
206 /* send remove event to scb */
207 avdt_scb_event(p_scb, AVDT_SCB_API_REMOVE_EVT, NULL);
208 }
209 return result;
210 }
211
212 /*******************************************************************************
213 *
214 * Function AVDT_DiscoverReq
215 *
216 * Description This function initiates a connection to the AVDTP service
217 * on the peer device, if not already present, and discovers
218 * the stream endpoints on the peer device. (Please note
219 * that AVDTP discovery is unrelated to SDP discovery).
220 * This function can be called at any time regardless of
221 * whether there is an AVDTP connection to the peer device.
222 *
223 * When discovery is complete, an AVDT_DISCOVER_CFM_EVT
224 * is sent to the application via its callback function.
225 * The application must not call AVDT_GetCapReq() or
226 * AVDT_DiscoverReq() again to the same device until
227 * discovery is complete.
228 *
229 * The memory addressed by sep_info is allocated by the
230 * application. This memory is written to by AVDTP as part
231 * of the discovery procedure. This memory must remain
232 * accessible until the application receives the
233 * AVDT_DISCOVER_CFM_EVT.
234 *
235 * Returns AVDT_SUCCESS if successful, otherwise error.
236 *
237 ******************************************************************************/
AVDT_DiscoverReq(BD_ADDR bd_addr,tAVDT_SEP_INFO * p_sep_info,uint8_t max_seps,tAVDT_CTRL_CBACK * p_cback)238 uint16_t AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO* p_sep_info,
239 uint8_t max_seps, tAVDT_CTRL_CBACK* p_cback) {
240 tAVDT_CCB* p_ccb;
241 uint16_t result = AVDT_SUCCESS;
242 tAVDT_CCB_EVT evt;
243
244 /* find channel control block for this bd addr; if none, allocate one */
245 p_ccb = avdt_ccb_by_bd(bd_addr);
246 if (p_ccb == NULL) {
247 p_ccb = avdt_ccb_alloc(bd_addr);
248 if (p_ccb == NULL) {
249 /* could not allocate channel control block */
250 result = AVDT_NO_RESOURCES;
251 }
252 }
253
254 if (result == AVDT_SUCCESS) {
255 /* make sure no discovery or get capabilities req already in progress */
256 if (p_ccb->proc_busy) {
257 result = AVDT_BUSY;
258 }
259 /* send event to ccb */
260 else {
261 evt.discover.p_sep_info = p_sep_info;
262 evt.discover.num_seps = max_seps;
263 evt.discover.p_cback = p_cback;
264 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_REQ_EVT, &evt);
265 }
266 }
267 return result;
268 }
269
270 /*******************************************************************************
271 *
272 * Function avdt_get_cap_req
273 *
274 * Description internal function to serve both AVDT_GetCapReq and
275 * AVDT_GetAllCapReq
276 *
277 * Returns AVDT_SUCCESS if successful, otherwise error.
278 *
279 ******************************************************************************/
avdt_get_cap_req(BD_ADDR bd_addr,tAVDT_CCB_API_GETCAP * p_evt)280 static uint16_t avdt_get_cap_req(BD_ADDR bd_addr, tAVDT_CCB_API_GETCAP* p_evt) {
281 tAVDT_CCB* p_ccb = NULL;
282 uint16_t result = AVDT_SUCCESS;
283
284 /* verify SEID */
285 if ((p_evt->single.seid < AVDT_SEID_MIN) ||
286 (p_evt->single.seid > AVDT_SEID_MAX)) {
287 AVDT_TRACE_ERROR("seid: %d", p_evt->single.seid);
288 result = AVDT_BAD_PARAMS;
289 }
290 /* find channel control block for this bd addr; if none, allocate one */
291 else {
292 p_ccb = avdt_ccb_by_bd(bd_addr);
293 if (p_ccb == NULL) {
294 p_ccb = avdt_ccb_alloc(bd_addr);
295 if (p_ccb == NULL) {
296 /* could not allocate channel control block */
297 result = AVDT_NO_RESOURCES;
298 }
299 }
300 }
301
302 if (result == AVDT_SUCCESS) {
303 /* make sure no discovery or get capabilities req already in progress */
304 if (p_ccb->proc_busy) {
305 result = AVDT_BUSY;
306 }
307 /* send event to ccb */
308 else {
309 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_REQ_EVT, (tAVDT_CCB_EVT*)p_evt);
310 }
311 }
312 return result;
313 }
314
315 /*******************************************************************************
316 *
317 * Function AVDT_GetCapReq
318 *
319 * Description This function initiates a connection to the AVDTP service
320 * on the peer device, if not already present, and gets the
321 * capabilities of a stream endpoint on the peer device.
322 * This function can be called at any time regardless of
323 * whether there is an AVDTP connection to the peer device.
324 *
325 * When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
326 * sent to the application via its callback function. The
327 * application must not call AVDT_GetCapReq() or
328 * AVDT_DiscoverReq() again until the procedure is complete.
329 *
330 * The memory pointed to by p_cfg is allocated by the
331 * application. This memory is written to by AVDTP as part
332 * of the get capabilities procedure. This memory must
333 * remain accessible until the application receives
334 * the AVDT_GETCAP_CFM_EVT.
335 *
336 * Returns AVDT_SUCCESS if successful, otherwise error.
337 *
338 ******************************************************************************/
AVDT_GetCapReq(BD_ADDR bd_addr,uint8_t seid,tAVDT_CFG * p_cfg,tAVDT_CTRL_CBACK * p_cback)339 uint16_t AVDT_GetCapReq(BD_ADDR bd_addr, uint8_t seid, tAVDT_CFG* p_cfg,
340 tAVDT_CTRL_CBACK* p_cback) {
341 tAVDT_CCB_API_GETCAP getcap;
342
343 getcap.single.seid = seid;
344 getcap.single.sig_id = AVDT_SIG_GETCAP;
345 getcap.p_cfg = p_cfg;
346 getcap.p_cback = p_cback;
347 return avdt_get_cap_req(bd_addr, &getcap);
348 }
349
350 /*******************************************************************************
351 *
352 * Function AVDT_GetAllCapReq
353 *
354 * Description This function initiates a connection to the AVDTP service
355 * on the peer device, if not already present, and gets the
356 * capabilities of a stream endpoint on the peer device.
357 * This function can be called at any time regardless of
358 * whether there is an AVDTP connection to the peer device.
359 *
360 * When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
361 * sent to the application via its callback function. The
362 * application must not call AVDT_GetCapReq() or
363 * AVDT_DiscoverReq() again until the procedure is complete.
364 *
365 * The memory pointed to by p_cfg is allocated by the
366 * application. This memory is written to by AVDTP as part
367 * of the get capabilities procedure. This memory must
368 * remain accessible until the application receives
369 * the AVDT_GETCAP_CFM_EVT.
370 *
371 * Returns AVDT_SUCCESS if successful, otherwise error.
372 *
373 ******************************************************************************/
AVDT_GetAllCapReq(BD_ADDR bd_addr,uint8_t seid,tAVDT_CFG * p_cfg,tAVDT_CTRL_CBACK * p_cback)374 uint16_t AVDT_GetAllCapReq(BD_ADDR bd_addr, uint8_t seid, tAVDT_CFG* p_cfg,
375 tAVDT_CTRL_CBACK* p_cback) {
376 tAVDT_CCB_API_GETCAP getcap;
377
378 getcap.single.seid = seid;
379 getcap.single.sig_id = AVDT_SIG_GET_ALLCAP;
380 getcap.p_cfg = p_cfg;
381 getcap.p_cback = p_cback;
382 return avdt_get_cap_req(bd_addr, &getcap);
383 }
384
385 /*******************************************************************************
386 *
387 * Function AVDT_DelayReport
388 *
389 * Description This functions sends a Delay Report to the peer device
390 * that is associated with a particular SEID.
391 * This function is called by SNK device.
392 *
393 * Returns AVDT_SUCCESS if successful, otherwise error.
394 *
395 ******************************************************************************/
AVDT_DelayReport(uint8_t handle,uint8_t seid,uint16_t delay)396 uint16_t AVDT_DelayReport(uint8_t handle, uint8_t seid, uint16_t delay) {
397 tAVDT_SCB* p_scb;
398 uint16_t result = AVDT_SUCCESS;
399 tAVDT_SCB_EVT evt;
400
401 /* map handle to scb */
402 p_scb = avdt_scb_by_hdl(handle);
403 if (p_scb == NULL) {
404 result = AVDT_BAD_HANDLE;
405 } else
406 /* send event to scb */
407 {
408 evt.apidelay.hdr.seid = seid;
409 evt.apidelay.delay = delay;
410 avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt);
411 }
412
413 return result;
414 }
415
416 /*******************************************************************************
417 *
418 * Function AVDT_OpenReq
419 *
420 * Description This function initiates a connection to the AVDTP service
421 * on the peer device, if not already present, and connects
422 * to a stream endpoint on a peer device. When the connection
423 * is completed, an AVDT_OPEN_CFM_EVT is sent to the
424 * application via the control callback function for this
425 * handle.
426 *
427 * Returns AVDT_SUCCESS if successful, otherwise error.
428 *
429 ******************************************************************************/
AVDT_OpenReq(uint8_t handle,BD_ADDR bd_addr,uint8_t seid,tAVDT_CFG * p_cfg)430 uint16_t AVDT_OpenReq(uint8_t handle, BD_ADDR bd_addr, uint8_t seid,
431 tAVDT_CFG* p_cfg) {
432 tAVDT_CCB* p_ccb = NULL;
433 tAVDT_SCB* p_scb = NULL;
434 uint16_t result = AVDT_SUCCESS;
435 tAVDT_SCB_EVT evt;
436
437 /* verify SEID */
438 if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX)) {
439 result = AVDT_BAD_PARAMS;
440 }
441 /* map handle to scb */
442 else {
443 p_scb = avdt_scb_by_hdl(handle);
444 if (p_scb == NULL) {
445 result = AVDT_BAD_HANDLE;
446 }
447 /* find channel control block for this bd addr; if none, allocate one */
448 else {
449 p_ccb = avdt_ccb_by_bd(bd_addr);
450 if (p_ccb == NULL) {
451 p_ccb = avdt_ccb_alloc(bd_addr);
452 if (p_ccb == NULL) {
453 /* could not allocate channel control block */
454 result = AVDT_NO_RESOURCES;
455 }
456 }
457 }
458 }
459
460 /* send event to scb */
461 if (result == AVDT_SUCCESS) {
462 evt.msg.config_cmd.hdr.seid = seid;
463 evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
464 evt.msg.config_cmd.int_seid = handle;
465 evt.msg.config_cmd.p_cfg = p_cfg;
466 avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt);
467 }
468 return result;
469 }
470
471 /*******************************************************************************
472 *
473 * Function AVDT_ConfigRsp
474 *
475 * Description Respond to a configure request from the peer device. This
476 * function must be called if the application receives an
477 * AVDT_CONFIG_IND_EVT through its control callback.
478 *
479 *
480 * Returns AVDT_SUCCESS if successful, otherwise error.
481 *
482 ******************************************************************************/
AVDT_ConfigRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t category)483 uint16_t AVDT_ConfigRsp(uint8_t handle, uint8_t label, uint8_t error_code,
484 uint8_t category) {
485 tAVDT_SCB* p_scb;
486 tAVDT_SCB_EVT evt;
487 uint16_t result = AVDT_SUCCESS;
488 uint8_t event_code;
489
490 /* map handle to scb */
491 p_scb = avdt_scb_by_hdl(handle);
492 if (p_scb == NULL) {
493 result = AVDT_BAD_HANDLE;
494 }
495 /* handle special case when this function is called but peer has not send
496 ** a configuration cmd; ignore and return error result
497 */
498 else if (!p_scb->in_use) {
499 result = AVDT_BAD_HANDLE;
500 }
501 /* send event to scb */
502 else {
503 evt.msg.hdr.err_code = error_code;
504 evt.msg.hdr.err_param = category;
505 evt.msg.hdr.label = label;
506 if (error_code == 0) {
507 event_code = AVDT_SCB_API_SETCONFIG_RSP_EVT;
508 } else {
509 event_code = AVDT_SCB_API_SETCONFIG_REJ_EVT;
510 }
511 avdt_scb_event(p_scb, event_code, &evt);
512 }
513
514 return result;
515 }
516
517 /*******************************************************************************
518 *
519 * Function AVDT_StartReq
520 *
521 * Description Start one or more stream endpoints. This initiates the
522 * transfer of media packets for the streams. All stream
523 * endpoints must previously be opened. When the streams
524 * are started, an AVDT_START_CFM_EVT is sent to the
525 * application via the control callback function for each
526 * stream.
527 *
528 *
529 * Returns AVDT_SUCCESS if successful, otherwise error.
530 *
531 ******************************************************************************/
AVDT_StartReq(uint8_t * p_handles,uint8_t num_handles)532 uint16_t AVDT_StartReq(uint8_t* p_handles, uint8_t num_handles) {
533 tAVDT_SCB* p_scb = NULL;
534 tAVDT_CCB_EVT evt;
535 uint16_t result = AVDT_SUCCESS;
536 int i;
537
538 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
539 result = AVDT_BAD_PARAMS;
540 } else {
541 /* verify handles */
542 for (i = 0; i < num_handles; i++) {
543 p_scb = avdt_scb_by_hdl(p_handles[i]);
544 if (p_scb == NULL) {
545 result = AVDT_BAD_HANDLE;
546 break;
547 }
548 }
549 }
550
551 if (result == AVDT_SUCCESS) {
552 if (p_scb->p_ccb == NULL) {
553 result = AVDT_BAD_HANDLE;
554 } else {
555 /* send event to ccb */
556 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
557 evt.msg.multi.num_seps = num_handles;
558 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_START_REQ_EVT, &evt);
559 }
560 }
561 return result;
562 }
563
564 /*******************************************************************************
565 *
566 * Function AVDT_SuspendReq
567 *
568 * Description Suspend one or more stream endpoints. This suspends the
569 * transfer of media packets for the streams. All stream
570 * endpoints must previously be open and started. When the
571 * streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to
572 * the application via the control callback function for
573 * each stream.
574 *
575 *
576 * Returns AVDT_SUCCESS if successful, otherwise error.
577 *
578 ******************************************************************************/
AVDT_SuspendReq(uint8_t * p_handles,uint8_t num_handles)579 uint16_t AVDT_SuspendReq(uint8_t* p_handles, uint8_t num_handles) {
580 tAVDT_SCB* p_scb = NULL;
581 tAVDT_CCB_EVT evt;
582 uint16_t result = AVDT_SUCCESS;
583 int i;
584
585 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
586 result = AVDT_BAD_PARAMS;
587 } else {
588 /* verify handles */
589 for (i = 0; i < num_handles; i++) {
590 p_scb = avdt_scb_by_hdl(p_handles[i]);
591 if (p_scb == NULL) {
592 result = AVDT_BAD_HANDLE;
593 break;
594 }
595 }
596 }
597
598 if (result == AVDT_SUCCESS) {
599 if (p_scb->p_ccb == NULL) {
600 result = AVDT_BAD_HANDLE;
601 } else {
602 /* send event to ccb */
603 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
604 evt.msg.multi.num_seps = num_handles;
605 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_SUSPEND_REQ_EVT, &evt);
606 }
607 }
608
609 return result;
610 }
611
612 /*******************************************************************************
613 *
614 * Function AVDT_CloseReq
615 *
616 * Description Close a stream endpoint. This stops the transfer of media
617 * packets and closes the transport channel associated with
618 * this stream endpoint. When the stream is closed, an
619 * AVDT_CLOSE_CFM_EVT is sent to the application via the
620 * control callback function for this handle.
621 *
622 *
623 * Returns AVDT_SUCCESS if successful, otherwise error.
624 *
625 ******************************************************************************/
AVDT_CloseReq(uint8_t handle)626 uint16_t AVDT_CloseReq(uint8_t handle) {
627 tAVDT_SCB* p_scb;
628 uint16_t result = AVDT_SUCCESS;
629
630 /* map handle to scb */
631 p_scb = avdt_scb_by_hdl(handle);
632 if (p_scb == NULL) {
633 result = AVDT_BAD_HANDLE;
634 } else
635 /* send event to scb */
636 {
637 avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_REQ_EVT, NULL);
638 }
639
640 return result;
641 }
642
643 /*******************************************************************************
644 *
645 * Function AVDT_ReconfigReq
646 *
647 * Description Reconfigure a stream endpoint. This allows the application
648 * to change the codec or content protection capabilities of
649 * a stream endpoint after it has been opened. This function
650 * can only be called if the stream is opened but not started
651 * or if the stream has been suspended. When the procedure
652 * is completed, an AVDT_RECONFIG_CFM_EVT is sent to the
653 * application via the control callback function for this
654 * handle.
655 *
656 *
657 * Returns AVDT_SUCCESS if successful, otherwise error.
658 *
659 ******************************************************************************/
AVDT_ReconfigReq(uint8_t handle,tAVDT_CFG * p_cfg)660 uint16_t AVDT_ReconfigReq(uint8_t handle, tAVDT_CFG* p_cfg) {
661 tAVDT_SCB* p_scb;
662 uint16_t result = AVDT_SUCCESS;
663 tAVDT_SCB_EVT evt;
664
665 /* map handle to scb */
666 p_scb = avdt_scb_by_hdl(handle);
667 if (p_scb == NULL) {
668 result = AVDT_BAD_HANDLE;
669 }
670 /* send event to scb */
671 else {
672 /* force psc_mask to zero */
673 p_cfg->psc_mask = 0;
674
675 evt.msg.reconfig_cmd.p_cfg = p_cfg;
676 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_REQ_EVT, &evt);
677 }
678 return result;
679 }
680
681 /*******************************************************************************
682 *
683 * Function AVDT_ReconfigRsp
684 *
685 * Description Respond to a reconfigure request from the peer device.
686 * This function must be called if the application receives
687 * an AVDT_RECONFIG_IND_EVT through its control callback.
688 *
689 *
690 * Returns AVDT_SUCCESS if successful, otherwise error.
691 *
692 ******************************************************************************/
AVDT_ReconfigRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t category)693 uint16_t AVDT_ReconfigRsp(uint8_t handle, uint8_t label, uint8_t error_code,
694 uint8_t category) {
695 tAVDT_SCB* p_scb;
696 tAVDT_SCB_EVT evt;
697 uint16_t result = AVDT_SUCCESS;
698
699 /* map handle to scb */
700 p_scb = avdt_scb_by_hdl(handle);
701 if (p_scb == NULL) {
702 result = AVDT_BAD_HANDLE;
703 }
704 /* send event to scb */
705 else {
706 evt.msg.hdr.err_code = error_code;
707 evt.msg.hdr.err_param = category;
708 evt.msg.hdr.label = label;
709 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, &evt);
710 }
711
712 return result;
713 }
714
715 /*******************************************************************************
716 *
717 * Function AVDT_SecurityReq
718 *
719 * Description Send a security request to the peer device. When the
720 * security procedure is completed, an AVDT_SECURITY_CFM_EVT
721 * is sent to the application via the control callback function
722 * for this handle. (Please note that AVDTP security
723 * procedures are unrelated to Bluetooth link level security.)
724 *
725 *
726 * Returns AVDT_SUCCESS if successful, otherwise error.
727 *
728 ******************************************************************************/
AVDT_SecurityReq(uint8_t handle,uint8_t * p_data,uint16_t len)729 uint16_t AVDT_SecurityReq(uint8_t handle, uint8_t* p_data, uint16_t len) {
730 tAVDT_SCB* p_scb;
731 uint16_t result = AVDT_SUCCESS;
732 tAVDT_SCB_EVT evt;
733
734 /* map handle to scb */
735 p_scb = avdt_scb_by_hdl(handle);
736 if (p_scb == NULL) {
737 result = AVDT_BAD_HANDLE;
738 }
739 /* send event to scb */
740 else {
741 evt.msg.security_rsp.p_data = p_data;
742 evt.msg.security_rsp.len = len;
743 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_REQ_EVT, &evt);
744 }
745 return result;
746 }
747
748 /*******************************************************************************
749 *
750 * Function AVDT_SecurityRsp
751 *
752 * Description Respond to a security request from the peer device.
753 * This function must be called if the application receives
754 * an AVDT_SECURITY_IND_EVT through its control callback.
755 * (Please note that AVDTP security procedures are unrelated
756 * to Bluetooth link level security.)
757 *
758 *
759 * Returns AVDT_SUCCESS if successful, otherwise error.
760 *
761 ******************************************************************************/
AVDT_SecurityRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t * p_data,uint16_t len)762 uint16_t AVDT_SecurityRsp(uint8_t handle, uint8_t label, uint8_t error_code,
763 uint8_t* p_data, uint16_t len) {
764 tAVDT_SCB* p_scb;
765 uint16_t result = AVDT_SUCCESS;
766 tAVDT_SCB_EVT evt;
767
768 /* map handle to scb */
769 p_scb = avdt_scb_by_hdl(handle);
770 if (p_scb == NULL) {
771 result = AVDT_BAD_HANDLE;
772 }
773 /* send event to scb */
774 else {
775 evt.msg.security_rsp.hdr.err_code = error_code;
776 evt.msg.security_rsp.hdr.label = label;
777 evt.msg.security_rsp.p_data = p_data;
778 evt.msg.security_rsp.len = len;
779 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, &evt);
780 }
781 return result;
782 }
783
784 /*******************************************************************************
785 *
786 * Function AVDT_WriteReqOpt
787 *
788 * Description Send a media packet to the peer device. The stream must
789 * be started before this function is called. Also, this
790 * function can only be called if the stream is a SRC.
791 *
792 * When AVDTP has sent the media packet and is ready for the
793 * next packet, an AVDT_WRITE_CFM_EVT is sent to the
794 * application via the control callback. The application must
795 * wait for the AVDT_WRITE_CFM_EVT before it makes the next
796 * call to AVDT_WriteReq(). If the applications calls
797 * AVDT_WriteReq() before it receives the event the packet
798 * will not be sent. The application may make its first call
799 * to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
800 * or AVDT_START_IND_EVT.
801 *
802 * The application passes the packet using the BT_HDR
803 * structure.
804 * This structure is described in section 2.1. The offset
805 * field must be equal to or greater than AVDT_MEDIA_OFFSET
806 * (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used).
807 * This allows enough space in the buffer for the L2CAP and
808 * AVDTP headers.
809 *
810 * The memory pointed to by p_pkt must be a GKI buffer
811 * allocated by the application. This buffer will be freed
812 * by the protocol stack; the application must not free
813 * this buffer.
814 *
815 * The opt parameter allows passing specific options like:
816 * - NO_RTP : do not add the RTP header to buffer
817 *
818 * Returns AVDT_SUCCESS if successful, otherwise error.
819 *
820 ******************************************************************************/
AVDT_WriteReqOpt(uint8_t handle,BT_HDR * p_pkt,uint32_t time_stamp,uint8_t m_pt,tAVDT_DATA_OPT_MASK opt)821 uint16_t AVDT_WriteReqOpt(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
822 uint8_t m_pt, tAVDT_DATA_OPT_MASK opt) {
823 tAVDT_SCB* p_scb;
824 tAVDT_SCB_EVT evt;
825 uint16_t result = AVDT_SUCCESS;
826
827 /* map handle to scb */
828 p_scb = avdt_scb_by_hdl(handle);
829 if (p_scb == NULL) {
830 result = AVDT_BAD_HANDLE;
831 } else {
832 evt.apiwrite.p_buf = p_pkt;
833 evt.apiwrite.time_stamp = time_stamp;
834 evt.apiwrite.m_pt = m_pt;
835 evt.apiwrite.opt = opt;
836 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
837 }
838
839 return result;
840 }
841
842 /*******************************************************************************
843 *
844 * Function AVDT_WriteReq
845 *
846 * Description Send a media packet to the peer device. The stream must
847 * be started before this function is called. Also, this
848 * function can only be called if the stream is a SRC.
849 *
850 * When AVDTP has sent the media packet and is ready for the
851 * next packet, an AVDT_WRITE_CFM_EVT is sent to the
852 * application via the control callback. The application must
853 * wait for the AVDT_WRITE_CFM_EVT before it makes the next
854 * call to AVDT_WriteReq(). If the applications calls
855 * AVDT_WriteReq() before it receives the event the packet
856 * will not be sent. The application may make its first call
857 * to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
858 * or AVDT_START_IND_EVT.
859 *
860 * The application passes the packet using the BT_HDR
861 * structure.
862 * This structure is described in section 2.1. The offset
863 * field must be equal to or greater than AVDT_MEDIA_OFFSET.
864 * This allows enough space in the buffer for the L2CAP and
865 * AVDTP headers.
866 *
867 * The memory pointed to by p_pkt must be a GKI buffer
868 * allocated by the application. This buffer will be freed
869 * by the protocol stack; the application must not free
870 * this buffer.
871 *
872 *
873 * Returns AVDT_SUCCESS if successful, otherwise error.
874 *
875 ******************************************************************************/
AVDT_WriteReq(uint8_t handle,BT_HDR * p_pkt,uint32_t time_stamp,uint8_t m_pt)876 uint16_t AVDT_WriteReq(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
877 uint8_t m_pt) {
878 return AVDT_WriteReqOpt(handle, p_pkt, time_stamp, m_pt, AVDT_DATA_OPT_NONE);
879 }
880
881 /*******************************************************************************
882 *
883 * Function AVDT_ConnectReq
884 *
885 * Description This function initiates an AVDTP signaling connection
886 * to the peer device. When the connection is completed, an
887 * AVDT_CONNECT_IND_EVT is sent to the application via its
888 * control callback function. If the connection attempt fails
889 * an AVDT_DISCONNECT_IND_EVT is sent. The security mask
890 * parameter overrides the outgoing security mask set in
891 * AVDT_Register().
892 *
893 * Returns AVDT_SUCCESS if successful, otherwise error.
894 *
895 ******************************************************************************/
AVDT_ConnectReq(BD_ADDR bd_addr,uint8_t sec_mask,tAVDT_CTRL_CBACK * p_cback)896 uint16_t AVDT_ConnectReq(BD_ADDR bd_addr, uint8_t sec_mask,
897 tAVDT_CTRL_CBACK* p_cback) {
898 tAVDT_CCB* p_ccb = NULL;
899 uint16_t result = AVDT_SUCCESS;
900 tAVDT_CCB_EVT evt;
901
902 /* find channel control block for this bd addr; if none, allocate one */
903 p_ccb = avdt_ccb_by_bd(bd_addr);
904 if (p_ccb == NULL) {
905 p_ccb = avdt_ccb_alloc(bd_addr);
906 if (p_ccb == NULL) {
907 /* could not allocate channel control block */
908 result = AVDT_NO_RESOURCES;
909 }
910 } else if (p_ccb->ll_opened == false) {
911 AVDT_TRACE_WARNING("AVDT_ConnectReq: CCB LL is in the middle of opening");
912
913 /* ccb was already allocated for the incoming signalling. */
914 result = AVDT_BUSY;
915 }
916
917 if (result == AVDT_SUCCESS) {
918 /* send event to ccb */
919 evt.connect.p_cback = p_cback;
920 evt.connect.sec_mask = sec_mask;
921 avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt);
922 }
923 return result;
924 }
925
926 /*******************************************************************************
927 *
928 * Function AVDT_DisconnectReq
929 *
930 * Description This function disconnect an AVDTP signaling connection
931 * to the peer device. When disconnected an
932 * AVDT_DISCONNECT_IND_EVT is sent to the application via its
933 * control callback function.
934 *
935 * Returns AVDT_SUCCESS if successful, otherwise error.
936 *
937 ******************************************************************************/
AVDT_DisconnectReq(BD_ADDR bd_addr,tAVDT_CTRL_CBACK * p_cback)938 uint16_t AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK* p_cback) {
939 tAVDT_CCB* p_ccb = NULL;
940 uint16_t result = AVDT_SUCCESS;
941 tAVDT_CCB_EVT evt;
942
943 /* find channel control block for this bd addr; if none, error */
944 p_ccb = avdt_ccb_by_bd(bd_addr);
945 if (p_ccb == NULL) {
946 result = AVDT_BAD_PARAMS;
947 }
948
949 if (result == AVDT_SUCCESS) {
950 /* send event to ccb */
951 evt.disconnect.p_cback = p_cback;
952 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt);
953 }
954 return result;
955 }
956
957 /*******************************************************************************
958 *
959 * Function AVDT_GetL2CapChannel
960 *
961 * Description Get the L2CAP CID used by the handle.
962 *
963 * Returns CID if successful, otherwise 0.
964 *
965 ******************************************************************************/
AVDT_GetL2CapChannel(uint8_t handle)966 uint16_t AVDT_GetL2CapChannel(uint8_t handle) {
967 tAVDT_SCB* p_scb;
968 tAVDT_CCB* p_ccb;
969 uint8_t tcid;
970 uint16_t lcid = 0;
971
972 /* map handle to scb */
973 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) &&
974 ((p_ccb = p_scb->p_ccb) != NULL)) {
975 /* get tcid from type, scb */
976 tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
977
978 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
979 }
980
981 return (lcid);
982 }
983
984 /*******************************************************************************
985 *
986 * Function AVDT_GetSignalChannel
987 *
988 * Description Get the L2CAP CID used by the signal channel of the given
989 * handle.
990 *
991 * Returns CID if successful, otherwise 0.
992 *
993 ******************************************************************************/
AVDT_GetSignalChannel(uint8_t handle,BD_ADDR bd_addr)994 uint16_t AVDT_GetSignalChannel(uint8_t handle, BD_ADDR bd_addr) {
995 tAVDT_SCB* p_scb;
996 tAVDT_CCB* p_ccb;
997 uint8_t tcid = 0; /* tcid is always 0 for signal channel */
998 uint16_t lcid = 0;
999
1000 /* map handle to scb */
1001 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) &&
1002 ((p_ccb = p_scb->p_ccb) != NULL)) {
1003 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1004 } else {
1005 p_ccb = avdt_ccb_by_bd(bd_addr);
1006 if (p_ccb != NULL) {
1007 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1008 }
1009 }
1010
1011 return (lcid);
1012 }
1013
1014 #if (AVDT_REPORTING == TRUE)
1015 /*******************************************************************************
1016 *
1017 * Function AVDT_SendReport
1018 *
1019 * Description
1020 *
1021 *
1022 *
1023 * Returns
1024 *
1025 ******************************************************************************/
AVDT_SendReport(uint8_t handle,AVDT_REPORT_TYPE type,tAVDT_REPORT_DATA * p_data)1026 uint16_t AVDT_SendReport(uint8_t handle, AVDT_REPORT_TYPE type,
1027 tAVDT_REPORT_DATA* p_data) {
1028 tAVDT_SCB* p_scb;
1029 uint16_t result = AVDT_BAD_PARAMS;
1030 tAVDT_TC_TBL* p_tbl;
1031 uint8_t *p, *plen, *pm1, *p_end;
1032 uint32_t ssrc;
1033 uint16_t len;
1034
1035 /* map handle to scb && verify parameters */
1036 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) && (p_scb->p_ccb != NULL) &&
1037 (((type == AVDT_RTCP_PT_SR) && (p_scb->cs.tsep == AVDT_TSEP_SRC)) ||
1038 ((type == AVDT_RTCP_PT_RR) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) ||
1039 (type == AVDT_RTCP_PT_SDES))) {
1040 result = AVDT_NO_RESOURCES;
1041
1042 /* build SR - assume fit in one packet */
1043 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
1044 if (p_tbl->state == AVDT_AD_ST_OPEN) {
1045 BT_HDR* p_pkt = (BT_HDR*)osi_malloc(p_tbl->peer_mtu);
1046
1047 p_pkt->offset = L2CAP_MIN_OFFSET;
1048 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1049 pm1 = p;
1050 *p++ = AVDT_MEDIA_OCTET1 | 1;
1051 *p++ = type;
1052 /* save the location for length */
1053 plen = p;
1054 p += 2;
1055 ssrc = avdt_scb_gen_ssrc(p_scb);
1056 UINT32_TO_BE_STREAM(p, ssrc);
1057
1058 switch (type) {
1059 case AVDT_RTCP_PT_SR: /* Sender Report */
1060 *pm1 = AVDT_MEDIA_OCTET1;
1061 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec);
1062 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac);
1063 UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time);
1064 UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count);
1065 UINT32_TO_BE_STREAM(p, p_data->sr.octet_count);
1066 break;
1067
1068 case AVDT_RTCP_PT_RR: /* Receiver Report */
1069 *p++ = p_data->rr.frag_lost;
1070 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1071 p_data->rr.packet_lost &= 0xFFFFFF;
1072 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1073 UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost);
1074 UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd);
1075 UINT32_TO_BE_STREAM(p, p_data->rr.jitter);
1076 UINT32_TO_BE_STREAM(p, p_data->rr.lsr);
1077 UINT32_TO_BE_STREAM(p, p_data->rr.dlsr);
1078 break;
1079
1080 case AVDT_RTCP_PT_SDES: /* Source Description */
1081 *p++ = AVDT_RTCP_SDES_CNAME;
1082 len = strlen((char*)p_data->cname);
1083 if (len > AVDT_MAX_CNAME_SIZE) len = AVDT_MAX_CNAME_SIZE;
1084 *p++ = (uint8_t)len;
1085 strlcpy((char*)p, (char*)p_data->cname, len + 1);
1086 p += len;
1087 break;
1088 }
1089 p_end = p;
1090 len = p - pm1 - 1;
1091 UINT16_TO_BE_STREAM(plen, len);
1092
1093 /* set the actual payload length */
1094 p_pkt->len = p_end - p;
1095 /* send the packet */
1096 if (L2CAP_DW_FAILED !=
1097 avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt))
1098 result = AVDT_SUCCESS;
1099 }
1100 }
1101
1102 return result;
1103 }
1104 #endif
1105
1106 /******************************************************************************
1107 *
1108 * Function AVDT_SetTraceLevel
1109 *
1110 * Description Sets the trace level for AVDT. If 0xff is passed, the
1111 * current trace level is returned.
1112 *
1113 * Input Parameters:
1114 * new_level: The level to set the AVDT tracing to:
1115 * 0xff-returns the current setting.
1116 * 0-turns off tracing.
1117 * >= 1-Errors.
1118 * >= 2-Warnings.
1119 * >= 3-APIs.
1120 * >= 4-Events.
1121 * >= 5-Debug.
1122 *
1123 * Returns The new trace level or current trace level if
1124 * the input parameter is 0xff.
1125 *
1126 *****************************************************************************/
AVDT_SetTraceLevel(uint8_t new_level)1127 uint8_t AVDT_SetTraceLevel(uint8_t new_level) {
1128 if (new_level != 0xFF) avdt_cb.trace_level = new_level;
1129
1130 return (avdt_cb.trace_level);
1131 }
1132