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