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 #define LOG_TAG "bluetooth-a2dp"
18 
19 #include "a2dp_vendor_ldac_decoder.h"
20 
21 #include <bluetooth/log.h>
22 #include <dlfcn.h>
23 #include <ldacBT.h>
24 #include <ldacBT_bco_for_fluoride.h>
25 #include <pthread.h>
26 #include <string.h>
27 
28 #include <cstdint>
29 
30 #include "a2dp_vendor_ldac.h"
31 #include "a2dp_vendor_ldac_constants.h"
32 #include "avdt_api.h"
33 #include "stack/include/bt_hdr.h"
34 
35 using namespace bluetooth;
36 
37 namespace std {
38 template <>
39 struct formatter<LDACBT_SMPL_FMT_T> : enum_formatter<LDACBT_SMPL_FMT_T> {};
40 }  // namespace std
41 
42 //
43 // Decoder for LDAC Source Codec
44 //
45 
46 //
47 // The LDAC BCO shared library, and the functions to use
48 //
49 static const char* LDAC_BCO_LIB_NAME = "libldacBT_bco.so";
50 static void* ldac_bco_lib_handle = NULL;
51 
52 static const char* LDAC_BCO_INIT_NAME = "ldac_BCO_init";
53 typedef HANDLE_LDAC_BCO (*tLDAC_BCO_INIT)(decoded_data_callback_t decode_callback);
54 
55 static const char* LDAC_BCO_CLEANUP_NAME = "ldac_BCO_cleanup";
56 typedef int32_t (*tLDAC_BCO_CLEANUP)(HANDLE_LDAC_BCO hLdacBco);
57 
58 static const char* LDAC_BCO_DECODE_PACKET_NAME = "ldac_BCO_decode_packet";
59 typedef int32_t (*tLDAC_BCO_DECODE_PACKET)(HANDLE_LDAC_BCO hLdacBco, void* data, int32_t length);
60 
61 static const char* LDAC_BCO_START_NAME = "ldac_BCO_start";
62 typedef int32_t (*tLDAC_BCO_START)(HANDLE_LDAC_BCO hLdacBco);
63 
64 static const char* LDAC_BCO_SUSPEND_NAME = "ldac_BCO_suspend";
65 typedef int32_t (*tLDAC_BCO_SUSPEND)(HANDLE_LDAC_BCO hLdacBco);
66 
67 static const char* LDAC_BCO_CONFIGURE_NAME = "ldac_BCO_configure";
68 typedef int32_t (*tLDAC_BCO_CONFIGURE)(HANDLE_LDAC_BCO hLdacBco, int32_t sample_rate,
69                                        int32_t bits_per_sample, int32_t channel_mode);
70 
71 static tLDAC_BCO_INIT ldac_BCO_init_func;
72 static tLDAC_BCO_CLEANUP ldac_BCO_cleanup_func;
73 static tLDAC_BCO_DECODE_PACKET ldac_BCO_decode_packet_func;
74 static tLDAC_BCO_START ldac_BCO_start_func;
75 static tLDAC_BCO_SUSPEND ldac_BCO_suspend_func;
76 static tLDAC_BCO_CONFIGURE ldac_BCO_configure_func;
77 
78 // offset
79 #define A2DP_LDAC_OFFSET (AVDT_MEDIA_OFFSET + A2DP_LDAC_MPL_HDR_LEN)
80 
81 typedef struct {
82   uint32_t sample_rate;
83   uint8_t channel_mode;
84   uint8_t bits_per_sample;
85   int pcm_wlength;
86   LDACBT_SMPL_FMT_T pcm_fmt;
87 } tA2DP_LDAC_DECODER_PARAMS;
88 
89 typedef struct {
90   pthread_mutex_t mutex;
91   bool use_SCMS_T;
92   bool is_peer_edr;          // True if the peer device supports EDR
93   bool peer_supports_3mbps;  // True if the peer device supports 3Mbps EDR
94   uint16_t peer_mtu;         // MTU of the A2DP peer
95   uint32_t timestamp;        // Timestamp for the A2DP frames
96 
97   HANDLE_LDAC_BCO ldac_handle_bco;
98   bool has_ldac_handle;  // True if ldac_handle is valid
99   unsigned char* decode_buf;
100   decoded_data_callback_t decode_callback;
101 } tA2DP_LDAC_DECODER_CB;
102 
103 static tA2DP_LDAC_DECODER_CB a2dp_ldac_decoder_cb;
104 
load_func(const char * func_name)105 static void* load_func(const char* func_name) {
106   void* func_ptr = dlsym(ldac_bco_lib_handle, func_name);
107   if (func_ptr == NULL) {
108     log::error("cannot find function '{}' in the decoder library: {}", func_name, dlerror());
109     A2DP_VendorUnloadDecoderLdac();
110     return NULL;
111   }
112   return func_ptr;
113 }
114 
A2DP_VendorLoadDecoderLdac(void)115 bool A2DP_VendorLoadDecoderLdac(void) {
116   if (ldac_bco_lib_handle != NULL) {
117     return true;  // Already loaded
118   }
119 
120   // Initialize the control block
121   memset(&a2dp_ldac_decoder_cb, 0, sizeof(a2dp_ldac_decoder_cb));
122 
123   pthread_mutex_init(&(a2dp_ldac_decoder_cb.mutex), NULL);
124 
125   // Open the decoder library
126   ldac_bco_lib_handle = dlopen(LDAC_BCO_LIB_NAME, RTLD_NOW);
127   if (ldac_bco_lib_handle == NULL) {
128     log::info("cannot open LDAC decoder library {}: {}", LDAC_BCO_LIB_NAME, dlerror());
129     return false;
130   }
131 
132   // Load all functions
133   ldac_BCO_init_func = (tLDAC_BCO_INIT)load_func(LDAC_BCO_INIT_NAME);
134   if (ldac_BCO_init_func == NULL) {
135     return false;
136   }
137 
138   ldac_BCO_cleanup_func = (tLDAC_BCO_CLEANUP)load_func(LDAC_BCO_CLEANUP_NAME);
139   if (ldac_BCO_cleanup_func == NULL) {
140     return false;
141   }
142 
143   ldac_BCO_decode_packet_func = (tLDAC_BCO_DECODE_PACKET)load_func(LDAC_BCO_DECODE_PACKET_NAME);
144   if (ldac_BCO_decode_packet_func == NULL) {
145     return false;
146   }
147 
148   ldac_BCO_start_func = (tLDAC_BCO_START)load_func(LDAC_BCO_START_NAME);
149   if (ldac_BCO_start_func == NULL) {
150     return false;
151   }
152 
153   ldac_BCO_suspend_func = (tLDAC_BCO_SUSPEND)load_func(LDAC_BCO_SUSPEND_NAME);
154   if (ldac_BCO_suspend_func == NULL) {
155     return false;
156   }
157 
158   ldac_BCO_configure_func = (tLDAC_BCO_CONFIGURE)load_func(LDAC_BCO_CONFIGURE_NAME);
159   if (ldac_BCO_configure_func == NULL) {
160     return false;
161   }
162 
163   return true;
164 }
165 
A2DP_VendorUnloadDecoderLdac(void)166 void A2DP_VendorUnloadDecoderLdac(void) {
167   // Cleanup any LDAC-related state
168   if (a2dp_ldac_decoder_cb.has_ldac_handle && ldac_BCO_cleanup_func != NULL) {
169     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
170   }
171   pthread_mutex_destroy(&(a2dp_ldac_decoder_cb.mutex));
172   memset(&a2dp_ldac_decoder_cb, 0, sizeof(a2dp_ldac_decoder_cb));
173 
174   ldac_BCO_init_func = NULL;
175   ldac_BCO_cleanup_func = NULL;
176   ldac_BCO_decode_packet_func = NULL;
177   ldac_BCO_start_func = NULL;
178   ldac_BCO_suspend_func = NULL;
179   ldac_BCO_configure_func = NULL;
180 
181   if (ldac_bco_lib_handle != NULL) {
182     dlclose(ldac_bco_lib_handle);
183     ldac_bco_lib_handle = NULL;
184   }
185 }
186 
a2dp_vendor_ldac_decoder_init(decoded_data_callback_t decode_callback)187 bool a2dp_vendor_ldac_decoder_init(decoded_data_callback_t decode_callback) {
188   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
189 
190   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
191     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
192   }
193 
194   a2dp_ldac_decoder_cb.ldac_handle_bco = ldac_BCO_init_func(decode_callback);
195   a2dp_ldac_decoder_cb.has_ldac_handle = (a2dp_ldac_decoder_cb.ldac_handle_bco != NULL);
196 
197   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
198   return true;
199 }
200 
a2dp_vendor_ldac_decoder_cleanup(void)201 void a2dp_vendor_ldac_decoder_cleanup(void) {
202   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
203   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
204     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
205   }
206   a2dp_ldac_decoder_cb.ldac_handle_bco = NULL;
207   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
208 }
209 
a2dp_vendor_ldac_decoder_decode_packet(BT_HDR * p_buf)210 bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) {
211   if (p_buf == nullptr) {
212     log::error("Dropping packet with nullptr");
213     return false;
214   }
215   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
216   unsigned char* pBuffer = reinterpret_cast<unsigned char*>(p_buf->data + p_buf->offset);
217   //  unsigned int bufferSize = p_buf->len;
218   unsigned int bytesValid = p_buf->len;
219   if (bytesValid == 0) {
220     pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
221     log::warn("Dropping packet with zero length");
222     return false;
223   }
224 
225   int bs_bytes, frame_number;
226 
227   frame_number = (int)pBuffer[0];
228   bs_bytes = (int)bytesValid;
229   bytesValid -= 1;
230   log::info("INPUT size : {}, frame : {}", bs_bytes, frame_number);
231 
232   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
233     ldac_BCO_decode_packet_func(a2dp_ldac_decoder_cb.ldac_handle_bco, pBuffer, bs_bytes);
234   }
235 
236   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
237   return true;
238 }
239 
a2dp_vendor_ldac_decoder_start(void)240 void a2dp_vendor_ldac_decoder_start(void) {
241   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
242   log::info("");
243   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
244     ldac_BCO_start_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
245   }
246   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
247 }
248 
a2dp_vendor_ldac_decoder_suspend(void)249 void a2dp_vendor_ldac_decoder_suspend(void) {
250   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
251   log::info("");
252   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
253     ldac_BCO_suspend_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
254   }
255   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
256 }
257 
a2dp_vendor_ldac_decoder_configure(const uint8_t * p_codec_info)258 void a2dp_vendor_ldac_decoder_configure(const uint8_t* p_codec_info) {
259   int32_t sample_rate;
260   int32_t bits_per_sample;
261   int32_t channel_mode;
262 
263   if (p_codec_info == NULL) {
264     log::error("p_codec_info is NULL");
265     return;
266   }
267 
268   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
269   sample_rate = A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
270   bits_per_sample = A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
271   channel_mode = A2DP_VendorGetChannelModeCodeLdac(p_codec_info);
272 
273   log::info(", sample_rate={}, bits_per_sample={}, channel_mode={}", sample_rate, bits_per_sample,
274             channel_mode);
275 
276   if (a2dp_ldac_decoder_cb.has_ldac_handle) {
277     ldac_BCO_configure_func(a2dp_ldac_decoder_cb.ldac_handle_bco, sample_rate, bits_per_sample,
278                             channel_mode);
279   }
280   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
281 }
282