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