1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Vendor Specific A2DP Codecs Support
19  */
20 
21 #define LOG_TAG "bluetooth-a2dp"
22 
23 #include "a2dp_vendor.h"
24 
25 #include <cstddef>
26 #include <cstdint>
27 #include <string>
28 
29 #include "a2dp_codec_api.h"
30 #include "a2dp_constants.h"
31 #include "a2dp_vendor_aptx.h"
32 #include "a2dp_vendor_aptx_constants.h"
33 #include "a2dp_vendor_aptx_hd.h"
34 #include "a2dp_vendor_aptx_hd_constants.h"
35 #include "a2dp_vendor_ldac.h"
36 #include "a2dp_vendor_ldac_constants.h"
37 #include "a2dp_vendor_opus.h"
38 #include "a2dp_vendor_opus_constants.h"
39 #include "avdt_api.h"
40 #include "hardware/bt_av.h"
41 #include "stack/include/bt_hdr.h"
42 
A2DP_IsVendorSourceCodecValid(const uint8_t * p_codec_info)43 bool A2DP_IsVendorSourceCodecValid(const uint8_t* p_codec_info) {
44   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
45   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
46 
47   // Check for aptX
48   if (vendor_id == A2DP_APTX_VENDOR_ID &&
49       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
50     return A2DP_IsCodecValidAptx(p_codec_info);
51   }
52 
53   // Check for aptX-HD
54   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
55       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
56     return A2DP_IsCodecValidAptxHd(p_codec_info);
57   }
58 
59   // Check for LDAC
60   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
61     return A2DP_IsCodecValidLdac(p_codec_info);
62   }
63 
64   // Check for Opus
65   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
66     return A2DP_IsCodecValidOpus(p_codec_info);
67   }
68 
69   // Add checks based on <vendor_id, codec_id>
70 
71   return false;
72 }
73 
A2DP_IsVendorPeerSourceCodecValid(const uint8_t * p_codec_info)74 bool A2DP_IsVendorPeerSourceCodecValid(const uint8_t* p_codec_info) {
75   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
76   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
77 
78   // Add checks based on <vendor_id, codec_id>
79   // NOTE: Should be done only for local Sink codecs.
80 
81   // Check for LDAC
82   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
83     return A2DP_IsCodecValidLdac(p_codec_info);
84   }
85 
86   // Check for Opus
87   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
88     return A2DP_IsCodecValidOpus(p_codec_info);
89   }
90 
91   return false;
92 }
93 
A2DP_IsVendorPeerSinkCodecValid(const uint8_t * p_codec_info)94 bool A2DP_IsVendorPeerSinkCodecValid(const uint8_t* p_codec_info) {
95   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
96   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
97 
98   // Check for aptX
99   if (vendor_id == A2DP_APTX_VENDOR_ID &&
100       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
101     return A2DP_IsCodecValidAptx(p_codec_info);
102   }
103 
104   // Check for aptX-HD
105   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
106       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
107     return A2DP_IsCodecValidAptxHd(p_codec_info);
108   }
109 
110   // Check for LDAC
111   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
112     return A2DP_IsCodecValidLdac(p_codec_info);
113   }
114 
115   // Check for Opus
116   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
117     return A2DP_IsCodecValidOpus(p_codec_info);
118   }
119 
120   // Add checks based on <vendor_id, codec_id>
121 
122   return false;
123 }
124 
A2DP_IsVendorSinkCodecSupported(const uint8_t * p_codec_info)125 tA2DP_STATUS A2DP_IsVendorSinkCodecSupported(const uint8_t* p_codec_info) {
126   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
127   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
128 
129   // Add checks based on <vendor_id, codec_id>
130   // NOTE: Should be done only for local Sink codecs.
131 
132   // Check for LDAC
133   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
134     return A2DP_IsVendorSinkCodecSupportedLdac(p_codec_info);
135   }
136 
137   // Check for Opus
138   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
139     return A2DP_IsVendorSinkCodecSupportedOpus(p_codec_info);
140   }
141 
142   return A2DP_NOT_SUPPORTED_CODEC_TYPE;
143 }
144 
A2DP_VendorUsesRtpHeader(bool content_protection_enabled,const uint8_t * p_codec_info)145 bool A2DP_VendorUsesRtpHeader(bool content_protection_enabled, const uint8_t* p_codec_info) {
146   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
147   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
148 
149   // Check for aptX
150   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
151     return A2DP_VendorUsesRtpHeaderAptx(content_protection_enabled, p_codec_info);
152   }
153 
154   // Check for aptX-HD
155   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
156     return A2DP_VendorUsesRtpHeaderAptxHd(content_protection_enabled, p_codec_info);
157   }
158 
159   // Check for LDAC
160   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
161     return A2DP_VendorUsesRtpHeaderLdac(content_protection_enabled, p_codec_info);
162   }
163 
164   // Check for Opus
165   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
166     return A2DP_VendorUsesRtpHeaderOpus(content_protection_enabled, p_codec_info);
167   }
168 
169   // Add checks based on <content_protection_enabled, vendor_id, codec_id>
170 
171   return true;
172 }
173 
A2DP_VendorCodecName(const uint8_t * p_codec_info)174 const char* A2DP_VendorCodecName(const uint8_t* p_codec_info) {
175   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
176   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
177 
178   // Check for aptX
179   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
180     return A2DP_VendorCodecNameAptx(p_codec_info);
181   }
182 
183   // Check for aptX-HD
184   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
185     return A2DP_VendorCodecNameAptxHd(p_codec_info);
186   }
187 
188   // Check for LDAC
189   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
190     return A2DP_VendorCodecNameLdac(p_codec_info);
191   }
192 
193   // Check for Opus
194   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
195     return A2DP_VendorCodecNameOpus(p_codec_info);
196   }
197 
198   // Add checks based on <vendor_id, codec_id>
199 
200   return "UNKNOWN VENDOR CODEC";
201 }
202 
A2DP_VendorCodecTypeEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)203 bool A2DP_VendorCodecTypeEquals(const uint8_t* p_codec_info_a, const uint8_t* p_codec_info_b) {
204   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
205   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
206 
207   if ((codec_type_a != codec_type_b) || (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
208     return false;
209   }
210 
211   uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
212   uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
213   uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
214   uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
215 
216   if (vendor_id_a != vendor_id_b || codec_id_a != codec_id_b) {
217     return false;
218   }
219 
220   // Check for aptX
221   if (vendor_id_a == A2DP_APTX_VENDOR_ID && codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
222     return A2DP_VendorCodecTypeEqualsAptx(p_codec_info_a, p_codec_info_b);
223   }
224 
225   // Check for aptX-HD
226   if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID && codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
227     return A2DP_VendorCodecTypeEqualsAptxHd(p_codec_info_a, p_codec_info_b);
228   }
229 
230   // Check for LDAC
231   if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
232     return A2DP_VendorCodecTypeEqualsLdac(p_codec_info_a, p_codec_info_b);
233   }
234 
235   // Check for Opus
236   if (vendor_id_a == A2DP_OPUS_VENDOR_ID && codec_id_a == A2DP_OPUS_CODEC_ID) {
237     return A2DP_VendorCodecTypeEqualsOpus(p_codec_info_a, p_codec_info_b);
238   }
239 
240   // OPTIONAL: Add extra vendor-specific checks based on the
241   // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
242 
243   return true;
244 }
245 
A2DP_VendorGetBitRate(const uint8_t * p_codec_info)246 int A2DP_VendorGetBitRate(const uint8_t* p_codec_info) {
247   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
248   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
249 
250   // Check for aptX
251   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
252     return A2DP_VendorGetBitRateAptx(p_codec_info);
253   }
254 
255   // Check for aptX-HD
256   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
257     return A2DP_VendorGetBitRateAptxHd(p_codec_info);
258   }
259 
260   // Check for LDAC
261   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
262     return A2DP_VendorGetBitRateLdac(p_codec_info);
263   }
264 
265   // Check for Opus
266   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
267     return A2DP_VendorGetBitRateOpus(p_codec_info);
268   }
269 
270   // Add checks based on <vendor_id, codec_id>
271 
272   return -1;
273 }
274 
A2DP_VendorGetSinkTrackChannelType(const uint8_t * p_codec_info)275 int A2DP_VendorGetSinkTrackChannelType(const uint8_t* p_codec_info) {
276   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
277   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
278 
279   // Add checks based on <vendor_id, codec_id>
280   // NOTE: Should be done only for local Sink codecs.
281 
282   // Check for LDAC
283   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
284     return A2DP_VendorGetSinkTrackChannelTypeLdac(p_codec_info);
285   }
286 
287   // Check for Opus
288   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
289     return A2DP_VendorGetSinkTrackChannelTypeOpus(p_codec_info);
290   }
291 
292   return -1;
293 }
294 
A2DP_VendorBuildCodecHeader(const uint8_t * p_codec_info,BT_HDR * p_buf,uint16_t frames_per_packet)295 bool A2DP_VendorBuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
296                                  uint16_t frames_per_packet) {
297   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
298   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
299 
300   // Check for aptX
301   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
302     return A2DP_VendorBuildCodecHeaderAptx(p_codec_info, p_buf, frames_per_packet);
303   }
304 
305   // Check for aptX-HD
306   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
307     return A2DP_VendorBuildCodecHeaderAptxHd(p_codec_info, p_buf, frames_per_packet);
308   }
309 
310   // Check for LDAC
311   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
312     return A2DP_VendorBuildCodecHeaderLdac(p_codec_info, p_buf, frames_per_packet);
313   }
314 
315   // Check for Opus
316   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
317     return A2DP_VendorBuildCodecHeaderOpus(p_codec_info, p_buf, frames_per_packet);
318   }
319 
320   // Add checks based on <vendor_id, codec_id>
321 
322   return false;
323 }
324 
A2DP_VendorGetEncoderInterface(const uint8_t * p_codec_info)325 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(const uint8_t* p_codec_info) {
326   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
327   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
328 
329   // Check for aptX
330   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
331     return A2DP_VendorGetEncoderInterfaceAptx(p_codec_info);
332   }
333 
334   // Check for aptX-HD
335   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
336     return A2DP_VendorGetEncoderInterfaceAptxHd(p_codec_info);
337   }
338 
339   // Check for LDAC
340   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
341     return A2DP_VendorGetEncoderInterfaceLdac(p_codec_info);
342   }
343 
344   // Check for Opus
345   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
346     return A2DP_VendorGetEncoderInterfaceOpus(p_codec_info);
347   }
348 
349   // Add checks based on <vendor_id, codec_id>
350 
351   return NULL;
352 }
353 
A2DP_VendorGetDecoderInterface(const uint8_t * p_codec_info)354 const tA2DP_DECODER_INTERFACE* A2DP_VendorGetDecoderInterface(const uint8_t* p_codec_info) {
355   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
356   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
357 
358   // Add checks based on <vendor_id, codec_id>
359   // NOTE: Should be done only for local Sink codecs.
360 
361   // Check for LDAC
362   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
363     return A2DP_VendorGetDecoderInterfaceLdac(p_codec_info);
364   }
365 
366   // Check for Opus
367   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
368     return A2DP_VendorGetDecoderInterfaceOpus(p_codec_info);
369   }
370 
371   return NULL;
372 }
373 
A2DP_VendorAdjustCodec(uint8_t * p_codec_info)374 bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
375   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
376   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
377 
378   // Check for aptX
379   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
380     return A2DP_VendorAdjustCodecAptx(p_codec_info);
381   }
382 
383   // Check for aptX-HD
384   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
385     return A2DP_VendorAdjustCodecAptxHd(p_codec_info);
386   }
387 
388   // Check for LDAC
389   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
390     return A2DP_VendorAdjustCodecLdac(p_codec_info);
391   }
392 
393   // Check for Opus
394   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
395     return A2DP_VendorAdjustCodecOpus(p_codec_info);
396   }
397 
398   // Add checks based on <vendor_id, codec_id>
399 
400   return false;
401 }
402 
A2DP_VendorSourceCodecIndex(const uint8_t * p_codec_info)403 btav_a2dp_codec_index_t A2DP_VendorSourceCodecIndex(const uint8_t* p_codec_info) {
404   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
405   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
406 
407   // Check for aptX
408   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
409     return A2DP_VendorSourceCodecIndexAptx(p_codec_info);
410   }
411 
412   // Check for aptX-HD
413   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
414     return A2DP_VendorSourceCodecIndexAptxHd(p_codec_info);
415   }
416 
417   // Check for LDAC
418   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
419     return A2DP_VendorSourceCodecIndexLdac(p_codec_info);
420   }
421 
422   // Check for Opus
423   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
424     return A2DP_VendorSourceCodecIndexOpus(p_codec_info);
425   }
426 
427   // Add checks based on <vendor_id, codec_id>
428 
429   return BTAV_A2DP_CODEC_INDEX_MAX;
430 }
431 
A2DP_VendorSinkCodecIndex(const uint8_t * p_codec_info)432 btav_a2dp_codec_index_t A2DP_VendorSinkCodecIndex(const uint8_t* p_codec_info) {
433   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
434   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
435 
436   // Add checks based on <vendor_id, codec_id>
437   // NOTE: Should be done only for local Sink codecs.
438 
439   // Check for LDAC
440   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
441     return A2DP_VendorSinkCodecIndexLdac(p_codec_info);
442   }
443 
444   // Check for Opus
445   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
446     return A2DP_VendorSinkCodecIndexOpus(p_codec_info);
447   }
448 
449   return BTAV_A2DP_CODEC_INDEX_MAX;
450 }
451 
A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index)452 const char* A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index) {
453   // Add checks based on codec_index
454   switch (codec_index) {
455     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
456     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
457     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
458     case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
459       break;  // These are not vendor-specific codecs
460     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
461       return A2DP_VendorCodecIndexStrAptx();
462     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
463       return A2DP_VendorCodecIndexStrAptxHd();
464     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
465       return A2DP_VendorCodecIndexStrLdac();
466     case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
467       return A2DP_VendorCodecIndexStrLdacSink();
468     case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
469       return "LC3 not implemented";
470     case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
471       return A2DP_VendorCodecIndexStrOpus();
472     case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
473       return A2DP_VendorCodecIndexStrOpusSink();
474     // Add a switch statement for each vendor-specific codec
475     case BTAV_A2DP_CODEC_INDEX_MAX:
476       break;
477     case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN:
478     case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN:
479       break;
480   }
481 
482   return "UNKNOWN CODEC INDEX";
483 }
484 
A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)485 bool A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index, AvdtpSepConfig* p_cfg) {
486   // Add checks based on codec_index
487   switch (codec_index) {
488     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
489     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
490     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
491     case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
492       break;  // These are not vendor-specific codecs
493     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
494       return A2DP_VendorInitCodecConfigAptx(p_cfg);
495     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
496       return A2DP_VendorInitCodecConfigAptxHd(p_cfg);
497     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
498       return A2DP_VendorInitCodecConfigLdac(p_cfg);
499     case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
500       return A2DP_VendorInitCodecConfigLdacSink(p_cfg);
501     case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
502       break;  // not implemented
503     case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
504       return A2DP_VendorInitCodecConfigOpus(p_cfg);
505     case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
506       return A2DP_VendorInitCodecConfigOpusSink(p_cfg);
507     // Add a switch statement for each vendor-specific codec
508     case BTAV_A2DP_CODEC_INDEX_MAX:
509       break;
510     case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN:
511     case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN:
512       break;
513   }
514 
515   return false;
516 }
517 
A2DP_VendorCodecInfoString(const uint8_t * p_codec_info)518 std::string A2DP_VendorCodecInfoString(const uint8_t* p_codec_info) {
519   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
520   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
521 
522   // Check for aptX
523   if (vendor_id == A2DP_APTX_VENDOR_ID && codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
524     return A2DP_VendorCodecInfoStringAptx(p_codec_info);
525   }
526 
527   // Check for aptX-HD
528   if (vendor_id == A2DP_APTX_HD_VENDOR_ID && codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
529     return A2DP_VendorCodecInfoStringAptxHd(p_codec_info);
530   }
531 
532   // Check for LDAC
533   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
534     return A2DP_VendorCodecInfoStringLdac(p_codec_info);
535   }
536 
537   // Check for Opus
538   if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
539     return A2DP_VendorCodecInfoStringOpus(p_codec_info);
540   }
541 
542   // Add checks based on <vendor_id, codec_id>
543 
544   return std::format("Unsupported codec vendor_id: 0x{:x} codec_id: 0x{:x}", vendor_id, codec_id);
545 }
546