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