1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - 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 #include "broadcaster_types.h"
19 
20 #include <base/strings/string_number_conversions.h>
21 
22 #include <vector>
23 
24 #include "bta/le_audio/audio_hal_client/audio_hal_client.h"
25 #include "bta_le_audio_broadcaster_api.h"
26 #include "btm_ble_api_types.h"
27 #include "internal_include/stack_config.h"
28 #include "osi/include/properties.h"
29 #include "stack/include/bt_types.h"
30 
31 using bluetooth::le_audio::BasicAudioAnnouncementBisConfig;
32 using bluetooth::le_audio::BasicAudioAnnouncementCodecConfig;
33 using bluetooth::le_audio::BasicAudioAnnouncementData;
34 using bluetooth::le_audio::BasicAudioAnnouncementSubgroup;
35 using bluetooth::le_audio::types::LeAudioContextType;
36 
37 namespace bluetooth::le_audio {
38 namespace broadcaster {
39 
EmitHeader(const BasicAudioAnnouncementData & announcement_data,std::vector<uint8_t> & data)40 static void EmitHeader(const BasicAudioAnnouncementData& announcement_data,
41                        std::vector<uint8_t>& data) {
42   size_t old_size = data.size();
43   data.resize(old_size + 3);
44 
45   // Set the cursor behind the old data
46   uint8_t* p_value = data.data() + old_size;
47 
48   UINT24_TO_STREAM(p_value, announcement_data.presentation_delay_us);
49 }
50 
EmitCodecConfiguration(const BasicAudioAnnouncementCodecConfig & config,std::vector<uint8_t> & data,const BasicAudioAnnouncementCodecConfig * lower_lvl_config)51 static void EmitCodecConfiguration(
52     const BasicAudioAnnouncementCodecConfig& config, std::vector<uint8_t>& data,
53     const BasicAudioAnnouncementCodecConfig* lower_lvl_config) {
54   size_t old_size = data.size();
55 
56   // Add 5 for full, or 1 for short Codec ID
57   uint8_t codec_config_length = 5;
58 
59   auto ltv = types::LeAudioLtvMap(config.codec_specific_params);
60   auto codec_spec_raw_sz = ltv.RawPacketSize();
61   if (config.vendor_codec_specific_params) {
62     codec_spec_raw_sz = config.vendor_codec_specific_params->size();
63   }
64 
65   // Add 1 for the codec spec. config length + config spec. data itself
66   codec_config_length += 1 + codec_spec_raw_sz;
67 
68   // Resize and set the cursor behind the old data
69   data.resize(old_size + codec_config_length);
70   uint8_t* p_value = data.data() + old_size;
71 
72   // Codec ID
73   UINT8_TO_STREAM(p_value, config.codec_id);
74   UINT16_TO_STREAM(p_value, config.vendor_company_id);
75   UINT16_TO_STREAM(p_value, config.vendor_codec_id);
76 
77   // Codec specific config length and data (either vendor specific or the LTVs)
78   UINT8_TO_STREAM(p_value, codec_spec_raw_sz);
79   if (config.vendor_codec_specific_params) {
80     ARRAY_TO_STREAM(
81         p_value, config.vendor_codec_specific_params->data(),
82         static_cast<int>(config.vendor_codec_specific_params->size()));
83   } else {
84     p_value = ltv.RawPacket(p_value);
85   }
86 }
87 
EmitMetadata(const std::map<uint8_t,std::vector<uint8_t>> & metadata,std::vector<uint8_t> & data)88 static void EmitMetadata(
89     const std::map<uint8_t, std::vector<uint8_t>>& metadata,
90     std::vector<uint8_t>& data) {
91   auto ltv = types::LeAudioLtvMap(metadata);
92   auto ltv_raw_sz = ltv.RawPacketSize();
93 
94   size_t old_size = data.size();
95   data.resize(old_size + ltv_raw_sz + 1);
96 
97   // Set the cursor behind the old data
98   uint8_t* p_value = data.data() + old_size;
99 
100   UINT8_TO_STREAM(p_value, ltv_raw_sz);
101   if (ltv_raw_sz > 0) {
102     p_value = ltv.RawPacket(p_value);
103   }
104 }
105 
EmitBroadcastName(const std::string & name,std::vector<uint8_t> & data)106 static void EmitBroadcastName(const std::string& name,
107                               std::vector<uint8_t>& data) {
108   int name_len = name.length();
109   size_t old_size = data.size();
110   data.resize(old_size + name_len + 2);
111 
112   // Set the cursor behind the old data
113   uint8_t* p_value = data.data() + old_size;
114   UINT8_TO_STREAM(p_value, name_len + 1);
115   UINT8_TO_STREAM(p_value, BTM_BLE_AD_TYPE_BROADCAST_NAME);
116 
117   std::vector<uint8_t> vec(name.begin(), name.end());
118   ARRAY_TO_STREAM(p_value, vec.data(), name_len);
119 }
120 
EmitBisConfigs(const std::vector<BasicAudioAnnouncementBisConfig> & bis_configs,std::vector<uint8_t> & data)121 static void EmitBisConfigs(
122     const std::vector<BasicAudioAnnouncementBisConfig>& bis_configs,
123     std::vector<uint8_t>& data) {
124   // Emit each BIS config - that's the level 3 data
125   for (auto const& bis_config : bis_configs) {
126     auto ltv = types::LeAudioLtvMap(bis_config.codec_specific_params);
127     auto ltv_raw_sz = ltv.RawPacketSize();
128 
129     size_t old_size = data.size();
130     data.resize(old_size + ltv_raw_sz + 2);
131 
132     // Set the cursor behind the old data
133     auto* p_value = data.data() + old_size;
134 
135     // BIS_index[i[k]]
136     UINT8_TO_STREAM(p_value, bis_config.bis_index);
137 
138     // Per BIS Codec Specific Params[i[k]]
139     UINT8_TO_STREAM(p_value, ltv_raw_sz);
140     if (ltv_raw_sz > 0) {
141       p_value = ltv.RawPacket(p_value);
142     }
143   }
144 }
145 
EmitSubgroup(const BasicAudioAnnouncementSubgroup & subgroup_config,std::vector<uint8_t> & data)146 static void EmitSubgroup(const BasicAudioAnnouncementSubgroup& subgroup_config,
147                          std::vector<uint8_t>& data) {
148   // That's the level 2 data
149 
150   // Resize for the num_bis
151   size_t initial_offset = data.size();
152   data.resize(initial_offset + 1);
153 
154   // Set the cursor behind the old data and adds the level 2 Num_BIS[i]
155   uint8_t* p_value = data.data() + initial_offset;
156   UINT8_TO_STREAM(p_value, subgroup_config.bis_configs.size());
157 
158   EmitCodecConfiguration(subgroup_config.codec_config, data, nullptr);
159   EmitMetadata(subgroup_config.metadata, data);
160 
161   // This adds the level 3 data
162   EmitBisConfigs(subgroup_config.bis_configs, data);
163 }
164 
ToRawPacket(BasicAudioAnnouncementData const & in,std::vector<uint8_t> & data)165 bool ToRawPacket(BasicAudioAnnouncementData const& in,
166                  std::vector<uint8_t>& data) {
167   EmitHeader(in, data);
168 
169   // Set the cursor behind the old data and resize
170   size_t old_size = data.size();
171   data.resize(old_size + 1);
172   uint8_t* p_value = data.data() + old_size;
173 
174   // Emit the subgroup size and each subgroup
175   // That's the level 1 Num_Subgroups
176   UINT8_TO_STREAM(p_value, in.subgroup_configs.size());
177   for (const auto& subgroup_config : in.subgroup_configs) {
178     // That's the level 2 and higher level data
179     EmitSubgroup(subgroup_config, data);
180   }
181 
182   return true;
183 }
184 
PrepareAdvertisingData(bool is_public,const std::string & broadcast_name,bluetooth::le_audio::BroadcastId & broadcast_id,const bluetooth::le_audio::PublicBroadcastAnnouncementData & public_announcement,std::vector<uint8_t> & adv_data)185 void PrepareAdvertisingData(
186     bool is_public, const std::string& broadcast_name,
187     bluetooth::le_audio::BroadcastId& broadcast_id,
188     const bluetooth::le_audio::PublicBroadcastAnnouncementData&
189         public_announcement,
190     std::vector<uint8_t>& adv_data) {
191   adv_data.resize(7);
192   uint8_t* data_ptr = adv_data.data();
193   UINT8_TO_STREAM(data_ptr, 6);
194   UINT8_TO_STREAM(data_ptr, BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE);
195   UINT16_TO_STREAM(data_ptr, kBroadcastAudioAnnouncementServiceUuid);
196   UINT24_TO_STREAM(data_ptr, broadcast_id);
197 
198   // Prepare public broadcast announcement data
199   if (is_public) {
200     size_t old_size = adv_data.size();
201     // 5: datalen(1) + adtype(1) + serviceuuid(2) + features(1)
202     adv_data.resize(old_size + 5);
203     // Skip the data length field until the full content is generated
204     data_ptr = adv_data.data() + old_size + 1;
205     UINT8_TO_STREAM(data_ptr, BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE);
206     UINT16_TO_STREAM(data_ptr, kPublicBroadcastAnnouncementServiceUuid);
207     UINT8_TO_STREAM(data_ptr, public_announcement.features);
208     // Set metadata length to 0 if no meta data present
209     EmitMetadata(public_announcement.metadata, adv_data);
210 
211     // Update the length field accordingly
212     data_ptr = adv_data.data() + old_size;
213     UINT8_TO_STREAM(data_ptr, adv_data.size() - old_size - 1);
214 
215     // Prepare broadcast name
216     if (!broadcast_name.empty()) {
217       EmitBroadcastName(broadcast_name, adv_data);
218     }
219   }
220 }
221 
PreparePeriodicData(const BasicAudioAnnouncementData & announcement,std::vector<uint8_t> & periodic_data)222 void PreparePeriodicData(const BasicAudioAnnouncementData& announcement,
223                          std::vector<uint8_t>& periodic_data) {
224   /* Account for AD Type + Service UUID */
225   periodic_data.resize(4);
226   /* Skip the data length field until the full content is generated */
227   uint8_t* data_ptr = periodic_data.data() + 1;
228   UINT8_TO_STREAM(data_ptr, BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE);
229   UINT16_TO_STREAM(data_ptr, kBasicAudioAnnouncementServiceUuid);
230 
231   /* Append the announcement */
232   ToRawPacket(announcement, periodic_data);
233 
234   /* Update the length field accordingly */
235   data_ptr = periodic_data.data();
236   UINT8_TO_STREAM(data_ptr, periodic_data.size() - 1);
237 }
238 
239 le_audio::LeAudioCodecConfiguration
GetAudioHalClientConfig() const240 BroadcastConfiguration::GetAudioHalClientConfig() const {
241   return {
242       // Get the maximum number of channels
243       .num_channels = GetNumChannelsMax(),
244       // Get the max sampling frequency
245       .sample_rate = GetSamplingFrequencyHzMax(),
246       // Use the default 16 bits per sample resolution in the audio framework
247       .bits_per_sample = 16,
248       // Get the data interval
249       .data_interval_us = GetSduIntervalUs(),
250   };
251 }
252 
operator <<(std::ostream & os,const bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig & config)253 std::ostream& operator<<(
254     std::ostream& os,
255     const bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig&
256         config) {
257   os << " BroadcastSubgroupCodecConfig={";
258   os << "CodecID="
259      << "{" << +config.GetLeAudioCodecId().coding_format << ":"
260      << +config.GetLeAudioCodecId().vendor_company_id << ":"
261      << +config.GetLeAudioCodecId().vendor_codec_id << "}, ";
262   os << "BISes=[";
263   if (!config.bis_codec_configs_.empty()) {
264     for (auto const& bis_config : config.bis_codec_configs_) {
265       os << bis_config << ", ";
266     }
267     os << "\b\b";
268   }
269   os << "]";
270   os << ", BitsPerSample=" << +config.GetBitsPerSample() << "}";
271   os << "}";
272   return os;
273 }
274 
operator <<(std::ostream & os,const le_audio::broadcaster::BroadcastSubgroupBisCodecConfig & config)275 std::ostream& operator<<(
276     std::ostream& os,
277     const le_audio::broadcaster::BroadcastSubgroupBisCodecConfig& config) {
278   os << "BisCfg={numBis=" << +config.GetNumBis()
279      << ", NumChannelsPerBis=" << +config.GetNumChannelsPerBis()
280      << ", CodecSpecific=" << config.GetCodecSpecData().GetAsCoreCodecConfig();
281   if (config.GetVendorCodecSpecific().has_value()) {
282     os << ", VendorSpecific=[";
283     if (!config.GetVendorCodecSpecific()->empty()) {
284       os << base::HexEncode(config.GetVendorCodecSpecific()->data(),
285                             config.GetVendorCodecSpecific()->size());
286     }
287     os << "]";
288   }
289   os << "}";
290   return os;
291 }
292 
operator <<(std::ostream & os,const bluetooth::le_audio::broadcaster::BroadcastQosConfig & config)293 std::ostream& operator<<(
294     std::ostream& os,
295     const bluetooth::le_audio::broadcaster::BroadcastQosConfig& config) {
296   os << " BroadcastQosConfig=[";
297   os << "RTN=" << +config.getRetransmissionNumber();
298   os << ", MaxTransportLatency=" << config.getMaxTransportLatency();
299   os << "]";
300   return os;
301 }
302 
operator <<(std::ostream & os,const le_audio::broadcaster::BroadcastConfiguration & config)303 std::ostream& operator<<(
304     std::ostream& os,
305     const le_audio::broadcaster::BroadcastConfiguration& config) {
306   os << "BroadcastCfg={";
307   for (const auto& subgroup_cfg : config.subgroups) {
308     os << subgroup_cfg << std::endl;
309   }
310   os << config.qos << std::endl;
311   os << config.data_path << std::endl;
312   os << ", sduIntervalUs=" << config.sduIntervalUs;
313   os << ", maxSduOctets=" << config.maxSduOctets;
314   os << ", phy=" << config.phy;
315   os << ", packing=" << config.packing;
316   os << ", framing=" << config.framing;
317   os << "}" << std::endl;
318 
319   return os;
320 }
321 
322 } /* namespace broadcaster */
323 }  // namespace bluetooth::le_audio
324 
325 /* Helper functions for comparing BroadcastAnnouncements */
326 namespace bluetooth::le_audio {
327 
isMetadataSame(std::map<uint8_t,std::vector<uint8_t>> m1,std::map<uint8_t,std::vector<uint8_t>> m2)328 static bool isMetadataSame(std::map<uint8_t, std::vector<uint8_t>> m1,
329                            std::map<uint8_t, std::vector<uint8_t>> m2) {
330   if (m1.size() != m2.size()) return false;
331 
332   for (auto& m1pair : m1) {
333     if (m2.count(m1pair.first) == 0) return false;
334 
335     auto& m2val = m2.at(m1pair.first);
336     if (m1pair.second.size() != m2val.size()) return false;
337 
338     if (m1pair.second.size() != 0) {
339       if (memcmp(m1pair.second.data(), m2val.data(), m2val.size()) != 0)
340         return false;
341     }
342   }
343   return true;
344 }
345 
operator ==(const BasicAudioAnnouncementData & lhs,const BasicAudioAnnouncementData & rhs)346 bool operator==(const BasicAudioAnnouncementData& lhs,
347                 const BasicAudioAnnouncementData& rhs) {
348   if (lhs.presentation_delay_us != rhs.presentation_delay_us) return false;
349 
350   if (lhs.subgroup_configs.size() != rhs.subgroup_configs.size()) return false;
351 
352   for (auto i = 0lu; i < lhs.subgroup_configs.size(); ++i) {
353     auto& lhs_subgroup = lhs.subgroup_configs[i];
354     auto& rhs_subgroup = rhs.subgroup_configs[i];
355 
356     if (lhs_subgroup.codec_config.codec_id !=
357         rhs_subgroup.codec_config.codec_id)
358       return false;
359 
360     if (lhs_subgroup.codec_config.vendor_company_id !=
361         rhs_subgroup.codec_config.vendor_company_id)
362       return false;
363 
364     if (lhs_subgroup.codec_config.vendor_codec_id !=
365         rhs_subgroup.codec_config.vendor_codec_id)
366       return false;
367 
368     if (!isMetadataSame(lhs_subgroup.codec_config.codec_specific_params,
369                         rhs_subgroup.codec_config.codec_specific_params))
370       return false;
371 
372     if (!isMetadataSame(lhs_subgroup.metadata, rhs_subgroup.metadata))
373       return false;
374 
375     for (auto j = 0lu; j < lhs_subgroup.bis_configs.size(); ++j) {
376       auto& lhs_bis_config = lhs_subgroup.bis_configs[i];
377       auto& rhs_bis_config = rhs_subgroup.bis_configs[i];
378       if (lhs_bis_config.bis_index != rhs_bis_config.bis_index) return false;
379 
380       if (!isMetadataSame(lhs_bis_config.codec_specific_params,
381                           rhs_bis_config.codec_specific_params))
382         return false;
383     }
384   }
385 
386   return true;
387 }
388 
operator ==(const PublicBroadcastAnnouncementData & lhs,const PublicBroadcastAnnouncementData & rhs)389 bool operator==(const PublicBroadcastAnnouncementData& lhs,
390                 const PublicBroadcastAnnouncementData& rhs) {
391   if (lhs.features != rhs.features) return false;
392   if (!isMetadataSame(lhs.metadata, rhs.metadata)) return false;
393 
394   return true;
395 }
396 }  // namespace bluetooth::le_audio
397