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