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