1 /* 2 * Copyright 2019 HIMSA II K/S - www.himsa.com. Represented by EHIMA - 3 * www.ehima.com 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 * This file contains the Audio Stream Control (LE_AUDIO) API function external 20 * definitions. 21 */ 22 23 #pragma once 24 25 #include <vector> 26 27 #include "le_audio_types.h" 28 29 namespace bluetooth::le_audio { 30 namespace client_parser { 31 namespace ascs { 32 /* 33 * All structures and defines are described in Audio Stream Control Service 34 * specification 35 */ 36 37 constexpr uint8_t kCtpResponseCodeSuccess = 0x00; 38 constexpr uint8_t kCtpResponseCodeUnsupportedOpcode = 0x01; 39 constexpr uint8_t kCtpResponseCodeInvalidLength = 0x02; 40 constexpr uint8_t kCtpResponseCodeInvalidAseId = 0x03; 41 constexpr uint8_t kCtpResponseCodeInvalidAseStateMachineTransition = 0x04; 42 constexpr uint8_t kCtpResponseCodeInvalidAseDirection = 0x05; 43 constexpr uint8_t kCtpResponseCodeUnsupportedAudioCapabilities = 0x06; 44 constexpr uint8_t kCtpResponseCodeUnsupportedConfigurationParameterValue = 0x07; 45 constexpr uint8_t kCtpResponseCodeRejectedConfigurationParameterValue = 0x08; 46 constexpr uint8_t kCtpResponseCodeInvalidConfigurationParameterValue = 0x09; 47 constexpr uint8_t kCtpResponseCodeUnsupportedMetadata = 0x0A; 48 constexpr uint8_t kCtpResponseCodeRejectedMetadata = 0x0B; 49 constexpr uint8_t kCtpResponseCodeInvalidMetadata = 0x0C; 50 constexpr uint8_t kCtpResponseCodeInsufficientResources = 0x0D; 51 constexpr uint8_t kCtpResponseCodeUnspecifiedError = 0x0E; 52 53 constexpr uint8_t kCtpResponseNoReason = 0x00; 54 constexpr uint8_t kCtpResponseCodecId = 0x01; 55 constexpr uint8_t kCtpResponseCodecSpecificConfiguration = 0x02; 56 constexpr uint8_t kCtpResponseSduInterval = 0x03; 57 constexpr uint8_t kCtpResponseFraming = 0x04; 58 constexpr uint8_t kCtpResponsePhy = 0x05; 59 constexpr uint8_t kCtpResponseMaximumSduSize = 0x06; 60 constexpr uint8_t kCtpResponseRetransmissionNumber = 0x07; 61 constexpr uint8_t kCtpResponseMaxTransportLatency = 0x08; 62 constexpr uint8_t kCtpResponsePresentationDelay = 0x09; 63 constexpr uint8_t kCtpResponseInvalidAseCisMapping = 0x0A; 64 65 constexpr uint8_t kCtpMetadataResponsePreferredAudioContexts = 0x01; 66 constexpr uint8_t kCtpMetadataResponseStreamingAudioContexts = 0x02; 67 constexpr uint8_t kCtpMetadataResponseProgramInfo = 0x03; 68 constexpr uint8_t kCtpMetadataResponseLanguage = 0x04; 69 constexpr uint8_t kCtpMetadataResponseCcidList = 0x05; 70 constexpr uint8_t kCtpMetadataResponseParentalRating = 0x06; 71 constexpr uint8_t kCtpMetadataResponseProgramInfoUri = 0x07; 72 constexpr uint8_t kCtpMetadataResponseExtendedMetadata = 0xFE; 73 constexpr uint8_t kCtpMetadataResponseVendorSpecific = 0xFF; 74 75 constexpr uint8_t kLeAudioErrorCtpUnsupporterdOpcode = 0xFF; 76 constexpr uint8_t kLeAudioErrorCtpTruncatedOperation = 0xFE; 77 constexpr uint8_t kLeAudioErrorCtpCtpErr = 0xFD; 78 79 /* ASE states */ 80 constexpr uint8_t kAseStateIdle = 0x00; 81 constexpr uint8_t kAseStateCodecConfigured = 0x01; 82 constexpr uint8_t kAseStateQosConfigured = 0x02; 83 constexpr uint8_t kAseStateEnabling = 0x03; 84 constexpr uint8_t kAseStateStreaming = 0x04; 85 constexpr uint8_t kAseStateDisabling = 0x05; 86 constexpr uint8_t kAseStateReleasing = 0x06; 87 88 /* Control point opcodes */ 89 constexpr uint8_t kCtpOpcodeCodecConfiguration = 0x01; 90 constexpr uint8_t kCtpOpcodeQosConfiguration = 0x02; 91 constexpr uint8_t kCtpOpcodeEnable = 0x03; 92 constexpr uint8_t kCtpOpcodeReceiverStartReady = 0x04; 93 constexpr uint8_t kCtpOpcodeDisable = 0x05; 94 constexpr uint8_t kCtpOpcodeReceiverStopReady = 0x06; 95 constexpr uint8_t kCtpOpcodeUpdateMetadata = 0x07; 96 constexpr uint8_t kCtpOpcodeRelease = 0x08; 97 98 /* ASE status masks */ 99 static constexpr uint32_t kAseRspHeaderMaskCtrlStatusFailureOpcode = 0x00FF0000; 100 static constexpr uint32_t kAseRspHeaderMaskCtrlStatusErrorCode = 0x0000FF00; 101 static constexpr uint32_t kAseRspHeaderMaskCtrlStatusErrorReason = 0x000000FF; 102 103 constexpr uint16_t kAseStatusCodecConfMinLen = 23; 104 struct ase_codec_configured_state_params { 105 uint8_t framing; 106 uint8_t preferred_phy; 107 uint8_t preferred_retrans_nb; 108 uint16_t max_transport_latency; 109 uint32_t pres_delay_min; 110 uint32_t pres_delay_max; 111 uint32_t preferred_pres_delay_min; 112 uint32_t preferred_pres_delay_max; 113 types::LeAudioCodecId codec_id; 114 std::vector<uint8_t> codec_spec_conf; 115 }; 116 117 constexpr uint16_t kAseStatusCodecQosConfMinLen = 15; 118 struct ase_qos_configured_state_params { 119 uint8_t cig_id; 120 uint8_t cis_id; 121 uint32_t sdu_interval; 122 uint8_t framing; 123 uint8_t phy; 124 uint16_t max_sdu; 125 uint8_t retrans_nb; 126 uint16_t max_transport_latency; 127 uint32_t pres_delay; 128 }; 129 130 constexpr uint16_t kAseStatusTransMinLen = 3; 131 struct ase_transient_state_params { 132 uint8_t cig_id; 133 uint8_t cis_id; 134 std::vector<uint8_t> metadata; 135 }; 136 137 constexpr uint16_t kCtpAseEntryMinLen = 3; 138 struct ctp_ase_entry { 139 uint8_t ase_id; 140 uint8_t response_code; 141 uint8_t reason; 142 }; 143 144 constexpr uint16_t kCtpNtfMinLen = 2; 145 struct ctp_ntf { 146 uint8_t op; 147 std::vector<struct ctp_ase_entry> entries; 148 }; 149 150 constexpr uint16_t kAseRspHdrMinLen = 2; 151 struct ase_rsp_hdr { 152 uint8_t id; 153 uint8_t state; 154 }; 155 156 constexpr uint8_t kCtpOpSize = 1; 157 constexpr uint8_t kAseNumSize = 1; 158 constexpr uint8_t kAseIdSize = 1; 159 160 constexpr uint16_t kCtpCodecConfMinLen = 9; 161 struct ctp_codec_conf { 162 uint8_t ase_id; 163 uint8_t target_latency; 164 uint8_t target_phy; 165 types::LeAudioCodecId codec_id; 166 std::vector<uint8_t> codec_config; 167 }; 168 169 constexpr uint16_t kCtpQosConfMinLen = 16; 170 struct ctp_qos_conf { 171 uint8_t ase_id; 172 uint8_t cig; 173 uint8_t cis; 174 uint32_t sdu_interval; 175 uint8_t framing; 176 uint8_t phy; 177 uint16_t max_sdu; 178 uint8_t retrans_nb; 179 uint16_t max_transport_latency; 180 uint32_t pres_delay; 181 }; 182 183 constexpr uint16_t kCtpEnableMinLen = 2; 184 struct ctp_enable { 185 uint8_t ase_id; 186 std::vector<uint8_t> metadata; 187 }; 188 189 constexpr uint16_t kCtpUpdateMetadataMinLen = 2; 190 struct ctp_update_metadata { 191 uint8_t ase_id; 192 std::vector<uint8_t> metadata; 193 }; 194 195 /* Device control and common functions */ 196 bool ParseAseStatusHeader(ase_rsp_hdr& rsp, uint16_t len, const uint8_t* value); 197 bool ParseAseStatusCodecConfiguredStateParams( 198 struct ase_codec_configured_state_params& rsp, uint16_t len, 199 const uint8_t* value); 200 bool ParseAseStatusQosConfiguredStateParams( 201 struct ase_qos_configured_state_params& rsp, uint16_t len, 202 const uint8_t* value); 203 bool ParseAseStatusTransientStateParams(struct ase_transient_state_params& rsp, 204 uint16_t len, const uint8_t* value); 205 bool ParseAseCtpNotification(struct ctp_ntf& ntf, uint16_t len, 206 const uint8_t* value); 207 bool PrepareAseCtpCodecConfig(const std::vector<struct ctp_codec_conf>& confs, 208 std::vector<uint8_t>& value); 209 bool PrepareAseCtpConfigQos(const std::vector<struct ctp_qos_conf>& confs, 210 std::vector<uint8_t>& value); 211 bool PrepareAseCtpEnable(const std::vector<struct ctp_enable>& confs, 212 std::vector<uint8_t>& value); 213 bool PrepareAseCtpAudioReceiverStartReady(const std::vector<uint8_t>& ids, 214 std::vector<uint8_t>& value); 215 bool PrepareAseCtpDisable(const std::vector<uint8_t>& ids, 216 std::vector<uint8_t>& value); 217 bool PrepareAseCtpAudioReceiverStopReady(const std::vector<uint8_t>& ids, 218 std::vector<uint8_t>& value); 219 bool PrepareAseCtpUpdateMetadata( 220 const std::vector<struct ctp_update_metadata>& confs, 221 std::vector<uint8_t>& value); 222 bool PrepareAseCtpRelease(const std::vector<uint8_t>& ids, 223 std::vector<uint8_t>& value); 224 } // namespace ascs 225 226 namespace pacs { 227 228 constexpr uint16_t kAcsPacRecordMinLen = 7; 229 constexpr uint8_t kAcsPacMetadataLenLen = 1; 230 constexpr uint16_t kAcsPacDiscoverRspMinLen = 1; 231 232 constexpr uint16_t kAudioLocationsRspMinLen = 4; 233 234 constexpr uint16_t kAseAudioAvailRspMinLen = 4; 235 236 constexpr uint16_t kAseAudioSuppContRspMinLen = 4; 237 238 int ParseSinglePac(std::vector<struct types::acs_ac_record>& pac_recs, 239 uint16_t len, const uint8_t* value); 240 bool ParsePacs(std::vector<struct types::acs_ac_record>& pac_recs, uint16_t len, 241 const uint8_t* value); 242 bool ParseAudioLocations(types::AudioLocations& audio_locations, uint16_t len, 243 const uint8_t* value); 244 bool ParseAvailableAudioContexts( 245 types::BidirectionalPair<types::AudioContexts>& rsp, uint16_t len, 246 const uint8_t* value); 247 bool ParseSupportedAudioContexts( 248 types::BidirectionalPair<types::AudioContexts>& rsp, uint16_t len, 249 const uint8_t* value); 250 } // namespace pacs 251 252 namespace tmap { 253 254 constexpr uint16_t kTmapRoleLen = 2; 255 256 bool ParseTmapRole(std::bitset<16>& role, uint16_t len, const uint8_t* value); 257 258 } // namespace tmap 259 } // namespace client_parser 260 } // namespace bluetooth::le_audio 261