Home | History | Annotate | Download | only in avdt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2002-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This module contains the channel control block state machine and
     22  *  functions which operate on the channel control block.
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "data_types.h"
     28 #include "bt_target.h"
     29 #include "avdt_api.h"
     30 #include "avdtc_api.h"
     31 #include "avdt_int.h"
     32 #include "gki.h"
     33 #include "btu.h"
     34 
     35 /*****************************************************************************
     36 ** state machine constants and types
     37 *****************************************************************************/
     38 #if AVDT_DEBUG == TRUE
     39 
     40 /* verbose state strings for trace */
     41 const char * const avdt_ccb_st_str[] = {
     42     "CCB_IDLE_ST",
     43     "CCB_OPENING_ST",
     44     "CCB_OPEN_ST",
     45     "CCB_CLOSING_ST"
     46 };
     47 
     48 /* verbose event strings for trace */
     49 const char * const avdt_ccb_evt_str[] = {
     50     "API_DISCOVER_REQ_EVT",
     51     "API_GETCAP_REQ_EVT",
     52     "API_START_REQ_EVT",
     53     "API_SUSPEND_REQ_EVT",
     54     "API_DISCOVER_RSP_EVT",
     55     "API_GETCAP_RSP_EVT",
     56     "API_START_RSP_EVT",
     57     "API_SUSPEND_RSP_EVT",
     58     "API_CONNECT_REQ_EVT",
     59     "API_DISCONNECT_REQ_EVT",
     60     "MSG_DISCOVER_CMD_EVT",
     61     "MSG_GETCAP_CMD_EVT",
     62     "MSG_START_CMD_EVT",
     63     "MSG_SUSPEND_CMD_EVT",
     64     "MSG_DISCOVER_RSP_EVT",
     65     "MSG_GETCAP_RSP_EVT",
     66     "MSG_START_RSP_EVT",
     67     "MSG_SUSPEND_RSP_EVT",
     68     "RCVRSP_EVT",
     69     "SENDMSG_EVT",
     70     "RET_TOUT_EVT",
     71     "RSP_TOUT_EVT",
     72     "IDLE_TOUT_EVT",
     73     "UL_OPEN_EVT",
     74     "UL_CLOSE_EVT",
     75     "LL_OPEN_EVT",
     76     "LL_CLOSE_EVT",
     77     "LL_CONG_EVT"
     78 };
     79 
     80 #endif
     81 
     82 
     83 /* action function list */
     84 const tAVDT_CCB_ACTION avdt_ccb_action[] = {
     85     avdt_ccb_chan_open,
     86     avdt_ccb_chan_close,
     87     avdt_ccb_chk_close,
     88     avdt_ccb_hdl_discover_cmd,
     89     avdt_ccb_hdl_discover_rsp,
     90     avdt_ccb_hdl_getcap_cmd,
     91     avdt_ccb_hdl_getcap_rsp,
     92     avdt_ccb_hdl_start_cmd,
     93     avdt_ccb_hdl_start_rsp,
     94     avdt_ccb_hdl_suspend_cmd,
     95     avdt_ccb_hdl_suspend_rsp,
     96     avdt_ccb_snd_discover_cmd,
     97     avdt_ccb_snd_discover_rsp,
     98     avdt_ccb_snd_getcap_cmd,
     99     avdt_ccb_snd_getcap_rsp,
    100     avdt_ccb_snd_start_cmd,
    101     avdt_ccb_snd_start_rsp,
    102     avdt_ccb_snd_suspend_cmd,
    103     avdt_ccb_snd_suspend_rsp,
    104     avdt_ccb_clear_cmds,
    105     avdt_ccb_cmd_fail,
    106     avdt_ccb_free_cmd,
    107     avdt_ccb_cong_state,
    108     avdt_ccb_ret_cmd,
    109     avdt_ccb_snd_cmd,
    110     avdt_ccb_snd_msg,
    111     avdt_ccb_set_reconn,
    112     avdt_ccb_clr_reconn,
    113     avdt_ccb_chk_reconn,
    114     avdt_ccb_chk_timer,
    115     avdt_ccb_set_conn,
    116     avdt_ccb_set_disconn,
    117     avdt_ccb_do_disconn,
    118     avdt_ccb_ll_closed,
    119     avdt_ccb_ll_opened,
    120     avdt_ccb_dealloc
    121 };
    122 
    123 /* state table information */
    124 #define AVDT_CCB_ACTIONS            2       /* number of actions */
    125 #define AVDT_CCB_NEXT_STATE         2       /* position of next state */
    126 #define AVDT_CCB_NUM_COLS           3       /* number of columns in state tables */
    127 
    128 /* state table for idle state */
    129 const UINT8 avdt_ccb_st_idle[][AVDT_CCB_NUM_COLS] = {
    130 /* Event                      Action 1                    Action 2                    Next state */
    131 /* API_DISCOVER_REQ_EVT */   {AVDT_CCB_SND_DISCOVER_CMD,  AVDT_CCB_CHAN_OPEN,         AVDT_CCB_OPENING_ST},
    132 /* API_GETCAP_REQ_EVT */     {AVDT_CCB_SND_GETCAP_CMD,    AVDT_CCB_CHAN_OPEN,         AVDT_CCB_OPENING_ST},
    133 /* API_START_REQ_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    134 /* API_SUSPEND_REQ_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    135 /* API_DISCOVER_RSP_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    136 /* API_GETCAP_RSP_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    137 /* API_START_RSP_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    138 /* API_SUSPEND_RSP_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    139 /* API_CONNECT_REQ_EVT */    {AVDT_CCB_SET_CONN,          AVDT_CCB_CHAN_OPEN,         AVDT_CCB_OPENING_ST},
    140 /* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    141 /* MSG_DISCOVER_CMD_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    142 /* MSG_GETCAP_CMD_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    143 /* MSG_START_CMD_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    144 /* MSG_SUSPEND_CMD_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    145 /* MSG_DISCOVER_RSP_EVT */   {AVDT_CCB_HDL_DISCOVER_RSP,  AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    146 /* MSG_GETCAP_RSP_EVT */     {AVDT_CCB_HDL_GETCAP_RSP,    AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    147 /* MSG_START_RSP_EVT */      {AVDT_CCB_HDL_START_RSP,     AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    148 /* MSG_SUSPEND_RSP_EVT */    {AVDT_CCB_HDL_SUSPEND_RSP,   AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    149 /* RCVRSP_EVT */             {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    150 /* SENDMSG_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    151 /* RET_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    152 /* RSP_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    153 /* IDLE_TOUT_EVT */          {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    154 /* UL_OPEN_EVT */            {AVDT_CCB_CHAN_OPEN,         AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    155 /* UL_CLOSE_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    156 /* LL_OPEN_EVT */            {AVDT_CCB_LL_OPENED,         AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    157 /* LL_CLOSE_EVT */           {AVDT_CCB_LL_CLOSED,         AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    158 /* LL_CONG_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST}
    159 };
    160 
    161 /* state table for opening state */
    162 const UINT8 avdt_ccb_st_opening[][AVDT_CCB_NUM_COLS] = {
    163 /* Event                      Action 1                    Action 2                    Next state */
    164 /* API_DISCOVER_REQ_EVT */   {AVDT_CCB_SND_DISCOVER_CMD,  AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    165 /* API_GETCAP_REQ_EVT */     {AVDT_CCB_SND_GETCAP_CMD,    AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    166 /* API_START_REQ_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    167 /* API_SUSPEND_REQ_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    168 /* API_DISCOVER_RSP_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    169 /* API_GETCAP_RSP_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    170 /* API_START_RSP_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    171 /* API_SUSPEND_RSP_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    172 /* API_CONNECT_REQ_EVT */    {AVDT_CCB_SET_CONN,          AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    173 /* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN,       AVDT_CCB_DO_DISCONN,        AVDT_CCB_CLOSING_ST},
    174 /* MSG_DISCOVER_CMD_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    175 /* MSG_GETCAP_CMD_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    176 /* MSG_START_CMD_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    177 /* MSG_SUSPEND_CMD_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    178 /* MSG_DISCOVER_RSP_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    179 /* MSG_GETCAP_RSP_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    180 /* MSG_START_RSP_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    181 /* MSG_SUSPEND_RSP_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    182 /* RCVRSP_EVT */             {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    183 /* SENDMSG_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    184 /* RET_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    185 /* RSP_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    186 /* IDLE_TOUT_EVT */          {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    187 /* UL_OPEN_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST},
    188 /* UL_CLOSE_EVT */           {AVDT_CCB_CLEAR_CMDS,        AVDT_CCB_CHAN_CLOSE,        AVDT_CCB_CLOSING_ST},
    189 /* LL_OPEN_EVT */            {AVDT_CCB_SND_CMD,           AVDT_CCB_LL_OPENED,         AVDT_CCB_OPEN_ST},
    190 /* LL_CLOSE_EVT */           {AVDT_CCB_LL_CLOSED,         AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    191 /* LL_CONG_EVT */            {AVDT_CCB_CONG_STATE,        AVDT_CCB_IGNORE,            AVDT_CCB_OPENING_ST}
    192 };
    193 
    194 /* state table for open state */
    195 const UINT8 avdt_ccb_st_open[][AVDT_CCB_NUM_COLS] = {
    196 /* Event                      Action 1                    Action 2                    Next state */
    197 /* API_DISCOVER_REQ_EVT */   {AVDT_CCB_SND_DISCOVER_CMD,  AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    198 /* API_GETCAP_REQ_EVT */     {AVDT_CCB_SND_GETCAP_CMD,    AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    199 /* API_START_REQ_EVT */      {AVDT_CCB_SND_START_CMD,     AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    200 /* API_SUSPEND_REQ_EVT */    {AVDT_CCB_SND_SUSPEND_CMD,   AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    201 /* API_DISCOVER_RSP_EVT */   {AVDT_CCB_SND_DISCOVER_RSP,  AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    202 /* API_GETCAP_RSP_EVT */     {AVDT_CCB_SND_GETCAP_RSP,    AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    203 /* API_START_RSP_EVT */      {AVDT_CCB_SND_START_RSP,     AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    204 /* API_SUSPEND_RSP_EVT */    {AVDT_CCB_SND_SUSPEND_RSP,   AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    205 /* API_CONNECT_REQ_EVT */    {AVDT_CCB_SET_CONN,          AVDT_CCB_LL_OPENED,         AVDT_CCB_OPEN_ST},
    206 /* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN,       AVDT_CCB_DO_DISCONN,        AVDT_CCB_CLOSING_ST},
    207 /* MSG_DISCOVER_CMD_EVT */   {AVDT_CCB_HDL_DISCOVER_CMD,  AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    208 /* MSG_GETCAP_CMD_EVT */     {AVDT_CCB_HDL_GETCAP_CMD,    AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    209 /* MSG_START_CMD_EVT */      {AVDT_CCB_HDL_START_CMD,     AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    210 /* MSG_SUSPEND_CMD_EVT */    {AVDT_CCB_HDL_SUSPEND_CMD,   AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    211 /* MSG_DISCOVER_RSP_EVT */   {AVDT_CCB_CHK_CLOSE,         AVDT_CCB_HDL_DISCOVER_RSP,  AVDT_CCB_OPEN_ST},
    212 /* MSG_GETCAP_RSP_EVT */     {AVDT_CCB_CHK_CLOSE,         AVDT_CCB_HDL_GETCAP_RSP,    AVDT_CCB_OPEN_ST},
    213 /* MSG_START_RSP_EVT */      {AVDT_CCB_HDL_START_RSP,     AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    214 /* MSG_SUSPEND_RSP_EVT */    {AVDT_CCB_HDL_SUSPEND_RSP,   AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    215 /* RCVRSP_EVT */             {AVDT_CCB_FREE_CMD,          AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    216 /* SENDMSG_EVT */            {AVDT_CCB_SND_MSG,           AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    217 /* RET_TOUT_EVT */           {AVDT_CCB_RET_CMD,           AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    218 /* RSP_TOUT_EVT */           {AVDT_CCB_CMD_FAIL,          AVDT_CCB_SND_CMD,           AVDT_CCB_OPEN_ST},
    219 /* IDLE_TOUT_EVT */          {AVDT_CCB_CLEAR_CMDS,        AVDT_CCB_CHAN_CLOSE,        AVDT_CCB_CLOSING_ST},
    220 /* UL_OPEN_EVT */            {AVDT_CCB_CHK_TIMER,         AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    221 /* UL_CLOSE_EVT */           {AVDT_CCB_CHK_CLOSE,         AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    222 /* LL_OPEN_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_OPEN_ST},
    223 /* LL_CLOSE_EVT */           {AVDT_CCB_LL_CLOSED,         AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    224 /* LL_CONG_EVT */            {AVDT_CCB_CONG_STATE,        AVDT_CCB_SND_MSG,           AVDT_CCB_OPEN_ST}
    225 };
    226 
    227 /* state table for closing state */
    228 const UINT8 avdt_ccb_st_closing[][AVDT_CCB_NUM_COLS] = {
    229 /* Event                      Action 1                    Action 2                    Next state */
    230 /* API_DISCOVER_REQ_EVT */   {AVDT_CCB_SET_RECONN,        AVDT_CCB_SND_DISCOVER_CMD,  AVDT_CCB_CLOSING_ST},
    231 /* API_GETCAP_REQ_EVT */     {AVDT_CCB_SET_RECONN,        AVDT_CCB_SND_GETCAP_CMD,    AVDT_CCB_CLOSING_ST},
    232 /* API_START_REQ_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    233 /* API_SUSPEND_REQ_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    234 /* API_DISCOVER_RSP_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    235 /* API_GETCAP_RSP_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    236 /* API_START_RSP_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    237 /* API_SUSPEND_RSP_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    238 /* API_CONNECT_REQ_EVT */    {AVDT_CCB_SET_RECONN,        AVDT_CCB_SET_CONN,          AVDT_CCB_CLOSING_ST},
    239 /* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_CLR_RECONN,        AVDT_CCB_SET_DISCONN,       AVDT_CCB_CLOSING_ST},
    240 /* MSG_DISCOVER_CMD_EVT */   {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    241 /* MSG_GETCAP_CMD_EVT */     {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    242 /* MSG_START_CMD_EVT */      {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    243 /* MSG_SUSPEND_CMD_EVT */    {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    244 /* MSG_DISCOVER_RSP_EVT */   {AVDT_CCB_HDL_DISCOVER_RSP,  AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    245 /* MSG_GETCAP_RSP_EVT */     {AVDT_CCB_HDL_GETCAP_RSP,    AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    246 /* MSG_START_RSP_EVT */      {AVDT_CCB_HDL_START_RSP,     AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    247 /* MSG_SUSPEND_RSP_EVT */    {AVDT_CCB_HDL_SUSPEND_RSP,   AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    248 /* RCVRSP_EVT */             {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    249 /* SENDMSG_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    250 /* RET_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    251 /* RSP_TOUT_EVT */           {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    252 /* IDLE_TOUT_EVT */          {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    253 /* UL_OPEN_EVT */            {AVDT_CCB_SET_RECONN,        AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    254 /* UL_CLOSE_EVT */           {AVDT_CCB_CLR_RECONN,        AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    255 /* LL_OPEN_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST},
    256 /* LL_CLOSE_EVT */           {AVDT_CCB_CHK_RECONN,        AVDT_CCB_IGNORE,            AVDT_CCB_IDLE_ST},
    257 /* LL_CONG_EVT */            {AVDT_CCB_IGNORE,            AVDT_CCB_IGNORE,            AVDT_CCB_CLOSING_ST}
    258 };
    259 
    260 /* type for state table */
    261 typedef const UINT8 (*tAVDT_CCB_ST_TBL)[AVDT_CCB_NUM_COLS];
    262 
    263 /* state table */
    264 const tAVDT_CCB_ST_TBL avdt_ccb_st_tbl[] = {
    265     avdt_ccb_st_idle,
    266     avdt_ccb_st_opening,
    267     avdt_ccb_st_open,
    268     avdt_ccb_st_closing
    269 };
    270 
    271 /*******************************************************************************
    272 **
    273 ** Function         avdt_ccb_init
    274 **
    275 ** Description      Initialize channel control block module.
    276 **
    277 **
    278 ** Returns          Nothing.
    279 **
    280 *******************************************************************************/
    281 void avdt_ccb_init(void)
    282 {
    283     memset(&avdt_cb.ccb[0], 0, sizeof(tAVDT_CCB) * AVDT_NUM_LINKS);
    284     avdt_cb.p_ccb_act = (tAVDT_CCB_ACTION *) avdt_ccb_action;
    285 }
    286 
    287 /*******************************************************************************
    288 **
    289 ** Function         avdt_ccb_event
    290 **
    291 ** Description      State machine event handling function for ccb
    292 **
    293 **
    294 ** Returns          Nothing.
    295 **
    296 *******************************************************************************/
    297 void avdt_ccb_event(tAVDT_CCB *p_ccb, UINT8 event, tAVDT_CCB_EVT *p_data)
    298 {
    299     tAVDT_CCB_ST_TBL    state_table;
    300     UINT8               action;
    301     int                 i;
    302 
    303 #if AVDT_DEBUG == TRUE
    304     AVDT_TRACE_EVENT3("CCB ccb=%d event=%s state=%s", avdt_ccb_to_idx(p_ccb), avdt_ccb_evt_str[event], avdt_ccb_st_str[p_ccb->state]);
    305 #endif
    306     BTTRC_AVDT_CCB_EVENT(event, p_ccb->state);
    307 
    308     /* look up the state table for the current state */
    309     state_table = avdt_ccb_st_tbl[p_ccb->state];
    310 
    311     /* set next state */
    312     if (p_ccb->state != state_table[event][AVDT_CCB_NEXT_STATE])
    313         BTTRC_AVDT_CCB_STATE(state_table[event][AVDT_CCB_NEXT_STATE]);
    314     p_ccb->state = state_table[event][AVDT_CCB_NEXT_STATE];
    315 
    316     /* execute action functions */
    317     for (i = 0; i < AVDT_CCB_ACTIONS; i++)
    318     {
    319         if ((action = state_table[event][i]) != AVDT_CCB_IGNORE)
    320         {
    321             BTTRC_AVDT_CCB_ACTION(action);
    322             (*avdt_cb.p_ccb_act[action])(p_ccb, p_data);
    323         }
    324         else
    325         {
    326             break;
    327         }
    328     }
    329 }
    330 
    331 
    332 /*******************************************************************************
    333 **
    334 ** Function         avdt_ccb_by_bd
    335 **
    336 ** Description      This lookup function finds the ccb for a BD address.
    337 **
    338 **
    339 ** Returns          pointer to the ccb, or NULL if none found.
    340 **
    341 *******************************************************************************/
    342 tAVDT_CCB *avdt_ccb_by_bd(BD_ADDR bd_addr)
    343 {
    344     tAVDT_CCB   *p_ccb = &avdt_cb.ccb[0];
    345     int         i;
    346 
    347     for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++)
    348     {
    349         /* if allocated ccb has matching ccb */
    350         if (p_ccb->allocated && (!memcmp(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN)))
    351         {
    352             break;
    353         }
    354     }
    355 
    356     if (i == AVDT_NUM_LINKS)
    357     {
    358         /* if no ccb found */
    359         p_ccb = NULL;
    360 
    361         AVDT_TRACE_DEBUG6("No ccb for addr %02x-%02x-%02x-%02x-%02x-%02x",
    362                           bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
    363     }
    364     return p_ccb;
    365 }
    366 
    367 /*******************************************************************************
    368 **
    369 ** Function         avdt_ccb_alloc
    370 **
    371 ** Description      Allocate a channel control block.
    372 **
    373 **
    374 ** Returns          pointer to the ccb, or NULL if none could be allocated.
    375 **
    376 *******************************************************************************/
    377 tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr)
    378 {
    379     tAVDT_CCB   *p_ccb = &avdt_cb.ccb[0];
    380     int         i;
    381 
    382     for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++)
    383     {
    384         if (!p_ccb->allocated)
    385         {
    386             p_ccb->allocated = TRUE;
    387             memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
    388             GKI_init_q(&p_ccb->cmd_q);
    389             GKI_init_q(&p_ccb->rsp_q);
    390             p_ccb->timer_entry.param = (UINT32) p_ccb;
    391             AVDT_TRACE_DEBUG1("avdt_ccb_alloc %d", i);
    392             break;
    393         }
    394     }
    395 
    396     if (i == AVDT_NUM_LINKS)
    397     {
    398         /* out of ccbs */
    399         p_ccb = NULL;
    400         AVDT_TRACE_WARNING0("Out of ccbs");
    401     }
    402     return p_ccb;
    403 }
    404 
    405 /*******************************************************************************
    406 **
    407 ** Function         avdt_ccb_dealloc
    408 **
    409 ** Description      Deallocate a stream control block.
    410 **
    411 **
    412 ** Returns          void.
    413 **
    414 *******************************************************************************/
    415 void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    416 {
    417     AVDT_TRACE_DEBUG1("avdt_ccb_dealloc %d", avdt_ccb_to_idx(p_ccb));
    418     btu_stop_timer(&p_ccb->timer_entry);
    419     memset(p_ccb, 0, sizeof(tAVDT_CCB));
    420 }
    421 
    422 /*******************************************************************************
    423 **
    424 ** Function         avdt_ccb_to_idx
    425 **
    426 ** Description      Given a pointer to an ccb, return its index.
    427 **
    428 **
    429 ** Returns          Index of ccb.
    430 **
    431 *******************************************************************************/
    432 UINT8 avdt_ccb_to_idx(tAVDT_CCB *p_ccb)
    433 {
    434     /* use array arithmetic to determine index */
    435     return (UINT8) (p_ccb - avdt_cb.ccb);
    436 }
    437 
    438 /*******************************************************************************
    439 **
    440 ** Function         avdt_ccb_by_idx
    441 **
    442 ** Description      Return ccb pointer based on ccb index.
    443 **
    444 **
    445 ** Returns          pointer to the ccb, or NULL if none found.
    446 **
    447 *******************************************************************************/
    448 tAVDT_CCB *avdt_ccb_by_idx(UINT8 idx)
    449 {
    450     tAVDT_CCB   *p_ccb;
    451 
    452     /* verify index */
    453     if (idx < AVDT_NUM_LINKS)
    454     {
    455         p_ccb = &avdt_cb.ccb[idx];
    456     }
    457     else
    458     {
    459         p_ccb = NULL;
    460         AVDT_TRACE_WARNING1("No ccb for idx %d", idx);
    461     }
    462     return p_ccb;
    463 }
    464 
    465