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