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