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