1 /*
2 * Copyright 2020 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 definitions for Basic Audio Profile / Audio Stream Control
20 * and Published Audio Capabilities definitions, structures etc.
21 */
22
23 #pragma once
24
25 #include <bluetooth/log.h>
26 #include <stdint.h>
27
28 #include <bitset>
29 #include <map>
30 #include <optional>
31 #include <string>
32 #include <variant>
33 #include <vector>
34
35 #include "bluetooth/uuid.h"
36 #include "bta/include/bta_le_audio_uuids.h"
37 #include "osi/include/alarm.h"
38 #include "stack/include/bt_types.h"
39 #include "stack/include/btm_iso_api_types.h"
40
41 namespace bluetooth::le_audio {
42
43 #define UINT8_TO_VEC_UINT8(u8) \
44 std::vector<uint8_t> { u8 }
45 #define UINT16_TO_VEC_UINT8(u16) \
46 std::vector<uint8_t>((uint8_t*)&u16, (uint8_t*)&u16 + sizeof(uint16_t))
47 #define UINT32_TO_VEC_UINT8(u32) \
48 std::vector<uint8_t>((uint8_t*)&u32, (uint8_t*)&u32 + sizeof(uint32_t))
49
50 #define VEC_UINT8_TO_UINT8(vec) vec.data()[0]
51 #define VEC_UINT8_TO_UINT16(vec) ((vec.data()[1] << 8) + vec.data()[0])
52 #define OFF_VEC_UINT8_TO_UINT16(vec, off) \
53 ((vec.data()[1 + off] << 8) + vec.data()[0 + off])
54 #define VEC_UINT8_TO_UINT32(vec) \
55 ((vec.data()[3] << 24) + (vec.data()[2] << 16) + (vec.data()[1] << 8) + \
56 vec.data()[0])
57
58 enum class DsaMode { DISABLED = 0, ACL, ISO_SW, ISO_HW };
59 typedef std::vector<DsaMode> DsaModes;
60
61 namespace uuid {
62 /* CAP service
63 * This service is used to identify peer role (which we are not using for now)
64 * and to wrap CSIS service as this is required to understand the context of the
65 * CSIS
66 */
67 static const bluetooth::Uuid kCapServiceUuid =
68 bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE);
69
70 /* Assigned numbers for attributes */
71 static const bluetooth::Uuid kPublishedAudioCapabilityServiceUuid =
72 bluetooth::Uuid::From16Bit(0x1850);
73 static const bluetooth::Uuid kAudioStreamControlServiceUuid =
74 bluetooth::Uuid::From16Bit(0x184E);
75
76 static const bluetooth::Uuid kTelephonyMediaAudioServiceUuid =
77 bluetooth::Uuid::From16Bit(0x1855);
78
79 /* Published Audio Capabilities Service Characteristics */
80 static const bluetooth::Uuid kSinkPublishedAudioCapabilityCharacteristicUuid =
81 bluetooth::Uuid::From16Bit(0x2BC9);
82 static const bluetooth::Uuid kSourcePublishedAudioCapabilityCharacteristicUuid =
83 bluetooth::Uuid::From16Bit(0x2BCB);
84 static const bluetooth::Uuid kSinkAudioLocationCharacteristicUuid =
85 bluetooth::Uuid::From16Bit(0x2BCA);
86 static const bluetooth::Uuid kSourceAudioLocationCharacteristicUuid =
87 bluetooth::Uuid::From16Bit(0x2BCC);
88
89 /* Audio Stream Control Service Characteristics */
90 static const bluetooth::Uuid kAudioContextAvailabilityCharacteristicUuid =
91 bluetooth::Uuid::From16Bit(0x2BCD);
92 static const bluetooth::Uuid kAudioSupportedContextCharacteristicUuid =
93 bluetooth::Uuid::From16Bit(0x2BCE);
94
95 /* Audio Stream Control Service Characteristics */
96 static const bluetooth::Uuid kSinkAudioStreamEndpointUuid =
97 bluetooth::Uuid::From16Bit(0x2BC4);
98 static const bluetooth::Uuid kSourceAudioStreamEndpointUuid =
99 bluetooth::Uuid::From16Bit(0x2BC5);
100 static const bluetooth::Uuid
101 kAudioStreamEndpointControlPointCharacteristicUuid =
102 bluetooth::Uuid::From16Bit(0x2BC6);
103
104 /* Telephony and Media Audio Service Characteristics */
105 static const bluetooth::Uuid kTelephonyMediaAudioProfileRoleCharacteristicUuid =
106 bluetooth::Uuid::From16Bit(0x2B51);
107 } // namespace uuid
108
109 namespace codec_spec_conf {
110 /* LTV Types */
111 constexpr uint8_t kLeAudioLtvTypeSamplingFreq = 0x01;
112 constexpr uint8_t kLeAudioLtvTypeFrameDuration = 0x02;
113 constexpr uint8_t kLeAudioLtvTypeAudioChannelAllocation = 0x03;
114 constexpr uint8_t kLeAudioLtvTypeOctetsPerCodecFrame = 0x04;
115 constexpr uint8_t kLeAudioLtvTypeCodecFrameBlocksPerSdu = 0x05;
116
117 /* Sampling Frequencies */
118 constexpr uint8_t kLeAudioSamplingFreq8000Hz = 0x01;
119 constexpr uint8_t kLeAudioSamplingFreq11025Hz = 0x02;
120 constexpr uint8_t kLeAudioSamplingFreq16000Hz = 0x03;
121 constexpr uint8_t kLeAudioSamplingFreq22050Hz = 0x04;
122 constexpr uint8_t kLeAudioSamplingFreq24000Hz = 0x05;
123 constexpr uint8_t kLeAudioSamplingFreq32000Hz = 0x06;
124 constexpr uint8_t kLeAudioSamplingFreq44100Hz = 0x07;
125 constexpr uint8_t kLeAudioSamplingFreq48000Hz = 0x08;
126 constexpr uint8_t kLeAudioSamplingFreq88200Hz = 0x09;
127 constexpr uint8_t kLeAudioSamplingFreq96000Hz = 0x0A;
128 constexpr uint8_t kLeAudioSamplingFreq176400Hz = 0x0B;
129 constexpr uint8_t kLeAudioSamplingFreq192000Hz = 0x0C;
130 constexpr uint8_t kLeAudioSamplingFreq384000Hz = 0x0D;
131
132 /* Frame Durations */
133 constexpr uint8_t kLeAudioCodecFrameDur7500us = 0x00;
134 constexpr uint8_t kLeAudioCodecFrameDur10000us = 0x01;
135
136 /* Audio Allocations */
137 constexpr uint32_t kLeAudioLocationNotAllowed = 0x00000000;
138 constexpr uint32_t kLeAudioLocationFrontLeft = 0x00000001;
139 constexpr uint32_t kLeAudioLocationFrontRight = 0x00000002;
140 constexpr uint32_t kLeAudioLocationFrontCenter = 0x00000004;
141 constexpr uint32_t kLeAudioLocationLowFreqEffects1 = 0x00000008;
142 constexpr uint32_t kLeAudioLocationBackLeft = 0x00000010;
143 constexpr uint32_t kLeAudioLocationBackRight = 0x00000020;
144 constexpr uint32_t kLeAudioLocationFrontLeftOfCenter = 0x00000040;
145 constexpr uint32_t kLeAudioLocationFrontRightOfCenter = 0x00000080;
146 constexpr uint32_t kLeAudioLocationBackCenter = 0x00000100;
147 constexpr uint32_t kLeAudioLocationLowFreqEffects2 = 0x00000200;
148 constexpr uint32_t kLeAudioLocationSideLeft = 0x00000400;
149 constexpr uint32_t kLeAudioLocationSideRight = 0x00000800;
150 constexpr uint32_t kLeAudioLocationTopFrontLeft = 0x00001000;
151 constexpr uint32_t kLeAudioLocationTopFrontRight = 0x00002000;
152 constexpr uint32_t kLeAudioLocationTopFrontCenter = 0x00004000;
153 constexpr uint32_t kLeAudioLocationTopCenter = 0x00008000;
154 constexpr uint32_t kLeAudioLocationTopBackLeft = 0x00010000;
155 constexpr uint32_t kLeAudioLocationTopBackRight = 0x00020000;
156 constexpr uint32_t kLeAudioLocationTopSideLeft = 0x00040000;
157 constexpr uint32_t kLeAudioLocationTopSideRight = 0x00080000;
158 constexpr uint32_t kLeAudioLocationTopBackCenter = 0x00100000;
159 constexpr uint32_t kLeAudioLocationBottomFrontCenter = 0x00200000;
160 constexpr uint32_t kLeAudioLocationBottomFrontLeft = 0x00400000;
161 constexpr uint32_t kLeAudioLocationBottomFrontRight = 0x00800000;
162 constexpr uint32_t kLeAudioLocationFrontLeftWide = 0x01000000;
163 constexpr uint32_t kLeAudioLocationFrontRightWide = 0x02000000;
164 constexpr uint32_t kLeAudioLocationLeftSurround = 0x04000000;
165 constexpr uint32_t kLeAudioLocationRightSurround = 0x08000000;
166
167 constexpr uint32_t kLeAudioLocationAnyLeft =
168 kLeAudioLocationFrontLeft | kLeAudioLocationBackLeft |
169 kLeAudioLocationFrontLeftOfCenter | kLeAudioLocationSideLeft |
170 kLeAudioLocationTopFrontLeft | kLeAudioLocationTopBackLeft |
171 kLeAudioLocationTopSideLeft | kLeAudioLocationBottomFrontLeft |
172 kLeAudioLocationFrontLeftWide | kLeAudioLocationLeftSurround;
173
174 constexpr uint32_t kLeAudioLocationAnyRight =
175 kLeAudioLocationFrontRight | kLeAudioLocationBackRight |
176 kLeAudioLocationFrontRightOfCenter | kLeAudioLocationSideRight |
177 kLeAudioLocationTopFrontRight | kLeAudioLocationTopBackRight |
178 kLeAudioLocationTopSideRight | kLeAudioLocationBottomFrontRight |
179 kLeAudioLocationFrontRightWide | kLeAudioLocationRightSurround;
180
181 constexpr uint32_t kLeAudioLocationStereo =
182 kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight;
183
184 /* Octets Per Frame */
185 constexpr uint16_t kLeAudioCodecFrameLen30 = 30;
186 constexpr uint16_t kLeAudioCodecFrameLen40 = 40;
187 constexpr uint16_t kLeAudioCodecFrameLen60 = 60;
188 constexpr uint16_t kLeAudioCodecFrameLen80 = 80;
189 constexpr uint16_t kLeAudioCodecFrameLen100 = 100;
190 constexpr uint16_t kLeAudioCodecFrameLen120 = 120;
191
192 } // namespace codec_spec_conf
193
194 constexpr uint8_t kInvalidCisId = 0xFF;
195
196 namespace codec_spec_caps {
SamplingFreqConfig2Capability(uint8_t conf)197 uint16_t constexpr SamplingFreqConfig2Capability(uint8_t conf) {
198 return (1 << (conf - 1));
199 }
200
FrameDurationConfig2Capability(uint8_t conf)201 uint8_t constexpr FrameDurationConfig2Capability(uint8_t conf) {
202 return (0x01 << (conf));
203 }
204
205 /* LTV Types - same values as in Codec Specific Configurations but 0x03 is
206 * named differently.
207 */
208 constexpr uint8_t kLeAudioLtvTypeSupportedSamplingFrequencies =
209 codec_spec_conf::kLeAudioLtvTypeSamplingFreq;
210 constexpr uint8_t kLeAudioLtvTypeSupportedFrameDurations =
211 codec_spec_conf::kLeAudioLtvTypeFrameDuration;
212 constexpr uint8_t kLeAudioLtvTypeSupportedAudioChannelCounts =
213 codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation;
214 constexpr uint8_t kLeAudioLtvTypeSupportedOctetsPerCodecFrame =
215 codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame;
216 constexpr uint8_t kLeAudioLtvTypeSupportedMaxCodecFramesPerSdu =
217 codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu;
218
219 /* Sampling Frequencies */
220 constexpr uint16_t kLeAudioSamplingFreq8000Hz =
221 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq8000Hz);
222 constexpr uint16_t kLeAudioSamplingFreq11025Hz =
223 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq11025Hz);
224 constexpr uint16_t kLeAudioSamplingFreq16000Hz =
225 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq16000Hz);
226 constexpr uint16_t kLeAudioSamplingFreq22050Hz =
227 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq22050Hz);
228 constexpr uint16_t kLeAudioSamplingFreq24000Hz =
229 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq24000Hz);
230 constexpr uint16_t kLeAudioSamplingFreq32000Hz =
231 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq32000Hz);
232 constexpr uint16_t kLeAudioSamplingFreq44100Hz =
233 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq44100Hz);
234 constexpr uint16_t kLeAudioSamplingFreq48000Hz =
235 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq48000Hz);
236 constexpr uint16_t kLeAudioSamplingFreq88200Hz =
237 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq88200Hz);
238 constexpr uint16_t kLeAudioSamplingFreq96000Hz =
239 SamplingFreqConfig2Capability(codec_spec_conf::kLeAudioSamplingFreq96000Hz);
240 constexpr uint16_t kLeAudioSamplingFreq176400Hz = SamplingFreqConfig2Capability(
241 codec_spec_conf::kLeAudioSamplingFreq176400Hz);
242 constexpr uint16_t kLeAudioSamplingFreq192000Hz = SamplingFreqConfig2Capability(
243 codec_spec_conf::kLeAudioSamplingFreq192000Hz);
244 constexpr uint16_t kLeAudioSamplingFreq384000Hz = SamplingFreqConfig2Capability(
245 codec_spec_conf::kLeAudioSamplingFreq384000Hz);
246
247 /* Frame Durations */
248 constexpr uint8_t kLeAudioCodecFrameDur7500us = FrameDurationConfig2Capability(
249 codec_spec_conf::kLeAudioCodecFrameDur7500us);
250 constexpr uint8_t kLeAudioCodecFrameDur10000us = FrameDurationConfig2Capability(
251 codec_spec_conf::kLeAudioCodecFrameDur10000us);
252 constexpr uint8_t kLeAudioCodecFrameDurPrefer7500us = 0x10;
253 constexpr uint8_t kLeAudioCodecFrameDurPrefer10000us = 0x20;
254
255 /* Audio Channel Counts */
256 /* Each bit represents support for additional channel: bit 0 - one channel,
257 * bit 1 - two, bit 3 - four channels. Multiple bits can be enabled at once.
258 */
259 constexpr uint8_t kLeAudioCodecChannelCountNone = 0x00;
260 constexpr uint8_t kLeAudioCodecChannelCountSingleChannel = 0x01;
261 constexpr uint8_t kLeAudioCodecChannelCountTwoChannel = 0x02;
262 constexpr uint8_t kLeAudioCodecChannelCountThreeChannel = 0x04;
263 constexpr uint8_t kLeAudioCodecChannelCountFourChannel = 0x08;
264 constexpr uint8_t kLeAudioCodecChannelCountFiveChannel = 0x10;
265 constexpr uint8_t kLeAudioCodecChannelCountSixChannel = 0x20;
266 constexpr uint8_t kLeAudioCodecChannelCountSevenChannel = 0x40;
267 constexpr uint8_t kLeAudioCodecChannelCountEightChannel = 0x80;
268
269 /* Octets Per Frame */
270 constexpr uint16_t kLeAudioCodecFrameLen30 =
271 codec_spec_conf::kLeAudioCodecFrameLen30;
272 constexpr uint16_t kLeAudioCodecFrameLen40 =
273 codec_spec_conf::kLeAudioCodecFrameLen40;
274 constexpr uint16_t kLeAudioCodecFrameLen60 =
275 codec_spec_conf::kLeAudioCodecFrameLen60;
276 constexpr uint16_t kLeAudioCodecFrameLen80 =
277 codec_spec_conf::kLeAudioCodecFrameLen80;
278 constexpr uint16_t kLeAudioCodecFrameLen120 =
279 codec_spec_conf::kLeAudioCodecFrameLen120;
280
281 }; // namespace codec_spec_caps
282
283 namespace types {
284 constexpr uint8_t kLeAudioCodingFormatLC3 = bluetooth::hci::kIsoCodingFormatLc3;
285 constexpr uint8_t kLeAudioCodingFormatVendorSpecific =
286 bluetooth::hci::kIsoCodingFormatVendorSpecific;
287 constexpr uint16_t kLeAudioVendorCompanyIdUndefined = 0x00;
288 constexpr uint16_t kLeAudioVendorCodecIdUndefined = 0x00;
289
290 constexpr uint16_t kLeAudioVendorCompanyIdGoogle = 0x00E0;
291 constexpr uint16_t kLeAudioVendorCodecIdHeadtracking = 0x0001;
292
293 /* Metadata types from Assigned Numbers */
294 constexpr uint8_t kLeAudioMetadataTypePreferredAudioContext = 0x01;
295 constexpr uint8_t kLeAudioMetadataTypeStreamingAudioContext = 0x02;
296 constexpr uint8_t kLeAudioMetadataTypeProgramInfo = 0x03;
297 constexpr uint8_t kLeAudioMetadataTypeLanguage = 0x04;
298 constexpr uint8_t kLeAudioMetadataTypeCcidList = 0x05;
299 constexpr uint8_t kLeAudioMetadataTypeparentalRating = 0x06;
300 constexpr uint8_t kLeAudioMetadataTypeProgramInfoUri = 0x07;
301 constexpr uint8_t kLeAudioMetadataTypeAudioActiveState = 0x08;
302 constexpr uint8_t kLeAudioMetadataTypeBroadcastAudioImmediateRenderingFlag =
303 0x09;
304 constexpr uint8_t kLeAudioMetadataTypeExtendedMetadata = 0xFE;
305 constexpr uint8_t kLeAudioMetadataTypeVendorSpecific = 0xFF;
306
307 constexpr uint8_t kLeAudioMetadataTypeLen = 1;
308 constexpr uint8_t kLeAudioMetadataLenLen = 1;
309
310 constexpr uint8_t kLeAudioMetadataStreamingAudioContextLen = 2;
311
312 /* Android Headtracker Codec metadata */
313 constexpr uint8_t kLeAudioMetadataHeadtrackerTransportLen = 1;
314 constexpr uint8_t kLeAudioMetadataHeadtrackerTransportVal = 1;
315 constexpr uint8_t kLeAudioMetadataHeadtrackerTransportLeAcl = 1;
316 constexpr uint8_t kLeAudioMetadataHeadtrackerTransportLeIso = 2;
317
318 /* CSIS Types */
319 constexpr uint8_t kDefaultScanDurationS = 5;
320 constexpr uint8_t kDefaultCsisSetSize = 2;
321
322 constexpr uint8_t kLeAudioDirectionSink = 0x01;
323 constexpr uint8_t kLeAudioDirectionSource = 0x02;
324 constexpr uint8_t kLeAudioDirectionBoth =
325 kLeAudioDirectionSink | kLeAudioDirectionSource;
326
327 /* Audio stream config types */
328 constexpr uint8_t kFramingUnframedPduSupported = 0x00;
329 constexpr uint8_t kFramingUnframedPduUnsupported = 0x01;
330
331 constexpr uint8_t kTargetLatencyUndefined = 0x00;
332 constexpr uint8_t kTargetLatencyLower = 0x01;
333 constexpr uint8_t kTargetLatencyBalancedLatencyReliability = 0x02;
334 constexpr uint8_t kTargetLatencyHigherReliability = 0x03;
335
336 constexpr uint8_t kTargetPhyUndefined = 0x00;
337 constexpr uint8_t kTargetPhy1M = 0x01;
338 constexpr uint8_t kTargetPhy2M = 0x02;
339 constexpr uint8_t kTargetPhyCoded = 0x03;
340
341 constexpr uint32_t kPresDelayNoPreference = 0x00000000;
342
343 constexpr uint16_t kMaxTransportLatencyMin = 0x0005;
344 constexpr uint16_t kMaxTransportLatencyMax = 0x0FA0;
345
346 enum class CigState : uint8_t { NONE, CREATING, CREATED, REMOVING, RECOVERING };
347
348 /* ASE states according to BAP defined state machine states */
349 enum class AseState : uint8_t {
350 BTA_LE_AUDIO_ASE_STATE_IDLE = 0x00,
351 BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED = 0x01,
352 BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED = 0x02,
353 BTA_LE_AUDIO_ASE_STATE_ENABLING = 0x03,
354 BTA_LE_AUDIO_ASE_STATE_STREAMING = 0x04,
355 BTA_LE_AUDIO_ASE_STATE_DISABLING = 0x05,
356 BTA_LE_AUDIO_ASE_STATE_RELEASING = 0x06,
357 };
358
359 enum class CisState {
360 IDLE,
361 ASSIGNED,
362 CONNECTING,
363 CONNECTED,
364 DISCONNECTING,
365 };
366
367 enum class DataPathState {
368 IDLE,
369 CONFIGURING,
370 CONFIGURED,
371 REMOVING,
372 };
373
374 enum class CisType {
375 CIS_TYPE_BIDIRECTIONAL,
376 CIS_TYPE_UNIDIRECTIONAL_SINK,
377 CIS_TYPE_UNIDIRECTIONAL_SOURCE,
378 };
379
380 struct cis {
381 uint8_t id;
382 CisType type;
383 uint16_t conn_handle;
384 RawAddress addr;
385 };
386
387 enum class CodecLocation {
388 HOST,
389 ADSP,
390 CONTROLLER,
391 };
392
393 /* Context Types */
394 enum class LeAudioContextType : uint16_t {
395 UNINITIALIZED = 0x0000,
396 UNSPECIFIED = 0x0001,
397 CONVERSATIONAL = 0x0002,
398 MEDIA = 0x0004,
399 GAME = 0x0008,
400 INSTRUCTIONAL = 0x0010,
401 VOICEASSISTANTS = 0x0020,
402 LIVE = 0x0040,
403 SOUNDEFFECTS = 0x0080,
404 NOTIFICATIONS = 0x0100,
405 RINGTONE = 0x0200,
406 ALERTS = 0x0400,
407 EMERGENCYALARM = 0x0800,
408 RFU = 0x1000,
409 };
410
411 class AudioContexts {
412 using T = std::underlying_type<LeAudioContextType>::type;
413 T mValue;
414
415 public:
AudioContexts()416 explicit constexpr AudioContexts()
417 : mValue(static_cast<T>(LeAudioContextType::UNINITIALIZED)) {}
AudioContexts(const T & v)418 explicit constexpr AudioContexts(const T& v) : mValue(v) {}
AudioContexts(const LeAudioContextType & v)419 explicit constexpr AudioContexts(const LeAudioContextType& v)
420 : mValue(static_cast<T>(v)) {}
AudioContexts(const AudioContexts & other)421 constexpr AudioContexts(const AudioContexts& other)
422 : mValue(static_cast<T>(other.value())) {}
423
value()424 constexpr T value() const { return mValue; }
value_ref()425 T& value_ref() { return mValue; }
none()426 bool none() const {
427 return mValue == static_cast<T>(LeAudioContextType::UNINITIALIZED);
428 }
any()429 bool any() const { return !none(); }
430
set(const LeAudioContextType & v)431 void set(const LeAudioContextType& v) { mValue |= static_cast<T>(v); }
set_all(const AudioContexts & v)432 void set_all(const AudioContexts& v) { mValue |= v.value(); }
unset(const LeAudioContextType & v)433 void unset(const LeAudioContextType& v) { mValue &= ~static_cast<T>(v); }
unset_all(const AudioContexts & v)434 void unset_all(const AudioContexts& v) { mValue &= ~v.value(); }
435
test(const LeAudioContextType & v)436 bool test(const LeAudioContextType& v) const {
437 return (mValue & static_cast<T>(v)) != 0;
438 }
test_all(const AudioContexts & v)439 bool test_all(const AudioContexts& v) const {
440 return (mValue & v.value()) == v.value();
441 }
test_any(const AudioContexts & v)442 bool test_any(const AudioContexts& v) const {
443 return (mValue & v.value()) != 0;
444 }
clear()445 void clear() { mValue = static_cast<T>(LeAudioContextType::UNINITIALIZED); }
446
447 std::string to_string() const;
448
449 AudioContexts& operator=(AudioContexts&& other) = default;
450 AudioContexts& operator=(const AudioContexts&) = default;
451 bool operator==(const AudioContexts& other) const {
452 return value() == other.value();
453 };
454 bool operator!=(const AudioContexts& other) const {
455 return value() != other.value();
456 };
457 constexpr AudioContexts operator~() const { return AudioContexts(~value()); }
458 };
459
460 AudioContexts operator|(std::underlying_type<LeAudioContextType>::type lhs,
461 const LeAudioContextType rhs);
462 AudioContexts& operator|=(AudioContexts& lhs, AudioContexts const& rhs);
463 AudioContexts& operator&=(AudioContexts& lhs, AudioContexts const& rhs);
464
465 constexpr AudioContexts operator^(const AudioContexts& lhs,
466 const AudioContexts& rhs) {
467 return AudioContexts(lhs.value() ^ rhs.value());
468 }
469 constexpr AudioContexts operator|(const AudioContexts& lhs,
470 const AudioContexts& rhs) {
471 return AudioContexts(lhs.value() | rhs.value());
472 }
473 constexpr AudioContexts operator&(const AudioContexts& lhs,
474 const AudioContexts& rhs) {
475 return AudioContexts(lhs.value() & rhs.value());
476 }
477 constexpr AudioContexts operator|(const LeAudioContextType& lhs,
478 const LeAudioContextType& rhs) {
479 using T = std::underlying_type<LeAudioContextType>::type;
480 return AudioContexts(static_cast<T>(lhs) | static_cast<T>(rhs));
481 }
482 constexpr AudioContexts operator|(const LeAudioContextType& lhs,
483 const AudioContexts& rhs) {
484 return AudioContexts(lhs) | rhs;
485 }
486 constexpr AudioContexts operator|(const AudioContexts& lhs,
487 const LeAudioContextType& rhs) {
488 return lhs | AudioContexts(rhs);
489 }
490
491 std::string ToHexString(const types::LeAudioContextType& value);
492
493 template <typename T>
494 struct BidirectionalPair {
495 T sink;
496 T source;
497
498 const T& get(uint8_t direction) const;
499 T& get(uint8_t direction);
500 };
501
502 template <typename T>
503 T get_bidirectional(BidirectionalPair<T> p);
504
505 template <typename T>
506 bool operator==(const types::BidirectionalPair<T>& lhs,
507 const types::BidirectionalPair<T>& rhs) {
508 return (lhs.sink == rhs.sink) && (lhs.source == rhs.source);
509 }
510
511 /* Configuration strategy */
512 enum class LeAudioConfigurationStrategy : uint8_t {
513 MONO_ONE_CIS_PER_DEVICE = 0x00, /* Common true wireless speakers */
514 STEREO_TWO_CISES_PER_DEVICE =
515 0x01, /* Requires 2 ASEs and 2 Audio Allocation for left/right */
516 STEREO_ONE_CIS_PER_DEVICE = 0x02, /* Requires channel count 2*/
517 RFU = 0x03,
518 };
519
520 constexpr LeAudioContextType kLeAudioContextAllTypesArray[] = {
521 LeAudioContextType::UNSPECIFIED, LeAudioContextType::CONVERSATIONAL,
522 LeAudioContextType::MEDIA, LeAudioContextType::GAME,
523 LeAudioContextType::INSTRUCTIONAL, LeAudioContextType::VOICEASSISTANTS,
524 LeAudioContextType::LIVE, LeAudioContextType::SOUNDEFFECTS,
525 LeAudioContextType::NOTIFICATIONS, LeAudioContextType::RINGTONE,
526 LeAudioContextType::ALERTS, LeAudioContextType::EMERGENCYALARM,
527 };
528
529 constexpr AudioContexts kLeAudioContextAllTypes =
530 LeAudioContextType::UNSPECIFIED | LeAudioContextType::CONVERSATIONAL |
531 LeAudioContextType::MEDIA | LeAudioContextType::GAME |
532 LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::VOICEASSISTANTS |
533 LeAudioContextType::LIVE | LeAudioContextType::SOUNDEFFECTS |
534 LeAudioContextType::NOTIFICATIONS | LeAudioContextType::RINGTONE |
535 LeAudioContextType::ALERTS | LeAudioContextType::EMERGENCYALARM;
536
537 constexpr AudioContexts kLeAudioContextAllBidir =
538 LeAudioContextType::GAME | LeAudioContextType::LIVE |
539 LeAudioContextType::CONVERSATIONAL | LeAudioContextType::VOICEASSISTANTS;
540
541 constexpr AudioContexts kLeAudioContextAllRemoteSource =
542 LeAudioContextType::GAME | LeAudioContextType::LIVE |
543 LeAudioContextType::CONVERSATIONAL | LeAudioContextType::VOICEASSISTANTS;
544
545 constexpr AudioContexts kLeAudioContextAllRemoteSinkOnly =
546 LeAudioContextType::MEDIA | LeAudioContextType::INSTRUCTIONAL |
547 LeAudioContextType::SOUNDEFFECTS | LeAudioContextType::NOTIFICATIONS |
548 LeAudioContextType::RINGTONE | LeAudioContextType::ALERTS |
549 LeAudioContextType::EMERGENCYALARM;
550
551 /* Print formaters for LTV data */
552 std::string CodecCapabilitiesLtvFormat(const uint8_t& type,
553 const std::vector<uint8_t>& value);
554
555 /* Structures */
556 /** LE Audio ASE codec configuration parameters, built from LTV types defined
557 * in the BT Assigned Numbers.
558 * NOTE: This base structure does not support the vendor specific parameters.
559 */
560 struct LeAudioCoreCodecConfig {
561 static const std::map<uint8_t, uint32_t> sampling_freq_map;
562 static const std::map<uint32_t, uint8_t> sample_rate_map;
563
564 static const std::map<uint8_t, uint32_t> frame_duration_map;
565 static const std::map<uint32_t, uint8_t> data_interval_map;
566
567 std::optional<uint8_t> sampling_frequency;
568 std::optional<uint8_t> frame_duration;
569 std::optional<uint32_t> audio_channel_allocation;
570 std::optional<uint16_t> octets_per_codec_frame;
571 std::optional<uint8_t> codec_frames_blocks_per_sdu;
572
GetSamplingFrequencyHzLeAudioCoreCodecConfig573 static uint32_t GetSamplingFrequencyHz(uint8_t sample_freq) {
574 return sampling_freq_map.count(sample_freq)
575 ? sampling_freq_map.at(sample_freq)
576 : 0;
577 }
578
GetFrameDurationUsLeAudioCoreCodecConfig579 static uint32_t GetFrameDurationUs(uint8_t framn_dur) {
580 return frame_duration_map.count(framn_dur)
581 ? frame_duration_map.at(framn_dur)
582 : 0;
583 }
584
GetOctectsPerFrameLeAudioCoreCodecConfig585 uint16_t GetOctectsPerFrame() const {
586 return octets_per_codec_frame.value_or(0);
587 }
588
589 /** Returns the sampling frequency representation in Hz */
GetSamplingFrequencyHzLeAudioCoreCodecConfig590 uint32_t GetSamplingFrequencyHz() const {
591 if (sampling_frequency)
592 return sampling_freq_map.count(*sampling_frequency)
593 ? sampling_freq_map.at(*sampling_frequency)
594 : 0;
595 return 0;
596 }
597
598 /** Returns the frame duration representation in us */
GetFrameDurationUsLeAudioCoreCodecConfig599 uint32_t GetFrameDurationUs() const {
600 if (frame_duration)
601 return frame_duration_map.count(*frame_duration)
602 ? frame_duration_map.at(*frame_duration)
603 : 0;
604
605 return 0;
606 }
607 };
608
609 struct LeAudioCoreCodecCapabilities {
HasSupportedSamplingFrequenciesLeAudioCoreCodecCapabilities610 bool HasSupportedSamplingFrequencies() const {
611 return supported_sampling_frequencies.has_value();
612 }
HasSupportedFrameDurationsLeAudioCoreCodecCapabilities613 bool HasSupportedFrameDurations() const {
614 return supported_frame_durations.has_value();
615 }
HasSupportedOctetsPerCodecFrameLeAudioCoreCodecCapabilities616 bool HasSupportedOctetsPerCodecFrame() const {
617 return supported_min_octets_per_codec_frame.has_value() &&
618 supported_max_octets_per_codec_frame.has_value();
619 }
HasSupportedAudioChannelCountsLeAudioCoreCodecCapabilities620 bool HasSupportedAudioChannelCounts() const {
621 return supported_audio_channel_counts.has_value();
622 }
HasSupportedMaxCodecFramesPerSduLeAudioCoreCodecCapabilities623 bool HasSupportedMaxCodecFramesPerSdu() const {
624 return supported_max_codec_frames_per_sdu.has_value();
625 }
626
IsSamplingFrequencyConfigSupportedLeAudioCoreCodecCapabilities627 bool IsSamplingFrequencyConfigSupported(uint8_t value) const {
628 return supported_sampling_frequencies.value_or(0) &
629 codec_spec_caps::SamplingFreqConfig2Capability(value);
630 }
IsFrameDurationConfigSupportedLeAudioCoreCodecCapabilities631 bool IsFrameDurationConfigSupported(uint8_t value) const {
632 return supported_frame_durations.value_or(0) &
633 codec_spec_caps::FrameDurationConfig2Capability(value);
634 }
IsAudioChannelCountsSupportedLeAudioCoreCodecCapabilities635 bool IsAudioChannelCountsSupported(uint8_t value) const {
636 if (value > 0)
637 return supported_audio_channel_counts.value_or(0) & (0b1 << (value - 1));
638
639 return false;
640 }
IsOctetsPerCodecFrameConfigSupportedLeAudioCoreCodecCapabilities641 bool IsOctetsPerCodecFrameConfigSupported(uint16_t value) const {
642 return (value >= supported_min_octets_per_codec_frame.value_or(0)) &&
643 (value <= supported_max_octets_per_codec_frame.value_or(0));
644 }
IsCodecFramesPerSduSupportedLeAudioCoreCodecCapabilities645 bool IsCodecFramesPerSduSupported(uint8_t value) const {
646 return value <= supported_max_codec_frames_per_sdu.value_or(1);
647 }
648
649 std::optional<uint16_t> supported_sampling_frequencies;
650 std::optional<uint8_t> supported_frame_durations;
651 std::optional<uint8_t> supported_audio_channel_counts;
652 std::optional<uint16_t> supported_min_octets_per_codec_frame;
653 std::optional<uint16_t> supported_max_octets_per_codec_frame;
654 std::optional<uint8_t> supported_max_codec_frames_per_sdu;
655 };
656
657 struct LeAudioMetadata {
658 std::optional<uint16_t> preferred_audio_context;
659 std::optional<uint16_t> streaming_audio_context;
660 std::optional<std::string> program_info;
661 std::optional<std::string> language; // ISO 639-3 (3 lowercase letter codes)
662 std::optional<std::vector<uint8_t>> ccid_list;
663 std::optional<uint8_t> parental_rating;
664 std::optional<std::string> program_info_uri;
665 std::optional<std::vector<uint8_t>> extended_metadata;
666 std::optional<std::vector<uint8_t>> vendor_specific;
667 std::optional<bool> audio_active_state;
668 std::optional<bool> broadcast_audio_immediate_rendering;
669 };
670
671 std::ostream& operator<<(std::ostream& os, const LeAudioMetadata& config);
672
673 #define LTV_ENTRY_SAMPLING_FREQUENCY(value) \
674 { \
675 le_audio::codec_spec_conf::kLeAudioLtvTypeSamplingFreq, \
676 std::vector<uint8_t>({(value) & 0xFF}) \
677 }
678
679 #define LTV_ENTRY_FRAME_DURATION(value) \
680 { \
681 le_audio::codec_spec_conf::kLeAudioLtvTypeFrameDuration, \
682 std::vector<uint8_t>({(value) & 0xFF}) \
683 }
684
685 #define LTV_ENTRY_AUDIO_CHANNEL_ALLOCATION(value) \
686 { \
687 le_audio::codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation, \
688 std::vector<uint8_t>({(uint8_t)(value) & 0xFF, \
689 (uint8_t)((value) << 8) & 0xFF, \
690 (uint8_t)((value) << 16) & 0xFF, \
691 (uint8_t)((value) << 24) & 0xFF}) \
692 }
693
694 #define LTV_ENTRY_OCTETS_PER_CODEC_FRAME(value) \
695 { \
696 le_audio::codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame, \
697 std::vector<uint8_t>( \
698 {(uint8_t)(value) & 0xFF, (uint8_t)((value) << 8) & 0xFF}) \
699 }
700
701 #define LTV_ENTRY_FRAME_BLOCKS_PER_SDU(value) \
702 { \
703 le_audio::codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu, \
704 std::vector<uint8_t>({(value) & 0xFF}) \
705 }
706
707 class LeAudioLtvMap {
708 public:
LeAudioLtvMap(std::map<uint8_t,std::vector<uint8_t>> values)709 LeAudioLtvMap(std::map<uint8_t, std::vector<uint8_t>> values)
710 : values(values),
711 value_hash(0),
712 core_config(std::nullopt),
713 core_capabilities(std::nullopt),
714 metadata(std::nullopt) {}
715 LeAudioLtvMap() = default;
716 ~LeAudioLtvMap() = default;
717
718 bool operator==(const LeAudioLtvMap& other) const {
719 return GetHash() == other.GetHash();
720 }
721
722 bool operator!=(const LeAudioLtvMap& other) const {
723 return GetHash() != other.GetHash();
724 }
725
726 std::optional<std::vector<uint8_t>> Find(uint8_t type) const;
At(uint8_t type)727 const auto& At(uint8_t type) const { return values.at(type); }
728
Add(uint8_t type,std::vector<uint8_t> value)729 LeAudioLtvMap& Add(uint8_t type, std::vector<uint8_t> value) {
730 values.insert_or_assign(type, std::move(value));
731 invalidate();
732 return *this;
733 }
734
735 // Add vendor specific data preceded with 2 octets of company ID
Add(uint8_t type,uint16_t vendorCompanyId,std::vector<uint8_t> value)736 LeAudioLtvMap& Add(uint8_t type, uint16_t vendorCompanyId,
737 std::vector<uint8_t> value) {
738 std::vector<uint8_t> data(value.size() + 2);
739 auto ptr = data.data();
740 UINT16_TO_STREAM(ptr, vendorCompanyId);
741 ARRAY_TO_STREAM(ptr, value.data(), (int)value.size());
742 return Add(type, data);
743 }
744
Add(uint8_t type,const std::string & value)745 LeAudioLtvMap& Add(uint8_t type, const std::string& value) {
746 std::vector<uint8_t> v(value.size());
747 auto ptr = v.data();
748 ARRAY_TO_STREAM(ptr, value.c_str(), (int)value.size());
749 values.insert_or_assign(type, v);
750 invalidate();
751 return *this;
752 }
753
Add(uint8_t type,bool value)754 LeAudioLtvMap& Add(uint8_t type, bool value) {
755 std::vector<uint8_t> v(1);
756 auto ptr = v.data();
757 UINT8_TO_STREAM(ptr, value ? 0x01 : 0x00);
758 values.insert_or_assign(type, v);
759 invalidate();
760 return *this;
761 }
762
Add(uint8_t type,uint8_t value)763 LeAudioLtvMap& Add(uint8_t type, uint8_t value) {
764 std::vector<uint8_t> v(sizeof(value));
765 auto ptr = v.data();
766
767 UINT8_TO_STREAM(ptr, value);
768 values.insert_or_assign(type, v);
769 invalidate();
770 return *this;
771 }
Add(uint8_t type,uint16_t value)772 LeAudioLtvMap& Add(uint8_t type, uint16_t value) {
773 std::vector<uint8_t> v(sizeof(value));
774 auto ptr = v.data();
775
776 UINT16_TO_STREAM(ptr, value);
777 values.insert_or_assign(type, std::move(v));
778 invalidate();
779 return *this;
780 }
Add(uint8_t type,uint32_t value)781 LeAudioLtvMap& Add(uint8_t type, uint32_t value) {
782 std::vector<uint8_t> v(sizeof(value));
783 auto ptr = v.data();
784
785 UINT32_TO_STREAM(ptr, value);
786 values.insert_or_assign(type, std::move(v));
787 invalidate();
788 return *this;
789 }
Remove(uint8_t type)790 void Remove(uint8_t type) {
791 values.erase(type);
792 invalidate();
793 }
794 void RemoveAllTypes(const LeAudioLtvMap& other);
IsEmpty()795 bool IsEmpty() const { return values.empty(); }
Clear()796 void Clear() {
797 invalidate();
798 values.clear();
799 }
Size()800 size_t Size() const { return values.size(); }
Values()801 const std::map<uint8_t, std::vector<uint8_t>>& Values() const {
802 return values;
803 }
804
805 const struct LeAudioCoreCodecConfig& GetAsCoreCodecConfig() const;
806 const struct LeAudioCoreCodecCapabilities& GetAsCoreCodecCapabilities() const;
807 const struct LeAudioMetadata& GetAsLeAudioMetadata() const;
808 LeAudioLtvMap GetIntersection(const LeAudioLtvMap& other) const;
809
810 std::string ToString(
811 const std::string& indent_string,
812 std::string (*format)(const uint8_t&, const std::vector<uint8_t>&)) const;
813 size_t RawPacketSize() const;
814 uint8_t* RawPacket(uint8_t* p_buf) const;
815 std::vector<uint8_t> RawPacket() const;
816 static LeAudioLtvMap Parse(const uint8_t* value, uint8_t len, bool& success);
817 bool Parse(const uint8_t* value, uint8_t len);
818 void Append(const LeAudioLtvMap& other);
GetHash()819 size_t GetHash() const {
820 if (value_hash == 0) RecalculateValueHash();
821 return value_hash;
822 }
823
824 private:
invalidate()825 void invalidate() {
826 core_config = std::nullopt;
827 core_capabilities = std::nullopt;
828 metadata = std::nullopt;
829 value_hash = 0;
830 }
831
LtvMapToMetadata(const LeAudioLtvMap & ltvs)832 static LeAudioMetadata LtvMapToMetadata(const LeAudioLtvMap& ltvs) {
833 LeAudioMetadata metadata;
834
835 auto vec_opt = ltvs.Find(types::kLeAudioMetadataTypePreferredAudioContext);
836 if (vec_opt &&
837 (vec_opt->size() ==
838 sizeof(decltype(metadata.preferred_audio_context)::value_type))) {
839 auto ptr = vec_opt->data();
840 STREAM_TO_UINT16(metadata.preferred_audio_context, ptr);
841 }
842
843 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeStreamingAudioContext);
844 if (vec_opt &&
845 (vec_opt->size() ==
846 sizeof(decltype(metadata.streaming_audio_context)::value_type))) {
847 auto ptr = vec_opt->data();
848 STREAM_TO_UINT16(metadata.streaming_audio_context, ptr);
849 }
850
851 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeProgramInfo);
852 if (vec_opt) {
853 metadata.program_info = std::string(
854 reinterpret_cast<const char*>(vec_opt->data()), vec_opt->size());
855 }
856
857 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeLanguage);
858 if (vec_opt && (vec_opt->size() == 3)) { // it is always 3 in ISO 639-3
859 metadata.language = std::string(
860 reinterpret_cast<const char*>(vec_opt->data()), vec_opt->size());
861 }
862
863 metadata.ccid_list = ltvs.Find(types::kLeAudioMetadataTypeCcidList);
864
865 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeparentalRating);
866 if (vec_opt && (vec_opt->size() ==
867 sizeof(decltype(metadata.parental_rating)::value_type))) {
868 auto ptr = vec_opt->data();
869 STREAM_TO_UINT8(metadata.parental_rating, ptr);
870 }
871
872 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeProgramInfoUri);
873 if (vec_opt) {
874 metadata.program_info_uri = std::string(
875 reinterpret_cast<const char*>(vec_opt->data()), vec_opt->size());
876 }
877
878 vec_opt = ltvs.Find(types::kLeAudioMetadataTypeAudioActiveState);
879 if (vec_opt &&
880 (vec_opt->size() ==
881 sizeof(decltype(metadata.audio_active_state)::value_type))) {
882 auto ptr = vec_opt->data();
883 uint8_t val;
884 STREAM_TO_UINT8(val, ptr);
885 metadata.audio_active_state = val ? true : false;
886 }
887
888 vec_opt = ltvs.Find(
889 types::kLeAudioMetadataTypeBroadcastAudioImmediateRenderingFlag);
890 if (vec_opt) {
891 metadata.broadcast_audio_immediate_rendering = true;
892 }
893
894 metadata.extended_metadata =
895 ltvs.Find(types::kLeAudioMetadataTypeExtendedMetadata);
896 metadata.vendor_specific =
897 ltvs.Find(types::kLeAudioMetadataTypeVendorSpecific);
898
899 return metadata;
900 }
901
LtvMapToCoreCodecConfig(const LeAudioLtvMap & ltvs)902 static LeAudioCoreCodecConfig LtvMapToCoreCodecConfig(
903 const LeAudioLtvMap& ltvs) {
904 LeAudioCoreCodecConfig core;
905
906 auto vec_opt = ltvs.Find(codec_spec_conf::kLeAudioLtvTypeSamplingFreq);
907 if (vec_opt && (vec_opt->size() ==
908 sizeof(decltype(core.sampling_frequency)::value_type))) {
909 auto ptr = vec_opt->data();
910 STREAM_TO_UINT8(core.sampling_frequency, ptr);
911 }
912
913 vec_opt = ltvs.Find(codec_spec_conf::kLeAudioLtvTypeFrameDuration);
914 if (vec_opt && (vec_opt->size() ==
915 sizeof(decltype(core.frame_duration)::value_type))) {
916 auto ptr = vec_opt->data();
917 STREAM_TO_UINT8(core.frame_duration, ptr);
918 }
919
920 vec_opt = ltvs.Find(codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation);
921 if (vec_opt &&
922 (vec_opt->size() ==
923 sizeof(decltype(core.audio_channel_allocation)::value_type))) {
924 auto ptr = vec_opt->data();
925 STREAM_TO_UINT32(core.audio_channel_allocation, ptr);
926 }
927
928 vec_opt = ltvs.Find(codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame);
929 if (vec_opt &&
930 (vec_opt->size() ==
931 sizeof(decltype(core.octets_per_codec_frame)::value_type))) {
932 auto ptr = vec_opt->data();
933 STREAM_TO_UINT16(core.octets_per_codec_frame, ptr);
934 }
935
936 vec_opt = ltvs.Find(codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu);
937 if (vec_opt &&
938 (vec_opt->size() ==
939 sizeof(decltype(core.codec_frames_blocks_per_sdu)::value_type))) {
940 auto ptr = vec_opt->data();
941 STREAM_TO_UINT8(core.codec_frames_blocks_per_sdu, ptr);
942 }
943
944 return core;
945 }
946
LtvMapToCoreCodecCapabilities(const LeAudioLtvMap & pacs)947 static LeAudioCoreCodecCapabilities LtvMapToCoreCodecCapabilities(
948 const LeAudioLtvMap& pacs) {
949 LeAudioCoreCodecCapabilities core;
950
951 auto pac =
952 pacs.Find(codec_spec_caps::kLeAudioLtvTypeSupportedSamplingFrequencies);
953 if (pac &&
954 (pac.value().size() ==
955 sizeof(decltype(core.supported_sampling_frequencies)::value_type))) {
956 core.supported_sampling_frequencies = VEC_UINT8_TO_UINT16(pac.value());
957 }
958
959 pac = pacs.Find(codec_spec_caps::kLeAudioLtvTypeSupportedFrameDurations);
960 if (pac && (pac.value().size() ==
961 sizeof(decltype(core.supported_frame_durations)::value_type))) {
962 core.supported_frame_durations = VEC_UINT8_TO_UINT8(pac.value());
963 }
964
965 pac =
966 pacs.Find(codec_spec_caps::kLeAudioLtvTypeSupportedOctetsPerCodecFrame);
967 if (pac &&
968 (pac.value().size() ==
969 (sizeof(
970 decltype(core.supported_min_octets_per_codec_frame)::value_type) +
971 sizeof(decltype(core.supported_max_octets_per_codec_frame)::
972 value_type)))) {
973 core.supported_min_octets_per_codec_frame =
974 VEC_UINT8_TO_UINT16(pac.value());
975 core.supported_max_octets_per_codec_frame = OFF_VEC_UINT8_TO_UINT16(
976 pac.value(),
977 sizeof(
978 decltype(core.supported_min_octets_per_codec_frame)::value_type));
979 }
980
981 /*
982 * BAP_1.0.1 4.3.1 Codec_Specific_Capabilities LTV requirements:
983 * The absence of the Supported_Audio_Channel_Counts LTV structure shall be
984 * interpreted as equivalent to a Supported_Audio_Channel_Counts value of
985 * 0x01 (one Audio Channel supported).
986 */
987 pac =
988 pacs.Find(codec_spec_caps::kLeAudioLtvTypeSupportedAudioChannelCounts);
989 if (pac &&
990 (pac.value().size() ==
991 sizeof(decltype(core.supported_audio_channel_counts)::value_type))) {
992 core.supported_audio_channel_counts = VEC_UINT8_TO_UINT8(pac.value());
993 } else {
994 core.supported_audio_channel_counts = 0b1;
995 }
996
997 /*
998 * BAP_1.0.1 4.3.1 Codec_Specific_Capabilities LTV requirements:
999 * The absence of the Supported_Max_Codec_Frames_Per_SDU LTV structure shall
1000 * be interpreted as equivalent to a Supported_Max_Codec_Frames_Per_SDU
1001 * value of 1 codec frame per Audio Channel per SDU maximum.
1002 */
1003 pac = pacs.Find(
1004 codec_spec_caps::kLeAudioLtvTypeSupportedMaxCodecFramesPerSdu);
1005 if (pac &&
1006 (pac.value().size() ==
1007 sizeof(
1008 decltype(core.supported_max_codec_frames_per_sdu)::value_type))) {
1009 core.supported_max_codec_frames_per_sdu = VEC_UINT8_TO_UINT8(pac.value());
1010 } else {
1011 core.supported_max_codec_frames_per_sdu = 1;
1012 }
1013
1014 return core;
1015 }
1016
RecalculateValueHash()1017 void RecalculateValueHash() const {
1018 if (IsEmpty()) {
1019 value_hash = 0;
1020 return;
1021 }
1022
1023 auto value_vec = RawPacket();
1024 value_hash = std::hash<std::string_view>{}(
1025 {reinterpret_cast<const char*>(value_vec.data()), value_vec.size()});
1026 }
1027
1028 std::map<uint8_t, std::vector<uint8_t>> values = {};
1029 mutable size_t value_hash = 0;
1030 // Lazy-constructed views of the LTV data
1031 mutable std::optional<struct LeAudioCoreCodecConfig> core_config =
1032 std::nullopt;
1033 mutable std::optional<struct LeAudioCoreCodecCapabilities> core_capabilities =
1034 std::nullopt;
1035 mutable std::optional<struct LeAudioMetadata> metadata = std::nullopt;
1036 };
1037
1038 struct LeAudioCodecId {
1039 uint8_t coding_format;
1040 uint16_t vendor_company_id;
1041 uint16_t vendor_codec_id;
1042
1043 friend bool operator==(const LeAudioCodecId& lhs, const LeAudioCodecId& rhs) {
1044 if (lhs.coding_format != rhs.coding_format) return false;
1045
1046 if (lhs.coding_format == kLeAudioCodingFormatVendorSpecific &&
1047 (lhs.vendor_company_id != rhs.vendor_company_id ||
1048 lhs.vendor_codec_id != rhs.vendor_codec_id))
1049 return false;
1050
1051 return true;
1052 }
1053
1054 friend bool operator!=(const LeAudioCodecId& lhs, const LeAudioCodecId& rhs) {
1055 return !(lhs == rhs);
1056 }
1057 };
1058
1059 /* Google vendor specific codec for Headtracking */
1060 constexpr LeAudioCodecId kLeAudioCodecHeadtracking = {
1061 kLeAudioCodingFormatVendorSpecific, kLeAudioVendorCompanyIdGoogle,
1062 kLeAudioVendorCodecIdHeadtracking};
1063
1064 struct IsoDataPathConfiguration {
1065 types::LeAudioCodecId codecId = {0, 0, 0};
1066 bool isTransparent = true;
1067 uint32_t controllerDelayUs = 0;
1068 std::vector<uint8_t> configuration = {};
1069
1070 bool operator==(const IsoDataPathConfiguration& other) const {
1071 if (codecId != other.codecId) return false;
1072 if (isTransparent != other.isTransparent) return false;
1073 if (controllerDelayUs != other.controllerDelayUs) return false;
1074 if (configuration.size() != other.configuration.size()) return false;
1075 if ((!other.configuration.empty()) &&
1076 memcmp(configuration.data(), other.configuration.data(),
1077 other.configuration.size())) {
1078 return false;
1079 }
1080 return true;
1081 }
1082
1083 bool operator!=(const IsoDataPathConfiguration& other) const {
1084 return !(*this == other);
1085 }
1086 };
1087
1088 std::ostream& operator<<(
1089 std::ostream& os, const le_audio::types::IsoDataPathConfiguration& config);
1090
1091 struct DataPathConfiguration {
1092 uint8_t dataPathId = 0;
1093 std::vector<uint8_t> dataPathConfig = {};
1094 IsoDataPathConfiguration isoDataPathConfig;
1095
1096 bool operator==(const DataPathConfiguration& other) const {
1097 if (dataPathId != other.dataPathId) return false;
1098 if (isoDataPathConfig != other.isoDataPathConfig) return false;
1099 if (dataPathConfig.size() != other.dataPathConfig.size()) return false;
1100 if ((!other.dataPathConfig.empty()) &&
1101 memcmp(dataPathConfig.data(), other.dataPathConfig.data(),
1102 other.dataPathConfig.size())) {
1103 return false;
1104 }
1105 return true;
1106 }
1107
1108 bool operator!=(const DataPathConfiguration& other) const {
1109 return !(*this == other);
1110 }
1111 };
1112
1113 std::ostream& operator<<(std::ostream& os,
1114 const le_audio::types::DataPathConfiguration& config);
1115
1116 struct hdl_pair {
1117 hdl_pair() = default;
hdl_pairhdl_pair1118 hdl_pair(uint16_t val_hdl, uint16_t ccc_hdl)
1119 : val_hdl(val_hdl), ccc_hdl(ccc_hdl) {}
1120
1121 uint16_t val_hdl = 0;
1122 uint16_t ccc_hdl = 0;
1123 };
1124
1125 struct AseQosConfiguration {
1126 uint32_t presentation_delay = 0;
1127 uint32_t sdu_interval = 0;
1128 uint16_t max_transport_latency = 0;
1129 uint16_t max_sdu_size = 0;
1130 uint8_t retrans_nb = 0;
1131 uint8_t framing = 0;
1132 uint8_t phy = 0;
1133 };
1134
1135 struct AseQosPreferences {
1136 uint8_t supported_framing = 0;
1137 uint8_t preferred_phy = 0;
1138 uint8_t preferred_retrans_nb = 0;
1139 uint32_t pres_delay_min = 0;
1140 uint32_t pres_delay_max = 0;
1141 uint32_t preferred_pres_delay_min = 0;
1142 uint32_t preferred_pres_delay_max = 0;
1143 };
1144
1145 struct ase {
1146 static constexpr uint8_t kAseIdInvalid = 0x00;
1147
1148 ase(uint16_t val_hdl, uint16_t ccc_hdl, uint8_t direction,
1149 uint8_t initial_id = kAseIdInvalid)
hdlsase1150 : hdls(val_hdl, ccc_hdl),
1151 id(initial_id),
1152 cis_id(kInvalidCisId),
1153 direction(direction),
1154 target_latency(types::kTargetLatencyBalancedLatencyReliability),
1155 active(false),
1156 reconfigure(false),
1157 cis_state(CisState::IDLE),
1158 data_path_state(DataPathState::IDLE),
1159 configured_for_context_type(LeAudioContextType::UNINITIALIZED),
1160 autonomous_operation_timer_(nullptr),
1161 autonomous_target_state_(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE),
1162 state(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {}
1163
1164 struct hdl_pair hdls;
1165 uint8_t id;
1166 uint8_t cis_id;
1167 const uint8_t direction;
1168 uint8_t target_latency;
1169 uint16_t cis_conn_hdl = 0;
1170
1171 bool active;
1172 bool reconfigure;
1173 CisState cis_state;
1174 DataPathState data_path_state;
1175 LeAudioContextType configured_for_context_type;
1176
1177 /* Codec configuration */
1178 LeAudioCodecId codec_id;
1179 LeAudioLtvMap codec_config;
1180 std::vector<uint8_t> vendor_codec_config;
1181 uint8_t channel_count;
1182
1183 /* Data path configuration */
1184 DataPathConfiguration data_path_configuration;
1185
1186 /* Qos configuration */
1187 AseQosConfiguration qos_config;
1188
1189 /* QoS requirements in Codec Configured state */
1190 AseQosPreferences qos_preferences;
1191
1192 std::vector<uint8_t> metadata;
1193
1194 /* Autonomous change data */
1195 alarm_t* autonomous_operation_timer_;
1196 types::AseState autonomous_target_state_;
1197
1198 AseState state;
1199 };
1200
1201 struct acs_ac_record {
1202 LeAudioCodecId codec_id;
1203 LeAudioLtvMap codec_spec_caps;
1204 std::vector<uint8_t> codec_spec_caps_raw;
1205 std::vector<uint8_t> metadata;
1206 };
1207
1208 using PublishedAudioCapabilities =
1209 std::vector<std::tuple<hdl_pair, std::vector<acs_ac_record>>>;
1210 using AudioLocations = std::bitset<32>;
1211
1212 std::ostream& operator<<(std::ostream& os, const AseState& state);
1213 std::ostream& operator<<(std::ostream& os, const CigState& state);
1214 std::ostream& operator<<(std::ostream& os, const LeAudioCodecId& codec_id);
1215 std::ostream& operator<<(std::ostream& os,
1216 const LeAudioCoreCodecConfig& config);
1217 std::string contextTypeToStr(const LeAudioContextType& context);
1218 std::ostream& operator<<(std::ostream& os, const LeAudioContextType& context);
1219 std::ostream& operator<<(std::ostream& os, const DataPathState& state);
1220 std::ostream& operator<<(std::ostream& os, const CisState& state);
1221 std::ostream& operator<<(std::ostream& os, const AudioContexts& contexts);
1222 } // namespace types
1223
1224 namespace set_configurations {
1225
1226 struct CodecConfigSetting {
1227 /* Codec identifier */
1228 types::LeAudioCodecId id;
1229
1230 /* Codec Specific Configuration */
1231 types::LeAudioLtvMap params;
1232 /* Vendor Specific Configuration */
1233 std::vector<uint8_t> vendor_params;
1234
1235 /* Channel count per device */
1236 uint8_t channel_count_per_iso_stream;
1237
1238 /* Octects per fram for codec */
1239 uint16_t GetOctectsPerFrame() const;
1240 /* Sampling freqency requested for codec */
1241 uint32_t GetSamplingFrequencyHz() const;
1242 /* Data fetch/feed interval for codec in microseconds */
1243 uint32_t GetDataIntervalUs() const;
1244 /* Audio bit depth required for codec */
1245 uint8_t GetBitsPerSample() const;
1246 /* Audio channels number for a device */
GetChannelCountPerIsoStreamCodecConfigSetting1247 uint8_t GetChannelCountPerIsoStream() const {
1248 return channel_count_per_iso_stream;
1249 }
1250
1251 bool operator==(const CodecConfigSetting& other) const {
1252 return (id == other.id) &&
1253 (channel_count_per_iso_stream ==
1254 other.channel_count_per_iso_stream) &&
1255 (vendor_params == other.vendor_params) && (params == other.params);
1256 }
1257
1258 bool operator!=(const CodecConfigSetting& other) const {
1259 return !(*this == other);
1260 }
1261
1262 /* TODO: Add vendor parameter or Ltv map viewers for
1263 * vendor specific LTV types.
1264 */
1265 };
1266
1267 std::ostream& operator<<(std::ostream& os, const CodecConfigSetting& config);
1268
1269 struct QosConfigSetting {
1270 uint8_t target_latency;
1271 uint8_t retransmission_number;
1272 uint16_t max_transport_latency;
1273 int sduIntervalUs;
1274 int maxSdu;
1275
1276 bool operator!=(const QosConfigSetting& other) { return !(*this == other); }
1277
1278 bool operator==(const QosConfigSetting& other) const {
1279 return ((target_latency == other.target_latency) &&
1280 (retransmission_number == other.retransmission_number) &&
1281 (max_transport_latency == other.max_transport_latency));
1282 }
1283 };
1284
1285 std::ostream& operator<<(std::ostream& os, const QosConfigSetting& config);
1286
1287 struct AseConfiguration {
1288 AseConfiguration(CodecConfigSetting codec,
1289 QosConfigSetting qos = {.target_latency = 0,
1290 .retransmission_number = 0,
1291 .max_transport_latency = 0})
codecAseConfiguration1292 : codec(codec), qos(qos) {}
1293 types::DataPathConfiguration data_path_configuration;
1294 CodecConfigSetting codec;
1295 QosConfigSetting qos;
1296
1297 bool operator!=(const AseConfiguration& other) { return !(*this == other); }
1298
1299 bool operator==(const AseConfiguration& other) const {
1300 return ((data_path_configuration == other.data_path_configuration) &&
1301 (codec == other.codec) && (qos == other.qos));
1302 }
1303 };
1304
1305 std::ostream& operator<<(std::ostream& os, const AseConfiguration& config);
1306
1307 /* Defined audio scenarios */
1308 struct AudioSetConfiguration {
1309 std::string name = "";
1310 /* ISO data packing within the CIG */
1311 uint8_t packing = bluetooth::hci::kIsoCigPackingSequential;
1312 types::BidirectionalPair<std::vector<struct AseConfiguration>> confs;
1313
1314 bool operator!=(const AudioSetConfiguration& other) {
1315 return !(*this == other);
1316 }
1317
1318 bool operator==(const AudioSetConfiguration& other) const {
1319 return ((packing == other.packing) && (confs == other.confs));
1320 }
1321 };
1322
1323 std::ostream& operator<<(std::ostream& os, const AudioSetConfiguration& config);
1324
1325 using AudioSetConfigurations = std::vector<const AudioSetConfiguration*>;
1326
1327 const types::LeAudioCodecId LeAudioCodecIdLc3 = {
1328 .coding_format = types::kLeAudioCodingFormatLC3,
1329 .vendor_company_id = types::kLeAudioVendorCompanyIdUndefined,
1330 .vendor_codec_id = types::kLeAudioVendorCodecIdUndefined};
1331
1332 static constexpr uint32_t kChannelAllocationStereo =
1333 codec_spec_conf::kLeAudioLocationFrontLeft |
1334 codec_spec_conf::kLeAudioLocationFrontRight;
1335
1336 /* Declarations */
1337 void get_cis_count(types::LeAudioContextType context_type,
1338 int expected_device_cnt,
1339 types::LeAudioConfigurationStrategy strategy,
1340 int group_ase_snk_cnt, int group_ase_src_count,
1341 uint8_t& cis_count_bidir, uint8_t& cis_count_unidir_sink,
1342 uint8_t& cis_count_unidir_source);
1343 } // namespace set_configurations
1344
1345 struct stream_parameters {
1346 /* For now we have always same frequency for all the channels */
1347 uint32_t sample_frequency_hz;
1348 uint32_t frame_duration_us;
1349 uint16_t octets_per_codec_frame;
1350 uint32_t audio_channel_allocation;
1351 uint8_t codec_frames_blocks_per_sdu;
1352
1353 /* Total number of channels we request from the audio framework */
1354 uint8_t num_of_channels;
1355 int num_of_devices;
1356 /* cis_handle, audio location*/
1357 std::vector<std::pair<uint16_t, uint32_t>> stream_locations;
1358
clearstream_parameters1359 void clear() {
1360 sample_frequency_hz = 0;
1361 frame_duration_us = 0;
1362 octets_per_codec_frame = 0;
1363 audio_channel_allocation = 0;
1364 codec_frames_blocks_per_sdu = 0;
1365 num_of_channels = 0;
1366 num_of_devices = 0;
1367 stream_locations.clear();
1368 }
1369 };
1370
1371 struct stream_configuration {
1372 /* Whether the group should be reconfigured once the streaming stops */
1373 bool pending_configuration;
1374
1375 /* Currently selected remote device set configuration */
1376 std::shared_ptr<
1377 const bluetooth::le_audio::set_configurations::AudioSetConfiguration>
1378 conf;
1379
1380 /* Currently selected local audio codec */
1381 types::LeAudioCodecId codec_id;
1382
1383 /* Currently selected local Sink & Source configuration */
1384 types::BidirectionalPair<stream_parameters> stream_params;
1385 };
1386
1387 void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
1388 const std::vector<uint8_t>& ccid_list);
1389 void AppendMetadataLtvEntryForStreamingContext(
1390 std::vector<uint8_t>& metadata, types::AudioContexts context_type);
1391 uint8_t GetMaxCodecFramesPerSduFromPac(const types::acs_ac_record* pac_record);
1392 } // namespace bluetooth::le_audio
1393
1394 namespace fmt {
1395 template <>
1396 struct formatter<bluetooth::le_audio::DsaMode>
1397 : enum_formatter<bluetooth::le_audio::DsaMode> {};
1398 template <>
1399 struct formatter<bluetooth::le_audio::types::CisType>
1400 : enum_formatter<bluetooth::le_audio::types::CisType> {};
1401 template <>
1402 struct formatter<bluetooth::le_audio::types::LeAudioConfigurationStrategy>
1403 : enum_formatter<bluetooth::le_audio::types::LeAudioConfigurationStrategy> {
1404 };
1405 } // namespace fmt
1406