Home | History | Annotate | Download | only in a2dp
      1 /*
      2  * Copyright 2017 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 #define LOG_TAG "a2dp_vendor_ldac_abr"
     18 
     19 #include "a2dp_vendor_ldac_abr.h"
     20 
     21 #include <dlfcn.h>
     22 #include <inttypes.h>
     23 #include <stdio.h>
     24 #include <string.h>
     25 
     26 #include "osi/include/log.h"
     27 
     28 //
     29 // LDAC ABR(Adaptive Bit Rate) Source Code
     30 //
     31 
     32 //
     33 // The LDAC ABR shared library, and the functions to use
     34 //
     35 static const char* LDAC_ABR_LIB_NAME = "libldacBT_abr.so";
     36 static void* ldac_abr_lib_handle = NULL;
     37 
     38 static const char* LDAC_ABR_GET_HANDLE_NAME = "ldac_ABR_get_handle";
     39 typedef HANDLE_LDAC_ABR (*tLDAC_ABR_GET_HANDLE)(void);
     40 
     41 static const char* LDAC_ABR_FREE_HANDLE_NAME = "ldac_ABR_free_handle";
     42 typedef void (*tLDAC_ABR_FREE_HANDLE)(HANDLE_LDAC_ABR hLdacAbr);
     43 
     44 static const char* LDAC_ABR_INIT_NAME = "ldac_ABR_Init";
     45 typedef int (*tLDAC_ABR_INIT)(HANDLE_LDAC_ABR hLdacAbr,
     46                               unsigned int interval_ms);
     47 
     48 static const char* LDAC_ABR_SET_THRESHOLDS_NAME = "ldac_ABR_set_thresholds";
     49 typedef int (*tLDAC_ABR_SET_THRESHOLDS)(HANDLE_LDAC_ABR hLdacAbr,
     50                                         unsigned int th_critical,
     51                                         unsigned int th_dangerous_trend,
     52                                         unsigned int th_safety_4hqsq);
     53 
     54 static const char* LDAC_ABR_PROC_NAME = "ldac_ABR_Proc";
     55 typedef int (*tLDAC_ABR_PROC)(HANDLE_LDAC_BT hLdacParam,
     56                               HANDLE_LDAC_ABR hLdacAbr, unsigned int txq_length,
     57                               unsigned int flag_enable);
     58 
     59 static tLDAC_ABR_GET_HANDLE ldac_abr_get_handle_func;
     60 static tLDAC_ABR_FREE_HANDLE ldac_abr_free_handle_func;
     61 static tLDAC_ABR_INIT ldac_abr_init_func;
     62 static tLDAC_ABR_SET_THRESHOLDS ldac_abr_set_thresholds_func;
     63 static tLDAC_ABR_PROC ldac_abr_proc_func;
     64 
     65 bool A2DP_VendorLoadLdacAbr(void) {
     66   if (ldac_abr_lib_handle != NULL) return true;  // Already loaded
     67 
     68   // Open the LDAC ABR library
     69   ldac_abr_lib_handle = dlopen(LDAC_ABR_LIB_NAME, RTLD_NOW);
     70   if (ldac_abr_lib_handle == NULL) {
     71     LOG_ERROR(LOG_TAG, "%s: cannot open LDAC ABR library %s: %s", __func__,
     72               LDAC_ABR_LIB_NAME, dlerror());
     73     A2DP_VendorUnloadLdacAbr();
     74     return false;
     75   }
     76 
     77   // Load all functions
     78   ldac_abr_get_handle_func = (tLDAC_ABR_GET_HANDLE)dlsym(
     79       ldac_abr_lib_handle, LDAC_ABR_GET_HANDLE_NAME);
     80   if (ldac_abr_get_handle_func == NULL) {
     81     LOG_ERROR(LOG_TAG,
     82               "%s: cannot find function '%s' in the LDAC ABR library: %s",
     83               __func__, LDAC_ABR_GET_HANDLE_NAME, dlerror());
     84     A2DP_VendorUnloadLdacAbr();
     85     return false;
     86   }
     87 
     88   ldac_abr_free_handle_func = (tLDAC_ABR_FREE_HANDLE)dlsym(
     89       ldac_abr_lib_handle, LDAC_ABR_FREE_HANDLE_NAME);
     90   if (ldac_abr_free_handle_func == NULL) {
     91     LOG_ERROR(LOG_TAG,
     92               "%s: cannot find function '%s' in the LDAC ABR library: %s",
     93               __func__, LDAC_ABR_FREE_HANDLE_NAME, dlerror());
     94     A2DP_VendorUnloadLdacAbr();
     95     return false;
     96   }
     97 
     98   ldac_abr_init_func =
     99       (tLDAC_ABR_INIT)dlsym(ldac_abr_lib_handle, LDAC_ABR_INIT_NAME);
    100   if (ldac_abr_init_func == NULL) {
    101     LOG_ERROR(LOG_TAG,
    102               "%s: cannot find function '%s' in the LDAC ABR library: %s",
    103               __func__, LDAC_ABR_INIT_NAME, dlerror());
    104     A2DP_VendorUnloadLdacAbr();
    105     return false;
    106   }
    107 
    108   ldac_abr_set_thresholds_func = (tLDAC_ABR_SET_THRESHOLDS)dlsym(
    109       ldac_abr_lib_handle, LDAC_ABR_SET_THRESHOLDS_NAME);
    110   if (ldac_abr_set_thresholds_func == NULL) {
    111     LOG_ERROR(LOG_TAG,
    112               "%s: cannot find function '%s' in the LDAC ABR library: %s",
    113               __func__, LDAC_ABR_SET_THRESHOLDS_NAME, dlerror());
    114     A2DP_VendorUnloadLdacAbr();
    115     return false;
    116   }
    117 
    118   ldac_abr_proc_func =
    119       (tLDAC_ABR_PROC)dlsym(ldac_abr_lib_handle, LDAC_ABR_PROC_NAME);
    120   if (ldac_abr_proc_func == NULL) {
    121     LOG_ERROR(LOG_TAG,
    122               "%s: cannot find function '%s' in the LDAC ABR library: %s",
    123               __func__, LDAC_ABR_PROC_NAME, dlerror());
    124     A2DP_VendorUnloadLdacAbr();
    125     return false;
    126   }
    127 
    128   return true;
    129 }
    130 
    131 void A2DP_VendorUnloadLdacAbr(void) {
    132   ldac_abr_get_handle_func = NULL;
    133   ldac_abr_free_handle_func = NULL;
    134   ldac_abr_init_func = NULL;
    135   ldac_abr_set_thresholds_func = NULL;
    136   ldac_abr_proc_func = NULL;
    137 
    138   if (ldac_abr_lib_handle != NULL) {
    139     dlclose(ldac_abr_lib_handle);
    140     ldac_abr_lib_handle = NULL;
    141   }
    142 }
    143 
    144 HANDLE_LDAC_ABR a2dp_ldac_abr_get_handle(void) {
    145   return ldac_abr_get_handle_func();
    146 }
    147 
    148 void a2dp_ldac_abr_free_handle(HANDLE_LDAC_ABR hLdacAbr) {
    149   return ldac_abr_free_handle_func(hLdacAbr);
    150 }
    151 
    152 int a2dp_ldac_abr_init(HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms) {
    153   return ldac_abr_init_func(hLdacAbr, interval_ms);
    154 }
    155 
    156 int a2dp_ldac_abr_set_thresholds(HANDLE_LDAC_ABR hLdacAbr,
    157                                  unsigned int th_critical,
    158                                  unsigned int th_dangerous_trend,
    159                                  unsigned int th_4hqsq) {
    160   return ldac_abr_set_thresholds_func(hLdacAbr, th_critical, th_dangerous_trend,
    161                                       th_4hqsq);
    162 }
    163 
    164 int a2dp_ldac_abr_proc(HANDLE_LDAC_BT hLdacParam, HANDLE_LDAC_ABR hLdacAbr,
    165                        size_t transmit_queue_length, unsigned int flag_enable) {
    166   return ldac_abr_proc_func(hLdacParam, hLdacAbr, transmit_queue_length,
    167                             flag_enable);
    168 }