a2dp_vendor_ldac_abr.cc revision dfc02a91a19b2968506140655180b2491ac46a48
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// 35static const char* LDAC_ABR_LIB_NAME = "libldacBT_abr.so"; 36static void* ldac_abr_lib_handle = NULL; 37 38static const char* LDAC_ABR_GET_HANDLE_NAME = "ldac_ABR_get_handle"; 39typedef HANDLE_LDAC_ABR (*tLDAC_ABR_GET_HANDLE)(void); 40 41static const char* LDAC_ABR_FREE_HANDLE_NAME = "ldac_ABR_free_handle"; 42typedef void (*tLDAC_ABR_FREE_HANDLE)(HANDLE_LDAC_ABR hLdacAbr); 43 44static const char* LDAC_ABR_INIT_NAME = "ldac_ABR_Init"; 45typedef int (*tLDAC_ABR_INIT)(HANDLE_LDAC_ABR hLdacAbr, 46 unsigned int interval_ms); 47 48static const char* LDAC_ABR_SET_THRESHOLDS_NAME = "ldac_ABR_set_thresholds"; 49typedef 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 54static const char* LDAC_ABR_PROC_NAME = "ldac_ABR_Proc"; 55typedef int (*tLDAC_ABR_PROC)(HANDLE_LDAC_BT hLdacParam, 56 HANDLE_LDAC_ABR hLdacAbr, unsigned int txq_length, 57 unsigned int flag_enable); 58 59static tLDAC_ABR_GET_HANDLE ldac_abr_get_handle_func; 60static tLDAC_ABR_FREE_HANDLE ldac_abr_free_handle_func; 61static tLDAC_ABR_INIT ldac_abr_init_func; 62static tLDAC_ABR_SET_THRESHOLDS ldac_abr_set_thresholds_func; 63static tLDAC_ABR_PROC ldac_abr_proc_func; 64 65bool 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 131void 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 144HANDLE_LDAC_ABR a2dp_ldac_abr_get_handle(void) { 145 return ldac_abr_get_handle_func(); 146} 147 148void a2dp_ldac_abr_free_handle(HANDLE_LDAC_ABR hLdacAbr) { 149 return ldac_abr_free_handle_func(hLdacAbr); 150} 151 152int a2dp_ldac_abr_init(HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms) { 153 return ldac_abr_init_func(hLdacAbr, interval_ms); 154} 155 156int 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 164int 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}