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