1 /******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include "audio_hal_interface/hearing_aid_software_encoding.h"
20 #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
21 #include "bta_hearing_aid_api.h"
22 #include "btu.h"
23 #include "osi/include/wakelock.h"
24 #include "uipc.h"
25
26 #include <base/files/file_util.h>
27 #include <include/hardware/bt_av.h>
28
29 #include "common/repeating_timer.h"
30 #include "common/time_util.h"
31
32 using base::FilePath;
33 extern const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event);
34
35 namespace {
36 int bit_rate = -1;
37 int sample_rate = -1;
38 int data_interval_ms = -1;
39 int num_channels = 2;
40 bluetooth::common::RepeatingTimer audio_timer;
41 HearingAidAudioReceiver* localAudioReceiver = nullptr;
42 std::unique_ptr<tUIPC_STATE> uipc_hearing_aid = nullptr;
43
44 struct AudioHalStats {
45 size_t media_read_total_underflow_bytes;
46 size_t media_read_total_underflow_count;
47 uint64_t media_read_last_underflow_us;
48
AudioHalStats__anond0d475210111::AudioHalStats49 AudioHalStats() { Reset(); }
50
Reset__anond0d475210111::AudioHalStats51 void Reset() {
52 media_read_total_underflow_bytes = 0;
53 media_read_total_underflow_count = 0;
54 media_read_last_underflow_us = 0;
55 }
56 };
57
58 AudioHalStats stats;
59
60 bool hearing_aid_on_resume_req(bool start_media_task);
61 bool hearing_aid_on_suspend_req();
62
send_audio_data()63 void send_audio_data() {
64 uint32_t bytes_per_tick =
65 (num_channels * sample_rate * data_interval_ms * (bit_rate / 8)) / 1000;
66
67 uint16_t event;
68 uint8_t p_buf[bytes_per_tick];
69
70 uint32_t bytes_read;
71 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
72 bytes_read = bluetooth::audio::hearing_aid::read(p_buf, bytes_per_tick);
73 } else {
74 bytes_read = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, &event,
75 p_buf, bytes_per_tick);
76 }
77
78 VLOG(2) << "bytes_read: " << bytes_read;
79 if (bytes_read < bytes_per_tick) {
80 stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read;
81 stats.media_read_total_underflow_count++;
82 stats.media_read_last_underflow_us =
83 bluetooth::common::time_get_os_boottime_us();
84 }
85
86 std::vector<uint8_t> data(p_buf, p_buf + bytes_read);
87
88 if (localAudioReceiver != nullptr) {
89 localAudioReceiver->OnAudioDataReady(data);
90 }
91 }
92
hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status)93 void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) {
94 uint8_t ack = status;
95 DVLOG(2) << "Hearing Aid audio ctrl ack: " << status;
96 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
97 }
98
start_audio_ticks()99 void start_audio_ticks() {
100 wakelock_acquire();
101 audio_timer.SchedulePeriodic(get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
102 base::TimeDelta::FromMilliseconds(data_interval_ms));
103 }
104
stop_audio_ticks()105 void stop_audio_ticks() {
106 audio_timer.CancelAndWait();
107 wakelock_release();
108 }
109
hearing_aid_data_cb(tUIPC_CH_ID,tUIPC_EVENT event)110 void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
111 DVLOG(2) << "Hearing Aid audio data event: " << event;
112 switch (event) {
113 case UIPC_OPEN_EVT:
114 LOG(INFO) << __func__ << ": UIPC_OPEN_EVT";
115 /*
116 * Read directly from media task from here on (keep callback for
117 * connection events.
118 */
119 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO,
120 UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
121 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
122 reinterpret_cast<void*>(0));
123
124 if (data_interval_ms != HA_INTERVAL_10_MS &&
125 data_interval_ms != HA_INTERVAL_20_MS) {
126 LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
127 }
128
129 start_audio_ticks();
130 break;
131 case UIPC_CLOSE_EVT:
132 LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT";
133 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
134 stop_audio_ticks();
135 break;
136 default:
137 LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event;
138 }
139 }
140
hearing_aid_recv_ctrl_data()141 void hearing_aid_recv_ctrl_data() {
142 tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE;
143 int n;
144
145 uint8_t read_cmd = 0; /* The read command size is one octet */
146 n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, NULL, &read_cmd, 1);
147 cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd);
148
149 /* detach on ctrl channel means audioflinger process was terminated */
150 if (n == 0) {
151 LOG(WARNING) << __func__ << "CTRL CH DETACHED";
152 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL);
153 return;
154 }
155
156 LOG(INFO) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd);
157 // a2dp_cmd_pending = cmd;
158
159 tHEARING_AID_CTRL_ACK ctrl_ack_status;
160
161 switch (cmd) {
162 case HEARING_AID_CTRL_CMD_CHECK_READY:
163 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
164 break;
165
166 case HEARING_AID_CTRL_CMD_START:
167 ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
168 // timer is restarted in UIPC_Open
169 if (!hearing_aid_on_resume_req(false)) {
170 ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
171 } else {
172 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb,
173 HEARING_AID_DATA_PATH);
174 }
175 hearing_aid_send_ack(ctrl_ack_status);
176 break;
177
178 case HEARING_AID_CTRL_CMD_STOP:
179 if (!hearing_aid_on_suspend_req()) {
180 LOG(INFO) << __func__ << ":HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but ignored.";
181 }
182 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
183 break;
184
185 case HEARING_AID_CTRL_CMD_SUSPEND:
186 ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
187 if (!hearing_aid_on_suspend_req()) {
188 ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
189 }
190 hearing_aid_send_ack(ctrl_ack_status);
191 break;
192
193 case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: {
194 btav_a2dp_codec_config_t codec_config;
195 btav_a2dp_codec_config_t codec_capability;
196 if (sample_rate == 16000) {
197 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
198 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
199 } else if (sample_rate == 24000) {
200 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
201 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
202 } else {
203 LOG(FATAL) << "unsupported sample rate: " << sample_rate;
204 }
205
206 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
207 codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
208
209 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
210 codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
211
212 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
213 // Send the current codec config
214 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
215 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
216 sizeof(btav_a2dp_codec_sample_rate_t));
217 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
218 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
219 sizeof(btav_a2dp_codec_bits_per_sample_t));
220 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
221 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
222 sizeof(btav_a2dp_codec_channel_mode_t));
223 // Send the current codec capability
224 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
225 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
226 sizeof(btav_a2dp_codec_sample_rate_t));
227 UIPC_Send(
228 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
229 reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
230 sizeof(btav_a2dp_codec_bits_per_sample_t));
231 UIPC_Send(
232 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
233 reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
234 sizeof(btav_a2dp_codec_channel_mode_t));
235 break;
236 }
237
238 case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: {
239 // TODO: we only support one config for now!
240 btav_a2dp_codec_config_t codec_config;
241 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
242 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
243 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
244
245 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
246 // Send the current codec config
247 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
248 reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
249 sizeof(btav_a2dp_codec_sample_rate_t)) !=
250 sizeof(btav_a2dp_codec_sample_rate_t)) {
251 LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL";
252 break;
253 }
254 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
255 reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
256 sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
257 sizeof(btav_a2dp_codec_bits_per_sample_t)) {
258 LOG(ERROR) << __func__
259 << "Error reading bits per sample from audio HAL";
260
261 break;
262 }
263 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
264 reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
265 sizeof(btav_a2dp_codec_channel_mode_t)) !=
266 sizeof(btav_a2dp_codec_channel_mode_t)) {
267 LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL";
268
269 break;
270 }
271 LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
272 << "sample_rate=" << codec_config.sample_rate
273 << "bits_per_sample=" << codec_config.bits_per_sample
274 << "channel_mode=" << codec_config.channel_mode;
275 break;
276 }
277
278 default:
279 LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd;
280 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE);
281 break;
282 }
283 LOG(INFO) << __func__
284 << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd)
285 << " DONE";
286 }
287
hearing_aid_ctrl_cb(tUIPC_CH_ID,tUIPC_EVENT event)288 void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
289 VLOG(2) << "Hearing Aid audio ctrl event: " << event;
290 switch (event) {
291 case UIPC_OPEN_EVT:
292 break;
293 case UIPC_CLOSE_EVT:
294 /* restart ctrl server unless we are shutting down */
295 if (HearingAid::IsHearingAidRunning()) {
296 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb,
297 HEARING_AID_CTRL_PATH);
298 }
299 break;
300 case UIPC_RX_DATA_READY_EVT:
301 hearing_aid_recv_ctrl_data();
302 break;
303 default:
304 LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event;
305 }
306 }
307
hearing_aid_on_resume_req(bool start_media_task)308 bool hearing_aid_on_resume_req(bool start_media_task) {
309 // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_START)
310 if (localAudioReceiver != nullptr) {
311 // Call OnAudioResume and block till it returns.
312 std::promise<void> do_resume_promise;
313 std::future<void> do_resume_future = do_resume_promise.get_future();
314 bt_status_t status = do_in_main_thread(
315 FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
316 base::Unretained(localAudioReceiver),
317 std::move(do_resume_promise)));
318 if (status == BT_STATUS_SUCCESS) {
319 do_resume_future.wait();
320 } else {
321 LOG(ERROR) << __func__
322 << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
323 << status;
324 return false;
325 }
326 } else {
327 LOG(ERROR) << __func__
328 << ": HEARING_AID_CTRL_CMD_START: audio receiver not started";
329 return false;
330 }
331
332 // hearing_aid_data_cb(UIPC_OPEN_EVT): start_media_task
333 if (start_media_task) {
334 if (data_interval_ms != HA_INTERVAL_10_MS &&
335 data_interval_ms != HA_INTERVAL_20_MS) {
336 LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
337 data_interval_ms = HA_INTERVAL_10_MS;
338 }
339 start_audio_ticks();
340 }
341 return true;
342 }
343
hearing_aid_on_suspend_req()344 bool hearing_aid_on_suspend_req() {
345 // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_SUSPEND): stop_media_task
346 stop_audio_ticks();
347 if (localAudioReceiver != nullptr) {
348 // Call OnAudioSuspend and block till it returns.
349 std::promise<void> do_suspend_promise;
350 std::future<void> do_suspend_future = do_suspend_promise.get_future();
351 bt_status_t status = do_in_main_thread(
352 FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
353 base::Unretained(localAudioReceiver),
354 std::move(do_suspend_promise)));
355 if (status == BT_STATUS_SUCCESS) {
356 do_suspend_future.wait();
357 return true;
358 } else {
359 LOG(ERROR) << __func__
360 << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
361 << status;
362 }
363 } else {
364 LOG(ERROR) << __func__
365 << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started";
366 }
367 return false;
368 }
369 } // namespace
370
Start(const CodecConfiguration & codecConfiguration,HearingAidAudioReceiver * audioReceiver,uint16_t remote_delay_ms)371 void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration,
372 HearingAidAudioReceiver* audioReceiver,
373 uint16_t remote_delay_ms) {
374 LOG(INFO) << __func__ << ": Hearing Aid Source Open";
375
376 bit_rate = codecConfiguration.bit_rate;
377 sample_rate = codecConfiguration.sample_rate;
378 data_interval_ms = codecConfiguration.data_interval_ms;
379
380 stats.Reset();
381
382 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
383 bluetooth::audio::hearing_aid::start_session();
384 bluetooth::audio::hearing_aid::set_remote_delay(remote_delay_ms);
385 }
386 localAudioReceiver = audioReceiver;
387 }
388
Stop()389 void HearingAidAudioSource::Stop() {
390 LOG(INFO) << __func__ << ": Hearing Aid Source Close";
391
392 localAudioReceiver = nullptr;
393 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
394 bluetooth::audio::hearing_aid::end_session();
395 }
396
397 stop_audio_ticks();
398 }
399
Initialize()400 void HearingAidAudioSource::Initialize() {
401 auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{
402 .on_resume_ = hearing_aid_on_resume_req,
403 .on_suspend_ = hearing_aid_on_suspend_req,
404 };
405 if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) {
406 LOG(WARNING) << __func__ << ": Using legacy HAL";
407 uipc_hearing_aid = UIPC_Init();
408 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH);
409 }
410 }
411
CleanUp()412 void HearingAidAudioSource::CleanUp() {
413 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
414 bluetooth::audio::hearing_aid::cleanup();
415 } else {
416 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL);
417 uipc_hearing_aid = nullptr;
418 }
419 }
420
DebugDump(int fd)421 void HearingAidAudioSource::DebugDump(int fd) {
422 uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
423 std::stringstream stream;
424 stream << " Hearing Aid Audio HAL:"
425 << "\n Counts (underflow) : "
426 << stats.media_read_total_underflow_count
427 << "\n Bytes (underflow) : "
428 << stats.media_read_total_underflow_bytes
429 << "\n Last update time ago in ms (underflow) : "
430 << (stats.media_read_last_underflow_us > 0
431 ? (unsigned long long)(now_us -
432 stats.media_read_last_underflow_us) /
433 1000
434 : 0)
435 << std::endl;
436 dprintf(fd, "%s", stream.str().c_str());
437 }
438