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