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 "a2dp_vendor"
22
23 #include "a2dp_vendor.h"
24
25 #include "a2dp_vendor_aptx.h"
26 #include "a2dp_vendor_aptx_hd.h"
27 #include "a2dp_vendor_ldac.h"
28 #include "a2dp_vendor_opus.h"
29 #include "bt_target.h"
30 #include "osi/include/log.h"
31 #include "osi/include/osi.h"
32 #include "stack/include/bt_hdr.h"
33
A2DP_IsVendorSourceCodecValid(const uint8_t * p_codec_info)34 bool A2DP_IsVendorSourceCodecValid(const uint8_t* p_codec_info) {
35 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
36 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
37
38 // Check for aptX
39 if (vendor_id == A2DP_APTX_VENDOR_ID &&
40 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
41 return A2DP_IsVendorSourceCodecValidAptx(p_codec_info);
42 }
43
44 // Check for aptX-HD
45 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
46 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
47 return A2DP_IsVendorSourceCodecValidAptxHd(p_codec_info);
48 }
49
50 // Check for LDAC
51 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
52 return A2DP_IsVendorSourceCodecValidLdac(p_codec_info);
53 }
54
55 // Check for Opus
56 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
57 return A2DP_IsVendorSourceCodecValidOpus(p_codec_info);
58 }
59
60 // Add checks based on <vendor_id, codec_id>
61
62 return false;
63 }
64
A2DP_IsVendorSinkCodecValid(const uint8_t * p_codec_info)65 bool A2DP_IsVendorSinkCodecValid(const uint8_t* p_codec_info) {
66 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
67 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
68
69 // Add checks based on <vendor_id, codec_id>
70 // NOTE: Should be done only for local Sink codecs.
71
72 // Check for LDAC
73 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
74 return A2DP_IsVendorSinkCodecValidLdac(p_codec_info);
75 }
76
77 // Check for Opus
78 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
79 return A2DP_IsVendorSinkCodecValidOpus(p_codec_info);
80 }
81
82 return false;
83 }
84
A2DP_IsVendorPeerSourceCodecValid(const uint8_t * p_codec_info)85 bool A2DP_IsVendorPeerSourceCodecValid(const uint8_t* p_codec_info) {
86 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
87 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
88
89 // Add checks based on <vendor_id, codec_id>
90 // NOTE: Should be done only for local Sink codecs.
91
92 // Check for LDAC
93 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
94 return A2DP_IsVendorPeerSourceCodecValidLdac(p_codec_info);
95 }
96
97 // Check for Opus
98 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
99 return A2DP_IsVendorPeerSourceCodecValidOpus(p_codec_info);
100 }
101
102 return false;
103 }
104
A2DP_IsVendorPeerSinkCodecValid(const uint8_t * p_codec_info)105 bool A2DP_IsVendorPeerSinkCodecValid(const uint8_t* p_codec_info) {
106 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
107 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
108
109 // Check for aptX
110 if (vendor_id == A2DP_APTX_VENDOR_ID &&
111 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
112 return A2DP_IsVendorPeerSinkCodecValidAptx(p_codec_info);
113 }
114
115 // Check for aptX-HD
116 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
117 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
118 return A2DP_IsVendorPeerSinkCodecValidAptxHd(p_codec_info);
119 }
120
121 // Check for LDAC
122 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
123 return A2DP_IsVendorPeerSinkCodecValidLdac(p_codec_info);
124 }
125
126 // Check for Opus
127 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
128 return A2DP_IsVendorPeerSinkCodecValidOpus(p_codec_info);
129 }
130
131 // Add checks based on <vendor_id, codec_id>
132
133 return false;
134 }
135
A2DP_IsVendorSinkCodecSupported(const uint8_t * p_codec_info)136 bool A2DP_IsVendorSinkCodecSupported(const uint8_t* p_codec_info) {
137 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
138 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
139
140 // Add checks based on <vendor_id, codec_id>
141 // NOTE: Should be done only for local Sink codecs.
142
143 // Check for LDAC
144 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
145 return A2DP_IsVendorSinkCodecSupportedLdac(p_codec_info);
146 }
147
148 // Check for Opus
149 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
150 return A2DP_IsVendorSinkCodecSupportedOpus(p_codec_info);
151 }
152
153 return false;
154 }
155
A2DP_IsVendorPeerSourceCodecSupported(const uint8_t * p_codec_info)156 bool A2DP_IsVendorPeerSourceCodecSupported(const uint8_t* p_codec_info) {
157 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
158 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
159
160 // Add checks based on <vendor_id, codec_id> and peer codec capabilities
161 // NOTE: Should be done only for local Sink codecs.
162
163 // Check for LDAC
164 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
165 return A2DP_IsPeerSourceCodecSupportedLdac(p_codec_info);
166 }
167
168 // Check for Opus
169 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
170 return A2DP_IsPeerSourceCodecSupportedOpus(p_codec_info);
171 }
172
173 return false;
174 }
175
A2DP_VendorCodecGetVendorId(const uint8_t * p_codec_info)176 uint32_t A2DP_VendorCodecGetVendorId(const uint8_t* p_codec_info) {
177 const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_VENDOR_ID_START_IDX];
178
179 uint32_t vendor_id = (p[0] & 0x000000ff) | ((p[1] << 8) & 0x0000ff00) |
180 ((p[2] << 16) & 0x00ff0000) |
181 ((p[3] << 24) & 0xff000000);
182
183 return vendor_id;
184 }
185
A2DP_VendorCodecGetCodecId(const uint8_t * p_codec_info)186 uint16_t A2DP_VendorCodecGetCodecId(const uint8_t* p_codec_info) {
187 const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_CODEC_ID_START_IDX];
188
189 uint16_t codec_id = (p[0] & 0x00ff) | ((p[1] << 8) & 0xff00);
190
191 return codec_id;
192 }
193
A2DP_VendorUsesRtpHeader(bool content_protection_enabled,const uint8_t * p_codec_info)194 bool A2DP_VendorUsesRtpHeader(bool content_protection_enabled,
195 const uint8_t* p_codec_info) {
196 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
197 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
198
199 // Check for aptX
200 if (vendor_id == A2DP_APTX_VENDOR_ID &&
201 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
202 return A2DP_VendorUsesRtpHeaderAptx(content_protection_enabled,
203 p_codec_info);
204 }
205
206 // Check for aptX-HD
207 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
208 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
209 return A2DP_VendorUsesRtpHeaderAptxHd(content_protection_enabled,
210 p_codec_info);
211 }
212
213 // Check for LDAC
214 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
215 return A2DP_VendorUsesRtpHeaderLdac(content_protection_enabled,
216 p_codec_info);
217 }
218
219 // Check for Opus
220 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
221 return A2DP_VendorUsesRtpHeaderOpus(content_protection_enabled,
222 p_codec_info);
223 }
224
225 // Add checks based on <content_protection_enabled, vendor_id, codec_id>
226
227 return true;
228 }
229
A2DP_VendorCodecName(const uint8_t * p_codec_info)230 const char* A2DP_VendorCodecName(const uint8_t* p_codec_info) {
231 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
232 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
233
234 // Check for aptX
235 if (vendor_id == A2DP_APTX_VENDOR_ID &&
236 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
237 return A2DP_VendorCodecNameAptx(p_codec_info);
238 }
239
240 // Check for aptX-HD
241 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
242 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
243 return A2DP_VendorCodecNameAptxHd(p_codec_info);
244 }
245
246 // Check for LDAC
247 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
248 return A2DP_VendorCodecNameLdac(p_codec_info);
249 }
250
251 // Check for Opus
252 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
253 return A2DP_VendorCodecNameOpus(p_codec_info);
254 }
255
256 // Add checks based on <vendor_id, codec_id>
257
258 return "UNKNOWN VENDOR CODEC";
259 }
260
A2DP_VendorCodecTypeEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)261 bool A2DP_VendorCodecTypeEquals(const uint8_t* p_codec_info_a,
262 const uint8_t* p_codec_info_b) {
263 tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
264 tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
265
266 if ((codec_type_a != codec_type_b) ||
267 (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
268 return false;
269 }
270
271 uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
272 uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
273 uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
274 uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
275
276 if (vendor_id_a != vendor_id_b || codec_id_a != codec_id_b) return false;
277
278 // Check for aptX
279 if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
280 codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
281 return A2DP_VendorCodecTypeEqualsAptx(p_codec_info_a, p_codec_info_b);
282 }
283
284 // Check for aptX-HD
285 if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
286 codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
287 return A2DP_VendorCodecTypeEqualsAptxHd(p_codec_info_a, p_codec_info_b);
288 }
289
290 // Check for LDAC
291 if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
292 return A2DP_VendorCodecTypeEqualsLdac(p_codec_info_a, p_codec_info_b);
293 }
294
295 // Check for Opus
296 if (vendor_id_a == A2DP_OPUS_VENDOR_ID && codec_id_a == A2DP_OPUS_CODEC_ID) {
297 return A2DP_VendorCodecTypeEqualsOpus(p_codec_info_a, p_codec_info_b);
298 }
299
300 // OPTIONAL: Add extra vendor-specific checks based on the
301 // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
302
303 return true;
304 }
305
A2DP_VendorCodecEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)306 bool A2DP_VendorCodecEquals(const uint8_t* p_codec_info_a,
307 const uint8_t* p_codec_info_b) {
308 tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
309 tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
310
311 if ((codec_type_a != codec_type_b) ||
312 (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
313 return false;
314 }
315
316 uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
317 uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
318 uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
319 uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
320
321 if ((vendor_id_a != vendor_id_b) || (codec_id_a != codec_id_b)) return false;
322
323 // Check for aptX
324 if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
325 codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
326 return A2DP_VendorCodecEqualsAptx(p_codec_info_a, p_codec_info_b);
327 }
328
329 // Check for aptX-HD
330 if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
331 codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
332 return A2DP_VendorCodecEqualsAptxHd(p_codec_info_a, p_codec_info_b);
333 }
334
335 // Check for LDAC
336 if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
337 return A2DP_VendorCodecEqualsLdac(p_codec_info_a, p_codec_info_b);
338 }
339
340 // Check for Opus
341 if (vendor_id_a == A2DP_OPUS_VENDOR_ID && codec_id_a == A2DP_OPUS_CODEC_ID) {
342 return A2DP_VendorCodecEqualsOpus(p_codec_info_a, p_codec_info_b);
343 }
344
345 // Add extra vendor-specific checks based on the
346 // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
347
348 return false;
349 }
350
A2DP_VendorGetBitRate(const uint8_t * p_codec_info)351 int A2DP_VendorGetBitRate(const uint8_t* p_codec_info) {
352 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
353 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
354
355 // Check for aptX
356 if (vendor_id == A2DP_APTX_VENDOR_ID &&
357 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
358 return A2DP_VendorGetBitRateAptx(p_codec_info);
359 }
360
361 // Check for aptX-HD
362 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
363 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
364 return A2DP_VendorGetBitRateAptxHd(p_codec_info);
365 }
366
367 // Check for LDAC
368 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
369 return A2DP_VendorGetBitRateLdac(p_codec_info);
370 }
371
372 // Check for Opus
373 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
374 return A2DP_VendorGetBitRateOpus(p_codec_info);
375 }
376
377 // Add checks based on <vendor_id, codec_id>
378
379 return -1;
380 }
381
A2DP_VendorGetTrackSampleRate(const uint8_t * p_codec_info)382 int A2DP_VendorGetTrackSampleRate(const uint8_t* p_codec_info) {
383 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
384 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
385
386 // Check for aptX
387 if (vendor_id == A2DP_APTX_VENDOR_ID &&
388 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
389 return A2DP_VendorGetTrackSampleRateAptx(p_codec_info);
390 }
391
392 // Check for aptX-HD
393 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
394 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
395 return A2DP_VendorGetTrackSampleRateAptxHd(p_codec_info);
396 }
397
398 // Check for LDAC
399 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
400 return A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
401 }
402
403 // Check for Opus
404 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
405 return A2DP_VendorGetTrackSampleRateOpus(p_codec_info);
406 }
407
408 // Add checks based on <vendor_id, codec_id>
409
410 return -1;
411 }
412
A2DP_VendorGetTrackBitsPerSample(const uint8_t * p_codec_info)413 int A2DP_VendorGetTrackBitsPerSample(const uint8_t* p_codec_info) {
414 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
415 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
416
417 // Check for aptX
418 if (vendor_id == A2DP_APTX_VENDOR_ID &&
419 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
420 return A2DP_VendorGetTrackBitsPerSampleAptx(p_codec_info);
421 }
422
423 // Check for aptX-HD
424 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
425 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
426 return A2DP_VendorGetTrackBitsPerSampleAptxHd(p_codec_info);
427 }
428
429 // Check for LDAC
430 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
431 return A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
432 }
433
434 // Check for Opus
435 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
436 return A2DP_VendorGetTrackBitsPerSampleOpus(p_codec_info);
437 }
438
439 // Add checks based on <vendor_id, codec_id>
440
441 return -1;
442 }
443
A2DP_VendorGetTrackChannelCount(const uint8_t * p_codec_info)444 int A2DP_VendorGetTrackChannelCount(const uint8_t* p_codec_info) {
445 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
446 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
447
448 // Check for aptX
449 if (vendor_id == A2DP_APTX_VENDOR_ID &&
450 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
451 return A2DP_VendorGetTrackChannelCountAptx(p_codec_info);
452 }
453
454 // Check for aptX-HD
455 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
456 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
457 return A2DP_VendorGetTrackChannelCountAptxHd(p_codec_info);
458 }
459
460 // Check for LDAC
461 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
462 return A2DP_VendorGetTrackChannelCountLdac(p_codec_info);
463 }
464
465 // Check for Opus
466 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
467 return A2DP_VendorGetTrackChannelCountOpus(p_codec_info);
468 }
469
470 // Add checks based on <vendor_id, codec_id>
471
472 return -1;
473 }
474
A2DP_VendorGetSinkTrackChannelType(const uint8_t * p_codec_info)475 int A2DP_VendorGetSinkTrackChannelType(const uint8_t* p_codec_info) {
476 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
477 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
478
479 // Add checks based on <vendor_id, codec_id>
480 // NOTE: Should be done only for local Sink codecs.
481
482 // Check for LDAC
483 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
484 return A2DP_VendorGetSinkTrackChannelTypeLdac(p_codec_info);
485 }
486
487 // Check for Opus
488 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
489 return A2DP_VendorGetSinkTrackChannelTypeOpus(p_codec_info);
490 }
491
492 return -1;
493 }
494
A2DP_VendorGetPacketTimestamp(const uint8_t * p_codec_info,const uint8_t * p_data,uint32_t * p_timestamp)495 bool A2DP_VendorGetPacketTimestamp(const uint8_t* p_codec_info,
496 const uint8_t* p_data,
497 uint32_t* p_timestamp) {
498 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
499 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
500
501 // Check for aptX
502 if (vendor_id == A2DP_APTX_VENDOR_ID &&
503 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
504 return A2DP_VendorGetPacketTimestampAptx(p_codec_info, p_data, p_timestamp);
505 }
506
507 // Check for aptX-HD
508 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
509 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
510 return A2DP_VendorGetPacketTimestampAptxHd(p_codec_info, p_data,
511 p_timestamp);
512 }
513
514 // Check for LDAC
515 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
516 return A2DP_VendorGetPacketTimestampLdac(p_codec_info, p_data, p_timestamp);
517 }
518
519 // Check for Opus
520 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
521 return A2DP_VendorGetPacketTimestampOpus(p_codec_info, p_data, p_timestamp);
522 }
523
524 // Add checks based on <vendor_id, codec_id>
525
526 return false;
527 }
528
A2DP_VendorBuildCodecHeader(const uint8_t * p_codec_info,BT_HDR * p_buf,uint16_t frames_per_packet)529 bool A2DP_VendorBuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
530 uint16_t frames_per_packet) {
531 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
532 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
533
534 // Check for aptX
535 if (vendor_id == A2DP_APTX_VENDOR_ID &&
536 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
537 return A2DP_VendorBuildCodecHeaderAptx(p_codec_info, p_buf,
538 frames_per_packet);
539 }
540
541 // Check for aptX-HD
542 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
543 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
544 return A2DP_VendorBuildCodecHeaderAptxHd(p_codec_info, p_buf,
545 frames_per_packet);
546 }
547
548 // Check for LDAC
549 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
550 return A2DP_VendorBuildCodecHeaderLdac(p_codec_info, p_buf,
551 frames_per_packet);
552 }
553
554 // Check for Opus
555 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
556 return A2DP_VendorBuildCodecHeaderOpus(p_codec_info, p_buf,
557 frames_per_packet);
558 }
559
560 // Add checks based on <vendor_id, codec_id>
561
562 return false;
563 }
564
A2DP_VendorGetEncoderInterface(const uint8_t * p_codec_info)565 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
566 const uint8_t* p_codec_info) {
567 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
568 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
569
570 // Check for aptX
571 if (vendor_id == A2DP_APTX_VENDOR_ID &&
572 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
573 return A2DP_VendorGetEncoderInterfaceAptx(p_codec_info);
574 }
575
576 // Check for aptX-HD
577 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
578 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
579 return A2DP_VendorGetEncoderInterfaceAptxHd(p_codec_info);
580 }
581
582 // Check for LDAC
583 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
584 return A2DP_VendorGetEncoderInterfaceLdac(p_codec_info);
585 }
586
587 // Check for Opus
588 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
589 return A2DP_VendorGetEncoderInterfaceOpus(p_codec_info);
590 }
591
592 // Add checks based on <vendor_id, codec_id>
593
594 return NULL;
595 }
596
A2DP_VendorGetDecoderInterface(const uint8_t * p_codec_info)597 const tA2DP_DECODER_INTERFACE* A2DP_VendorGetDecoderInterface(
598 const uint8_t* p_codec_info) {
599 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
600 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
601
602 // Add checks based on <vendor_id, codec_id>
603 // NOTE: Should be done only for local Sink codecs.
604
605 // Check for LDAC
606 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
607 return A2DP_VendorGetDecoderInterfaceLdac(p_codec_info);
608 }
609
610 // Check for Opus
611 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
612 return A2DP_VendorGetDecoderInterfaceOpus(p_codec_info);
613 }
614
615 return NULL;
616 }
617
A2DP_VendorAdjustCodec(uint8_t * p_codec_info)618 bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
619 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
620 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
621
622 // Check for aptX
623 if (vendor_id == A2DP_APTX_VENDOR_ID &&
624 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
625 return A2DP_VendorAdjustCodecAptx(p_codec_info);
626 }
627
628 // Check for aptX-HD
629 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
630 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
631 return A2DP_VendorAdjustCodecAptxHd(p_codec_info);
632 }
633
634 // Check for LDAC
635 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
636 return A2DP_VendorAdjustCodecLdac(p_codec_info);
637 }
638
639 // Check for Opus
640 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
641 return A2DP_VendorAdjustCodecOpus(p_codec_info);
642 }
643
644 // Add checks based on <vendor_id, codec_id>
645
646 return false;
647 }
648
A2DP_VendorSourceCodecIndex(const uint8_t * p_codec_info)649 btav_a2dp_codec_index_t A2DP_VendorSourceCodecIndex(
650 const uint8_t* p_codec_info) {
651 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
652 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
653
654 // Check for aptX
655 if (vendor_id == A2DP_APTX_VENDOR_ID &&
656 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
657 return A2DP_VendorSourceCodecIndexAptx(p_codec_info);
658 }
659
660 // Check for aptX-HD
661 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
662 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
663 return A2DP_VendorSourceCodecIndexAptxHd(p_codec_info);
664 }
665
666 // Check for LDAC
667 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
668 return A2DP_VendorSourceCodecIndexLdac(p_codec_info);
669 }
670
671 // Check for Opus
672 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
673 return A2DP_VendorSourceCodecIndexOpus(p_codec_info);
674 }
675
676 // Add checks based on <vendor_id, codec_id>
677
678 return BTAV_A2DP_CODEC_INDEX_MAX;
679 }
680
A2DP_VendorSinkCodecIndex(const uint8_t * p_codec_info)681 btav_a2dp_codec_index_t A2DP_VendorSinkCodecIndex(const uint8_t* p_codec_info) {
682 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
683 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
684
685 // Add checks based on <vendor_id, codec_id>
686 // NOTE: Should be done only for local Sink codecs.
687
688 // Check for LDAC
689 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
690 return A2DP_VendorSinkCodecIndexLdac(p_codec_info);
691 }
692
693 // Check for Opus
694 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
695 return A2DP_VendorSinkCodecIndexOpus(p_codec_info);
696 }
697
698 return BTAV_A2DP_CODEC_INDEX_MAX;
699 }
700
A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index)701 const char* A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index) {
702 // Add checks based on codec_index
703 switch (codec_index) {
704 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
705 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
706 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
707 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
708 break; // These are not vendor-specific codecs
709 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
710 return A2DP_VendorCodecIndexStrAptx();
711 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
712 return A2DP_VendorCodecIndexStrAptxHd();
713 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
714 return A2DP_VendorCodecIndexStrLdac();
715 case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
716 return A2DP_VendorCodecIndexStrLdacSink();
717 case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
718 return "LC3 not implemented";
719 case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
720 return A2DP_VendorCodecIndexStrOpus();
721 case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
722 return A2DP_VendorCodecIndexStrOpusSink();
723 // Add a switch statement for each vendor-specific codec
724 case BTAV_A2DP_CODEC_INDEX_MAX:
725 break;
726 }
727
728 return "UNKNOWN CODEC INDEX";
729 }
730
A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)731 bool A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,
732 AvdtpSepConfig* p_cfg) {
733 // Add checks based on codec_index
734 switch (codec_index) {
735 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
736 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
737 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
738 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
739 break; // These are not vendor-specific codecs
740 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
741 return A2DP_VendorInitCodecConfigAptx(p_cfg);
742 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
743 return A2DP_VendorInitCodecConfigAptxHd(p_cfg);
744 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
745 return A2DP_VendorInitCodecConfigLdac(p_cfg);
746 case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
747 return A2DP_VendorInitCodecConfigLdacSink(p_cfg);
748 case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
749 break; // not implemented
750 case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
751 return A2DP_VendorInitCodecConfigOpus(p_cfg);
752 case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
753 return A2DP_VendorInitCodecConfigOpusSink(p_cfg);
754 // Add a switch statement for each vendor-specific codec
755 case BTAV_A2DP_CODEC_INDEX_MAX:
756 break;
757 }
758
759 return false;
760 }
761
A2DP_VendorCodecInfoString(const uint8_t * p_codec_info)762 std::string A2DP_VendorCodecInfoString(const uint8_t* p_codec_info) {
763 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
764 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
765
766 // Check for aptX
767 if (vendor_id == A2DP_APTX_VENDOR_ID &&
768 codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
769 return A2DP_VendorCodecInfoStringAptx(p_codec_info);
770 }
771
772 // Check for aptX-HD
773 if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
774 codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
775 return A2DP_VendorCodecInfoStringAptxHd(p_codec_info);
776 }
777
778 // Check for LDAC
779 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
780 return A2DP_VendorCodecInfoStringLdac(p_codec_info);
781 }
782
783 // Check for Opus
784 if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) {
785 return A2DP_VendorCodecInfoStringOpus(p_codec_info);
786 }
787
788 // Add checks based on <vendor_id, codec_id>
789
790 return "Unsupported codec vendor_id: " + loghex(vendor_id) +
791 " codec_id: " + loghex(codec_id);
792 }
793