1 /******************************************************************************
3 * Copyright (C) 2002-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This module contains API of the audio/video distribution transport
24 ******************************************************************************/
28 #include "bt_target.h"
30 #include "avdtc_api.h"
37 /* Control block for AVDT */
38 #if AVDT_DYNAMIC_MEMORY == FALSE
43 /*******************************************************************************
45 ** Function avdt_process_timeout
47 ** Description This function is called by BTU when an AVDTP timer
48 ** expires. The function sends a timer event to the
49 ** appropriate CCB or SCB state machine.
51 ** This function is for use internal to the stack only.
56 *******************************************************************************/
57 void avdt_process_timeout(TIMER_LIST_ENT *p_tle)
60 UINT8 err_code = AVDT_ERR_TIMEOUT;
64 case BTU_TTYPE_AVDT_CCB_RET:
65 event = AVDT_CCB_RET_TOUT_EVT + AVDT_CCB_MKR;
68 case BTU_TTYPE_AVDT_CCB_RSP:
69 event = AVDT_CCB_RSP_TOUT_EVT + AVDT_CCB_MKR;
72 case BTU_TTYPE_AVDT_CCB_IDLE:
73 event = AVDT_CCB_IDLE_TOUT_EVT + AVDT_CCB_MKR;
76 case BTU_TTYPE_AVDT_SCB_TC:
77 event = AVDT_SCB_TC_TOUT_EVT;
84 if (event & AVDT_CCB_MKR)
86 avdt_ccb_event((tAVDT_CCB *) p_tle->param, (UINT8) (event & ~AVDT_CCB_MKR),
87 (tAVDT_CCB_EVT *) &err_code);
91 avdt_scb_event((tAVDT_SCB *) p_tle->param, event, NULL);
95 /*******************************************************************************
97 ** Function AVDT_Register
99 ** Description This is the system level registration function for the
100 ** AVDTP protocol. This function initializes AVDTP and
101 ** prepares the protocol stack for its use. This function
102 ** must be called once by the system or platform using AVDTP
103 ** before the other functions of the API an be used.
108 *******************************************************************************/
109 void AVDT_Register(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback)
111 /* register PSM with L2CAP */
112 L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO *) &avdt_l2c_appl);
114 /* set security level */
115 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
116 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
117 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
118 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
120 /* do not use security on the media channel */
121 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
122 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
123 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
124 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
126 #if AVDT_REPORTING == TRUE
127 /* do not use security on the reporting channel */
128 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
129 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
130 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
131 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
134 /* initialize AVDTP data structures */
139 /* copy registration struct */
140 memcpy(&avdt_cb.rcb, p_reg, sizeof(tAVDT_REG));
141 avdt_cb.p_conn_cback = p_cback;
144 /*******************************************************************************
146 ** Function AVDT_Deregister
148 ** Description This function is called to deregister use AVDTP protocol.
149 ** It is called when AVDTP is no longer being used by any
150 ** application in the system. Before this function can be
151 ** called, all streams must be removed with AVDT_RemoveStream().
156 *******************************************************************************/
157 void AVDT_Deregister(void)
159 /* deregister PSM with L2CAP */
160 L2CA_Deregister(AVDT_PSM);
163 /*******************************************************************************
165 ** Function AVDT_SINK_Activate
167 ** Description Activate SEP of A2DP Sink. In Use parameter is adjusted.
168 ** In Use will be made false in case of activation. A2DP SRC
169 ** will receive in_use as false and can open A2DP Sink
174 *******************************************************************************/
175 void AVDT_SINK_Activate()
177 tAVDT_SCB *p_scb = &avdt_cb.scb[0];
179 AVDT_TRACE_DEBUG("AVDT_SINK_Activate");
180 /* for all allocated scbs */
181 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
183 if ((p_scb->allocated) && (p_scb->cs.tsep == AVDT_TSEP_SNK))
185 AVDT_TRACE_DEBUG("AVDT_SINK_Activate found scb");
186 p_scb->sink_activated = TRUE;
188 p_scb->in_use = FALSE;
194 /*******************************************************************************
196 ** Function AVDT_SINK_Deactivate
198 ** Description Deactivate SEP of A2DP Sink. In Use parameter is adjusted.
199 ** In Use will be made TRUE in case of activation. A2DP SRC
200 ** will receive in_use as true and will not open A2DP Sink
205 *******************************************************************************/
206 void AVDT_SINK_Deactivate()
208 tAVDT_SCB *p_scb = &avdt_cb.scb[0];
210 AVDT_TRACE_DEBUG("AVDT_SINK_Deactivate");
211 /* for all allocated scbs */
212 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
214 if ((p_scb->allocated) && (p_scb->cs.tsep == AVDT_TSEP_SNK))
216 AVDT_TRACE_DEBUG("AVDT_SINK_Deactivate, found scb");
217 p_scb->sink_activated = FALSE;
219 p_scb->in_use = TRUE;
225 void AVDT_AbortReq(UINT8 handle)
227 AVDT_TRACE_ERROR("%s", __func__);
229 tAVDT_SCB *p_scb = avdt_scb_by_hdl(handle);
232 avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_REQ_EVT, NULL);
234 AVDT_TRACE_ERROR("%s Improper SCB, can not abort the stream", __func__);
238 /*******************************************************************************
240 ** Function AVDT_CreateStream
242 ** Description Create a stream endpoint. After a stream endpoint is
243 ** created an application can initiate a connection between
244 ** this endpoint and an endpoint on a peer device. In
245 ** addition, a peer device can discover, get the capabilities,
246 ** and connect to this endpoint.
249 ** Returns AVDT_SUCCESS if successful, otherwise error.
251 *******************************************************************************/
252 UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs)
254 UINT16 result = AVDT_SUCCESS;
257 /* Verify parameters; if invalid, return failure */
258 if (((p_cs->cfg.psc_mask & (~AVDT_PSC)) != 0) || (p_cs->p_ctrl_cback == NULL))
260 result = AVDT_BAD_PARAMS;
262 /* Allocate scb; if no scbs, return failure */
263 else if ((p_scb = avdt_scb_alloc(p_cs)) == NULL)
265 result = AVDT_NO_RESOURCES;
269 *p_handle = avdt_scb_to_hdl(p_scb);
274 /*******************************************************************************
276 ** Function AVDT_RemoveStream
278 ** Description Remove a stream endpoint. This function is called when
279 ** the application is no longer using a stream endpoint.
280 ** If this function is called when the endpoint is connected
281 ** the connection is closed and then the stream endpoint
285 ** Returns AVDT_SUCCESS if successful, otherwise error.
287 *******************************************************************************/
288 UINT16 AVDT_RemoveStream(UINT8 handle)
290 UINT16 result = AVDT_SUCCESS;
294 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
296 result = AVDT_BAD_HANDLE;
300 /* send remove event to scb */
301 avdt_scb_event(p_scb, AVDT_SCB_API_REMOVE_EVT, NULL);
306 /*******************************************************************************
308 ** Function AVDT_DiscoverReq
310 ** Description This function initiates a connection to the AVDTP service
311 ** on the peer device, if not already present, and discovers
312 ** the stream endpoints on the peer device. (Please note
313 ** that AVDTP discovery is unrelated to SDP discovery).
314 ** This function can be called at any time regardless of whether
315 ** there is an AVDTP connection to the peer device.
317 ** When discovery is complete, an AVDT_DISCOVER_CFM_EVT
318 ** is sent to the application via its callback function.
319 ** The application must not call AVDT_GetCapReq() or
320 ** AVDT_DiscoverReq() again to the same device until
321 ** discovery is complete.
323 ** The memory addressed by sep_info is allocated by the
324 ** application. This memory is written to by AVDTP as part
325 ** of the discovery procedure. This memory must remain
326 ** accessible until the application receives the
327 ** AVDT_DISCOVER_CFM_EVT.
329 ** Returns AVDT_SUCCESS if successful, otherwise error.
331 *******************************************************************************/
332 UINT16 AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO *p_sep_info,
333 UINT8 max_seps, tAVDT_CTRL_CBACK *p_cback)
336 UINT16 result = AVDT_SUCCESS;
339 /* find channel control block for this bd addr; if none, allocate one */
340 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
342 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
344 /* could not allocate channel control block */
345 result = AVDT_NO_RESOURCES;
349 if (result == AVDT_SUCCESS)
351 /* make sure no discovery or get capabilities req already in progress */
352 if (p_ccb->proc_busy)
356 /* send event to ccb */
359 evt.discover.p_sep_info = p_sep_info;
360 evt.discover.num_seps = max_seps;
361 evt.discover.p_cback = p_cback;
362 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_REQ_EVT, &evt);
368 /*******************************************************************************
370 ** Function avdt_get_cap_req
372 ** Description internal function to serve both AVDT_GetCapReq and
375 ** Returns AVDT_SUCCESS if successful, otherwise error.
377 *******************************************************************************/
378 static UINT16 avdt_get_cap_req(BD_ADDR bd_addr, tAVDT_CCB_API_GETCAP *p_evt)
380 tAVDT_CCB *p_ccb = NULL;
381 UINT16 result = AVDT_SUCCESS;
384 if ((p_evt->single.seid < AVDT_SEID_MIN) || (p_evt->single.seid > AVDT_SEID_MAX))
386 AVDT_TRACE_ERROR("seid: %d", p_evt->single.seid);
387 result = AVDT_BAD_PARAMS;
389 /* find channel control block for this bd addr; if none, allocate one */
390 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
392 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
394 /* could not allocate channel control block */
395 result = AVDT_NO_RESOURCES;
399 if (result == AVDT_SUCCESS)
401 /* make sure no discovery or get capabilities req already in progress */
402 if (p_ccb->proc_busy)
406 /* send event to ccb */
409 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_REQ_EVT, (tAVDT_CCB_EVT *)p_evt);
415 /*******************************************************************************
417 ** Function AVDT_GetCapReq
419 ** Description This function initiates a connection to the AVDTP service
420 ** on the peer device, if not already present, and gets the
421 ** capabilities of a stream endpoint on the peer device.
422 ** This function can be called at any time regardless of
423 ** whether there is an AVDTP connection to the peer device.
425 ** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
426 ** sent to the application via its callback function. The
427 ** application must not call AVDT_GetCapReq() or
428 ** AVDT_DiscoverReq() again until the procedure is complete.
430 ** The memory pointed to by p_cfg is allocated by the
431 ** application. This memory is written to by AVDTP as part
432 ** of the get capabilities procedure. This memory must
433 ** remain accessible until the application receives
434 ** the AVDT_GETCAP_CFM_EVT.
436 ** Returns AVDT_SUCCESS if successful, otherwise error.
438 *******************************************************************************/
439 UINT16 AVDT_GetCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback)
441 tAVDT_CCB_API_GETCAP getcap;
443 getcap.single.seid = seid;
444 getcap.single.sig_id = AVDT_SIG_GETCAP;
445 getcap.p_cfg = p_cfg;
446 getcap.p_cback = p_cback;
447 return avdt_get_cap_req (bd_addr, &getcap);
450 /*******************************************************************************
452 ** Function AVDT_GetAllCapReq
454 ** Description This function initiates a connection to the AVDTP service
455 ** on the peer device, if not already present, and gets the
456 ** capabilities of a stream endpoint on the peer device.
457 ** This function can be called at any time regardless of
458 ** whether there is an AVDTP connection to the peer device.
460 ** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
461 ** sent to the application via its callback function. The
462 ** application must not call AVDT_GetCapReq() or
463 ** AVDT_DiscoverReq() again until the procedure is complete.
465 ** The memory pointed to by p_cfg is allocated by the
466 ** application. This memory is written to by AVDTP as part
467 ** of the get capabilities procedure. This memory must
468 ** remain accessible until the application receives
469 ** the AVDT_GETCAP_CFM_EVT.
471 ** Returns AVDT_SUCCESS if successful, otherwise error.
473 *******************************************************************************/
474 UINT16 AVDT_GetAllCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback)
476 tAVDT_CCB_API_GETCAP getcap;
478 getcap.single.seid = seid;
479 getcap.single.sig_id = AVDT_SIG_GET_ALLCAP;
480 getcap.p_cfg = p_cfg;
481 getcap.p_cback = p_cback;
482 return avdt_get_cap_req (bd_addr, &getcap);
485 /*******************************************************************************
487 ** Function AVDT_DelayReport
489 ** Description This functions sends a Delay Report to the peer device
490 ** that is associated with a particular SEID.
491 ** This function is called by SNK device.
493 ** Returns AVDT_SUCCESS if successful, otherwise error.
495 *******************************************************************************/
496 UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay)
499 UINT16 result = AVDT_SUCCESS;
502 /* map handle to scb */
503 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
505 result = AVDT_BAD_HANDLE;
508 /* send event to scb */
510 evt.apidelay.hdr.seid = seid;
511 evt.apidelay.delay = delay;
512 avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt);
518 /*******************************************************************************
520 ** Function AVDT_OpenReq
522 ** Description This function initiates a connection to the AVDTP service
523 ** on the peer device, if not already present, and connects
524 ** to a stream endpoint on a peer device. When the connection
525 ** is completed, an AVDT_OPEN_CFM_EVT is sent to the
526 ** application via the control callback function for this handle.
528 ** Returns AVDT_SUCCESS if successful, otherwise error.
530 *******************************************************************************/
531 UINT16 AVDT_OpenReq(UINT8 handle, BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg)
533 tAVDT_CCB *p_ccb = NULL;
534 tAVDT_SCB *p_scb = NULL;
535 UINT16 result = AVDT_SUCCESS;
539 if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX))
541 result = AVDT_BAD_PARAMS;
543 /* map handle to scb */
544 else if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
546 result = AVDT_BAD_HANDLE;
548 /* find channel control block for this bd addr; if none, allocate one */
549 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
551 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
553 /* could not allocate channel control block */
554 result = AVDT_NO_RESOURCES;
558 /* send event to scb */
559 if (result == AVDT_SUCCESS)
561 evt.msg.config_cmd.hdr.seid = seid;
562 evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
563 evt.msg.config_cmd.int_seid = handle;
564 evt.msg.config_cmd.p_cfg = p_cfg;
565 avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt);
570 /*******************************************************************************
572 ** Function AVDT_ConfigRsp
574 ** Description Respond to a configure request from the peer device. This
575 ** function must be called if the application receives an
576 ** AVDT_CONFIG_IND_EVT through its control callback.
579 ** Returns AVDT_SUCCESS if successful, otherwise error.
581 *******************************************************************************/
582 UINT16 AVDT_ConfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category)
586 UINT16 result = AVDT_SUCCESS;
589 /* map handle to scb */
590 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
592 result = AVDT_BAD_HANDLE;
594 /* handle special case when this function is called but peer has not send
595 ** a configuration cmd; ignore and return error result
597 else if (!p_scb->in_use)
599 result = AVDT_BAD_HANDLE;
601 /* send event to scb */
604 evt.msg.hdr.err_code = error_code;
605 evt.msg.hdr.err_param = category;
606 evt.msg.hdr.label = label;
609 event_code = AVDT_SCB_API_SETCONFIG_RSP_EVT;
613 event_code = AVDT_SCB_API_SETCONFIG_REJ_EVT;
615 avdt_scb_event(p_scb, event_code, &evt);
621 /*******************************************************************************
623 ** Function AVDT_StartReq
625 ** Description Start one or more stream endpoints. This initiates the
626 ** transfer of media packets for the streams. All stream
627 ** endpoints must previously be opened. When the streams
628 ** are started, an AVDT_START_CFM_EVT is sent to the
629 ** application via the control callback function for each stream.
632 ** Returns AVDT_SUCCESS if successful, otherwise error.
634 *******************************************************************************/
635 UINT16 AVDT_StartReq(UINT8 *p_handles, UINT8 num_handles)
637 tAVDT_SCB *p_scb = NULL;
639 UINT16 result = AVDT_SUCCESS;
642 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS))
644 result = AVDT_BAD_PARAMS;
649 for (i = 0; i < num_handles; i++)
651 if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL)
653 result = AVDT_BAD_HANDLE;
659 if (result == AVDT_SUCCESS)
661 if (p_scb->p_ccb == NULL)
663 result = AVDT_BAD_HANDLE;
667 /* send event to ccb */
668 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
669 evt.msg.multi.num_seps = num_handles;
670 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_START_REQ_EVT, &evt);
676 /*******************************************************************************
678 ** Function AVDT_SuspendReq
680 ** Description Suspend one or more stream endpoints. This suspends the
681 ** transfer of media packets for the streams. All stream
682 ** endpoints must previously be open and started. When the
683 ** streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to
684 ** the application via the control callback function for
688 ** Returns AVDT_SUCCESS if successful, otherwise error.
690 *******************************************************************************/
691 UINT16 AVDT_SuspendReq(UINT8 *p_handles, UINT8 num_handles)
693 tAVDT_SCB *p_scb = NULL;
695 UINT16 result = AVDT_SUCCESS;
698 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS))
700 result = AVDT_BAD_PARAMS;
705 for (i = 0; i < num_handles; i++)
707 if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL)
709 result = AVDT_BAD_HANDLE;
715 if (result == AVDT_SUCCESS)
717 if (p_scb->p_ccb == NULL)
719 result = AVDT_BAD_HANDLE;
723 /* send event to ccb */
724 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
725 evt.msg.multi.num_seps = num_handles;
726 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_SUSPEND_REQ_EVT, &evt);
733 /*******************************************************************************
735 ** Function AVDT_CloseReq
737 ** Description Close a stream endpoint. This stops the transfer of media
738 ** packets and closes the transport channel associated with
739 ** this stream endpoint. When the stream is closed, an
740 ** AVDT_CLOSE_CFM_EVT is sent to the application via the
741 ** control callback function for this handle.
744 ** Returns AVDT_SUCCESS if successful, otherwise error.
746 *******************************************************************************/
747 UINT16 AVDT_CloseReq(UINT8 handle)
750 UINT16 result = AVDT_SUCCESS;
752 /* map handle to scb */
753 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
755 result = AVDT_BAD_HANDLE;
758 /* send event to scb */
760 avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_REQ_EVT, NULL);
766 /*******************************************************************************
768 ** Function AVDT_ReconfigReq
770 ** Description Reconfigure a stream endpoint. This allows the application
771 ** to change the codec or content protection capabilities of
772 ** a stream endpoint after it has been opened. This function
773 ** can only be called if the stream is opened but not started
774 ** or if the stream has been suspended. When the procedure
775 ** is completed, an AVDT_RECONFIG_CFM_EVT is sent to the
776 ** application via the control callback function for this handle.
779 ** Returns AVDT_SUCCESS if successful, otherwise error.
781 *******************************************************************************/
782 UINT16 AVDT_ReconfigReq(UINT8 handle, tAVDT_CFG *p_cfg)
785 UINT16 result = AVDT_SUCCESS;
788 /* map handle to scb */
789 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
791 result = AVDT_BAD_HANDLE;
793 /* send event to scb */
796 /* force psc_mask to zero */
799 evt.msg.reconfig_cmd.p_cfg = p_cfg;
800 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_REQ_EVT, &evt);
805 /*******************************************************************************
807 ** Function AVDT_ReconfigRsp
809 ** Description Respond to a reconfigure request from the peer device.
810 ** This function must be called if the application receives
811 ** an AVDT_RECONFIG_IND_EVT through its control callback.
814 ** Returns AVDT_SUCCESS if successful, otherwise error.
816 *******************************************************************************/
817 UINT16 AVDT_ReconfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category)
821 UINT16 result = AVDT_SUCCESS;
823 /* map handle to scb */
824 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
826 result = AVDT_BAD_HANDLE;
828 /* send event to scb */
831 evt.msg.hdr.err_code = error_code;
832 evt.msg.hdr.err_param = category;
833 evt.msg.hdr.label = label;
834 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, &evt);
840 /*******************************************************************************
842 ** Function AVDT_SecurityReq
844 ** Description Send a security request to the peer device. When the
845 ** security procedure is completed, an AVDT_SECURITY_CFM_EVT
846 ** is sent to the application via the control callback function
847 ** for this handle. (Please note that AVDTP security procedures
848 ** are unrelated to Bluetooth link level security.)
851 ** Returns AVDT_SUCCESS if successful, otherwise error.
853 *******************************************************************************/
854 UINT16 AVDT_SecurityReq(UINT8 handle, UINT8 *p_data, UINT16 len)
857 UINT16 result = AVDT_SUCCESS;
860 /* map handle to scb */
861 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
863 result = AVDT_BAD_HANDLE;
865 /* send event to scb */
868 evt.msg.security_rsp.p_data = p_data;
869 evt.msg.security_rsp.len = len;
870 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_REQ_EVT, &evt);
875 /*******************************************************************************
877 ** Function AVDT_SecurityRsp
879 ** Description Respond to a security request from the peer device.
880 ** This function must be called if the application receives
881 ** an AVDT_SECURITY_IND_EVT through its control callback.
882 ** (Please note that AVDTP security procedures are unrelated
883 ** to Bluetooth link level security.)
886 ** Returns AVDT_SUCCESS if successful, otherwise error.
888 *******************************************************************************/
889 UINT16 AVDT_SecurityRsp(UINT8 handle, UINT8 label, UINT8 error_code,
890 UINT8 *p_data, UINT16 len)
893 UINT16 result = AVDT_SUCCESS;
896 /* map handle to scb */
897 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
899 result = AVDT_BAD_HANDLE;
901 /* send event to scb */
904 evt.msg.security_rsp.hdr.err_code = error_code;
905 evt.msg.security_rsp.hdr.label = label;
906 evt.msg.security_rsp.p_data = p_data;
907 evt.msg.security_rsp.len = len;
908 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, &evt);
913 /*******************************************************************************
915 ** Function AVDT_WriteReqOpt
917 ** Description Send a media packet to the peer device. The stream must
918 ** be started before this function is called. Also, this
919 ** function can only be called if the stream is a SRC.
921 ** When AVDTP has sent the media packet and is ready for the
922 ** next packet, an AVDT_WRITE_CFM_EVT is sent to the
923 ** application via the control callback. The application must
924 ** wait for the AVDT_WRITE_CFM_EVT before it makes the next
925 ** call to AVDT_WriteReq(). If the applications calls
926 ** AVDT_WriteReq() before it receives the event the packet
927 ** will not be sent. The application may make its first call
928 ** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
929 ** or AVDT_START_IND_EVT.
931 ** The application passes the packet using the BT_HDR structure.
932 ** This structure is described in section 2.1. The offset
933 ** field must be equal to or greater than AVDT_MEDIA_OFFSET
934 ** (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used).
935 ** This allows enough space in the buffer for the L2CAP and
938 ** The memory pointed to by p_pkt must be a GKI buffer
939 ** allocated by the application. This buffer will be freed
940 ** by the protocol stack; the application must not free
943 ** The opt parameter allows passing specific options like:
944 ** - NO_RTP : do not add the RTP header to buffer
946 ** Returns AVDT_SUCCESS if successful, otherwise error.
948 *******************************************************************************/
949 UINT16 AVDT_WriteReqOpt(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt, tAVDT_DATA_OPT_MASK opt)
953 UINT16 result = AVDT_SUCCESS;
955 /* map handle to scb */
956 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
958 result = AVDT_BAD_HANDLE;
962 evt.apiwrite.p_buf = p_pkt;
963 evt.apiwrite.time_stamp = time_stamp;
964 evt.apiwrite.m_pt = m_pt;
965 evt.apiwrite.opt = opt;
966 #if AVDT_MULTIPLEXING == TRUE
967 GKI_init_q (&evt.apiwrite.frag_q);
969 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
975 /*******************************************************************************
977 ** Function AVDT_WriteReq
979 ** Description Send a media packet to the peer device. The stream must
980 ** be started before this function is called. Also, this
981 ** function can only be called if the stream is a SRC.
983 ** When AVDTP has sent the media packet and is ready for the
984 ** next packet, an AVDT_WRITE_CFM_EVT is sent to the
985 ** application via the control callback. The application must
986 ** wait for the AVDT_WRITE_CFM_EVT before it makes the next
987 ** call to AVDT_WriteReq(). If the applications calls
988 ** AVDT_WriteReq() before it receives the event the packet
989 ** will not be sent. The application may make its first call
990 ** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
991 ** or AVDT_START_IND_EVT.
993 ** The application passes the packet using the BT_HDR structure.
994 ** This structure is described in section 2.1. The offset
995 ** field must be equal to or greater than AVDT_MEDIA_OFFSET.
996 ** This allows enough space in the buffer for the L2CAP and
999 ** The memory pointed to by p_pkt must be a GKI buffer
1000 ** allocated by the application. This buffer will be freed
1001 ** by the protocol stack; the application must not free
1005 ** Returns AVDT_SUCCESS if successful, otherwise error.
1007 *******************************************************************************/
1008 UINT16 AVDT_WriteReq(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt)
1010 return AVDT_WriteReqOpt(handle, p_pkt, time_stamp, m_pt, AVDT_DATA_OPT_NONE);
1013 /*******************************************************************************
1015 ** Function AVDT_ConnectReq
1017 ** Description This function initiates an AVDTP signaling connection
1018 ** to the peer device. When the connection is completed, an
1019 ** AVDT_CONNECT_IND_EVT is sent to the application via its
1020 ** control callback function. If the connection attempt fails
1021 ** an AVDT_DISCONNECT_IND_EVT is sent. The security mask
1022 ** parameter overrides the outgoing security mask set in
1025 ** Returns AVDT_SUCCESS if successful, otherwise error.
1027 *******************************************************************************/
1028 UINT16 AVDT_ConnectReq(BD_ADDR bd_addr, UINT8 sec_mask, tAVDT_CTRL_CBACK *p_cback)
1030 tAVDT_CCB *p_ccb = NULL;
1031 UINT16 result = AVDT_SUCCESS;
1034 /* find channel control block for this bd addr; if none, allocate one */
1035 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
1037 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
1039 /* could not allocate channel control block */
1040 result = AVDT_NO_RESOURCES;
1043 else if (p_ccb->ll_opened == FALSE)
1045 AVDT_TRACE_WARNING("AVDT_ConnectReq: CCB LL is in the middle of opening");
1047 /* ccb was already allocated for the incoming signalling. */
1051 if (result == AVDT_SUCCESS)
1053 /* send event to ccb */
1054 evt.connect.p_cback = p_cback;
1055 evt.connect.sec_mask = sec_mask;
1056 avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt);
1061 /*******************************************************************************
1063 ** Function AVDT_DisconnectReq
1065 ** Description This function disconnect an AVDTP signaling connection
1066 ** to the peer device. When disconnected an
1067 ** AVDT_DISCONNECT_IND_EVT is sent to the application via its
1068 ** control callback function.
1070 ** Returns AVDT_SUCCESS if successful, otherwise error.
1072 *******************************************************************************/
1073 UINT16 AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK *p_cback)
1075 tAVDT_CCB *p_ccb = NULL;
1076 UINT16 result = AVDT_SUCCESS;
1079 /* find channel control block for this bd addr; if none, error */
1080 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
1082 result = AVDT_BAD_PARAMS;
1085 if (result == AVDT_SUCCESS)
1087 /* send event to ccb */
1088 evt.disconnect.p_cback = p_cback;
1089 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt);
1094 /*******************************************************************************
1096 ** Function AVDT_GetL2CapChannel
1098 ** Description Get the L2CAP CID used by the handle.
1100 ** Returns CID if successful, otherwise 0.
1102 *******************************************************************************/
1103 UINT16 AVDT_GetL2CapChannel(UINT8 handle)
1110 /* map handle to scb */
1111 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
1112 && ((p_ccb = p_scb->p_ccb) != NULL))
1114 /* get tcid from type, scb */
1115 tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
1117 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1123 /*******************************************************************************
1125 ** Function AVDT_GetSignalChannel
1127 ** Description Get the L2CAP CID used by the signal channel of the given handle.
1129 ** Returns CID if successful, otherwise 0.
1131 *******************************************************************************/
1132 UINT16 AVDT_GetSignalChannel(UINT8 handle, BD_ADDR bd_addr)
1136 UINT8 tcid = 0; /* tcid is always 0 for signal channel */
1139 /* map handle to scb */
1140 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
1141 && ((p_ccb = p_scb->p_ccb) != NULL))
1143 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1145 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) != NULL)
1147 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1153 #if AVDT_MULTIPLEXING == TRUE
1154 /*******************************************************************************
1156 ** Function AVDT_WriteDataReq
1158 ** Description Send a media packet to the peer device. The stream must
1159 ** be started before this function is called. Also, this
1160 ** function can only be called if the stream is a SRC.
1162 ** When AVDTP has sent the media packet and is ready for the
1163 ** next packet, an AVDT_WRITE_CFM_EVT is sent to the
1164 ** application via the control callback. The application must
1165 ** wait for the AVDT_WRITE_CFM_EVT before it makes the next
1166 ** call to AVDT_WriteDataReq(). If the applications calls
1167 ** AVDT_WriteDataReq() before it receives the event the packet
1168 ** will not be sent. The application may make its first call
1169 ** to AVDT_WriteDataReq() after it receives an
1170 ** AVDT_START_CFM_EVT or AVDT_START_IND_EVT.
1172 ** Returns AVDT_SUCCESS if successful, otherwise error.
1174 *******************************************************************************/
1175 extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len,
1176 UINT32 time_stamp, UINT8 m_pt, UINT8 marker)
1181 UINT16 result = AVDT_SUCCESS;
1185 /* check length of media frame */
1186 if(data_len > AVDT_MAX_MEDIA_SIZE)
1188 result = AVDT_BAD_PARAMS;
1191 /* map handle to scb */
1192 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
1194 result = AVDT_BAD_HANDLE;
1197 AVDT_TRACE_WARNING("mux_tsid_media:%d", p_scb->curr_cfg.mux_tsid_media);
1199 if (p_scb->p_pkt != NULL
1200 || p_scb->p_ccb == NULL
1201 || !GKI_queue_is_empty(&p_scb->frag_q)
1202 || p_scb->frag_off != 0
1203 || p_scb->curr_cfg.mux_tsid_media == 0)
1205 result = AVDT_ERR_BAD_STATE;
1206 AVDT_TRACE_WARNING("p_scb->p_pkt=%x, p_scb->p_ccb=%x, IsQueueEmpty=%x, p_scb->frag_off=%x",
1207 p_scb->p_pkt, p_scb->p_ccb, GKI_queue_is_empty(&p_scb->frag_q), p_scb->frag_off);
1210 evt.apiwrite.p_buf = 0; /* it will indicate using of fragments queue frag_q */
1211 /* create queue of media fragments */
1212 GKI_init_q (&evt.apiwrite.frag_q);
1214 /* compose fragments from media payload and put fragments into gueue */
1215 avdt_scb_queue_frags(p_scb, &p_data, &data_len, &evt.apiwrite.frag_q);
1217 if(GKI_queue_is_empty(&evt.apiwrite.frag_q))
1219 AVDT_TRACE_WARNING("AVDT_WriteDataReq out of GKI buffers");
1220 result = AVDT_ERR_RESOURCE;
1223 evt.apiwrite.data_len = data_len;
1224 evt.apiwrite.p_data = p_data;
1226 /* process the fragments queue */
1227 evt.apiwrite.time_stamp = time_stamp;
1228 evt.apiwrite.m_pt = m_pt | (marker<<7);
1229 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
1232 #if (BT_USE_TRACES == TRUE)
1233 if(result != AVDT_SUCCESS)
1235 AVDT_TRACE_WARNING("*** AVDT_WriteDataReq failed result=%d",result);
1242 #if AVDT_MULTIPLEXING == TRUE
1243 /*******************************************************************************
1245 ** Function AVDT_SetMediaBuf
1247 ** Description Assigns buffer for media packets or forbids using of assigned
1248 ** buffer if argument p_buf is NULL. This function can only
1249 ** be called if the stream is a SNK.
1251 ** AVDTP uses this buffer to reassemble fragmented media packets.
1252 ** When AVDTP receives a complete media packet, it calls the
1253 ** p_media_cback assigned by AVDT_CreateStream().
1254 ** This function can be called during callback to assign a
1255 ** different buffer for next media packet or can leave the current
1256 ** buffer for next packet.
1258 ** Returns AVDT_SUCCESS if successful, otherwise error.
1260 *******************************************************************************/
1261 extern UINT16 AVDT_SetMediaBuf(UINT8 handle, UINT8 *p_buf, UINT32 buf_len)
1264 UINT16 result = AVDT_SUCCESS;
1266 /* map handle to scb */
1267 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
1269 result = AVDT_BAD_HANDLE;
1273 if(p_buf && p_scb->cs.p_media_cback == NULL)
1274 result = AVDT_NO_RESOURCES;
1277 p_scb->p_media_buf = p_buf;
1278 p_scb->media_buf_len = buf_len;
1286 #if AVDT_REPORTING == TRUE
1287 /*******************************************************************************
1289 ** Function AVDT_SendReport
1297 *******************************************************************************/
1298 UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type,
1299 tAVDT_REPORT_DATA *p_data)
1302 UINT16 result = AVDT_BAD_PARAMS;
1304 tAVDT_TC_TBL *p_tbl;
1305 UINT8 *p, *plen, *pm1, *p_end;
1306 #if AVDT_MULTIPLEXING == TRUE
1307 UINT8 *p_al=NULL, u;
1312 /* map handle to scb && verify parameters */
1313 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
1314 && (p_scb->p_ccb != NULL)
1315 && (((type == AVDT_RTCP_PT_SR) && (p_scb->cs.tsep == AVDT_TSEP_SRC)) ||
1316 ((type == AVDT_RTCP_PT_RR) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) ||
1317 (type == AVDT_RTCP_PT_SDES)) )
1319 result = AVDT_NO_RESOURCES;
1321 /* build SR - assume fit in one packet */
1322 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
1323 if((p_tbl->state == AVDT_AD_ST_OPEN) &&
1324 (p_pkt = (BT_HDR *)GKI_getbuf(p_tbl->peer_mtu)) != NULL)
1326 p_pkt->offset = L2CAP_MIN_OFFSET;
1327 p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
1328 #if AVDT_MULTIPLEXING == TRUE
1329 if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)
1331 /* Adaptation Layer header later */
1337 *p++ = AVDT_MEDIA_OCTET1 | 1;
1339 /* save the location for length */
1342 ssrc = avdt_scb_gen_ssrc(p_scb);
1343 UINT32_TO_BE_STREAM(p, ssrc);
1347 case AVDT_RTCP_PT_SR: /* Sender Report */
1348 *pm1 = AVDT_MEDIA_OCTET1;
1349 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec);
1350 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac);
1351 UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time);
1352 UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count);
1353 UINT32_TO_BE_STREAM(p, p_data->sr.octet_count);
1356 case AVDT_RTCP_PT_RR: /* Receiver Report */
1357 *p++ = p_data->rr.frag_lost;
1358 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1359 p_data->rr.packet_lost &= 0xFFFFFF;
1360 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1361 UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost);
1362 UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd);
1363 UINT32_TO_BE_STREAM(p, p_data->rr.jitter);
1364 UINT32_TO_BE_STREAM(p, p_data->rr.lsr);
1365 UINT32_TO_BE_STREAM(p, p_data->rr.dlsr);
1368 case AVDT_RTCP_PT_SDES: /* Source Description */
1369 *p++ = AVDT_RTCP_SDES_CNAME;
1370 len = strlen((char *)p_data->cname);
1371 if(len > AVDT_MAX_CNAME_SIZE)
1372 len = AVDT_MAX_CNAME_SIZE;
1374 BCM_STRNCPY_S((char *)p, len+1, (char *)p_data->cname, len+1);
1380 UINT16_TO_BE_STREAM(plen, len);
1382 #if AVDT_MULTIPLEXING == TRUE
1383 if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)
1385 /* Adaptation Layer header */
1388 UINT16_TO_BE_STREAM(p_al, len );
1389 /* TSID, no-fragment bit and coding of length(9-bit length field) */
1391 *p = (p_scb->curr_cfg.mux_tsid_report<<3) | AVDT_ALH_LCODE_9BITM0;
1393 *p |= AVDT_ALH_LCODE_9BITM1;
1397 /* set the actual payload length */
1398 p_pkt->len = p_end - p;
1399 /* send the packet */
1400 if(L2CAP_DW_FAILED != avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt))
1401 result = AVDT_SUCCESS;
1409 /******************************************************************************
1411 ** Function AVDT_SetTraceLevel
1413 ** Description Sets the trace level for AVDT. If 0xff is passed, the
1414 ** current trace level is returned.
1416 ** Input Parameters:
1417 ** new_level: The level to set the AVDT tracing to:
1418 ** 0xff-returns the current setting.
1419 ** 0-turns off tracing.
1426 ** Returns The new trace level or current trace level if
1427 ** the input parameter is 0xff.
1429 ******************************************************************************/
1430 UINT8 AVDT_SetTraceLevel (UINT8 new_level)
1432 if (new_level != 0xFF)
1433 avdt_cb.trace_level = new_level;
1435 return (avdt_cb.trace_level);