• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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