/* * Copyright (C) 2021-2022 Huawei Device Co., Ltd. * 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. */ #include "avdtp_ctrl.h" #include "avdtp_impl.h" #include "avdtp_message.h" #include "btm.h" #include "btm/btm_thread.h" #include "log.h" #include "securec.h" /** * Action function list */ const AvdtStreamAction AVDT_STREAM_ACTION[] = { AvdtActSetConfigReq, /* 0 */ AvdtActSetConfigRsp, AvdtActSetConfigInd, AvdtActSetConfigCfm, AvdtActGetConfigReq, AvdtActGetConfigRsp, AvdtActGetConfigInd, AvdtActGetConfigCfm, AvdtActOpenReq, AvdtActOpenRsp, AvdtActOpenInd, /* 10 */ AvdtActOpenCfm, AvdtActReconfigReq, AvdtActReconfigRsp, AvdtActReconfigInd, AvdtActReconfigCfm, AvdtActStartReq, AvdtActStartRsp, AvdtActStartInd, AvdtActStartCfm, AvdtActSuspendReq, /* 20 */ AvdtActSuspendRsp, AvdtActSuspendInd, AvdtActSuspendCfm, AvdtActCloseReq, AvdtActCloseRsp, AvdtActCloseInd, AvdtActCloseCfm, AvdtActAbortReq, AvdtActAbortRsp, AvdtActAbortInd, /* 30 */ AvdtActAbortCfm, AvdtActDelayRptReq, AvdtActDelayRptRsp, AvdtActDelayRptInd, AvdtActDelayRptCfm, AvdtActWriteReq, AvdtActWriteCfm, AvdtActReadInd, AvdtActStreamOpenReq, AvdtActStreamOpenRsp, /* 40 */ AvdtActStreamOpenInd, AvdtActStreamOpenCfm, AvdtActStreamCloseReq, AvdtActStreamCloseRsp, AvdtActStreamCloseInd, AvdtActStreamCloseCfm, AvdtActBadStateRej, /* 47 */ }; const AvdtSigAction AVDT_SIG_ACTION[] = { AvdtActDiscoverReq, /* 0 */ AvdtActDiscoverRsp, AvdtActDiscoverInd, AvdtActDiscoverCfm, AvdtActGetCapReq, AvdtActGetCapRsp, AvdtActGetCapInd, AvdtActGetCapCfm, AvdtActGetAllCapReq, AvdtActGetAllCapRsp, AvdtActGetAllCapInd, /* 10 */ AvdtActGetAllCapCfm, AvdtActConnReq, AvdtActConnRsp, AvdtActConnInd, AvdtActConnCfm, AvdtActDisconnReq, AvdtActDisconnRsp, AvdtActDisconnInd, AvdtActDisconnCfm, AvdtActSndMsg, /* 20 */ }; AvdtCB g_avdtCb; /** * State table information */ #define AVDT_STREAM_NEXT_STATE 1 #define AVDT_STREAM_NUM_COLS 2 #define AVDT_2MB_MODE 1 #define AVDT_3MB_MODE 2 /** * Init status: Idle */ const uint8_t AVDT_STREAM_ST_IDLE[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SETCONFIGURE_REQ, AVDT_IDLE_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SETCONFIGURE_RSP, AVDT_CONFIGURE_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SETCONFIGURE_IND, AVDT_IDLE_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SETCONFIGURE_CFM, AVDT_CONFIGURE_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_ABORT_REQ, AVDT_IDLE_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_ABORT_RSP, AVDT_IDLE_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_ABORT_IND, AVDT_IDLE_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_ABORT_CFM, AVDT_IDLE_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_IDLE_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_IDLE_ST}, }; /** * Configure Status */ const uint8_t AVDT_STREAM_ST_CONFIG[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SETCONFIGURE_IND, AVDT_CONFIGURE_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_GETCONFIGURE_REQ, AVDT_CONFIGURE_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_GETCONFIGURE_RSP, AVDT_CONFIGURE_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_GETCONFIGURE_IND, AVDT_CONFIGURE_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_GETCONFIGURE_CFM, AVDT_CONFIGURE_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_OPEN_REQ, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_OPEN_IND, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_CONFIGURE_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_CONFIGURE_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_CONFIGURE_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_CONFIGURE_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_ABORT_REQ, AVDT_CONFIGURE_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_ABORT_RSP, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_ABORT_IND, AVDT_CONFIGURE_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_ABORT_CFM, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_DELAY_REQ, AVDT_CONFIGURE_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_DELAY_RSP, AVDT_CONFIGURE_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_DELAY_IND, AVDT_CONFIGURE_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_DELAY_CFM, AVDT_CONFIGURE_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CONFIGURE_ST}, }; /** * Opening Status */ const uint8_t AVDT_STREAM_ST_OPENING[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_OPEN_RSP, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_OPEN_CFM, AVDT_OPENING_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_OPENING_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_OPENING_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_ABORT_REQ, AVDT_OPENING_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_ABORT_RSP, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_ABORT_IND, AVDT_OPENING_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_ABORT_CFM, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_DELAY_REQ, AVDT_OPENING_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_DELAY_RSP, AVDT_OPENING_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_DELAY_IND, AVDT_OPENING_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_DELAY_CFM, AVDT_OPENING_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_STREAM_OPEN_REQ, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_STREAM_OPEN_RSP, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_STREAM_OPEN_IND, AVDT_OPENING_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_STREAM_OPEN_CFM, AVDT_OPEN_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPENING_ST}, }; /** * Open status */ const uint8_t AVDT_STREAM_ST_OPEN[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_GETCONFIGURE_REQ, AVDT_OPEN_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_GETCONFIGURE_RSP, AVDT_OPEN_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_GETCONFIGURE_IND, AVDT_OPEN_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_GETCONFIGURE_CFM, AVDT_OPEN_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_RECONFIGURE_REQ, AVDT_OPEN_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_RECONFIGURE_RSP, AVDT_OPEN_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_RECONFIGURE_IND, AVDT_OPEN_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_RECONFIGURE_CFM, AVDT_OPEN_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_START_REQ, AVDT_OPEN_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_START_RSP, AVDT_STREAMING_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_START_IND, AVDT_OPEN_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_START_CFM, AVDT_STREAMING_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_OPEN_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_CLOSE_REQ, AVDT_OPEN_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_CLOSE_RSP, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_CLOSE_IND, AVDT_OPEN_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_CLOSE_CFM, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_ABORT_REQ, AVDT_OPEN_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_ABORT_RSP, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_ABORT_IND, AVDT_OPEN_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_ABORT_CFM, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_DELAY_REQ, AVDT_OPEN_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_DELAY_RSP, AVDT_OPEN_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_DELAY_IND, AVDT_OPEN_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_DELAY_CFM, AVDT_OPEN_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_OPEN_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_STREAM_CLOSE_IND, AVDT_CLOSING_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_STREAM_CLOSE_CFM, AVDT_CLOSING_ST}, }; /** * Streaming status */ const uint8_t AVDT_STREAM_ST_STREAMING[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_GETCONFIGURE_REQ, AVDT_STREAMING_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_GETCONFIGURE_RSP, AVDT_STREAMING_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_GETCONFIGURE_IND, AVDT_STREAMING_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_GETCONFIGURE_CFM, AVDT_STREAMING_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SUSPEND_REQ, AVDT_STREAMING_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SUSPEND_RSP, AVDT_OPEN_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_SUSPEND_IND, AVDT_STREAMING_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SUSPEND_CFM, AVDT_OPEN_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_CLOSE_REQ, AVDT_STREAMING_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_CLOSE_RSP, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_CLOSE_IND, AVDT_STREAMING_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_CLOSE_CFM, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_ABORT_REQ, AVDT_STREAMING_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_ABORT_RSP, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_ABORT_IND, AVDT_STREAMING_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_ABORT_CFM, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_DELAY_REQ, AVDT_STREAMING_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_DELAY_RSP, AVDT_STREAMING_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_DELAY_IND, AVDT_STREAMING_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_DELAY_CFM, AVDT_STREAMING_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_WRITE_REQ, AVDT_STREAMING_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_STREAMING_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_STREAM_CLOSE_IND, AVDT_CLOSING_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_STREAM_CLOSE_CFM, AVDT_CLOSING_ST}, }; /* Closing status */ const uint8_t AVDT_STREAM_ST_CLOSING[][AVDT_STREAM_NUM_COLS] = { /* AVDT_SETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_GETCONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_GETCONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_GETCONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_GETCONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_RECONFIGURE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_RECONFIGURE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_RECONFIGURE_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_RECONFIGURE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_START_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_START_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_START_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_START_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SUSPEND_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SUSPEND_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SUSPEND_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_SUSPEND_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_IND_EVENT */ {AVDT_BAD_STATE_REJ, AVDT_CLOSING_ST}, /* AVDT_CLOSE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_ABORT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_DELAY_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_WRITE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_WRITE_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_READ_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_OPEN_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_OPEN_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_OPEN_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_OPEN_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_CLOSE_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_CLOSE_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_CLOSING_ST}, /* AVDT_STREAM_CLOSE_CMD_IND_EVENT */ {AVDT_STREAM_CLOSE_IND, AVDT_IDLE_ST}, /* AVDT_STREAM_CLOSE_CMD_CFM_EVENT */ {AVDT_STREAM_CLOSE_CFM, AVDT_IDLE_ST}, }; /** * Init status: Idle */ const uint8_t AVDT_SIG_ST_IDLE[][AVDT_STREAM_NUM_COLS] = { /* AVDT_DISCOVER_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCOVER_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCOVER_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCOVER_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETALLCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETALLCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETALLCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_GETALLCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_CONNECT_CMD_REQ_EVENT */ {AVDT_CONNECT_REQ, AVDT_SIG_CONFIGURE_ST}, /* AVDT_CONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_CONNECT_CMD_IND_EVENT */ {AVDT_CONNECT_IND, AVDT_SIG_OPEN_ST}, /* AVDT_CONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_IND_EVENT */ {AVDT_DISCONNECT_IND, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_SND_MSG_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, }; /** * Configure Status */ const uint8_t AVDT_SIG_ST_CONFIG[][AVDT_STREAM_NUM_COLS] = { /* AVDT_DISCOVER_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_DISCOVER_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_DISCOVER_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_DISCOVER_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETALLCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETALLCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETALLCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_GETALLCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_CONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_CONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_CONNECT_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_CONNECT_CMD_CFM_EVENT */ {AVDT_CONNECT_CFM, AVDT_SIG_OPEN_ST}, /* AVDT_DISCONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CONFIGURE_ST}, /* AVDT_DISCONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_IND_EVENT */ {AVDT_DISCONNECT_IND, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, /* AVDT_SND_MSG_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_IDLE_ST}, }; /** * Open status */ const uint8_t AVDT_SIG_ST_OPEN[][AVDT_STREAM_NUM_COLS] = { /* AVDT_DISCOVER_CMD_REQ_EVENT */ {AVDT_DISCOVER_REQ, AVDT_SIG_OPEN_ST}, /* AVDT_DISCOVER_CMD_RSP_EVENT */ {AVDT_DISCOVER_RSP, AVDT_SIG_OPEN_ST}, /* AVDT_DISCOVER_CMD_IND_EVENT */ {AVDT_DISCOVER_IND, AVDT_SIG_OPEN_ST}, /* AVDT_DISCOVER_CMD_CFM_EVENT */ {AVDT_DISCOVER_CFM, AVDT_SIG_OPEN_ST}, /* AVDT_GETCAP_CMD_REQ_EVENT */ {AVDT_GETCAP_REQ, AVDT_SIG_OPEN_ST}, /* AVDT_GETCAP_CMD_RSP_EVENT */ {AVDT_GETCAP_RSP, AVDT_SIG_OPEN_ST}, /* AVDT_GETCAP_CMD_IND_EVENT */ {AVDT_GETCAP_IND, AVDT_SIG_OPEN_ST}, /* AVDT_GETCAP_CMD_CFM_EVENT */ {AVDT_GETCAP_CFM, AVDT_SIG_OPEN_ST}, /* AVDT_GETALLCAP_CMD_REQ_EVENT */ {AVDT_GETALLCAP_REQ, AVDT_SIG_OPEN_ST}, /* AVDT_GETALLCAP_CMD_RSP_EVENT */ {AVDT_GETALLCAP_RSP, AVDT_SIG_OPEN_ST}, /* AVDT_GETALLCAP_CMD_IND_EVENT */ {AVDT_GETALLCAP_IND, AVDT_SIG_OPEN_ST}, /* AVDT_GETALLCAP_CMD_CFM_EVENT */ {AVDT_GETALLCAP_CFM, AVDT_SIG_OPEN_ST}, /* AVDT_CONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_CONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_CONNECT_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_CONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_DISCONNECT_CMD_REQ_EVENT */ {AVDT_DISCONNECT_REQ, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_DISCONNECT_CMD_IND_EVENT */ {AVDT_DISCONNECT_IND, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_OPEN_ST}, /* AVDT_SND_MSG_EVENT */ {AVDT_SND_MSG, AVDT_SIG_OPEN_ST}, }; /* Closing status */ const uint8_t AVDT_SIG_ST_CLOSING[][AVDT_STREAM_NUM_COLS] = { /* AVDT_DISCOVER_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCOVER_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCOVER_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCOVER_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETALLCAP_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETALLCAP_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETALLCAP_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_GETALLCAP_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_CONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_CONNECT_CMD_RSP_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_CONNECT_CMD_IND_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_CONNECT_CMD_CFM_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCONNECT_CMD_REQ_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, /* AVDT_DISCONNECT_CMD_RSP_EVENT */ {AVDT_DISCONNECT_RSP, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_IND_EVENT */ {AVDT_DISCONNECT_IND, AVDT_SIG_IDLE_ST}, /* AVDT_DISCONNECT_CMD_CFM_EVENT */ {AVDT_DISCONNECT_CFM, AVDT_SIG_IDLE_ST}, /* AVDT_SND_MSG_EVENT */ {AVDT_SSM_IGNORE, AVDT_SIG_CLOSING_ST}, }; typedef const uint8_t (*AVDT_STREAM_ST_TBL)[AVDT_STREAM_NUM_COLS]; typedef const uint8_t (*AVDT_SIG_ST_TBL)[AVDT_STREAM_NUM_COLS]; /** * Stream State table */ const AVDT_STREAM_ST_TBL AVDT_STREAM_TBL[] = { AVDT_STREAM_ST_IDLE, AVDT_STREAM_ST_CONFIG, AVDT_STREAM_ST_OPENING, AVDT_STREAM_ST_OPEN, AVDT_STREAM_ST_STREAMING, AVDT_STREAM_ST_CLOSING }; /** * Signal State table */ const AVDT_SIG_ST_TBL AVDT_SIG_TBL[] = {AVDT_SIG_ST_IDLE, AVDT_SIG_ST_CONFIG, AVDT_SIG_ST_OPEN, AVDT_SIG_ST_CLOSING}; /** * * @brief AvdtControlBlockInit * * @details Stream control block init functions. * * @return void * */ void AvdtControlBlockInit(void) { LOG_DEBUG("[AVDT]%{public}s:", __func__); (void)memset_s(&g_avdtCb, sizeof(AvdtCB), 0, sizeof(AvdtCB)); g_avdtCb.streamAction = AVDT_STREAM_ACTION; g_avdtCb.sigAction = AVDT_SIG_ACTION; g_avdtCb.avdtRegisted = false; g_avdtCb.sepRegisted = false; for (int j = 0; j < AVDT_MAX_NUM_SEP; j++) { g_avdtCb.streamHandles[j].handle = j + 1; } for (int k = 0; k < AVDT_NUM_LINKS; k++) { g_avdtCb.sigHandles[k].handle = k + 1; } } /** * * @brief AvdtStreamProcEvent * * @details State process function for stream channel. * * @return void * */ void AvdtStreamProcEvent(AvdtStreamCtrl *streamCtrl, uint8_t event, AvdtEventData *data) { LOG_DEBUG("[AVDT]%{public}s:event(%hhu),streamCtrl->state(%hhu)", __func__, event, streamCtrl->state); /* get the current state table */ AVDT_STREAM_ST_TBL curStatus = AVDT_STREAM_TBL[streamCtrl->state]; /* update the status of sigCtrl */ if (streamCtrl->state != curStatus[event][AVDT_STREAM_NEXT_STATE]) { streamCtrl->state = curStatus[event][AVDT_STREAM_NEXT_STATE]; } /* call the matched action */ uint8_t Action = curStatus[event][0]; if (AVDT_SSM_IGNORE != Action) { LOG_DEBUG("[AVDT]%{public}s: streamAction[Action:%hhu] nextState(%hhu)", __func__, Action, streamCtrl->state); g_avdtCb.streamAction[Action](streamCtrl, data); } return; } /** * * @brief AvdtSigProcEvent * * @details State process function for signal channel. * * @return void * */ void AvdtSigProcEvent(AvdtSigCtrl *sigCtrl, uint8_t event, AvdtEventData *data) { LOG_DEBUG("[AVDT]%{public}s:event(%hhu),sigCtrl->state(%hhu)", __func__, event, sigCtrl->state); /* get the current state table */ AVDT_STREAM_ST_TBL curStatus = AVDT_SIG_TBL[sigCtrl->state]; /* update the status of sigCtrl */ if (sigCtrl->state != curStatus[event][AVDT_STREAM_NEXT_STATE]) { sigCtrl->state = curStatus[event][AVDT_STREAM_NEXT_STATE]; } /* call the matched action */ uint8_t Action = curStatus[event][0]; if (Action != AVDT_SSM_IGNORE) { LOG_DEBUG("[AVDT]%{public}s: sigAction[Action:%hhu] nextState(%hhu)", __func__, Action, sigCtrl->state); g_avdtCb.sigAction[Action](sigCtrl, data); } return; } /** * * @brief AvdtGetSigCtrlByAddr * * @details Lookup the channel CtrlBlock by address * * @return NULL: No isAllocated ChannelCtrl; otherwise return the pointer * of ChannelCtrl. * */ AvdtSigCtrl *AvdtGetSigCtrlByAddr(const BtAddr *bdAddr) { LOG_DEBUG("[AVDT]%{public}s:", __func__); AvdtSigCtrl *sigCtrl = NULL; for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (g_avdtCb.sigCtrl[i] != NULL && !memcmp((char *)g_avdtCb.sigCtrl[i]->peerAddress.addr, (char *)&(bdAddr->addr), BT_ADDR_LENGTH)) { sigCtrl = g_avdtCb.sigCtrl[i]; break; } } return sigCtrl; } /** * * @brief AvdtGetSigCtrlByHandle * * @details Lookup the ChanelCtrl isAllocated by handle * * @return NULL: No isAllocated ChannelCtrl; otherwise the pointer * of ChannelCtrl. * */ AvdtSigCtrl *AvdtGetSigCtrlByHandle(uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s:handle(%hu)", __func__, handle); AvdtSigCtrl *sigCtrl = NULL; for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (g_avdtCb.sigCtrl[i] != NULL && g_avdtCb.sigCtrl[i]->handle == handle) { sigCtrl = g_avdtCb.sigCtrl[i]; LOG_DEBUG("[AVDT]%{public}s:Get sigCtrl index(%{public}d)", __func__, i); break; } } return sigCtrl; } /** * * @brief AvdtSigCtrlAllocate * * @details Allocate the ChannelCtrl for peer device. * * @return NULL: No reources; otherwise the pointer * of ChannelCtrl. * */ AvdtSigCtrl *AvdtSigCtrlAllocate(const BtAddr *bdAddr, uint8_t role) { LOG_DEBUG("[AVDT]%{public}s: role is (%hhu)", __func__, role); AvdtSigCtrl *sigCtrl = NULL; for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (g_avdtCb.sigCtrl[i] != NULL) { continue; } sigCtrl = (AvdtSigCtrl *)malloc(sizeof(AvdtSigCtrl)); if (sigCtrl == NULL) { continue; } (void)memset_s(sigCtrl, sizeof(AvdtSigCtrl), 0, sizeof(AvdtSigCtrl)); sigCtrl->peerAddress = *bdAddr; if (role == AVDT_ROLE_SRC) { sigCtrl->role = AVDT_ROLE_SRC; } else { sigCtrl->role = AVDT_ROLE_SNK; } sigCtrl->state = AVDT_SIG_IDLE_ST; sigCtrl->handle = AvdtAssignSigHandle(); sigCtrl->procCback = g_avdtCb.regInfo.ctrlCallback; LOG_DEBUG("[AVDT]%{public}s:Connected devices number:(%{public}d),sigCtrl->handle(%hu)", __func__, i, sigCtrl->handle); g_avdtCb.sigCtrl[i] = sigCtrl; break; } return sigCtrl; } /** * * @brief AvdtSigDealloc * * @details Deallocate the ChannelCtrl. * * @return void * */ void AvdtSigDealloc(void) { LOG_DEBUG("[AVDT]%{public}s:", __func__); for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (g_avdtCb.sigCtrl[i] != NULL) { AvdtFreeSigCtrlByHandle(g_avdtCb.sigCtrl[i]->handle); } } return; } /** * * @brief AvdtGetStreamCtrlByHandle * * @details Lookup the StreamCtrl isAllocated by handle * * @return NULL: No isAllocated Streamtrl; otherwise the pointer * of streamCtrl. * */ AvdtStreamCtrl *AvdtGetStreamCtrlByHandle(uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, handle); AvdtStreamCtrl *streamCtrl = NULL; for (int i = 0; i < AVDT_NUM_LINKS; i++) { for (int j = 0; j < AVDT_NUM_SEPS; j++) { if (g_avdtCb.sigCtrl[i] != NULL && handle != 0 && handle == g_avdtCb.sigCtrl[i]->streamCtrl[j].handle) { streamCtrl = &g_avdtCb.sigCtrl[i]->streamCtrl[j]; LOG_DEBUG("[AVDT]%{public}s: chCtrlBlock_i(%{public}d) j(%{public}d), streamhandle(%hu)", __func__, i, j, streamCtrl->handle); return streamCtrl; } } } return streamCtrl; } /** * * @brief AvdtStreamCtrlAllocate * * @details Allocate the stream ctrl block * * @return NULL: No reources; otherwise the pointer * of streamCtrl. * */ AvdtStreamCtrl *AvdtStreamCtrlAllocate(AvdtSigCtrl *sigCtrl, uint16_t codecIndex) { LOG_DEBUG("[AVDT]%{public}s:codecIndex(%hu)", __func__, codecIndex); AvdtStreamCtrl *streamCtrl = NULL; for (int i = 0; i < AVDT_NUM_SEPS; i++) { if (!sigCtrl->streamCtrl[i].isAllocated) { AvdtStreamConfig *config = AvdtGetSepConfigByCodecIndex(codecIndex); if (config != NULL) { streamCtrl = &sigCtrl->streamCtrl[i]; sigCtrl->streamCtrl[i].handle = AvdtAssignStreamHandle(); sigCtrl->streamCtrl[i].isUsed = false; sigCtrl->streamCtrl[i].isAllocated = true; sigCtrl->streamCtrl[i].codecIndex = codecIndex; sigCtrl->streamCtrl[i].sigHandle = sigCtrl->handle; LOG_DEBUG("[AVDT]%{public}s:create stream handle %hu [stream Index:%{public}d] [SepType:%hhu]", __func__, streamCtrl->handle, i, config->sepType); break; } } } return streamCtrl; } /** * * @brief AvdtStreamCtrlDeallocByHandle * * @details Deallocate the stream ctrl data * * @return void * */ void AvdtStreamCtrlDeallocByHandle(AvdtSigCtrl *sigCtrl, uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, handle); for (int i = 0; i < AVDT_NUM_SEPS; i++) { if (sigCtrl->streamCtrl[i].isUsed && sigCtrl->streamCtrl[i].handle == handle) { if (sigCtrl->streamCtrl[i].pkt != NULL) { PacketFree(sigCtrl->streamCtrl[i].pkt); sigCtrl->streamCtrl[i].pkt = NULL; } sigCtrl->streamCtrl[i].isUsed = false; sigCtrl->streamCtrl[i].state = AVDT_IDLE_ST; } } return; } /** * * @brief AvdtStreamCtrlDeallocAll * * @details Deallocate all stream ctrl of the sigCtrl * * @return void * */ void AvdtStreamCtrlDeallocAll(AvdtSigCtrl *sigCtrl) { LOG_DEBUG("[AVDT]%{public}s:", __func__); for (int i = 0; i < AVDT_NUM_SEPS; i++) { if (sigCtrl->streamCtrl[i].isAllocated) { if (sigCtrl->streamCtrl[i].pkt != NULL) { PacketFree(sigCtrl->streamCtrl[i].pkt); sigCtrl->streamCtrl[i].pkt = NULL; } AvdtFreeStreamHandle(sigCtrl->streamCtrl[i].handle); sigCtrl->streamCtrl[i].isAllocated = false; sigCtrl->streamCtrl[i].isUsed = false; } } return; } /** * * @brief AvdtTransChTabAllocate * * @details Allocate the transtation channel ctrl block * * @return NULL: No resources; otherwise the pointer of AvdtTransChannel. * */ AvdtTransChannel *AvdtTransChTabAllocate(uint8_t type, AvdtSigCtrl *sigCtrl, AvdtStreamCtrl *streamCtrl) { LOG_DEBUG("[AVDT]%{public}s: type(%hhu)", __func__, type); AvdtTransChannel *transCh = NULL; for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if (g_avdtCb.transTable[i] != NULL) { continue; } /* Allocate transcation channel table */ transCh = (AvdtTransChannel *)malloc(sizeof(AvdtTransChannel)); if (transCh == NULL) { continue; } g_avdtCb.transTable[i] = transCh; (void)memset_s(g_avdtCb.transTable[i], sizeof(AvdtTransChannel), 0, sizeof(AvdtTransChannel)); /* set the information ralted channel ctrl and stream ctrl */ g_avdtCb.transTable[i]->type = type; g_avdtCb.transTable[i]->cfgFlags = 0; g_avdtCb.transTable[i]->lcid = 0; (void)memcpy_s(&g_avdtCb.transTable[i]->addr, sizeof(BtAddr), &sigCtrl->peerAddress, sizeof(BtAddr)); if (type == AVDT_CH_TYPE_SIG) { g_avdtCb.transTable[i]->sigHandle = sigCtrl->handle; } else { g_avdtCb.transTable[i]->streamHandle = streamCtrl->handle; g_avdtCb.transTable[i]->sigHandle = sigCtrl->handle; } break; } return transCh; } /** * * @brief AvdtGetTransChTabByLcid * * @details Get the transtation channel by lcid * * @return The pointer of transcation channel matched lcid. * */ AvdtTransChannel *AvdtGetTransChTabByLcid(uint16_t lcid) { LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x)", __func__, lcid); AvdtTransChannel *transCh = NULL; for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if ((g_avdtCb.transTable[i] != NULL) && (lcid == g_avdtCb.transTable[i]->lcid)) { transCh = g_avdtCb.transTable[i]; break; } } return transCh; } /** * * @brief AvdtGetTransChTabByAddr * * @details Get the transtation channel by addr * * @return The pointer of transcation channel matched lcid. * */ AvdtTransChannel *AvdtGetTransChTabByAddr(const BtAddr *bdAddr, uint8_t type) { LOG_DEBUG("[AVDT]%{public}s: type(%hhu)", __func__, type); AvdtTransChannel *transCh = NULL; for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if ((g_avdtCb.transTable[i] != NULL) && !memcmp((char *)g_avdtCb.transTable[i]->addr.addr, (char *)&(bdAddr->addr), BT_ADDR_LENGTH) && type == g_avdtCb.transTable[i]->type) { transCh = g_avdtCb.transTable[i]; break; } } return transCh; } /** * * @brief AvdtGetTransChTabByHandle * * @details Get the transtation channel pointer by type and handle. * * @return The pointer of the transcation channel * ******************************************************************************/ AvdtTransChannel *AvdtGetTransChTabByHandle(uint8_t type, uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu) type(%hhu)", __func__, handle, type); AvdtTransChannel *transCh = NULL; for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if ((g_avdtCb.transTable[i] != NULL) && type == g_avdtCb.transTable[i]->type) { if (type == AVDT_CH_TYPE_SIG && handle == g_avdtCb.transTable[i]->sigHandle) { transCh = g_avdtCb.transTable[i]; } else if (type == AVDT_CH_TYPE_STREAM && handle == g_avdtCb.transTable[i]->streamHandle) { transCh = g_avdtCb.transTable[i]; } if (transCh != NULL) { LOG_DEBUG("[AVDT]%{public}s:transCh index(%{public}d)", __func__, i); break; } } } return transCh; } /** * * @brief AvdtTransChTabAllocate * * @details deallocate the transtation channel ctrl block * * @return void * */ void AvdtTransChDealloc(uint16_t lcid) { LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x)", __func__, lcid); for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if ((g_avdtCb.transTable[i] != NULL) && lcid == g_avdtCb.transTable[i]->lcid) { free(g_avdtCb.transTable[i]); g_avdtCb.transTable[i] = NULL; break; } } return; } /** * * @brief AvdtTransChDeallocAll * * @details deallocate all transtation channel ctrl block * * @return void * */ void AvdtTransChDeallocAll(void) { LOG_DEBUG("[AVDT]%{public}s", __func__); for (int i = 0; i < AVDT_CH_TABLE_SIZE; i++) { if (g_avdtCb.transTable[i] != NULL) { free(g_avdtCb.transTable[i]); g_avdtCb.transTable[i] = NULL; } } return; } /** * * @brief AvdtAssignSigHandle * * @details Assign the handle of signal channel control. * * @return The handle of signal channel control . * */ uint16_t AvdtAssignSigHandle(void) { uint16_t Handle = 0; for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (!g_avdtCb.sigHandles[i].isUsed) { Handle = g_avdtCb.sigHandles[i].handle; g_avdtCb.sigHandles[i].isUsed = true; break; } } LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, Handle); return Handle; } /** * * @brief AvdtAssignStreamHandle * * @details Assign the handle of stream channel control. * * @return The handle of stream channel control . * */ uint16_t AvdtAssignStreamHandle(void) { uint16_t Handle = 0; for (int i = 0; i < AVDT_MAX_NUM_SEP; i++) { if (!g_avdtCb.streamHandles[i].isUsed) { Handle = g_avdtCb.streamHandles[i].handle; g_avdtCb.streamHandles[i].isUsed = true; break; } } LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, Handle); return Handle; } /** * * @brief AvdtFreeSigHandle * * @details Free the signal handle. * * @return void. * */ void AvdtFreeSigHandle(uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, handle); for (int i = 0; i < AVDT_NUM_LINKS; i++) { if (g_avdtCb.sigHandles[i].isUsed && g_avdtCb.sigHandles[i].handle == handle) { g_avdtCb.sigHandles[i].isUsed = false; break; } } return; } /** * * @brief AvdtFreeStreamHandle * * @details Free the stream handle. * * @return void. * */ void AvdtFreeStreamHandle(uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, handle); for (int i = 0; i < AVDT_MAX_NUM_SEP; i++) { if (g_avdtCb.streamHandles[i].isUsed && g_avdtCb.streamHandles[i].handle == handle) { g_avdtCb.streamHandles[i].isUsed = false; break; } } return; } /** * * @brief AvdtFreeSigCtrlByHandle * * @details Free the channell. * * @return * */ void AvdtFreeSigCtrlByHandle(uint16_t handle) { LOG_DEBUG("[AVDT]%{public}s: handle(%hu)", __func__, handle); for (int i = 0; i < AVDT_NUM_LINKS; i++) { if ((g_avdtCb.sigCtrl[i] != NULL) && handle == g_avdtCb.sigCtrl[i]->handle) { AvdtFreeSigHandle(g_avdtCb.sigCtrl[i]->handle); if (g_avdtCb.sigCtrl[i]->currentMsg != NULL) { PacketFree(g_avdtCb.sigCtrl[i]->currentMsg); g_avdtCb.sigCtrl[i]->currentMsg = NULL; } if (g_avdtCb.sigCtrl[i]->rxMsg != NULL) { PacketFree(g_avdtCb.sigCtrl[i]->rxMsg); g_avdtCb.sigCtrl[i]->rxMsg = NULL; } if (g_avdtCb.sigCtrl[i] != NULL) { free(g_avdtCb.sigCtrl[i]); g_avdtCb.sigCtrl[i] = NULL; } LOG_DEBUG("[AVDT]%{public}s: Free channel handle(%hu)", __func__, handle); break; } } } /** * * @brief AvdtCreateTransLabel * * @details Create the transport label to mark message * * @return The transport label of signalling message * */ uint8_t AvdtCreateTransLabel(AvdtSigCtrl *sigCtrl) { LOG_DEBUG("[AVDT]%{public}s:", __func__); uint8_t TransLabel = (++sigCtrl->label) % AVDT_LABEL_MAX; return TransLabel; } /** * * @brief AvdtCreateHandle * * @details Allocate the sequence number of media packet. * * @return The sequence number of media packet. * */ uint16_t AvdtCreateSequenceNo(AvdtStreamCtrl *avdtStreamCtrl) { LOG_DEBUG("[AVDT]%{public}s:", __func__); uint16_t Sn = (avdtStreamCtrl->mediaSeq++) % AVDT_MEDIA_SEQ_MAX; return Sn; } /** * * @brief AvdtCtrlEvtCallback * * @details Control event callback to upper app. * * @return void. * */ NO_SANITIZE("cfi") void AvdtCtrlEvtCallback( AvdtSigCtrl *sigCtrl, uint16_t handle, const BtAddr *bdAddr, uint8_t event, const AvdtCtrlData *data, uint8_t role) { if (sigCtrl->procCback != NULL) { LOG_DEBUG("[AVDT]----------%{public}s: handle(%hu) EventId(%hhu), role(%hhu)", __func__, handle, event, role); sigCtrl->procCback(handle, bdAddr, event, data, role); } return; } /** * * @brief AvdtCreateSEP * @details Create a stream endpoint. * @return AVDT_SUCCESS if successful, otherwise error. * */ uint16_t AvdtCreateSEP(const BtAddr *bdAddr) { LOG_INFO("[AVDT]%{public}s:bdAddr((%02x:%02x:%02x:%02x:%02x:%02x)", __func__, BT_ADDR_FMT_DSC(bdAddr->addr)); uint16_t Ret = AVDT_SUCCESS; AvdtSigCtrl *sigCtrl = NULL; AvdtStreamCtrl *streamCtrl = NULL; /* Allocate channel ctrl and stream ctrl */ for (int i = 0; i < AVDT_NUM_SEPS; i++) { if (!g_avdtCb.localSEP[i].isExited) { continue; } sigCtrl = AvdtGetSigCtrlByAddr(bdAddr); if (sigCtrl == NULL) { sigCtrl = AvdtSigCtrlAllocate(bdAddr, AVDT_ROLE_UNKOWN); if (sigCtrl == NULL) { Ret = AVDT_NO_RESOURCES; return Ret; } } streamCtrl = AvdtStreamCtrlAllocate(sigCtrl, g_avdtCb.localSEP[i].localConfigure.codecIndex); if (streamCtrl == NULL) { Ret = AVDT_NO_RESOURCES; } else { LOG_DEBUG("[AVDT]%{public}s: streamCtrl->handle(%hu)", __func__, streamCtrl->handle); } if (Ret != AVDT_SUCCESS) { LOG_WARN("[AVDT]%{public}s: Ret(%hu)", __func__, Ret); } } return Ret; } /** * * @brief AvdtCheckSepExited * @details Check the sep is used. * @return the index of the used sep. else 0 * */ uint16_t AvdtCheckSepExited(uint16_t codecIndex) { LOG_DEBUG("[AVDT]%{public}s:codecIndex(%hu)", __func__, codecIndex); int sepId; for (sepId = 0; sepId < AVDT_NUM_SEPS; sepId++) { if (g_avdtCb.localSEP[sepId].isExited) { if ((codecIndex != 0) && (codecIndex == g_avdtCb.localSEP[sepId].localConfigure.codecIndex)) { break; } } } return sepId; } /** * * @brief AvdtSepAlloc * @details Allock Sep resourse. * @return the index of the sep. else 0 * */ uint16_t AvdtSepAlloc(AvdtStreamConfig *avdtStreamConfig) { LOG_DEBUG("[AVDT]%{public}s:", __func__); int sepId; for (sepId = 0; sepId < AVDT_NUM_SEPS; sepId++) { if (!g_avdtCb.localSEP[sepId].isExited) { (void)memcpy_s(&g_avdtCb.localSEP[sepId].localConfigure, sizeof(AvdtStreamConfig), avdtStreamConfig, sizeof(AvdtStreamConfig)); g_avdtCb.localSEP[sepId].isExited = true; LOG_DEBUG("[AVDT]%{public}s: localSEP(%{public}d): codecIndex(%hu) sepType(%hhu))", __func__, sepId, avdtStreamConfig->codecIndex, avdtStreamConfig->sepType); break; } } return sepId; } /** * * @brief AvdtGetSepConfigByCodecIndex * @details Get the sep config by codec index. * @return sep config info or NULL. * */ AvdtStreamConfig *AvdtGetSepConfigByCodecIndex(uint16_t codecIndex) { LOG_DEBUG("[AVDT]%{public}s: codecIndex(%hu)", __func__, codecIndex); AvdtStreamConfig *config = NULL; for (int i = 0; i < AVDT_NUM_SEPS; i++) { if (g_avdtCb.localSEP[i].isExited) { if (g_avdtCb.localSEP[i].localConfigure.codecIndex == codecIndex) { LOG_DEBUG("[AVDT]%{public}s:localSepIndex(%{public}d):", __func__, i); config = &g_avdtCb.localSEP[i].localConfigure; break; } } } return config; } /** * * @brief AvdtCheckSepIsUsed * @details Check if the sep is used. * @return Used:Sep ID Unused: 0. * */ uint16_t AvdtCheckSepIsUsed(AvdtSigCtrl *sigCtrl, uint16_t codecIndex) { LOG_DEBUG("[AVDT]%{public}s: codecIndex(%hu)", __func__, codecIndex); uint16_t Handle = 0; for (int i = 0; i < AVDT_NUM_SEPS; i++) { if ((sigCtrl->streamCtrl[i].isAllocated) && (codecIndex != 0) && (codecIndex == sigCtrl->streamCtrl[i].codecIndex)) { Handle = sigCtrl->streamCtrl[i].handle; break; } } return Handle; } uint8_t AvdtAsyncProcess(void (*callback)(void *context), void *context) { if (BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_AVDTP, callback, context)) { return AVDT_FAILED; } return AVDT_SUCCESS; } uint16_t AvdtGetMtu(void) { return g_avdtCb.regInfo.mtu; } void AvdtRegister(const AvdtRegisterParam *reg) { LOG_DEBUG("[AVDT]%{public}s:", __func__); if (!g_avdtCb.avdtRegisted) { g_avdtCb.regInfo = *reg; } g_avdtCb.avdtRegisted = true; return; } uint16_t AvdtRegisterLocalSEP(AvdtStreamConfig *avdtStreamConfig, uint8_t number) { LOG_DEBUG("[AVDT]%{public}s:", __func__); uint16_t Ret = AVDT_SUCCESS; if (g_avdtCb.sepRegisted) { LOG_WARN("[AVDT]%{public}s: Stream endpoint had been registered ", __func__); return Ret; } g_avdtCb.sepRegisted = true; /* judge avdt Ind,Cfm callback and service capabilities */ for (int i = 0; i < number; i++) { if (avdtStreamConfig[i].cfg.pscMask == 0 || ((avdtStreamConfig[i].cfg.pscMask & (~AVDT_PSC_MSK)) != 0)) { LOG_WARN("[AVDT]%{public}s: service capabilities(0x%x) is invalid", __func__, avdtStreamConfig[i].cfg.pscMask); Ret = AVDT_BAD_PARAMS; return Ret; } else { if (AvdtCheckSepExited(avdtStreamConfig[i].codecIndex) < AVDT_NUM_SEPS) { LOG_INFO("[AVDT]%{public}s: The sep(%hu) had registered ", __func__, avdtStreamConfig[i].codecIndex); } else if (AvdtSepAlloc(&avdtStreamConfig[i]) == AVDT_NUM_SEPS) { LOG_WARN("[AVDT]%{public}s: No resources for scbHandle(%hu)", __func__, avdtStreamConfig[i].codecIndex); Ret = AVDT_NO_RESOURCES; } } } return Ret; } typedef struct { BtAddr addr; bool support; } AvdtRemoteDeviceSupportCallbackParam; static void AvdtRemoteDeviceSupport2MbCallbackTask(void *ctx) { AvdtRemoteDeviceSupportCallbackParam *param = (AvdtRemoteDeviceSupportCallbackParam *)ctx; if (param->support) { AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByAddr(¶m->addr); if (NULL != sigCtrl) { sigCtrl->edr = (sigCtrl->edr) | AVDT_2MB_MODE; LOG_INFO("[AVDT]%{public}s: edr(%hhu)", __func__, sigCtrl->edr); } } free(ctx); } static void AvdtRecvRemoteDeviceSupport2MbCallback(const BtAddr *addr, bool support) { LOG_INFO("[AVDT]%{public}s: addr(%02x:%02x:%02x:%02x:%02x:%02x),support(%{public}d)", __func__, BT_ADDR_FMT_DSC(addr->addr), support); AvdtRemoteDeviceSupportCallbackParam *supportParam = malloc(sizeof(AvdtRemoteDeviceSupportCallbackParam)); if (supportParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } supportParam->addr = *addr; supportParam->support = support; int ret = AvdtAsyncProcess(AvdtRemoteDeviceSupport2MbCallbackTask, supportParam); if (ret != AVDT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } static void AvdtRemoteDeviceSupport3MbCallbackTask(void *ctx) { AvdtRemoteDeviceSupportCallbackParam *param = (AvdtRemoteDeviceSupportCallbackParam *)ctx; if (param->support) { AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByAddr(¶m->addr); if (NULL != sigCtrl) { sigCtrl->edr = (sigCtrl->edr) | AVDT_3MB_MODE; LOG_INFO("[AVDT]%{public}s: edr(%hhu)", __func__, sigCtrl->edr); } } free(ctx); } static void AvdtRecvRemoteDeviceSupport3MbCallback(const BtAddr *addr, bool support) { LOG_INFO( "[AVDT]%{public}s: addr(%02x:%02x:%02x:%02x:%02x:%02x),support(%{public}d)", __func__, BT_ADDR_FMT_DSC(addr->addr), support); AvdtRemoteDeviceSupportCallbackParam *supportParam = malloc(sizeof(AvdtRemoteDeviceSupportCallbackParam)); if (supportParam == NULL) { LOG_ERROR("%{public}s: Alloc error.", __FUNCTION__); return; } supportParam->addr = *addr; supportParam->support = support; int ret = AvdtAsyncProcess(AvdtRemoteDeviceSupport3MbCallbackTask, supportParam); if (ret != AVDT_SUCCESS) { LOG_ERROR("%{public}s: Task error:%{public}d.", __FUNCTION__, ret); } } void AvdtIsEdr2MbMode(const BtAddr *bdAddr) { LOG_INFO("[AVDT]%{public}s: addr(%02x:%02x:%02x:%02x:%02x:%02x)", __func__, BT_ADDR_FMT_DSC(bdAddr->addr)); BTM_IsRemoteDeviceSupportEdrAcl2MbMode(bdAddr, AvdtRecvRemoteDeviceSupport2MbCallback); } void AvdtIsEdr3MbMode(const BtAddr *bdAddr) { LOG_INFO("[AVDT]%{public}s: addr(%02x:%02x:%02x:%02x:%02x:%02x)", __func__, BT_ADDR_FMT_DSC(bdAddr->addr)); BTM_IsRemoteDeviceSupportEdrAcl3MbMode(bdAddr, AvdtRecvRemoteDeviceSupport3MbCallback); }