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