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