Fork ESP-IDF's bluetooth component

i want better sbc encoding, and no cla will stop me
This commit is contained in:
jacqueline
2024-03-28 14:32:49 +11:00
parent 239e6d8950
commit ee29c25b29
1761 changed files with 737738 additions and 0 deletions
+596
View File
@@ -0,0 +1,596 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This module contains the AVDTP adaption layer.
*
******************************************************************************/
#include <assert.h>
#include "common/bt_trace.h"
#include <string.h>
#include "stack/bt_types.h"
#include "common/bt_target.h"
#include "common/bt_defs.h"
#include "stack/avdt_api.h"
#include "stack/avdtc_api.h"
#include "avdt_int.h"
#include "stack/l2c_api.h"
#include "stack/l2cdefs.h"
#include "osi/allocator.h"
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function avdt_ad_type_to_tcid
**
** Description Derives the TCID from the channel type and SCB.
**
**
** Returns TCID value.
**
*******************************************************************************/
UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb)
{
UINT8 scb_idx;
if (type == AVDT_CHAN_SIG) {
return 0;
} else {
scb_idx = avdt_scb_to_hdl(p_scb) - 1;
/*
AVDT_TRACE_DEBUG("type: %d, tcid: %d", type, ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type));
*/
return ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type);
}
}
/*******************************************************************************
**
** Function avdt_ad_tcid_to_type
**
** Description Derives the channel type from the TCID.
**
**
** Returns Channel type value.
**
*******************************************************************************/
static UINT8 avdt_ad_tcid_to_type(UINT8 tcid)
{
UINT8 type;
if (tcid == 0) {
type = AVDT_CHAN_SIG;
} else {
/* tcid translates to type based on number of channels, as follows:
** only media channel : tcid=1,2,3,4,5,6... type=1,1,1,1,1,1...
** media and report : tcid=1,2,3,4,5,6... type=1,2,1,2,1,2...
** media, report, recov : tcid=1,2,3,4,5,6... type=1,2,3,1,2,3...
*/
type = ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1;
}
AVDT_TRACE_DEBUG("tcid: %d, type: %d\n", tcid, type);
return type;
}
/*******************************************************************************
**
** Function avdt_ad_init
**
** Description Initialize adaption layer.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_init(void)
{
int i;
tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
memset(&avdt_cb.ad, 0, sizeof(tAVDT_AD));
/* make sure the peer_mtu is a valid value */
for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
}
}
/*******************************************************************************
**
** Function avdt_ad_tc_tbl_by_st
**
** Description Find adaption layer transport channel table entry matching
** the given state.
**
**
** Returns Pointer to matching entry. For control channel it returns
** the matching entry. For media or other it returns the
** first matching entry (there could be more than one).
**
*******************************************************************************/
tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state)
{
int i;
tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
UINT8 ccb_idx;
if (p_ccb == NULL) {
/* resending security req */
for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
/* must be AVDT_CHAN_SIG - tcid always zero */
if ((p_tbl->tcid == 0) &&
(p_tbl->state == state)) {
break;
}
}
} else {
ccb_idx = avdt_ccb_to_idx(p_ccb);
for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
if (type == AVDT_CHAN_SIG) {
/* if control channel, tcid always zero */
if ((p_tbl->tcid == 0) &&
(p_tbl->ccb_idx == ccb_idx) &&
(p_tbl->state == state)) {
break;
}
} else {
/* if other channel, tcid is always > zero */
if ((p_tbl->tcid > 0) &&
(p_tbl->ccb_idx == ccb_idx) &&
(p_tbl->state == state)) {
break;
}
}
}
}
/* if nothing found return null */
if (i == AVDT_NUM_TC_TBL) {
p_tbl = NULL;
}
return p_tbl;
}
/*******************************************************************************
**
** Function avdt_ad_tc_tbl_by_lcid
**
** Description Find adaption layer transport channel table entry by LCID.
**
**
** Returns Pointer to entry.
**
*******************************************************************************/
tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid)
{
UINT8 idx;
idx = avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID];
if (idx < AVDT_NUM_TC_TBL) {
return &avdt_cb.ad.tc_tbl[idx];
} else {
return NULL;
}
}
/*******************************************************************************
**
** Function avdt_ad_tc_tbl_by_type
**
** Description This function retrieves the transport channel table entry
** for a particular channel.
**
**
** Returns Pointer to transport channel table entry.
**
*******************************************************************************/
tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
{
UINT8 tcid;
int i;
tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
UINT8 ccb_idx = avdt_ccb_to_idx(p_ccb);
/* get tcid from type, scb */
tcid = avdt_ad_type_to_tcid(type, p_scb);
for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
if ((p_tbl->tcid == tcid) && (p_tbl->ccb_idx == ccb_idx)) {
break;
}
}
assert(i != AVDT_NUM_TC_TBL);
return p_tbl;
}
/*******************************************************************************
**
** Function avdt_ad_tc_tbl_alloc
**
** Description Allocate an entry in the traffic channel table.
**
**
** Returns Pointer to entry.
**
*******************************************************************************/
tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb)
{
int i;
tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
/* find next free entry in tc table */
for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
if (p_tbl->state == AVDT_AD_ST_UNUSED) {
break;
}
}
/* sanity check */
assert(i != AVDT_NUM_TC_TBL);
/* initialize entry */
p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
p_tbl->cfg_flags = 0;
p_tbl->ccb_idx = avdt_ccb_to_idx(p_ccb);
p_tbl->state = AVDT_AD_ST_IDLE;
return p_tbl;
}
/*******************************************************************************
**
** Function avdt_ad_tc_tbl_to_idx
**
** Description Convert a transport channel table entry to an index.
**
**
** Returns Index value.
**
*******************************************************************************/
UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl)
{
AVDT_TRACE_DEBUG("avdt_ad_tc_tbl_to_idx: %d\n", (p_tbl - avdt_cb.ad.tc_tbl));
/* use array arithmetic to determine index */
return (UINT8) (p_tbl - avdt_cb.ad.tc_tbl);
}
/*******************************************************************************
**
** Function avdt_ad_tc_close_ind
**
** Description This function is called by the L2CAP interface when the
** L2CAP channel is closed. It looks up the CCB or SCB for
** the channel and sends it a close event. The reason
** parameter is the same value passed by the L2CAP
** callback function.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
{
tAVDT_CCB *p_ccb;
tAVDT_SCB *p_scb;
tAVDT_SCB_TC_CLOSE close;
// UNUSED(reason);
close.old_tc_state = p_tbl->state;
/* clear avdt_ad_tc_tbl entry */
p_tbl->state = AVDT_AD_ST_UNUSED;
p_tbl->cfg_flags = 0;
p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
AVDT_TRACE_DEBUG("avdt_ad_tc_close_ind tcid: %d, old: %d\n",
p_tbl->tcid, close.old_tc_state);
/* if signaling channel, notify ccb that channel open */
if (p_tbl->tcid == 0) {
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
p_ccb->disc_rsn = (reason == AVDT_DISC_RSN_ABNORMAL) ? AVDT_DISC_RSN_ABNORMAL : AVDT_DISC_RSN_NORMAL;
avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL);
}
/* if media or other channel, notify scb that channel close */
else {
/* look up scb in stream routing table by ccb, tcid */
p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
if (p_scb != NULL) {
close.tcid = p_tbl->tcid;
close.type = avdt_ad_tcid_to_type(p_tbl->tcid);
close.disc_rsn = (reason == AVDT_DISC_RSN_ABNORMAL) ? AVDT_DISC_RSN_ABNORMAL : AVDT_DISC_RSN_NORMAL;
avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, (tAVDT_SCB_EVT *)&close);
}
}
}
/*******************************************************************************
**
** Function avdt_ad_tc_open_ind
**
** Description This function is called by the L2CAP interface when
** the L2CAP channel is opened. It looks up the CCB or SCB
** for the channel and sends it an open event.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl)
{
tAVDT_CCB *p_ccb;
tAVDT_SCB *p_scb;
tAVDT_OPEN open;
tAVDT_EVT_HDR evt;
p_tbl->state = AVDT_AD_ST_OPEN;
/* if signaling channel, notify ccb that channel open */
if (p_tbl->tcid == 0) {
/* set the signal channel to use high priority within the ACL link */
L2CA_SetTxPriority(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][AVDT_CHAN_SIG].lcid, L2CAP_CHNL_PRIORITY_HIGH);
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
/* use err_param to indicate the role of connection.
* AVDT_ACP, if ACP */
evt.err_param = AVDT_INT;
if (p_tbl->cfg_flags & AVDT_L2C_CFG_CONN_ACP) {
evt.err_param = AVDT_ACP;
}
avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, (tAVDT_CCB_EVT *)&evt);
}
/* if media or other channel, notify scb that channel open */
else {
/* look up scb in stream routing table by ccb, tcid */
p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
/* put lcid in event data */
if (p_scb != NULL) {
open.peer_mtu = p_tbl->peer_mtu;
open.lcid = avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].lcid;
open.hdr.err_code = avdt_ad_tcid_to_type(p_tbl->tcid);
avdt_scb_event(p_scb, AVDT_SCB_TC_OPEN_EVT, (tAVDT_SCB_EVT *) &open);
}
}
}
/*******************************************************************************
**
** Function avdt_ad_tc_cong_ind
**
** Description This function is called by the L2CAP interface layer when
** L2CAP calls the congestion callback. It looks up the CCB
** or SCB for the channel and sends it a congestion event.
** The is_congested parameter is the same value passed by
** the L2CAP callback function.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested)
{
tAVDT_CCB *p_ccb;
tAVDT_SCB *p_scb;
/* if signaling channel, notify ccb of congestion */
if (p_tbl->tcid == 0) {
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
avdt_ccb_event(p_ccb, AVDT_CCB_LL_CONG_EVT, (tAVDT_CCB_EVT *) &is_congested);
}
/* if media or other channel, notify scb that channel open */
else {
/* look up scb in stream routing table by ccb, tcid */
p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
if (p_scb != NULL) {
avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, (tAVDT_SCB_EVT *) &is_congested);
}
}
}
/*******************************************************************************
**
** Function avdt_ad_tc_data_ind
**
** Description This function is called by the L2CAP interface layer when
** incoming data is received from L2CAP. It looks up the CCB
** or SCB for the channel and routes the data accordingly.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf)
{
tAVDT_CCB *p_ccb;
tAVDT_SCB *p_scb;
/* store type (media, recovery, reporting) */
p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid);
/* if signaling channel, handle control message */
if (p_tbl->tcid == 0) {
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
avdt_msg_ind(p_ccb, p_buf);
}
/* if media or other channel, send event to scb */
else {
p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
if (p_scb != NULL) {
avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT *) &p_buf);
} else {
osi_free(p_buf);
AVDT_TRACE_ERROR(" avdt_ad_tc_data_ind buffer freed");
}
}
}
/*******************************************************************************
**
** Function avdt_ad_write_req
**
** Description This function is called by a CCB or SCB to send data to a
** transport channel. It looks up the LCID of the channel
** based on the type, CCB, and SCB (if present). Then it
** passes the data to L2CA_DataWrite().
**
**
** Returns AVDT_AD_SUCCESS, if data accepted, else FALSE
** AVDT_AD_CONGESTED, if data accepted and the channel is congested
** AVDT_AD_FAILED, if error
**
*******************************************************************************/
UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf)
{
UINT8 tcid;
/* get tcid from type, scb */
tcid = avdt_ad_type_to_tcid(type, p_scb);
return L2CA_DataWrite(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid, p_buf);
}
/*******************************************************************************
**
** Function avdt_ad_open_req
**
** Description This function is called by a CCB or SCB to open a transport
** channel. This function allocates and initializes a
** transport channel table entry. The channel can be opened
** in two roles: as an initiator or acceptor. When opened
** as an initiator the function will start an L2CAP connection.
** When opened as an acceptor the function simply configures
** the table entry to listen for an incoming channel.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role)
{
tAVDT_TC_TBL *p_tbl;
UINT16 lcid;
if ((p_tbl = avdt_ad_tc_tbl_alloc(p_ccb)) == NULL) {
AVDT_TRACE_ERROR("avdt_ad_open_req: Cannot allocate p_tbl");
return;
}
p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb);
AVDT_TRACE_DEBUG("avdt_ad_open_req: type: %d, role: %d, tcid:%d\n",
type, role, p_tbl->tcid);
if (type == AVDT_CHAN_SIG) {
/* if signaling, get mtu from registration control block */
p_tbl->my_mtu = avdt_cb.rcb.ctrl_mtu;
p_tbl->my_flush_to = L2CAP_DEFAULT_FLUSH_TO;
} else {
/* otherwise get mtu from scb */
p_tbl->my_mtu = p_scb->cs.mtu;
p_tbl->my_flush_to = p_scb->cs.flush_to;
/* also set scb_hdl in rt_tbl */
avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb);
AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].scb_hdl = %d\n",
avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
avdt_scb_to_hdl(p_scb));
}
/* if we're acceptor, we're done; just sit back and listen */
if (role == AVDT_ACP) {
p_tbl->state = AVDT_AD_ST_ACP;
}
/* else we're inititator, start the L2CAP connection */
else {
p_tbl->state = AVDT_AD_ST_CONN;
/* call l2cap connect req */
if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0) {
/* if connect req ok, store tcid in lcid table */
avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl);
AVDT_TRACE_DEBUG("avdt_cb.ad.lcid_tbl[%d] = %d\n",
(lcid - L2CAP_BASE_APPL_CID), avdt_ad_tc_tbl_to_idx(p_tbl));
avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].lcid = 0x%x\n",
avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
lcid);
} else {
/* if connect req failed, call avdt_ad_tc_close_ind() */
avdt_ad_tc_close_ind(p_tbl, 0);
}
}
}
/*******************************************************************************
**
** Function avdt_ad_close_req
**
** Description This function is called by a CCB or SCB to close a
** transport channel. The function looks up the LCID for the
** channel and calls L2CA_DisconnectReq().
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
{
UINT8 tcid;
tAVDT_TC_TBL *p_tbl;
p_tbl = avdt_ad_tc_tbl_by_type(type, p_ccb, p_scb);
AVDT_TRACE_DEBUG("avdt_ad_close_req state: %d\n", p_tbl->state);
switch (p_tbl->state) {
case AVDT_AD_ST_UNUSED:
/* probably for reporting */
break;
case AVDT_AD_ST_ACP:
/* if we're listening on this channel, send ourselves a close ind */
avdt_ad_tc_close_ind(p_tbl, 0);
break;
default:
/* get tcid from type, scb */
tcid = avdt_ad_type_to_tcid(type, p_scb);
/* call l2cap disconnect req */
L2CA_DisconnectReq(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid);
}
}
#endif /* #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) */
File diff suppressed because it is too large Load Diff
+456
View File
@@ -0,0 +1,456 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This module contains the channel control block state machine and
* functions which operate on the channel control block.
*
******************************************************************************/
#include <string.h>
#include "stack/bt_types.h"
#include "common/bt_target.h"
#include "common/bt_defs.h"
#include "stack/avdt_api.h"
#include "stack/avdtc_api.h"
#include "avdt_int.h"
#include "stack/btu.h"
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
/*****************************************************************************
** state machine constants and types
*****************************************************************************/
#if AVDT_DEBUG == TRUE
/* verbose state strings for trace */
const char *const avdt_ccb_st_str[] = {
"CCB_IDLE_ST",
"CCB_OPENING_ST",
"CCB_OPEN_ST",
"CCB_CLOSING_ST"
};
/* verbose event strings for trace */
const char *const avdt_ccb_evt_str[] = {
"API_DISCOVER_REQ_EVT",
"API_GETCAP_REQ_EVT",
"API_START_REQ_EVT",
"API_SUSPEND_REQ_EVT",
"API_DISCOVER_RSP_EVT",
"API_GETCAP_RSP_EVT",
"API_START_RSP_EVT",
"API_SUSPEND_RSP_EVT",
"API_CONNECT_REQ_EVT",
"API_DISCONNECT_REQ_EVT",
"MSG_DISCOVER_CMD_EVT",
"MSG_GETCAP_CMD_EVT",
"MSG_START_CMD_EVT",
"MSG_SUSPEND_CMD_EVT",
"MSG_DISCOVER_RSP_EVT",
"MSG_GETCAP_RSP_EVT",
"MSG_START_RSP_EVT",
"MSG_SUSPEND_RSP_EVT",
"RCVRSP_EVT",
"SENDMSG_EVT",
"RET_TOUT_EVT",
"RSP_TOUT_EVT",
"IDLE_TOUT_EVT",
"UL_OPEN_EVT",
"UL_CLOSE_EVT",
"LL_OPEN_EVT",
"LL_CLOSE_EVT",
"LL_CONG_EVT"
};
#endif
/* action function list */
const tAVDT_CCB_ACTION avdt_ccb_action[] = {
avdt_ccb_chan_open,
avdt_ccb_chan_close,
avdt_ccb_chk_close,
avdt_ccb_hdl_discover_cmd,
avdt_ccb_hdl_discover_rsp,
avdt_ccb_hdl_getcap_cmd,
avdt_ccb_hdl_getcap_rsp,
avdt_ccb_hdl_start_cmd,
avdt_ccb_hdl_start_rsp,
avdt_ccb_hdl_suspend_cmd,
avdt_ccb_hdl_suspend_rsp,
avdt_ccb_snd_discover_cmd,
avdt_ccb_snd_discover_rsp,
avdt_ccb_snd_getcap_cmd,
avdt_ccb_snd_getcap_rsp,
avdt_ccb_snd_start_cmd,
avdt_ccb_snd_start_rsp,
avdt_ccb_snd_suspend_cmd,
avdt_ccb_snd_suspend_rsp,
avdt_ccb_clear_cmds,
avdt_ccb_cmd_fail,
avdt_ccb_free_cmd,
avdt_ccb_cong_state,
avdt_ccb_ret_cmd,
avdt_ccb_snd_cmd,
avdt_ccb_snd_msg,
avdt_ccb_set_reconn,
avdt_ccb_clr_reconn,
avdt_ccb_chk_reconn,
avdt_ccb_chk_timer,
avdt_ccb_set_conn,
avdt_ccb_set_disconn,
avdt_ccb_do_disconn,
avdt_ccb_ll_closed,
avdt_ccb_ll_opened,
avdt_ccb_dealloc
};
/* state table information */
#define AVDT_CCB_ACTIONS 2 /* number of actions */
#define AVDT_CCB_NEXT_STATE 2 /* position of next state */
#define AVDT_CCB_NUM_COLS 3 /* number of columns in state tables */
/* state table for idle state */
const UINT8 avdt_ccb_st_idle[][AVDT_CCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST},
/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST},
/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST},
/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* UL_OPEN_EVT */ {AVDT_CCB_CHAN_OPEN, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* UL_CLOSE_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* LL_OPEN_EVT */ {AVDT_CCB_LL_OPENED, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* LL_CONG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}
};
/* state table for opening state */
const UINT8 avdt_ccb_st_opening[][AVDT_CCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN, AVDT_CCB_DO_DISCONN, AVDT_CCB_CLOSING_ST},
/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* UL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST},
/* UL_CLOSE_EVT */ {AVDT_CCB_CLEAR_CMDS, AVDT_CCB_CHAN_CLOSE, AVDT_CCB_CLOSING_ST},
/* LL_OPEN_EVT */ {AVDT_CCB_SND_CMD, AVDT_CCB_LL_OPENED, AVDT_CCB_OPEN_ST},
/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* LL_CONG_EVT */ {AVDT_CCB_CONG_STATE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}
};
/* state table for open state */
const UINT8 avdt_ccb_st_open[][AVDT_CCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_START_REQ_EVT */ {AVDT_CCB_SND_START_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_SND_SUSPEND_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_SND_DISCOVER_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_GETCAP_RSP_EVT */ {AVDT_CCB_SND_GETCAP_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_START_RSP_EVT */ {AVDT_CCB_SND_START_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_SND_SUSPEND_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_LL_OPENED, AVDT_CCB_OPEN_ST},
/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN, AVDT_CCB_DO_DISCONN, AVDT_CCB_CLOSING_ST},
/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_HDL_DISCOVER_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_HDL_GETCAP_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* MSG_START_CMD_EVT */ {AVDT_CCB_HDL_START_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_HDL_SUSPEND_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_OPEN_ST},
/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_OPEN_ST},
/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* RCVRSP_EVT */ {AVDT_CCB_FREE_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* SENDMSG_EVT */ {AVDT_CCB_SND_MSG, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* RET_TOUT_EVT */ {AVDT_CCB_RET_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* RSP_TOUT_EVT */ {AVDT_CCB_CMD_FAIL, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST},
/* IDLE_TOUT_EVT */ {AVDT_CCB_CLEAR_CMDS, AVDT_CCB_CHAN_CLOSE, AVDT_CCB_CLOSING_ST},
/* UL_OPEN_EVT */ {AVDT_CCB_CHK_TIMER, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* UL_CLOSE_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* LL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST},
/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* LL_CONG_EVT */ {AVDT_CCB_CONG_STATE, AVDT_CCB_SND_MSG, AVDT_CCB_OPEN_ST}
};
/* state table for closing state */
const UINT8 avdt_ccb_st_closing[][AVDT_CCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_CLOSING_ST},
/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_CLOSING_ST},
/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SET_CONN, AVDT_CCB_CLOSING_ST},
/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_CLR_RECONN, AVDT_CCB_SET_DISCONN, AVDT_CCB_CLOSING_ST},
/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* UL_OPEN_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* UL_CLOSE_EVT */ {AVDT_CCB_CLR_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* LL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST},
/* LL_CLOSE_EVT */ {AVDT_CCB_CHK_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST},
/* LL_CONG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}
};
/* type for state table */
typedef const UINT8 (*tAVDT_CCB_ST_TBL)[AVDT_CCB_NUM_COLS];
/* state table */
const tAVDT_CCB_ST_TBL avdt_ccb_st_tbl[] = {
avdt_ccb_st_idle,
avdt_ccb_st_opening,
avdt_ccb_st_open,
avdt_ccb_st_closing
};
/*******************************************************************************
**
** Function avdt_ccb_init
**
** Description Initialize channel control block module.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ccb_init(void)
{
memset(&avdt_cb.ccb[0], 0, sizeof(tAVDT_CCB) * AVDT_NUM_LINKS);
avdt_cb.p_ccb_act = (tAVDT_CCB_ACTION *) avdt_ccb_action;
}
/*******************************************************************************
**
** Function avdt_ccb_event
**
** Description State machine event handling function for ccb
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_ccb_event(tAVDT_CCB *p_ccb, UINT8 event, tAVDT_CCB_EVT *p_data)
{
tAVDT_CCB_ST_TBL state_table;
UINT8 action;
int i;
#if AVDT_DEBUG == TRUE
AVDT_TRACE_EVENT("CCB ccb=%d event=%s state=%s\n", avdt_ccb_to_idx(p_ccb), avdt_ccb_evt_str[event], avdt_ccb_st_str[p_ccb->state]);
#endif
/* look up the state table for the current state */
state_table = avdt_ccb_st_tbl[p_ccb->state];
/* set next state */
if (p_ccb->state != state_table[event][AVDT_CCB_NEXT_STATE]) {
p_ccb->state = state_table[event][AVDT_CCB_NEXT_STATE];
}
/* execute action functions */
for (i = 0; i < AVDT_CCB_ACTIONS; i++) {
if ((action = state_table[event][i]) != AVDT_CCB_IGNORE) {
(*avdt_cb.p_ccb_act[action])(p_ccb, p_data);
} else {
break;
}
}
}
/*******************************************************************************
**
** Function avdt_ccb_by_bd
**
** Description This lookup function finds the ccb for a BD address.
**
**
** Returns pointer to the ccb, or NULL if none found.
**
*******************************************************************************/
tAVDT_CCB *avdt_ccb_by_bd(BD_ADDR bd_addr)
{
tAVDT_CCB *p_ccb = &avdt_cb.ccb[0];
int i;
for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
/* if allocated ccb has matching ccb */
if (p_ccb->allocated && (!memcmp(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN))) {
break;
}
}
if (i == AVDT_NUM_LINKS) {
/* if no ccb found */
p_ccb = NULL;
AVDT_TRACE_DEBUG("No ccb for addr %02x-%02x-%02x-%02x-%02x-%02x\n",
bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
}
return p_ccb;
}
/*******************************************************************************
**
** Function avdt_ccb_alloc
**
** Description Allocate a channel control block.
**
**
** Returns pointer to the ccb, or NULL if none could be allocated.
**
*******************************************************************************/
tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr)
{
tAVDT_CCB *p_ccb = &avdt_cb.ccb[0];
int i;
for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
if (!p_ccb->allocated) {
p_ccb->allocated = TRUE;
memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
p_ccb->cmd_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_ccb->rsp_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_ccb->timer_entry.param = (UINT32) p_ccb;
AVDT_TRACE_DEBUG("avdt_ccb_alloc %d\n", i);
break;
}
}
if (i == AVDT_NUM_LINKS) {
/* out of ccbs */
p_ccb = NULL;
AVDT_TRACE_WARNING("Out of ccbs");
}
return p_ccb;
}
/*******************************************************************************
**
** Function avdt_ccb_dealloc
**
** Description Deallocate a stream control block.
**
**
** Returns void.
**
*******************************************************************************/
void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_ccb_dealloc %d\n", avdt_ccb_to_idx(p_ccb));
btu_free_timer(&p_ccb->timer_entry);
fixed_queue_free(p_ccb->cmd_q, NULL);
fixed_queue_free(p_ccb->rsp_q, NULL);
memset(p_ccb, 0, sizeof(tAVDT_CCB));
}
/*******************************************************************************
**
** Function avdt_ccb_to_idx
**
** Description Given a pointer to an ccb, return its index.
**
**
** Returns Index of ccb.
**
*******************************************************************************/
UINT8 avdt_ccb_to_idx(tAVDT_CCB *p_ccb)
{
/* use array arithmetic to determine index */
return (UINT8) (p_ccb - avdt_cb.ccb);
}
/*******************************************************************************
**
** Function avdt_ccb_by_idx
**
** Description Return ccb pointer based on ccb index.
**
**
** Returns pointer to the ccb, or NULL if none found.
**
*******************************************************************************/
tAVDT_CCB *avdt_ccb_by_idx(UINT8 idx)
{
tAVDT_CCB *p_ccb;
/* verify index */
if (idx < AVDT_NUM_LINKS) {
p_ccb = &avdt_cb.ccb[idx];
} else {
p_ccb = NULL;
AVDT_TRACE_WARNING("No ccb for idx %d\n", idx);
}
return p_ccb;
}
#endif /* #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) */
File diff suppressed because it is too large Load Diff
+501
View File
@@ -0,0 +1,501 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This AVDTP adaption layer module interfaces to L2CAP
*
******************************************************************************/
#include <string.h>
#include "stack/bt_types.h"
#include "common/bt_target.h"
#include "common/bt_defs.h"
#include "stack/avdt_api.h"
#include "stack/avdtc_api.h"
#include "avdt_int.h"
#include "stack/l2c_api.h"
#include "stack/l2cdefs.h"
#include "stack/btm_api.h"
#include "btm_int.h"
#include "osi/allocator.h"
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
/* callback function declarations */
void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id);
void avdt_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result);
void avdt_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg);
void avdt_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg);
void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed);
void avdt_l2c_disconnect_cfm_cback(UINT16 lcid, UINT16 result);
void avdt_l2c_congestion_ind_cback(UINT16 lcid, BOOLEAN is_congested);
void avdt_l2c_data_ind_cback(UINT16 lcid, BT_HDR *p_buf);
/* L2CAP callback function structure */
const tL2CAP_APPL_INFO avdt_l2c_appl = {
avdt_l2c_connect_ind_cback,
avdt_l2c_connect_cfm_cback,
NULL,
avdt_l2c_config_ind_cback,
avdt_l2c_config_cfm_cback,
avdt_l2c_disconnect_ind_cback,
avdt_l2c_disconnect_cfm_cback,
NULL,
avdt_l2c_data_ind_cback,
avdt_l2c_congestion_ind_cback,
NULL /* tL2CA_TX_COMPLETE_CB */
};
/*******************************************************************************
**
** Function avdt_sec_check_complete_term
**
** Description The function called when Security Manager finishes
** verification of the service side connection
**
** Returns void
**
*******************************************************************************/
static void avdt_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport,
void *p_ref_data, UINT8 res)
{
tAVDT_CCB *p_ccb = NULL;
tL2CAP_CFG_INFO cfg;
tAVDT_TC_TBL *p_tbl;
UNUSED(p_ref_data);
AVDT_TRACE_DEBUG("avdt_sec_check_complete_term res: %d\n", res);
if (!bd_addr) {
AVDT_TRACE_WARNING("avdt_sec_check_complete_term: NULL BD_ADDR");
return;
}
p_ccb = avdt_ccb_by_bd(bd_addr);
p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_ACP);
if (p_tbl == NULL) {
return;
}
if (res == BTM_SUCCESS) {
/* Send response to the L2CAP layer. */
L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK, L2CAP_CONN_OK);
/* store idx in LCID table, store LCID in routing table */
avdt_cb.ad.lcid_tbl[p_tbl->lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl);
avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = p_tbl->lcid;
/* transition to configuration state */
p_tbl->state = AVDT_AD_ST_CFG;
/* Send L2CAP config req */
memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
cfg.mtu_present = TRUE;
cfg.mtu = p_tbl->my_mtu;
cfg.flush_to_present = TRUE;
cfg.flush_to = p_tbl->my_flush_to;
L2CA_ConfigReq(p_tbl->lcid, &cfg);
} else {
L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK);
avdt_ad_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
}
}
/*******************************************************************************
**
** Function avdt_sec_check_complete_orig
**
** Description The function called when Security Manager finishes
** verification of the service side connection
**
** Returns void
**
*******************************************************************************/
static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport,
void *p_ref_data, UINT8 res)
{
tAVDT_CCB *p_ccb = NULL;
tL2CAP_CFG_INFO cfg;
tAVDT_TC_TBL *p_tbl;
UNUSED(p_ref_data);
AVDT_TRACE_DEBUG("avdt_sec_check_complete_orig res: %d\n", res);
if (bd_addr) {
p_ccb = avdt_ccb_by_bd(bd_addr);
}
p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_INT);
if (p_tbl == NULL) {
return;
}
if ( res == BTM_SUCCESS ) {
/* set channel state */
p_tbl->state = AVDT_AD_ST_CFG;
/* Send L2CAP config req */
memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
cfg.mtu_present = TRUE;
cfg.mtu = p_tbl->my_mtu;
cfg.flush_to_present = TRUE;
cfg.flush_to = p_tbl->my_flush_to;
L2CA_ConfigReq(p_tbl->lcid, &cfg);
} else {
L2CA_DisconnectReq (p_tbl->lcid);
avdt_ad_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
}
}
/*******************************************************************************
**
** Function avdt_l2c_connect_ind_cback
**
** Description This is the L2CAP connect indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id)
{
tAVDT_CCB *p_ccb;
tAVDT_TC_TBL *p_tbl = NULL;
UINT16 result;
tL2CAP_CFG_INFO cfg;
tBTM_STATUS rc;
UNUSED(psm);
/* do we already have a control channel for this peer? */
if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) {
/* no, allocate ccb */
if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL) {
/* no ccb available, reject L2CAP connection */
result = L2CAP_CONN_NO_RESOURCES;
} else {
/* allocate and set up entry; first channel is always signaling */
p_tbl = avdt_ad_tc_tbl_alloc(p_ccb);
p_tbl->my_mtu = avdt_cb.rcb.ctrl_mtu;
p_tbl->my_flush_to = L2CAP_DEFAULT_FLUSH_TO;
p_tbl->tcid = AVDT_CHAN_SIG;
p_tbl->lcid = lcid;
p_tbl->id = id;
p_tbl->state = AVDT_AD_ST_SEC_ACP;
p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_ACP;
/* Check the security */
rc = btm_sec_mx_access_request (bd_addr, AVDT_PSM,
FALSE, BTM_SEC_PROTO_AVDT,
AVDT_CHAN_SIG,
&avdt_sec_check_complete_term, NULL);
if (rc == BTM_CMD_STARTED) {
L2CA_ConnectRsp (p_ccb->peer_addr, p_tbl->id, lcid, L2CAP_CONN_PENDING, L2CAP_CONN_OK);
}
return;
}
}
/* deal with simultaneous control channel connect case */
else if ((p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_CONN)) != NULL) {
/* reject their connection */
result = L2CAP_CONN_NO_RESOURCES;
}
/* this must be a traffic channel; are we accepting a traffic channel
** for this ccb?
*/
else if ((p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_MEDIA, p_ccb, AVDT_AD_ST_ACP)) != NULL) {
/* yes; proceed with connection */
result = L2CAP_CONN_OK;
}
#if AVDT_REPORTING == TRUE
/* this must be a reporting channel; are we accepting a reporting channel
** for this ccb?
*/
else if ((p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_REPORT, p_ccb, AVDT_AD_ST_ACP)) != NULL) {
/* yes; proceed with connection */
result = L2CAP_CONN_OK;
}
#endif
/* else we're not listening for traffic channel; reject */
else {
result = L2CAP_CONN_NO_PSM;
}
/* Send L2CAP connect rsp */
L2CA_ConnectRsp(bd_addr, id, lcid, result, 0);
/* if result ok, proceed with connection */
if (result == L2CAP_CONN_OK) {
/* store idx in LCID table, store LCID in routing table */
avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl);
avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
/* transition to configuration state */
p_tbl->state = AVDT_AD_ST_CFG;
/* Send L2CAP config req */
memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
cfg.mtu_present = TRUE;
cfg.mtu = p_tbl->my_mtu;
cfg.flush_to_present = TRUE;
cfg.flush_to = p_tbl->my_flush_to;
L2CA_ConfigReq(lcid, &cfg);
}
}
/*******************************************************************************
**
** Function avdt_l2c_connect_cfm_cback
**
** Description This is the L2CAP connect confirm callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result)
{
tAVDT_TC_TBL *p_tbl;
tL2CAP_CFG_INFO cfg;
tAVDT_CCB *p_ccb;
AVDT_TRACE_DEBUG("avdt_l2c_connect_cfm_cback lcid: %d, result: %d\n",
lcid, result);
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
/* if in correct state */
if (p_tbl->state == AVDT_AD_ST_CONN) {
/* if result successful */
if (result == L2CAP_CONN_OK) {
if (p_tbl->tcid != AVDT_CHAN_SIG) {
/* set channel state */
p_tbl->state = AVDT_AD_ST_CFG;
/* Send L2CAP config req */
memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
cfg.mtu_present = TRUE;
cfg.mtu = p_tbl->my_mtu;
cfg.flush_to_present = TRUE;
cfg.flush_to = p_tbl->my_flush_to;
L2CA_ConfigReq(lcid, &cfg);
} else {
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
if (p_ccb == NULL) {
result = L2CAP_CONN_NO_RESOURCES;
} else {
/* set channel state */
p_tbl->state = AVDT_AD_ST_SEC_INT;
p_tbl->lcid = lcid;
p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_INT;
/* Check the security */
btm_sec_mx_access_request (p_ccb->peer_addr, AVDT_PSM,
TRUE, BTM_SEC_PROTO_AVDT,
AVDT_CHAN_SIG,
&avdt_sec_check_complete_orig, NULL);
}
}
}
/* failure; notify adaption that channel closed */
if (result != L2CAP_CONN_OK) {
avdt_ad_tc_close_ind(p_tbl, result);
}
}
}
}
/*******************************************************************************
**
** Function avdt_l2c_config_cfm_cback
**
** Description This is the L2CAP config confirm callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
tAVDT_TC_TBL *p_tbl;
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
p_tbl->lcid = lcid;
/* if in correct state */
if (p_tbl->state == AVDT_AD_ST_CFG) {
/* if result successful */
if (p_cfg->result == L2CAP_CONN_OK) {
/* update cfg_flags */
p_tbl->cfg_flags |= AVDT_L2C_CFG_CFM_DONE;
/* if configuration complete */
if (p_tbl->cfg_flags & AVDT_L2C_CFG_IND_DONE) {
avdt_ad_tc_open_ind(p_tbl);
}
}
/* else failure */
else {
/* Send L2CAP disconnect req */
L2CA_DisconnectReq(lcid);
}
}
}
}
/*******************************************************************************
**
** Function avdt_l2c_config_ind_cback
**
** Description This is the L2CAP config indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
tAVDT_TC_TBL *p_tbl;
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
/* store the mtu in tbl */
if (p_cfg->mtu_present) {
p_tbl->peer_mtu = p_cfg->mtu;
} else {
p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
}
AVDT_TRACE_DEBUG("peer_mtu: %d, lcid: x%x\n", p_tbl->peer_mtu, lcid);
/* send L2CAP configure response */
memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO));
p_cfg->result = L2CAP_CFG_OK;
L2CA_ConfigRsp(lcid, p_cfg);
/* if first config ind */
if ((p_tbl->cfg_flags & AVDT_L2C_CFG_IND_DONE) == 0) {
/* update cfg_flags */
p_tbl->cfg_flags |= AVDT_L2C_CFG_IND_DONE;
/* if configuration complete */
if (p_tbl->cfg_flags & AVDT_L2C_CFG_CFM_DONE) {
avdt_ad_tc_open_ind(p_tbl);
}
}
}
}
/*******************************************************************************
**
** Function avdt_l2c_disconnect_ind_cback
**
** Description This is the L2CAP disconnect indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
{
tAVDT_TC_TBL *p_tbl;
UINT16 disc_rsn = AVDT_DISC_RSN_NORMAL;
tAVDT_CCB *p_ccb;
AVDT_TRACE_DEBUG("avdt_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d\n",
lcid, ack_needed);
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
if (ack_needed) {
/* send L2CAP disconnect response */
L2CA_DisconnectRsp(lcid);
} else {
if ((p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx)) != NULL) {
UINT16 rsn = L2CA_GetDisconnectReason(p_ccb->peer_addr, BT_TRANSPORT_BR_EDR);
if (rsn != 0 && rsn != HCI_ERR_PEER_USER) {
disc_rsn = AVDT_DISC_RSN_ABNORMAL;
AVDT_TRACE_EVENT("avdt link disc rsn 0x%x", rsn);
}
}
}
avdt_ad_tc_close_ind(p_tbl, disc_rsn);
}
}
/*******************************************************************************
**
** Function avdt_l2c_disconnect_cfm_cback
**
** Description This is the L2CAP disconnect confirm callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_disconnect_cfm_cback(UINT16 lcid, UINT16 result)
{
tAVDT_TC_TBL *p_tbl;
AVDT_TRACE_DEBUG("avdt_l2c_disconnect_cfm_cback lcid: %d, result: %d\n",
lcid, result);
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
avdt_ad_tc_close_ind(p_tbl, result);
}
}
/*******************************************************************************
**
** Function avdt_l2c_congestion_ind_cback
**
** Description This is the L2CAP congestion indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_congestion_ind_cback(UINT16 lcid, BOOLEAN is_congested)
{
tAVDT_TC_TBL *p_tbl;
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
avdt_ad_tc_cong_ind(p_tbl, is_congested);
}
}
/*******************************************************************************
**
** Function avdt_l2c_data_ind_cback
**
** Description This is the L2CAP data indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void avdt_l2c_data_ind_cback(UINT16 lcid, BT_HDR *p_buf)
{
tAVDT_TC_TBL *p_tbl;
/* look up info for this channel */
if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) {
avdt_ad_tc_data_ind(p_tbl, p_buf);
} else { /* prevent buffer leak */
osi_free(p_buf);
}
}
#endif /* #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) */
File diff suppressed because it is too large Load Diff
+796
View File
@@ -0,0 +1,796 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This module contains the stream control block and functions which
* operate on the stream control block.
*
******************************************************************************/
#include <string.h>
#include "stack/bt_types.h"
#include "common/bt_target.h"
#include "common/bt_defs.h"
#include "stack/avdt_api.h"
#include "stack/avdtc_api.h"
#include "avdt_int.h"
#include "stack/btu.h"
#include "osi/allocator.h"
#include "osi/fixed_queue.h"
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
/*****************************************************************************
** state machine constants and types
*****************************************************************************/
#if AVDT_DEBUG == TRUE
/* verbose state strings for trace */
const char *const avdt_scb_st_str[] = {
"SCB_IDLE_ST",
"SCB_CONF_ST",
"SCB_OPENING_ST",
"SCB_OPEN_ST",
"SCB_STREAM_ST",
"SCB_CLOSING_ST"
};
/* verbose event strings for trace */
const char *const avdt_scb_evt_str[] = {
"API_REMOVE_EVT",
"API_WRITE_REQ_EVT",
"API_GETCONFIG_REQ_EVT",
"API_DELAY_RPT_REQ",
"API_SETCONFIG_REQ_EVT",
"API_OPEN_REQ_EVT",
"API_CLOSE_REQ_EVT",
"API_RECONFIG_REQ_EVT",
"API_SECURITY_REQ_EVT",
"API_ABORT_REQ_EVT",
"API_GETCONFIG_RSP_EVT",
"API_SETCONFIG_RSP_EVT",
"API_SETCONFIG_REJ_EVT",
"API_OPEN_RSP_EVT",
"API_CLOSE_RSP_EVT",
"API_RECONFIG_RSP_EVT",
"API_SECURITY_RSP_EVT",
"API_ABORT_RSP_EVT",
"MSG_SETCONFIG_CMD_EVT",
"MSG_GETCONFIG_CMD_EVT",
"MSG_OPEN_CMD_EVT",
"MSG_START_CMD_EVT",
"MSG_SUSPEND_CMD_EVT",
"MSG_CLOSE_CMD_EVT",
"MSG_ABORT_CMD_EVT",
"MSG_RECONFIG_CMD_EVT",
"MSG_SECURITY_CMD_EVT",
"MSG_DELAY_RPT_CMD_EVT",
"MSG_DELAY_RPT_RSP_EVT",
"MSG_SETCONFIG_RSP_EVT",
"MSG_GETCONFIG_RSP_EVT",
"MSG_OPEN_RSP_EVT",
"MSG_START_RSP_EVT",
"MSG_SUSPEND_RSP_EVT",
"MSG_CLOSE_RSP_EVT",
"MSG_ABORT_RSP_EVT",
"MSG_RECONFIG_RSP_EVT",
"MSG_SECURITY_RSP_EVT",
"MSG_SETCONFIG_REJ_EVT",
"MSG_OPEN_REJ_EVT",
"MSG_START_REJ_EVT",
"MSG_SUSPEND_REJ_EVT",
"TC_TOUT_EVT",
"TC_OPEN_EVT",
"TC_CLOSE_EVT",
"TC_CONG_EVT",
"TC_DATA_EVT",
"CC_CLOSE_EVT",
"DELAY_RPT_RSP_TOUT_EVT"
};
#endif
/* action function list */
const tAVDT_SCB_ACTION avdt_scb_action[] = {
avdt_scb_hdl_abort_cmd,
avdt_scb_hdl_abort_rsp,
avdt_scb_hdl_close_cmd,
avdt_scb_hdl_close_rsp,
avdt_scb_hdl_getconfig_cmd,
avdt_scb_hdl_getconfig_rsp,
avdt_scb_hdl_open_cmd,
avdt_scb_hdl_open_rej,
avdt_scb_hdl_open_rsp,
avdt_scb_hdl_pkt,
avdt_scb_drop_pkt,
avdt_scb_hdl_reconfig_cmd,
avdt_scb_hdl_reconfig_rsp,
avdt_scb_hdl_security_cmd,
avdt_scb_hdl_security_rsp,
avdt_scb_hdl_setconfig_cmd,
avdt_scb_hdl_setconfig_rej,
avdt_scb_hdl_setconfig_rsp,
avdt_scb_hdl_start_cmd,
avdt_scb_hdl_start_rsp,
avdt_scb_hdl_suspend_cmd,
avdt_scb_hdl_suspend_rsp,
avdt_scb_hdl_tc_close,
#if AVDT_REPORTING == TRUE
avdt_scb_hdl_tc_close_sto,
#endif
avdt_scb_hdl_tc_open,
#if AVDT_REPORTING == TRUE
avdt_scb_hdl_tc_open_sto,
#endif
avdt_scb_snd_delay_rpt_req,
avdt_scb_hdl_delay_rpt_cmd,
avdt_scb_hdl_delay_rpt_rsp,
avdt_scb_hdl_write_req,
avdt_scb_snd_abort_req,
avdt_scb_snd_abort_rsp,
avdt_scb_snd_close_req,
avdt_scb_snd_stream_close,
avdt_scb_snd_close_rsp,
avdt_scb_snd_getconfig_req,
avdt_scb_snd_getconfig_rsp,
avdt_scb_snd_open_req,
avdt_scb_snd_open_rsp,
avdt_scb_snd_reconfig_req,
avdt_scb_snd_reconfig_rsp,
avdt_scb_snd_security_req,
avdt_scb_snd_security_rsp,
avdt_scb_snd_setconfig_req,
avdt_scb_snd_setconfig_rej,
avdt_scb_snd_setconfig_rsp,
avdt_scb_snd_tc_close,
avdt_scb_cb_err,
avdt_scb_cong_state,
avdt_scb_rej_state,
avdt_scb_rej_in_use,
avdt_scb_rej_not_in_use,
avdt_scb_set_remove,
avdt_scb_free_pkt,
avdt_scb_clr_pkt,
avdt_scb_chk_snd_pkt,
avdt_scb_tc_timer,
avdt_scb_clr_vars,
avdt_scb_dealloc,
avdt_scb_hdl_delay_rpt_tout,
avdt_scb_init_open_req,
avdt_scb_send_delay_report_cmd
};
/* state table information */
#define AVDT_SCB_ACTIONS 2 /* number of actions */
#define AVDT_SCB_NEXT_STATE 2 /* position of next state */
#define AVDT_SCB_NUM_COLS 3 /* number of columns in state tables */
/* state table for idle state */
const UINT8 avdt_scb_st_idle[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_DEALLOC, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_FREE_PKT, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_SND_SETCONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_SND_SETCONFIG_RSP, AVDT_SCB_SEND_DELAY_REPORT_CMD_EVT, AVDT_SCB_CONF_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_SND_SETCONFIG_REJ, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_HDL_SETCONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_REJ_NOT_IN_USE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_SETCONFIG_RSP, AVDT_SCB_INIT_OPEN_REQ_EVT, AVDT_SCB_CONF_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_HDL_SETCONFIG_REJ, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_OPEN_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_CLR_VARS, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}
};
/* state table for configured state */
const UINT8 avdt_scb_st_conf[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_SET_REMOVE, AVDT_SCB_CONF_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_FREE_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_SND_GETCONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_SND_DELAY_RPT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_SND_OPEN_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_SND_SECURITY_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_SND_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_SND_OPEN_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_SND_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IDLE_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_IN_USE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_HDL_GETCONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_HDL_OPEN_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_HDL_SECURITY_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_HDL_DELAY_RPT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_HDL_OPEN_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_HDL_ABORT_RSP, AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IDLE_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_HDL_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_HDL_OPEN_REJ, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* TC_OPEN_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_HDL_DELAY_RPT_TOUT, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}
};
/* state table for opening state */
const UINT8 avdt_scb_st_opening[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_SND_CLOSE_REQ, AVDT_SCB_SET_REMOVE, AVDT_SCB_CLOSING_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_FREE_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_SND_GETCONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_SND_DELAY_RPT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_SND_CLOSE_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_SND_SECURITY_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_SND_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_SND_CLOSE_RSP, AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_SND_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_HDL_GETCONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_HDL_CLOSE_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_HDL_SECURITY_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_HDL_DELAY_RPT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_HDL_ABORT_RSP, AVDT_SCB_CLOSING_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_HDL_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* TC_OPEN_EVT */ {AVDT_SCB_HDL_TC_OPEN, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST}
};
/* state table for open state */
const UINT8 avdt_scb_st_open[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_SND_CLOSE_REQ, AVDT_SCB_SET_REMOVE, AVDT_SCB_CLOSING_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_FREE_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_SND_GETCONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_SND_DELAY_RPT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_SND_CLOSE_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_SND_RECONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_SND_SECURITY_REQ, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_SND_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_SND_CLOSE_RSP, AVDT_SCB_TC_TIMER, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_SND_RECONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_SND_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_TC_TIMER, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_HDL_GETCONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_HDL_START_CMD, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_HDL_CLOSE_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_HDL_RECONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_HDL_SECURITY_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_HDL_DELAY_RPT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_HDL_RECONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_HDL_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
#if AVDT_REPORTING == TRUE
/* TC_OPEN_EVT */ {AVDT_SCB_HDL_TC_OPEN_STO, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE_STO, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
#else
/* TC_OPEN_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
#endif
/* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST}
};
/* state table for streaming state */
const UINT8 avdt_scb_st_stream[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_SND_STREAM_CLOSE, AVDT_SCB_SET_REMOVE, AVDT_SCB_CLOSING_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_HDL_WRITE_REQ, AVDT_SCB_CHK_SND_PKT, AVDT_SCB_STREAM_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_SND_GETCONFIG_REQ, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_SND_DELAY_RPT_REQ, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_SND_STREAM_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_SND_SECURITY_REQ, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_SND_ABORT_REQ, AVDT_SCB_CLR_PKT, AVDT_SCB_CLOSING_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_SND_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_SND_CLOSE_RSP, AVDT_SCB_TC_TIMER, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_SND_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_TC_TIMER, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_HDL_GETCONFIG_CMD, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_HDL_SUSPEND_CMD, AVDT_SCB_CLR_PKT, AVDT_SCB_OPEN_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_HDL_CLOSE_CMD, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_CLR_PKT, AVDT_SCB_STREAM_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_HDL_SECURITY_CMD, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_HDL_DELAY_RPT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_GETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_CLR_PKT, AVDT_SCB_OPEN_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_HDL_RECONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_HDL_SECURITY_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* TC_OPEN_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_CHK_SND_PKT, AVDT_SCB_STREAM_ST},
/* TC_DATA_EVT */ {AVDT_SCB_HDL_PKT, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST}
};
/* state table for closing state */
const UINT8 avdt_scb_st_closing[][AVDT_SCB_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* API_REMOVE_EVT */ {AVDT_SCB_SET_REMOVE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_WRITE_REQ_EVT */ {AVDT_SCB_FREE_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_GETCONFIG_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_DELAY_RPT_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_SETCONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_OPEN_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_CLOSE_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_SECURITY_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_ABORT_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_SECURITY_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* API_ABORT_RSP_EVT */ {AVDT_SCB_SND_ABORT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_GETCONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_OPEN_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_START_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SUSPEND_CMD_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_CLOSE_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_ABORT_CMD_EVT */ {AVDT_SCB_HDL_ABORT_CMD, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_RECONFIG_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SUSPEND_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_CLOSE_RSP_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_HDL_CLOSE_RSP, AVDT_SCB_CLOSING_ST},
/* MSG_ABORT_RSP_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_HDL_ABORT_RSP, AVDT_SCB_CLOSING_ST},
/* MSG_RECONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SECURITY_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SETCONFIG_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_OPEN_REJ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_START_REJ_EVT */ {AVDT_SCB_HDL_START_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* MSG_SUSPEND_REJ_EVT */ {AVDT_SCB_HDL_SUSPEND_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* TC_TOUT_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* TC_OPEN_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST},
/* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* CC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST},
/* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}
};
/* type for state table */
typedef const UINT8 (*tAVDT_SCB_ST_TBL)[AVDT_SCB_NUM_COLS];
/* state table */
const tAVDT_SCB_ST_TBL avdt_scb_st_tbl[] = {
avdt_scb_st_idle,
avdt_scb_st_conf,
avdt_scb_st_opening,
avdt_scb_st_open,
avdt_scb_st_stream,
avdt_scb_st_closing
};
/*******************************************************************************
**
** Function avdt_scb_event
**
** Description State machine event handling function for scb
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_scb_event(tAVDT_SCB *p_scb, UINT8 event, tAVDT_SCB_EVT *p_data)
{
tAVDT_SCB_ST_TBL state_table;
UINT8 action;
int i;
#if AVDT_DEBUG == TRUE
AVDT_TRACE_EVENT("SCB hdl=%d event=%d/%s state=%s\n", avdt_scb_to_hdl(p_scb), event, avdt_scb_evt_str[event], avdt_scb_st_str[p_scb->state]);
#endif
/* set current event */
p_scb->curr_evt = event;
/* look up the state table for the current state */
state_table = avdt_scb_st_tbl[p_scb->state];
/* set next state */
if (p_scb->state != state_table[event][AVDT_SCB_NEXT_STATE]) {
p_scb->state = state_table[event][AVDT_SCB_NEXT_STATE];
}
/* execute action functions */
for (i = 0; i < AVDT_SCB_ACTIONS; i++) {
if ((action = state_table[event][i]) != AVDT_SCB_IGNORE) {
(*avdt_cb.p_scb_act[action])(p_scb, p_data);
} else {
break;
}
}
}
/*******************************************************************************
**
** Function avdt_scb_init
**
** Description Initialize stream control block module.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_scb_init(void)
{
memset(&avdt_cb.scb[0], 0, sizeof(tAVDT_SCB) * AVDT_NUM_SEPS);
avdt_cb.p_scb_act = (tAVDT_SCB_ACTION *) avdt_scb_action;
avdt_cb.delay_value = AVDT_DELAY_RPT_DFT_VALUE;
}
/*******************************************************************************
**
** Function avdt_scb_alloc
**
** Description Allocate a stream control block.
**
**
** Returns pointer to the scb, or NULL if none could be allocated.
**
*******************************************************************************/
tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs)
{
tAVDT_SCB *p_scb = &avdt_cb.scb[0];
int i;
/* find available scb */
for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) {
if (!p_scb->allocated) {
memset(p_scb, 0, sizeof(tAVDT_SCB));
p_scb->allocated = TRUE;
p_scb->p_ccb = NULL;
/* initialize sink as activated */
if (p_cs->tsep == AVDT_TSEP_SNK) {
p_scb->sink_activated = TRUE;
}
memcpy(&p_scb->cs, p_cs, sizeof(tAVDT_CS));
#if AVDT_MULTIPLEXING == TRUE
/* initialize fragments gueue */
p_scb->frag_q = fixed_queue_new(QUEUE_SIZE_MAX);
if (p_cs->cfg.psc_mask & AVDT_PSC_MUX) {
p_scb->cs.cfg.mux_tcid_media = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
#if AVDT_REPORTING == TRUE
if (p_cs->cfg.psc_mask & AVDT_PSC_REPORT) {
p_scb->cs.cfg.mux_tcid_report = avdt_ad_type_to_tcid(AVDT_CHAN_REPORT, p_scb);
}
#endif
}
#endif
p_scb->timer_entry.param = (UINT32) p_scb;
AVDT_TRACE_DEBUG("avdt_scb_alloc hdl=%d, psc_mask:0x%x\n", i + 1, p_cs->cfg.psc_mask);
break;
}
}
if (i == AVDT_NUM_SEPS) {
/* out of ccbs */
p_scb = NULL;
AVDT_TRACE_WARNING("Out of scbs");
}
return p_scb;
}
/*******************************************************************************
**
** Function avdt_scb_dealloc
**
** Description Deallocate a stream control block.
**
**
** Returns void.
**
*******************************************************************************/
void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
{
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d\n", avdt_scb_to_hdl(p_scb));
btu_free_timer(&p_scb->timer_entry);
#if AVDT_MULTIPLEXING == TRUE
/* free fragments we're holding, if any; it shouldn't happen */
fixed_queue_free(p_scb->frag_q, osi_free_func);
#endif
memset(p_scb, 0, sizeof(tAVDT_SCB));
}
/*******************************************************************************
**
** Function avdt_scb_to_hdl
**
** Description Given a pointer to an scb, return its handle (or seid).
**
**
** Returns Index of scb.
**
*******************************************************************************/
UINT8 avdt_scb_to_hdl(tAVDT_SCB *p_scb)
{
return (UINT8) (p_scb - avdt_cb.scb + 1);
}
/*******************************************************************************
**
** Function avdt_scb_by_hdl
**
** Description Given an scb handle (or seid), return a pointer to the scb.
**
**
** Returns Pointer to scb or NULL if index is out of range or scb
** is not allocated.
**
*******************************************************************************/
tAVDT_SCB *avdt_scb_by_hdl(UINT8 hdl)
{
tAVDT_SCB *p_scb;
/* verify index */
if ((hdl > 0) && (hdl <= AVDT_NUM_SEPS)) {
p_scb = &avdt_cb.scb[hdl - 1];
/* verify scb is allocated */
if (!p_scb->allocated) {
p_scb = NULL;
AVDT_TRACE_WARNING("scb hdl %d not allocated\n", hdl);
}
} else {
p_scb = NULL;
AVDT_TRACE_WARNING("scb hdl %d out of range\n", hdl);
}
return p_scb;
}
/*******************************************************************************
**
** Function avdt_scb_verify
**
** Description Verify the condition of a list of scbs.
**
**
** Returns SEID that failed, or 0 if success.
**
*******************************************************************************/
UINT8 avdt_scb_verify(tAVDT_CCB *p_ccb, UINT8 state, UINT8 *p_seid, UINT16 num_seid, UINT8 *p_err_code)
{
int i;
tAVDT_SCB *p_scb;
UINT8 nsc_mask;
UINT8 ret = 0;
AVDT_TRACE_DEBUG("avdt_scb_verify state %d\n", state);
/* set nonsupported command mask */
/* translate public state into private state */
nsc_mask = 0;
if (state == AVDT_VERIFY_SUSPEND) {
nsc_mask = AVDT_NSC_SUSPEND;
}
/* verify every scb */
for (i = 0, *p_err_code = 0; (i < num_seid) && (*p_err_code == 0) && (i < AVDT_NUM_SEPS); i++) {
if ((p_scb = avdt_scb_by_hdl(p_seid[i])) == NULL) {
*p_err_code = AVDT_ERR_BAD_STATE;
} else if (p_scb->p_ccb != p_ccb) {
*p_err_code = AVDT_ERR_BAD_STATE;
} else if (p_scb->cs.nsc_mask & nsc_mask) {
*p_err_code = AVDT_ERR_NSC;
}
switch (state) {
case AVDT_VERIFY_OPEN:
case AVDT_VERIFY_START:
if (p_scb->state != AVDT_SCB_OPEN_ST && p_scb->state != AVDT_SCB_STREAM_ST) {
*p_err_code = AVDT_ERR_BAD_STATE;
}
break;
case AVDT_VERIFY_SUSPEND:
case AVDT_VERIFY_STREAMING:
if (p_scb->state != AVDT_SCB_STREAM_ST) {
*p_err_code = AVDT_ERR_BAD_STATE;
}
break;
}
}
if ((i != num_seid) && (i < AVDT_NUM_SEPS)) {
ret = p_seid[i];
}
return ret;
}
/*******************************************************************************
**
** Function avdt_scb_peer_seid_list
**
** Description Given a list of SCB handles, return a list of peer SEIDs
** for the handles, copied in place into the struct passed in.
**
**
** Returns Nothing.
**
*******************************************************************************/
void avdt_scb_peer_seid_list(tAVDT_MULTI *p_multi)
{
int i;
tAVDT_SCB *p_scb;
for (i = 0; i < p_multi->num_seps; i++) {
if ((p_scb = avdt_scb_by_hdl(p_multi->seid_list[i])) != NULL) {
p_multi->seid_list[i] = p_scb->peer_seid;
}
}
}
#endif /* #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,207 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This contains constants definitions and other information from the AVDTP
* specification. This file is intended for use internal to AVDT only.
*
******************************************************************************/
#ifndef AVDT_DEFS_H
#define AVDT_DEFS_H
#include "common/bt_target.h"
#if (AVDT_INCLUDED == TRUE)
/*****************************************************************************
** constants
*****************************************************************************/
/* signalling packet type */
#define AVDT_PKT_TYPE_SINGLE 0 /* single packet */
#define AVDT_PKT_TYPE_START 1 /* start packet */
#define AVDT_PKT_TYPE_CONT 2 /* continue packet */
#define AVDT_PKT_TYPE_END 3 /* end packet */
/* signalling message type */
#define AVDT_MSG_TYPE_CMD 0 /* command */
#define AVDT_MSG_TYPE_GRJ 1 /* general reject */
#define AVDT_MSG_TYPE_RSP 2 /* response accept */
#define AVDT_MSG_TYPE_REJ 3 /* response reject */
/* signalling messages */
#define AVDT_SIG_DISCOVER 1 /* discover */
#define AVDT_SIG_GETCAP 2 /* get capabilities */
#define AVDT_SIG_SETCONFIG 3 /* set configuration */
#define AVDT_SIG_GETCONFIG 4 /* get configuration */
#define AVDT_SIG_RECONFIG 5 /* reconfigure */
#define AVDT_SIG_OPEN 6 /* open */
#define AVDT_SIG_START 7 /* start */
#define AVDT_SIG_CLOSE 8 /* close */
#define AVDT_SIG_SUSPEND 9 /* suspend */
#define AVDT_SIG_ABORT 10 /* abort */
#define AVDT_SIG_SECURITY 11 /* security control */
#define AVDT_SIG_GET_ALLCAP 12 /* get all capabilities */
#define AVDT_SIG_DELAY_RPT 13 /* delay report */
/* maximum signal value */
#define AVDT_SIG_MAX AVDT_SIG_DELAY_RPT
/* used for general reject */
#define AVDT_SIG_NONE 0
/* some maximum and minimum sizes of signalling messages */
#define AVDT_DISCOVER_REQ_MIN 1
#define AVDT_DISCOVER_REQ_MAX 124
/* service category information element field values */
#define AVDT_CAT_TRANS 1 /* Media Transport */
#define AVDT_CAT_REPORT 2 /* Reporting */
#define AVDT_CAT_RECOV 3 /* Recovery */
#define AVDT_CAT_PROTECT 4 /* Content Protection */
#define AVDT_CAT_HDRCMP 5 /* Header Compression */
#define AVDT_CAT_MUX 6 /* Multiplexing */
#define AVDT_CAT_CODEC 7 /* Media Codec */
#define AVDT_CAT_DELAY_RPT 8 /* Delay Reporting */
#define AVDT_CAT_MAX_CUR AVDT_CAT_DELAY_RPT
/* min/max lengths of service category information elements */
#define AVDT_LEN_TRANS_MIN 0
#define AVDT_LEN_REPORT_MIN 0
#define AVDT_LEN_RECOV_MIN 3
#define AVDT_LEN_PROTECT_MIN 2
#define AVDT_LEN_HDRCMP_MIN 1
#define AVDT_LEN_MUX_MIN 3
#define AVDT_LEN_CODEC_MIN 2
#define AVDT_LEN_DELAY_RPT_MIN 0
#define AVDT_LEN_TRANS_MAX 0
#define AVDT_LEN_REPORT_MAX 0
#define AVDT_LEN_RECOV_MAX 3
#define AVDT_LEN_PROTECT_MAX 255
#define AVDT_LEN_HDRCMP_MAX 1
#define AVDT_LEN_MUX_MAX 7
#define AVDT_LEN_CODEC_MAX 255
#define AVDT_LEN_DELAY_RPT_MAX 0
/* minimum possible size of configuration or capabilities data */
#define AVDT_LEN_CFG_MIN 2
/* minimum and maximum lengths for different message types */
#define AVDT_LEN_SINGLE 1
#define AVDT_LEN_SETCONFIG_MIN 2
#define AVDT_LEN_RECONFIG_MIN 1
#define AVDT_LEN_MULTI_MIN 1
#define AVDT_LEN_SECURITY_MIN 1
#define AVDT_LEN_DELAY_RPT 3
/* header lengths for different packet types */
#define AVDT_LEN_TYPE_SINGLE 2 /* single packet */
#define AVDT_LEN_TYPE_START 3 /* start packet */
#define AVDT_LEN_TYPE_CONT 1 /* continue packet */
#define AVDT_LEN_TYPE_END 1 /* end packet */
/* length of general reject message */
#define AVDT_LEN_GEN_REJ 2
/* recovery service capabilities information elements */
#define AVDT_RECOV_MRWS_MIN 0x01 /* min value for maximum recovery window */
#define AVDT_RECOV_MRWS_MAX 0x18 /* max value for maximum recovery window */
#define AVDT_RECOV_MNMP_MIN 0x01 /* min value for maximum number of media packets */
#define AVDT_RECOV_MNMP_MAX 0x18 /* max value for maximum number of media packets */
/* SEID value range */
#define AVDT_SEID_MIN 0x01
#define AVDT_SEID_MAX 0x3E
/* first byte of media packet header */
#define AVDT_MEDIA_OCTET1 0x80
/* for adaptation layer header */
#define AVDT_ALH_LCODE_MASK 0x03 /* coding of length field */
#define AVDT_ALH_LCODE_NONE 0x00 /* No length field present. Take length from l2cap */
#define AVDT_ALH_LCODE_16BIT 0x01 /* 16bit length field */
#define AVDT_ALH_LCODE_9BITM0 0x02 /* 9 bit length field, MSB = 0, 8 LSBs in 1 octet following */
#define AVDT_ALH_LCODE_9BITM1 0x03 /* 9 bit length field, MSB = 1, 8 LSBs in 1 octet following */
#define AVDT_ALH_FRAG_MASK 0x04 /* set this for continuation packet */
/*****************************************************************************
** message parsing and building macros
*****************************************************************************/
#define AVDT_MSG_PRS_HDR(p, lbl, pkt, msg) \
lbl = *(p) >> 4; \
pkt = (*(p) >> 2) & 0x03; \
msg = *(p)++ & 0x03;
#define AVDT_MSG_PRS_DISC(p, seid, in_use, type, tsep) \
seid = *(p) >> 2; \
in_use = (*(p)++ >> 1) & 0x01; \
type = *(p) >> 4; \
tsep = (*(p)++ >> 3) & 0x01;
#define AVDT_MSG_PRS_SIG(p, sig) \
sig = *(p)++ & 0x3F;
#define AVDT_MSG_PRS_SEID(p, seid) \
seid = *(p)++ >> 2;
#define AVDT_MSG_PRS_PKT_TYPE(p, pkt) \
pkt = (*(p) >> 2) & 0x03;
#define AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc) \
o_v = *(p) >> 6; \
o_p = (*(p) >> 5) & 0x01; \
o_x = (*(p) >> 4) & 0x01; \
o_cc = *(p)++ & 0x0F;
#define AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc) \
o_v = *(p) >> 6; \
o_p = (*(p) >> 5) & 0x01; \
o_cc = *(p)++ & 0x1F;
#define AVDT_MSG_PRS_M_PT(p, m_pt, marker) \
marker = *(p) >> 7; \
m_pt = *(p)++ & 0x7F;
#define AVDT_MSG_BLD_HDR(p, lbl, pkt, msg) \
*(p)++ = (UINT8) ((lbl) << 4) | ((pkt) << 2) | (msg);
#define AVDT_MSG_BLD_DISC(p, seid, in_use, type, tsep) \
*(p)++ = (UINT8) (((seid) << 2) | ((in_use) << 1)); \
*(p)++ = (UINT8) (((type) << 4) | ((tsep) << 3));
#define AVDT_MSG_BLD_SIG(p, sig) \
*(p)++ = (UINT8) (sig);
#define AVDT_MSG_BLD_SEID(p, seid) \
*(p)++ = (UINT8) ((seid) << 2);
#define AVDT_MSG_BLD_ERR(p, err) \
*(p)++ = (UINT8) (err);
#define AVDT_MSG_BLD_PARAM(p, param) \
*(p)++ = (UINT8) (param);
#define AVDT_MSG_BLD_NOSP(p, nosp) \
*(p)++ = (UINT8) (nosp);
#endif ///AVRC_INCLUDED == TRUE
#endif /* AVDT_DEFS_H */
@@ -0,0 +1,761 @@
/******************************************************************************
*
* Copyright (C) 2002-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains interfaces which are internal to AVDTP.
*
******************************************************************************/
#ifndef AVDT_INT_H
#define AVDT_INT_H
#include "stack/avdt_api.h"
#include "stack/avdtc_api.h"
#include "avdt_defs.h"
#include "stack/l2c_api.h"
#include "stack/btm_api.h"
#include "osi/fixed_queue.h"
#if (AVRC_INCLUDED == TRUE)
#ifndef AVDT_DEBUG
#define AVDT_DEBUG FALSE
#endif
/*****************************************************************************
** constants
*****************************************************************************/
/* channel types */
enum {
AVDT_CHAN_SIG, /* signaling channel */
AVDT_CHAN_MEDIA, /* media channel */
#if AVDT_REPORTING == TRUE
AVDT_CHAN_REPORT, /* reporting channel */
#endif
AVDT_CHAN_NUM_TYPES
};
/* protocol service capabilities of this AVDTP implementation */
/* for now multiplexing will be used only for fragmentation */
#if ((AVDT_MULTIPLEXING == TRUE) && (AVDT_REPORTING == TRUE))
#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT)
#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_REPORT)
#else /* AVDT_MULTIPLEXING && AVDT_REPORTING */
#if (AVDT_MULTIPLEXING == TRUE)
#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX | AVDT_PSC_DELAY_RPT)
#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_MUX)
#else /* AVDT_MULTIPLEXING */
#if (AVDT_REPORTING == TRUE)
#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT)
#define AVDT_LEG_PSC (AVDT_PSC_TRANS | AVDT_PSC_REPORT)
#else /* AVDT_REPORTING */
#define AVDT_PSC (AVDT_PSC_TRANS | AVDT_PSC_DELAY_RPT)
#define AVDT_LEG_PSC (AVDT_PSC_TRANS)
#endif /* AVDT_REPORTING */
#endif /* AVDT_MULTIPLEXING */
#endif /* AVDT_MULTIPLEXING && AVDT_REPORTING */
/* initiator/acceptor signaling roles */
#define AVDT_CLOSE_ACP 0
#define AVDT_CLOSE_INT 1
#define AVDT_OPEN_ACP 2
#define AVDT_OPEN_INT 3
#define AVDT_CONF_ACP 4
#define AVDT_CONF_INT 5
/* states for avdt_scb_verify */
#define AVDT_VERIFY_OPEN 0
#define AVDT_VERIFY_STREAMING 1
#define AVDT_VERIFY_SUSPEND 2
#define AVDT_VERIFY_START 3
/* to distinguish CCB events from SCB events */
#define AVDT_CCB_MKR 0x80
/* offset where AVDTP signaling message header starts in message */
#define AVDT_HDR_OFFSET (L2CAP_MIN_OFFSET + AVDT_NUM_SEPS)
/* offset where AVDTP signaling message content starts;
** use the size of a start header since it's the largest possible
** layout of signaling message in a buffer is:
**
** | BT_HDR | SCB handles | L2CAP + HCI header | AVDTP header | data ... |
**
** Note that we "hide" the scb handles at the top of the message buffer.
*/
#define AVDT_MSG_OFFSET (L2CAP_MIN_OFFSET + AVDT_NUM_SEPS + AVDT_LEN_TYPE_START)
/* scb transport channel connect timeout value */
#define AVDT_SCB_TC_CONN_TOUT 10
/* scb transport channel disconnect timeout value */
#define AVDT_SCB_TC_DISC_TOUT 10
/* scb transport delay reporting command timeout value */
#define AVDT_SCB_TC_DELAY_RPT_TOUT 5
/* maximum number of command retransmissions */
#ifndef AVDT_RET_MAX
#define AVDT_RET_MAX 1
#endif
/* ccb state machine states */
enum {
AVDT_CCB_IDLE_ST,
AVDT_CCB_OPENING_ST,
AVDT_CCB_OPEN_ST,
AVDT_CCB_CLOSING_ST
};
/* state machine action enumeration list */
enum {
AVDT_CCB_CHAN_OPEN,
AVDT_CCB_CHAN_CLOSE,
AVDT_CCB_CHK_CLOSE,
AVDT_CCB_HDL_DISCOVER_CMD,
AVDT_CCB_HDL_DISCOVER_RSP,
AVDT_CCB_HDL_GETCAP_CMD,
AVDT_CCB_HDL_GETCAP_RSP,
AVDT_CCB_HDL_START_CMD,
AVDT_CCB_HDL_START_RSP,
AVDT_CCB_HDL_SUSPEND_CMD,
AVDT_CCB_HDL_SUSPEND_RSP,
AVDT_CCB_SND_DISCOVER_CMD,
AVDT_CCB_SND_DISCOVER_RSP,
AVDT_CCB_SND_GETCAP_CMD,
AVDT_CCB_SND_GETCAP_RSP,
AVDT_CCB_SND_START_CMD,
AVDT_CCB_SND_START_RSP,
AVDT_CCB_SND_SUSPEND_CMD,
AVDT_CCB_SND_SUSPEND_RSP,
AVDT_CCB_CLEAR_CMDS,
AVDT_CCB_CMD_FAIL,
AVDT_CCB_FREE_CMD,
AVDT_CCB_CONG_STATE,
AVDT_CCB_RET_CMD,
AVDT_CCB_SND_CMD,
AVDT_CCB_SND_MSG,
AVDT_CCB_SET_RECONN,
AVDT_CCB_CLR_RECONN,
AVDT_CCB_CHK_RECONN,
AVDT_CCB_CHK_TIMER,
AVDT_CCB_SET_CONN,
AVDT_CCB_SET_DISCONN,
AVDT_CCB_DO_DISCONN,
AVDT_CCB_LL_CLOSED,
AVDT_CCB_LL_OPENED,
AVDT_CCB_DEALLOC,
AVDT_CCB_NUM_ACTIONS
};
#define AVDT_CCB_IGNORE AVDT_CCB_NUM_ACTIONS
/* ccb state machine events */
enum {
AVDT_CCB_API_DISCOVER_REQ_EVT,
AVDT_CCB_API_GETCAP_REQ_EVT,
AVDT_CCB_API_START_REQ_EVT,
AVDT_CCB_API_SUSPEND_REQ_EVT,
AVDT_CCB_API_DISCOVER_RSP_EVT,
AVDT_CCB_API_GETCAP_RSP_EVT,
AVDT_CCB_API_START_RSP_EVT,
AVDT_CCB_API_SUSPEND_RSP_EVT,
AVDT_CCB_API_CONNECT_REQ_EVT,
AVDT_CCB_API_DISCONNECT_REQ_EVT,
AVDT_CCB_MSG_DISCOVER_CMD_EVT,
AVDT_CCB_MSG_GETCAP_CMD_EVT,
AVDT_CCB_MSG_START_CMD_EVT,
AVDT_CCB_MSG_SUSPEND_CMD_EVT,
AVDT_CCB_MSG_DISCOVER_RSP_EVT,
AVDT_CCB_MSG_GETCAP_RSP_EVT,
AVDT_CCB_MSG_START_RSP_EVT,
AVDT_CCB_MSG_SUSPEND_RSP_EVT,
AVDT_CCB_RCVRSP_EVT,
AVDT_CCB_SENDMSG_EVT,
AVDT_CCB_RET_TOUT_EVT,
AVDT_CCB_RSP_TOUT_EVT,
AVDT_CCB_IDLE_TOUT_EVT,
AVDT_CCB_UL_OPEN_EVT,
AVDT_CCB_UL_CLOSE_EVT,
AVDT_CCB_LL_OPEN_EVT,
AVDT_CCB_LL_CLOSE_EVT,
AVDT_CCB_LL_CONG_EVT
};
/* scb state machine states; these state values are private to this module so
** the scb state cannot be read or set by actions functions
*/
enum {
AVDT_SCB_IDLE_ST,
AVDT_SCB_CONF_ST,
AVDT_SCB_OPENING_ST,
AVDT_SCB_OPEN_ST,
AVDT_SCB_STREAM_ST,
AVDT_SCB_CLOSING_ST
};
/* state machine action enumeration list */
enum {
AVDT_SCB_HDL_ABORT_CMD,
AVDT_SCB_HDL_ABORT_RSP,
AVDT_SCB_HDL_CLOSE_CMD,
AVDT_SCB_HDL_CLOSE_RSP,
AVDT_SCB_HDL_GETCONFIG_CMD,
AVDT_SCB_HDL_GETCONFIG_RSP,
AVDT_SCB_HDL_OPEN_CMD,
AVDT_SCB_HDL_OPEN_REJ,
AVDT_SCB_HDL_OPEN_RSP,
AVDT_SCB_HDL_PKT,
AVDT_SCB_DROP_PKT,
AVDT_SCB_HDL_RECONFIG_CMD,
AVDT_SCB_HDL_RECONFIG_RSP,
AVDT_SCB_HDL_SECURITY_CMD,
AVDT_SCB_HDL_SECURITY_RSP,
AVDT_SCB_HDL_SETCONFIG_CMD,
AVDT_SCB_HDL_SETCONFIG_REJ,
AVDT_SCB_HDL_SETCONFIG_RSP,
AVDT_SCB_HDL_START_CMD,
AVDT_SCB_HDL_START_RSP,
AVDT_SCB_HDL_SUSPEND_CMD,
AVDT_SCB_HDL_SUSPEND_RSP,
AVDT_SCB_HDL_TC_CLOSE,
#if AVDT_REPORTING == TRUE
AVDT_SCB_HDL_TC_CLOSE_STO,
#endif
AVDT_SCB_HDL_TC_OPEN,
#if AVDT_REPORTING == TRUE
AVDT_SCB_HDL_TC_OPEN_STO,
#endif
AVDT_SCB_SND_DELAY_RPT_REQ,
AVDT_SCB_HDL_DELAY_RPT_CMD,
AVDT_SCB_HDL_DELAY_RPT_RSP,
AVDT_SCB_HDL_WRITE_REQ,
AVDT_SCB_SND_ABORT_REQ,
AVDT_SCB_SND_ABORT_RSP,
AVDT_SCB_SND_CLOSE_REQ,
AVDT_SCB_SND_STREAM_CLOSE,
AVDT_SCB_SND_CLOSE_RSP,
AVDT_SCB_SND_GETCONFIG_REQ,
AVDT_SCB_SND_GETCONFIG_RSP,
AVDT_SCB_SND_OPEN_REQ,
AVDT_SCB_SND_OPEN_RSP,
AVDT_SCB_SND_RECONFIG_REQ,
AVDT_SCB_SND_RECONFIG_RSP,
AVDT_SCB_SND_SECURITY_REQ,
AVDT_SCB_SND_SECURITY_RSP,
AVDT_SCB_SND_SETCONFIG_REQ,
AVDT_SCB_SND_SETCONFIG_REJ,
AVDT_SCB_SND_SETCONFIG_RSP,
AVDT_SCB_SND_TC_CLOSE,
AVDT_SCB_CB_ERR,
AVDT_SCB_CONG_STATE,
AVDT_SCB_REJ_STATE,
AVDT_SCB_REJ_IN_USE,
AVDT_SCB_REJ_NOT_IN_USE,
AVDT_SCB_SET_REMOVE,
AVDT_SCB_FREE_PKT,
AVDT_SCB_CLR_PKT,
AVDT_SCB_CHK_SND_PKT,
AVDT_SCB_TC_TIMER,
AVDT_SCB_CLR_VARS,
AVDT_SCB_DEALLOC,
AVDT_SCB_HDL_DELAY_RPT_TOUT,
AVDT_SCB_INIT_OPEN_REQ_EVT,
AVDT_SCB_SEND_DELAY_REPORT_CMD_EVT,
AVDT_SCB_NUM_ACTIONS
};
#define AVDT_SCB_IGNORE AVDT_SCB_NUM_ACTIONS
/* scb state machine events */
enum {
AVDT_SCB_API_REMOVE_EVT,
AVDT_SCB_API_WRITE_REQ_EVT,
AVDT_SCB_API_GETCONFIG_REQ_EVT,
AVDT_SCB_API_DELAY_RPT_REQ_EVT,
AVDT_SCB_API_SETCONFIG_REQ_EVT,
AVDT_SCB_API_OPEN_REQ_EVT,
AVDT_SCB_API_CLOSE_REQ_EVT,
AVDT_SCB_API_RECONFIG_REQ_EVT,
AVDT_SCB_API_SECURITY_REQ_EVT,
AVDT_SCB_API_ABORT_REQ_EVT,
AVDT_SCB_API_GETCONFIG_RSP_EVT,
AVDT_SCB_API_SETCONFIG_RSP_EVT,
AVDT_SCB_API_SETCONFIG_REJ_EVT,
AVDT_SCB_API_OPEN_RSP_EVT,
AVDT_SCB_API_CLOSE_RSP_EVT,
AVDT_SCB_API_RECONFIG_RSP_EVT,
AVDT_SCB_API_SECURITY_RSP_EVT,
AVDT_SCB_API_ABORT_RSP_EVT,
AVDT_SCB_MSG_SETCONFIG_CMD_EVT,
AVDT_SCB_MSG_GETCONFIG_CMD_EVT,
AVDT_SCB_MSG_OPEN_CMD_EVT,
AVDT_SCB_MSG_START_CMD_EVT,
AVDT_SCB_MSG_SUSPEND_CMD_EVT,
AVDT_SCB_MSG_CLOSE_CMD_EVT,
AVDT_SCB_MSG_ABORT_CMD_EVT,
AVDT_SCB_MSG_RECONFIG_CMD_EVT,
AVDT_SCB_MSG_SECURITY_CMD_EVT,
AVDT_SCB_MSG_DELAY_RPT_CMD_EVT,
AVDT_SCB_MSG_DELAY_RPT_RSP_EVT,
AVDT_SCB_MSG_SETCONFIG_RSP_EVT,
AVDT_SCB_MSG_GETCONFIG_RSP_EVT,
AVDT_SCB_MSG_OPEN_RSP_EVT,
AVDT_SCB_MSG_START_RSP_EVT,
AVDT_SCB_MSG_SUSPEND_RSP_EVT,
AVDT_SCB_MSG_CLOSE_RSP_EVT,
AVDT_SCB_MSG_ABORT_RSP_EVT,
AVDT_SCB_MSG_RECONFIG_RSP_EVT,
AVDT_SCB_MSG_SECURITY_RSP_EVT,
AVDT_SCB_MSG_SETCONFIG_REJ_EVT,
AVDT_SCB_MSG_OPEN_REJ_EVT,
AVDT_SCB_MSG_START_REJ_EVT,
AVDT_SCB_MSG_SUSPEND_REJ_EVT,
AVDT_SCB_TC_TOUT_EVT,
AVDT_SCB_TC_OPEN_EVT,
AVDT_SCB_TC_CLOSE_EVT,
AVDT_SCB_TC_CONG_EVT,
AVDT_SCB_TC_DATA_EVT,
AVDT_SCB_CC_CLOSE_EVT,
AVDT_SCB_DELAY_RPT_RSP_TOUT_EVT
};
/* adaption layer number of stream routing table entries */
#if AVDT_REPORTING == TRUE
/* 2 channels(1 media, 1 report) for each SEP and one for signalling */
#define AVDT_NUM_RT_TBL ((AVDT_NUM_SEPS<<1) + 1)
#else
#define AVDT_NUM_RT_TBL (AVDT_NUM_SEPS + 1)
#endif
/* adaption layer number of transport channel table entries - moved to target.h
#define AVDT_NUM_TC_TBL (AVDT_NUM_SEPS + AVDT_NUM_LINKS) */
/* "states" used in transport channel table */
#define AVDT_AD_ST_UNUSED 0 /* Unused - unallocated */
#define AVDT_AD_ST_IDLE 1 /* No connection */
#define AVDT_AD_ST_ACP 2 /* Waiting to accept a connection */
#define AVDT_AD_ST_INT 3 /* Initiating a connection */
#define AVDT_AD_ST_CONN 4 /* Waiting for connection confirm */
#define AVDT_AD_ST_CFG 5 /* Waiting for configuration complete */
#define AVDT_AD_ST_OPEN 6 /* Channel opened */
#define AVDT_AD_ST_SEC_INT 7 /* Security process as INT */
#define AVDT_AD_ST_SEC_ACP 8 /* Security process as ACP */
/* Configuration flags. tAVDT_TC_TBL.cfg_flags */
#define AVDT_L2C_CFG_IND_DONE (1<<0)
#define AVDT_L2C_CFG_CFM_DONE (1<<1)
#define AVDT_L2C_CFG_CONN_INT (1<<2)
#define AVDT_L2C_CFG_CONN_ACP (1<<3)
/* result code for avdt_ad_write_req() (L2CA_DataWrite()) */
#define AVDT_AD_FAILED L2CAP_DW_FAILED /* FALSE */
#define AVDT_AD_SUCCESS L2CAP_DW_SUCCESS /* TRUE */
#define AVDT_AD_CONGESTED L2CAP_DW_CONGESTED /* 2 */
/*****************************************************************************
** data types
*****************************************************************************/
/* msg union of all message parameter types */
typedef union {
tAVDT_EVT_HDR hdr;
tAVDT_EVT_HDR single;
tAVDT_SETCONFIG config_cmd;
tAVDT_CONFIG reconfig_cmd;
tAVDT_MULTI multi;
tAVDT_SECURITY security_cmd;
tAVDT_DISCOVER discover_rsp;
tAVDT_CONFIG svccap;
tAVDT_SECURITY security_rsp;
tAVDT_DELAY_RPT delay_rpt_cmd;
} tAVDT_MSG;
/* data type for AVDT_CCB_API_DISCOVER_REQ_EVT */
typedef struct {
tAVDT_CTRL_CBACK *p_cback;
tAVDT_SEP_INFO *p_sep_info;
UINT8 num_seps;
} tAVDT_CCB_API_DISCOVER;
/* data type for AVDT_CCB_API_GETCAP_REQ_EVT */
typedef struct {
tAVDT_EVT_HDR single;
tAVDT_CTRL_CBACK *p_cback;
tAVDT_CFG *p_cfg;
} tAVDT_CCB_API_GETCAP;
/* data type for AVDT_CCB_API_CONNECT_REQ_EVT */
typedef struct {
tAVDT_CTRL_CBACK *p_cback;
UINT8 sec_mask;
} tAVDT_CCB_API_CONNECT;
/* data type for AVDT_CCB_API_DISCONNECT_REQ_EVT */
typedef struct {
tAVDT_CTRL_CBACK *p_cback;
} tAVDT_CCB_API_DISCONNECT;
/* union associated with ccb state machine events */
typedef union {
tAVDT_CCB_API_DISCOVER discover;
tAVDT_CCB_API_GETCAP getcap;
tAVDT_CCB_API_CONNECT connect;
tAVDT_CCB_API_DISCONNECT disconnect;
tAVDT_MSG msg;
BOOLEAN llcong;
UINT8 err_code;
} tAVDT_CCB_EVT;
/* channel control block type */
typedef struct {
BD_ADDR peer_addr; /* BD address of peer */
TIMER_LIST_ENT timer_entry; /* CCB timer list entry */
fixed_queue_t *cmd_q; /* Queue for outgoing command messages */
fixed_queue_t *rsp_q; /* Queue for outgoing response and reject messages */
tAVDT_CTRL_CBACK *proc_cback; /* Procedure callback function */
tAVDT_CTRL_CBACK *p_conn_cback; /* Connection/disconnection callback function */
void *p_proc_data; /* Pointer to data storage for procedure */
BT_HDR *p_curr_cmd; /* Current command being sent awaiting response */
BT_HDR *p_curr_msg; /* Current message being sent */
BT_HDR *p_rx_msg; /* Current message being received */
BOOLEAN allocated; /* Whether ccb is allocated */
UINT8 state; /* The CCB state machine state */
BOOLEAN ll_opened; /* TRUE if LL is opened */
BOOLEAN proc_busy; /* TRUE when a discover or get capabilities procedure in progress */
UINT8 proc_param; /* Procedure parameter; either SEID for get capabilities or number of SEPS for discover */
BOOLEAN cong; /* Whether signaling channel is congested */
UINT8 label; /* Message header "label" (sequence number) */
BOOLEAN reconn; /* If TRUE, reinitiate connection after transitioning from CLOSING to IDLE state */
UINT8 ret_count; /* Command retransmission count */
UINT8 disc_rsn; /* disconnection reason */
} tAVDT_CCB;
/* type for action functions */
typedef void (*tAVDT_CCB_ACTION)(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
/* type for AVDT_SCB_API_WRITE_REQ_EVT */
typedef struct {
BT_HDR *p_buf;
UINT32 time_stamp;
#if AVDT_MULTIPLEXING == TRUE
fixed_queue_t *frag_q; /* Queue for outgoing media fragments. p_buf should be 0 */
UINT8 *p_data;
UINT32 data_len;
#endif
UINT8 m_pt;
tAVDT_DATA_OPT_MASK opt;
} tAVDT_SCB_APIWRITE;
/* type for AVDT_SCB_TC_CLOSE_EVT */
typedef struct {
UINT8 old_tc_state; /* channel state before closed */
UINT8 tcid; /* TCID */
UINT8 type; /* channel type */
UINT8 disc_rsn; /* disconnection reason */
} tAVDT_SCB_TC_CLOSE;
/* type for scb event data */
typedef union {
tAVDT_MSG msg;
tAVDT_SCB_APIWRITE apiwrite;
tAVDT_DELAY_RPT apidelay;
tAVDT_OPEN open;
tAVDT_SCB_TC_CLOSE close;
BOOLEAN llcong;
BT_HDR *p_pkt;
} tAVDT_SCB_EVT;
/* stream control block type */
typedef struct {
tAVDT_CS cs; /* stream creation struct */
tAVDT_CFG curr_cfg; /* current configuration */
tAVDT_CFG req_cfg; /* requested configuration */
TIMER_LIST_ENT timer_entry; /* timer entry */
BT_HDR *p_pkt; /* packet waiting to be sent */
tAVDT_CCB *p_ccb; /* ccb associated with this scb */
UINT16 media_seq; /* media packet sequence number */
BOOLEAN allocated; /* whether scb is allocated or unused */
BOOLEAN in_use; /* whether stream being used by peer */
BOOLEAN sink_activated; /* A2DP Sink activated/de-activated from Application */
UINT8 role; /* initiator/acceptor role in current procedure */
BOOLEAN remove; /* whether CB is marked for removal */
UINT8 state; /* state machine state */
UINT8 peer_seid; /* SEID of peer stream */
UINT8 curr_evt; /* current event; set only by state machine */
BOOLEAN cong; /* Whether media transport channel is congested */
UINT8 close_code; /* Error code received in close response */
#if AVDT_MULTIPLEXING == TRUE
fixed_queue_t *frag_q; /* Queue for outgoing media fragments */
UINT32 frag_off; /* length of already received media fragments */
UINT32 frag_org_len; /* original length before fragmentation of receiving media packet */
UINT8 *p_next_frag; /* next fragment to send */
UINT8 *p_media_buf; /* buffer for media packet assigned by AVDT_SetMediaBuf */
UINT32 media_buf_len; /* length of buffer for media packet assigned by AVDT_SetMediaBuf */
#endif
} tAVDT_SCB;
/* type for action functions */
typedef void (*tAVDT_SCB_ACTION)(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
/* adaption layer type for transport channel table */
typedef struct {
UINT16 peer_mtu; /* L2CAP mtu of the peer device */
UINT16 my_mtu; /* Our MTU for this channel */
UINT16 my_flush_to; /* Our flush timeout for this channel */
UINT16 lcid;
UINT8 tcid; /* transport channel id */
UINT8 ccb_idx; /* channel control block associated with this tc */
UINT8 state; /* transport channel state */
UINT8 cfg_flags; /* L2CAP configuration flags */
UINT8 id;
} tAVDT_TC_TBL;
/* adaption layer type for stream routing table */
typedef struct {
UINT16 lcid; /* L2CAP LCID of the associated transport channel */
UINT8 scb_hdl; /* stream control block associated with this tc */
} tAVDT_RT_TBL;
/* adaption layer control block */
typedef struct {
tAVDT_RT_TBL rt_tbl[AVDT_NUM_LINKS][AVDT_NUM_RT_TBL];
tAVDT_TC_TBL tc_tbl[AVDT_NUM_TC_TBL];
UINT8 lcid_tbl[MAX_L2CAP_CHANNELS]; /* map LCID to tc_tbl index */
} tAVDT_AD;
/* Control block for AVDT */
typedef struct {
tAVDT_REG rcb; /* registration control block */
tAVDT_CCB ccb[AVDT_NUM_LINKS]; /* channel control blocks */
tAVDT_SCB scb[AVDT_NUM_SEPS]; /* stream control blocks */
tAVDT_AD ad; /* adaption layer control block */
tAVDTC_CTRL_CBACK *p_conf_cback; /* conformance callback function */
tAVDT_CCB_ACTION *p_ccb_act; /* pointer to CCB action functions */
tAVDT_SCB_ACTION *p_scb_act; /* pointer to SCB action functions */
tAVDT_CTRL_CBACK *p_conn_cback; /* connection callback function */
UINT8 trace_level; /* trace level */
UINT16 delay_value; /* delay reporting value */
} tAVDT_CB;
/*****************************************************************************
** function declarations
*****************************************************************************/
/* CCB function declarations */
extern void avdt_ccb_init(void);
extern void avdt_ccb_event(tAVDT_CCB *p_ccb, UINT8 event, tAVDT_CCB_EVT *p_data);
extern tAVDT_CCB *avdt_ccb_by_bd(BD_ADDR bd_addr);
extern tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr);
extern void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern UINT8 avdt_ccb_to_idx(tAVDT_CCB *p_ccb);
extern tAVDT_CCB *avdt_ccb_by_idx(UINT8 idx);
/* CCB action functions */
extern void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
extern void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data);
/* SCB function prototypes */
extern void avdt_scb_event(tAVDT_SCB *p_scb, UINT8 event, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_init(void);
extern tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs);
extern void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern UINT8 avdt_scb_to_hdl(tAVDT_SCB *p_scb);
extern tAVDT_SCB *avdt_scb_by_hdl(UINT8 hdl);
extern UINT8 avdt_scb_verify(tAVDT_CCB *p_ccb, UINT8 state, UINT8 *p_seid, UINT16 num_seid, UINT8 *p_err_code);
extern void avdt_scb_peer_seid_list(tAVDT_MULTI *p_multi);
extern UINT32 avdt_scb_gen_ssrc(tAVDT_SCB *p_scb);
/* SCB action functions */
extern void avdt_scb_hdl_abort_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_abort_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_close_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_close_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_getconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_getconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_open_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_open_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_open_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_drop_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_reconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_reconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_security_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_security_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_setconfig_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_start_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_start_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_suspend_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_suspend_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_delay_rpt_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_delay_rpt_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_delay_rpt_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_tc_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_tc_open(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_tc_close_sto(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_tc_open_sto(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_hdl_write_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_abort_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_abort_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_close_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_stream_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_close_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_getconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_getconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_open_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_open_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_reconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_reconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_security_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_security_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_setconfig_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_snd_tc_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_cb_err(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_cong_state(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_rej_state(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_rej_in_use(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_rej_not_in_use(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_set_remove(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_free_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_chk_snd_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_clr_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_tc_timer(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_clr_vars(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_queue_frags(tAVDT_SCB *p_scb, UINT8 **pp_data, UINT32 *p_data_len, fixed_queue_t *pq);
extern void avdt_scb_hdl_delay_rpt_tout(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_init_open_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_send_delay_report_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
/* msg function declarations */
extern BOOLEAN avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg);
extern void avdt_msg_send_cmd(tAVDT_CCB *p_ccb, void *p_scb, UINT8 sig_id, tAVDT_MSG *p_params);
extern void avdt_msg_send_rsp(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params);
extern void avdt_msg_send_rej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params);
extern void avdt_msg_send_grej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params);
extern void avdt_msg_ind(tAVDT_CCB *p_ccb, BT_HDR *p_buf);
/* adaption layer function declarations */
extern void avdt_ad_init(void);
extern UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb);
extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state);
extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid);
extern tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb);
extern UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl);
extern void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason);
extern void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl);
extern void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested);
extern void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf);
extern tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb);
extern UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf);
extern void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role);
extern void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb);
extern void avdt_process_timeout(TIMER_LIST_ENT *p_tle);
/*****************************************************************************
** macros
*****************************************************************************/
/* we store the scb and the label in the layer_specific field of the
** current cmd
*/
#define AVDT_BLD_LAYERSPEC(ls, msg, label) \
ls = (((label) << 4) | (msg))
#define AVDT_LAYERSPEC_LABEL(ls) ((UINT8)((ls) >> 4))
#define AVDT_LAYERSPEC_MSG(ls) ((UINT8)((ls) & 0x000F))
/*****************************************************************************
** global data
*****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************************************
** Main Control Block
*******************************************************************************/
#if AVDT_DYNAMIC_MEMORY == FALSE
extern tAVDT_CB avdt_cb;
#else
extern tAVDT_CB *avdt_cb_ptr;
#define avdt_cb (*avdt_cb_ptr)
#endif
/* L2CAP callback registration structure */
extern const tL2CAP_APPL_INFO avdt_l2c_appl;
/* reject message event lookup table */
extern const UINT8 avdt_msg_rej_2_evt[];
#ifdef __cplusplus
}
#endif
#endif ///AVRC_INCLUDED == TRUE
#endif /* AVDT_INT_H */