1 /* 2 * Copyright (C) 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 }