• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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(UNUSED_ATTR const uint8_t * p_codec_info)57 bool A2DP_IsVendorSinkCodecValid(UNUSED_ATTR 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   return false;
65 }
66 
A2DP_IsVendorPeerSourceCodecValid(UNUSED_ATTR const uint8_t * p_codec_info)67 bool A2DP_IsVendorPeerSourceCodecValid(
68     UNUSED_ATTR const uint8_t* p_codec_info) {
69   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
70   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
71 
72   // Add checks based on <vendor_id, codec_id>
73   // NOTE: Should be done only for local Sink codecs.
74 
75   return false;
76 }
77 
A2DP_IsVendorPeerSinkCodecValid(const uint8_t * p_codec_info)78 bool A2DP_IsVendorPeerSinkCodecValid(const uint8_t* p_codec_info) {
79   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
80   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
81 
82   // Check for aptX
83   if (vendor_id == A2DP_APTX_VENDOR_ID &&
84       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
85     return A2DP_IsVendorPeerSinkCodecValidAptx(p_codec_info);
86   }
87 
88   // Check for aptX-HD
89   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
90       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
91     return A2DP_IsVendorPeerSinkCodecValidAptxHd(p_codec_info);
92   }
93 
94   // Check for LDAC
95   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
96     return A2DP_IsVendorPeerSinkCodecValidLdac(p_codec_info);
97   }
98 
99   // Add checks based on <vendor_id, codec_id>
100 
101   return false;
102 }
103 
A2DP_IsVendorSinkCodecSupported(UNUSED_ATTR const uint8_t * p_codec_info)104 bool A2DP_IsVendorSinkCodecSupported(UNUSED_ATTR const uint8_t* p_codec_info) {
105   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
106   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
107 
108   // Add checks based on <vendor_id, codec_id>
109   // NOTE: Should be done only for local Sink codecs.
110 
111   return false;
112 }
113 
A2DP_IsVendorPeerSourceCodecSupported(UNUSED_ATTR const uint8_t * p_codec_info)114 bool A2DP_IsVendorPeerSourceCodecSupported(
115     UNUSED_ATTR const uint8_t* p_codec_info) {
116   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
117   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
118 
119   // Add checks based on <vendor_id, codec_id> and peer codec capabilities
120   // NOTE: Should be done only for local Sink codecs.
121 
122   return false;
123 }
124 
A2DP_VendorBuildSrc2SinkConfig(UNUSED_ATTR const uint8_t * p_src_cap,UNUSED_ATTR uint8_t * p_pref_cfg)125 tA2DP_STATUS A2DP_VendorBuildSrc2SinkConfig(
126     UNUSED_ATTR const uint8_t* p_src_cap, UNUSED_ATTR uint8_t* p_pref_cfg) {
127   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
128   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
129 
130   // Add checks based on <vendor_id, codec_id>
131   // NOTE: Should be done only for local Sink codecs.
132 
133   return A2DP_NS_CODEC_TYPE;
134 }
135 
A2DP_VendorCodecGetVendorId(const uint8_t * p_codec_info)136 uint32_t A2DP_VendorCodecGetVendorId(const uint8_t* p_codec_info) {
137   const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_VENDOR_ID_START_IDX];
138 
139   uint32_t vendor_id = (p[0] & 0x000000ff) | ((p[1] << 8) & 0x0000ff00) |
140                        ((p[2] << 16) & 0x00ff0000) |
141                        ((p[3] << 24) & 0xff000000);
142 
143   return vendor_id;
144 }
145 
A2DP_VendorCodecGetCodecId(const uint8_t * p_codec_info)146 uint16_t A2DP_VendorCodecGetCodecId(const uint8_t* p_codec_info) {
147   const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_CODEC_ID_START_IDX];
148 
149   uint16_t codec_id = (p[0] & 0x00ff) | ((p[1] << 8) & 0xff00);
150 
151   return codec_id;
152 }
153 
A2DP_VendorUsesRtpHeader(bool content_protection_enabled,const uint8_t * p_codec_info)154 bool A2DP_VendorUsesRtpHeader(bool content_protection_enabled,
155                               const uint8_t* p_codec_info) {
156   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
157   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
158 
159   // Check for aptX
160   if (vendor_id == A2DP_APTX_VENDOR_ID &&
161       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
162     return A2DP_VendorUsesRtpHeaderAptx(content_protection_enabled,
163                                         p_codec_info);
164   }
165 
166   // Check for aptX-HD
167   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
168       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
169     return A2DP_VendorUsesRtpHeaderAptxHd(content_protection_enabled,
170                                           p_codec_info);
171   }
172 
173   // Check for LDAC
174   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
175     return A2DP_VendorUsesRtpHeaderLdac(content_protection_enabled,
176                                         p_codec_info);
177   }
178 
179   // Add checks based on <content_protection_enabled, vendor_id, codec_id>
180 
181   return true;
182 }
183 
A2DP_VendorCodecName(UNUSED_ATTR const uint8_t * p_codec_info)184 const char* A2DP_VendorCodecName(UNUSED_ATTR const uint8_t* p_codec_info) {
185   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
186   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
187 
188   // Check for aptX
189   if (vendor_id == A2DP_APTX_VENDOR_ID &&
190       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
191     return A2DP_VendorCodecNameAptx(p_codec_info);
192   }
193 
194   // Check for aptX-HD
195   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
196       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
197     return A2DP_VendorCodecNameAptxHd(p_codec_info);
198   }
199 
200   // Check for LDAC
201   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
202     return A2DP_VendorCodecNameLdac(p_codec_info);
203   }
204 
205   // Add checks based on <vendor_id, codec_id>
206 
207   return "UNKNOWN VENDOR CODEC";
208 }
209 
A2DP_VendorCodecTypeEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)210 bool A2DP_VendorCodecTypeEquals(const uint8_t* p_codec_info_a,
211                                 const uint8_t* p_codec_info_b) {
212   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
213   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
214 
215   if ((codec_type_a != codec_type_b) ||
216       (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
217     return false;
218   }
219 
220   uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
221   uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
222   uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
223   uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
224 
225   if (vendor_id_a != vendor_id_b || codec_id_a != codec_id_b) return false;
226 
227   // Check for aptX
228   if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
229       codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
230     return A2DP_VendorCodecTypeEqualsAptx(p_codec_info_a, p_codec_info_b);
231   }
232 
233   // Check for aptX-HD
234   if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
235       codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
236     return A2DP_VendorCodecTypeEqualsAptxHd(p_codec_info_a, p_codec_info_b);
237   }
238 
239   // Check for LDAC
240   if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
241     return A2DP_VendorCodecTypeEqualsLdac(p_codec_info_a, p_codec_info_b);
242   }
243 
244   // OPTIONAL: Add extra vendor-specific checks based on the
245   // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
246 
247   return true;
248 }
249 
A2DP_VendorCodecEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)250 bool A2DP_VendorCodecEquals(const uint8_t* p_codec_info_a,
251                             const uint8_t* p_codec_info_b) {
252   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
253   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
254 
255   if ((codec_type_a != codec_type_b) ||
256       (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
257     return false;
258   }
259 
260   uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
261   uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
262   uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
263   uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
264 
265   if ((vendor_id_a != vendor_id_b) || (codec_id_a != codec_id_b)) return false;
266 
267   // Check for aptX
268   if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
269       codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
270     return A2DP_VendorCodecEqualsAptx(p_codec_info_a, p_codec_info_b);
271   }
272 
273   // Check for aptX-HD
274   if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
275       codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
276     return A2DP_VendorCodecEqualsAptxHd(p_codec_info_a, p_codec_info_b);
277   }
278 
279   // Check for LDAC
280   if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
281     return A2DP_VendorCodecEqualsLdac(p_codec_info_a, p_codec_info_b);
282   }
283 
284   // Add extra vendor-specific checks based on the
285   // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
286 
287   return false;
288 }
289 
A2DP_VendorGetTrackSampleRate(const uint8_t * p_codec_info)290 int A2DP_VendorGetTrackSampleRate(const uint8_t* p_codec_info) {
291   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
292   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
293 
294   // Check for aptX
295   if (vendor_id == A2DP_APTX_VENDOR_ID &&
296       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
297     return A2DP_VendorGetTrackSampleRateAptx(p_codec_info);
298   }
299 
300   // Check for aptX-HD
301   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
302       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
303     return A2DP_VendorGetTrackSampleRateAptxHd(p_codec_info);
304   }
305 
306   // Check for LDAC
307   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
308     return A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
309   }
310 
311   // Add checks based on <vendor_id, codec_id>
312 
313   return -1;
314 }
315 
A2DP_VendorGetTrackBitsPerSample(const uint8_t * p_codec_info)316 int A2DP_VendorGetTrackBitsPerSample(const uint8_t* p_codec_info) {
317   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
318   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
319 
320   // Check for aptX
321   if (vendor_id == A2DP_APTX_VENDOR_ID &&
322       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
323     return A2DP_VendorGetTrackBitsPerSampleAptx(p_codec_info);
324   }
325 
326   // Check for aptX-HD
327   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
328       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
329     return A2DP_VendorGetTrackBitsPerSampleAptxHd(p_codec_info);
330   }
331 
332   // Check for LDAC
333   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
334     return A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
335   }
336 
337   // Add checks based on <vendor_id, codec_id>
338 
339   return -1;
340 }
341 
A2DP_VendorGetTrackChannelCount(const uint8_t * p_codec_info)342 int A2DP_VendorGetTrackChannelCount(const uint8_t* p_codec_info) {
343   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
344   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
345 
346   // Check for aptX
347   if (vendor_id == A2DP_APTX_VENDOR_ID &&
348       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
349     return A2DP_VendorGetTrackChannelCountAptx(p_codec_info);
350   }
351 
352   // Check for aptX-HD
353   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
354       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
355     return A2DP_VendorGetTrackChannelCountAptxHd(p_codec_info);
356   }
357 
358   // Check for LDAC
359   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
360     return A2DP_VendorGetTrackChannelCountLdac(p_codec_info);
361   }
362 
363   // Add checks based on <vendor_id, codec_id>
364 
365   return -1;
366 }
367 
A2DP_VendorGetSinkTrackChannelType(UNUSED_ATTR const uint8_t * p_codec_info)368 int A2DP_VendorGetSinkTrackChannelType(
369     UNUSED_ATTR const uint8_t* p_codec_info) {
370   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
371   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
372 
373   // Add checks based on <vendor_id, codec_id>
374   // NOTE: Should be done only for local Sink codecs.
375 
376   return -1;
377 }
378 
A2DP_VendorGetSinkFramesCountToProcess(UNUSED_ATTR uint64_t time_interval_ms,UNUSED_ATTR const uint8_t * p_codec_info)379 int A2DP_VendorGetSinkFramesCountToProcess(
380     UNUSED_ATTR uint64_t time_interval_ms,
381     UNUSED_ATTR const uint8_t* p_codec_info) {
382   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
383   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
384 
385   // Add checks based on <vendor_id, codec_id>
386   // NOTE: Should be done only for local Sink codecs.
387 
388   return -1;
389 }
390 
A2DP_VendorGetPacketTimestamp(const uint8_t * p_codec_info,const uint8_t * p_data,uint32_t * p_timestamp)391 bool A2DP_VendorGetPacketTimestamp(const uint8_t* p_codec_info,
392                                    const uint8_t* p_data,
393                                    uint32_t* p_timestamp) {
394   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
395   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
396 
397   // Check for aptX
398   if (vendor_id == A2DP_APTX_VENDOR_ID &&
399       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
400     return A2DP_VendorGetPacketTimestampAptx(p_codec_info, p_data, p_timestamp);
401   }
402 
403   // Check for aptX-HD
404   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
405       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
406     return A2DP_VendorGetPacketTimestampAptxHd(p_codec_info, p_data,
407                                                p_timestamp);
408   }
409 
410   // Check for LDAC
411   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
412     return A2DP_VendorGetPacketTimestampLdac(p_codec_info, p_data, p_timestamp);
413   }
414 
415   // Add checks based on <vendor_id, codec_id>
416 
417   return false;
418 }
419 
A2DP_VendorBuildCodecHeader(const uint8_t * p_codec_info,BT_HDR * p_buf,uint16_t frames_per_packet)420 bool A2DP_VendorBuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
421                                  uint16_t frames_per_packet) {
422   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
423   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
424 
425   // Check for aptX
426   if (vendor_id == A2DP_APTX_VENDOR_ID &&
427       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
428     return A2DP_VendorBuildCodecHeaderAptx(p_codec_info, p_buf,
429                                            frames_per_packet);
430   }
431 
432   // Check for aptX-HD
433   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
434       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
435     return A2DP_VendorBuildCodecHeaderAptxHd(p_codec_info, p_buf,
436                                              frames_per_packet);
437   }
438 
439   // Check for LDAC
440   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
441     return A2DP_VendorBuildCodecHeaderLdac(p_codec_info, p_buf,
442                                            frames_per_packet);
443   }
444 
445   // Add checks based on <vendor_id, codec_id>
446 
447   return false;
448 }
449 
A2DP_VendorGetEncoderInterface(const uint8_t * p_codec_info)450 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
451     const uint8_t* p_codec_info) {
452   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
453   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
454 
455   // Check for aptX
456   if (vendor_id == A2DP_APTX_VENDOR_ID &&
457       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
458     return A2DP_VendorGetEncoderInterfaceAptx(p_codec_info);
459   }
460 
461   // Check for aptX-HD
462   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
463       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
464     return A2DP_VendorGetEncoderInterfaceAptxHd(p_codec_info);
465   }
466 
467   // Check for LDAC
468   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
469     return A2DP_VendorGetEncoderInterfaceLdac(p_codec_info);
470   }
471 
472   // Add checks based on <vendor_id, codec_id>
473 
474   return NULL;
475 }
476 
A2DP_VendorAdjustCodec(uint8_t * p_codec_info)477 bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
478   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
479   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
480 
481   // Check for aptX
482   if (vendor_id == A2DP_APTX_VENDOR_ID &&
483       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
484     return A2DP_VendorAdjustCodecAptx(p_codec_info);
485   }
486 
487   // Check for aptX-HD
488   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
489       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
490     return A2DP_VendorAdjustCodecAptxHd(p_codec_info);
491   }
492 
493   // Check for LDAC
494   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
495     return A2DP_VendorAdjustCodecLdac(p_codec_info);
496   }
497 
498   // Add checks based on <vendor_id, codec_id>
499 
500   return false;
501 }
502 
A2DP_VendorSourceCodecIndex(const uint8_t * p_codec_info)503 btav_a2dp_codec_index_t A2DP_VendorSourceCodecIndex(
504     const uint8_t* p_codec_info) {
505   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
506   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
507 
508   // Check for aptX
509   if (vendor_id == A2DP_APTX_VENDOR_ID &&
510       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
511     return A2DP_VendorSourceCodecIndexAptx(p_codec_info);
512   }
513 
514   // Check for aptX-HD
515   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
516       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
517     return A2DP_VendorSourceCodecIndexAptxHd(p_codec_info);
518   }
519 
520   // Check for LDAC
521   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
522     return A2DP_VendorSourceCodecIndexLdac(p_codec_info);
523   }
524 
525   // Add checks based on <vendor_id, codec_id>
526 
527   return BTAV_A2DP_CODEC_INDEX_MAX;
528 }
529 
A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index)530 const char* A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index) {
531   // Add checks based on codec_index
532   switch (codec_index) {
533     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
534     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
535     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
536       break;  // These are not vendor-specific codecs
537     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
538       return A2DP_VendorCodecIndexStrAptx();
539     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
540       return A2DP_VendorCodecIndexStrAptxHd();
541     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
542       return A2DP_VendorCodecIndexStrLdac();
543     // Add a switch statement for each vendor-specific codec
544     case BTAV_A2DP_CODEC_INDEX_MAX:
545       break;
546   }
547 
548   return "UNKNOWN CODEC INDEX";
549 }
550 
A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,tAVDT_CFG * p_cfg)551 bool A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,
552                                 tAVDT_CFG* p_cfg) {
553   // Add checks based on codec_index
554   switch (codec_index) {
555     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
556     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
557     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
558       break;  // These are not vendor-specific codecs
559     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
560       return A2DP_VendorInitCodecConfigAptx(p_cfg);
561     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
562       return A2DP_VendorInitCodecConfigAptxHd(p_cfg);
563     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
564       return A2DP_VendorInitCodecConfigLdac(p_cfg);
565     // Add a switch statement for each vendor-specific codec
566     case BTAV_A2DP_CODEC_INDEX_MAX:
567       break;
568   }
569 
570   return false;
571 }
572