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 49 AudioHalStats() { Reset(); } 50 51 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 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 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 99 void start_audio_ticks() { 100 if (data_interval_ms != HA_INTERVAL_10_MS && 101 data_interval_ms != HA_INTERVAL_20_MS) { 102 LOG(FATAL) << " Unsupported data interval: " << data_interval_ms; 103 } 104 105 wakelock_acquire(); 106 audio_timer.SchedulePeriodic( 107 get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data), 108 base::TimeDelta::FromMilliseconds(data_interval_ms)); 109 LOG(INFO) << __func__ << ": running with data interval: " << data_interval_ms; 110 } 111 112 void stop_audio_ticks() { 113 LOG(INFO) << __func__ << ": stopped"; 114 audio_timer.CancelAndWait(); 115 wakelock_release(); 116 } 117 118 void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { 119 DVLOG(2) << "Hearing Aid audio data event: " << event; 120 switch (event) { 121 case UIPC_OPEN_EVT: 122 LOG(INFO) << __func__ << ": UIPC_OPEN_EVT"; 123 /* 124 * Read directly from media task from here on (keep callback for 125 * connection events. 126 */ 127 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, 128 UIPC_REG_REMOVE_ACTIVE_READSET, NULL); 129 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO, 130 reinterpret_cast<void*>(0)); 131 132 do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks)); 133 break; 134 case UIPC_CLOSE_EVT: 135 LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT"; 136 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 137 do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks)); 138 break; 139 default: 140 LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event; 141 } 142 } 143 144 void hearing_aid_recv_ctrl_data() { 145 tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE; 146 int n; 147 148 uint8_t read_cmd = 0; /* The read command size is one octet */ 149 n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, NULL, &read_cmd, 1); 150 cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd); 151 152 /* detach on ctrl channel means audioflinger process was terminated */ 153 if (n == 0) { 154 LOG(WARNING) << __func__ << "CTRL CH DETACHED"; 155 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL); 156 return; 157 } 158 159 LOG(INFO) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd); 160 // a2dp_cmd_pending = cmd; 161 162 tHEARING_AID_CTRL_ACK ctrl_ack_status; 163 164 switch (cmd) { 165 case HEARING_AID_CTRL_CMD_CHECK_READY: 166 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 167 break; 168 169 case HEARING_AID_CTRL_CMD_START: 170 ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS; 171 // timer is restarted in UIPC_Open 172 if (!hearing_aid_on_resume_req(false)) { 173 ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE; 174 } else { 175 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb, 176 HEARING_AID_DATA_PATH); 177 } 178 hearing_aid_send_ack(ctrl_ack_status); 179 break; 180 181 case HEARING_AID_CTRL_CMD_STOP: 182 if (!hearing_aid_on_suspend_req()) { 183 LOG(INFO) << __func__ << ":HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but ignored."; 184 } 185 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 186 break; 187 188 case HEARING_AID_CTRL_CMD_SUSPEND: 189 ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS; 190 if (!hearing_aid_on_suspend_req()) { 191 ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE; 192 } 193 hearing_aid_send_ack(ctrl_ack_status); 194 break; 195 196 case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: { 197 btav_a2dp_codec_config_t codec_config; 198 btav_a2dp_codec_config_t codec_capability; 199 if (sample_rate == 16000) { 200 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000; 201 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000; 202 } else if (sample_rate == 24000) { 203 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; 204 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; 205 } else { 206 LOG(FATAL) << "unsupported sample rate: " << sample_rate; 207 } 208 209 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; 210 codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; 211 212 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; 213 codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; 214 215 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 216 // Send the current codec config 217 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 218 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate), 219 sizeof(btav_a2dp_codec_sample_rate_t)); 220 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 221 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample), 222 sizeof(btav_a2dp_codec_bits_per_sample_t)); 223 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 224 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode), 225 sizeof(btav_a2dp_codec_channel_mode_t)); 226 // Send the current codec capability 227 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 228 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate), 229 sizeof(btav_a2dp_codec_sample_rate_t)); 230 UIPC_Send( 231 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 232 reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample), 233 sizeof(btav_a2dp_codec_bits_per_sample_t)); 234 UIPC_Send( 235 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 236 reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode), 237 sizeof(btav_a2dp_codec_channel_mode_t)); 238 break; 239 } 240 241 case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: { 242 // TODO: we only support one config for now! 243 btav_a2dp_codec_config_t codec_config; 244 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; 245 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE; 246 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE; 247 248 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 249 // Send the current codec config 250 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 251 reinterpret_cast<uint8_t*>(&codec_config.sample_rate), 252 sizeof(btav_a2dp_codec_sample_rate_t)) != 253 sizeof(btav_a2dp_codec_sample_rate_t)) { 254 LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL"; 255 break; 256 } 257 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 258 reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample), 259 sizeof(btav_a2dp_codec_bits_per_sample_t)) != 260 sizeof(btav_a2dp_codec_bits_per_sample_t)) { 261 LOG(ERROR) << __func__ 262 << "Error reading bits per sample from audio HAL"; 263 264 break; 265 } 266 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 267 reinterpret_cast<uint8_t*>(&codec_config.channel_mode), 268 sizeof(btav_a2dp_codec_channel_mode_t)) != 269 sizeof(btav_a2dp_codec_channel_mode_t)) { 270 LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL"; 271 272 break; 273 } 274 LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: " 275 << "sample_rate=" << codec_config.sample_rate 276 << "bits_per_sample=" << codec_config.bits_per_sample 277 << "channel_mode=" << codec_config.channel_mode; 278 break; 279 } 280 281 default: 282 LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd; 283 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE); 284 break; 285 } 286 LOG(INFO) << __func__ 287 << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd) 288 << " DONE"; 289 } 290 291 void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { 292 VLOG(2) << "Hearing Aid audio ctrl event: " << event; 293 switch (event) { 294 case UIPC_OPEN_EVT: 295 break; 296 case UIPC_CLOSE_EVT: 297 /* restart ctrl server unless we are shutting down */ 298 if (HearingAid::IsHearingAidRunning()) { 299 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, 300 HEARING_AID_CTRL_PATH); 301 } 302 break; 303 case UIPC_RX_DATA_READY_EVT: 304 hearing_aid_recv_ctrl_data(); 305 break; 306 default: 307 LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event; 308 } 309 } 310 311 bool hearing_aid_on_resume_req(bool start_media_task) { 312 if (localAudioReceiver == nullptr) { 313 LOG(ERROR) << __func__ 314 << ": HEARING_AID_CTRL_CMD_START: audio receiver not started"; 315 return false; 316 } 317 bt_status_t status; 318 if (start_media_task) { 319 status = do_in_main_thread( 320 FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume, 321 base::Unretained(localAudioReceiver), 322 start_audio_ticks)); 323 } else { 324 auto start_dummy_ticks = []() { 325 LOG(INFO) << "start_audio_ticks: waiting for data path opened"; 326 }; 327 status = do_in_main_thread( 328 FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume, 329 base::Unretained(localAudioReceiver), 330 start_dummy_ticks)); 331 } 332 if (status != BT_STATUS_SUCCESS) { 333 LOG(ERROR) << __func__ 334 << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err=" 335 << status; 336 return false; 337 } 338 return true; 339 } 340 341 bool hearing_aid_on_suspend_req() { 342 if (localAudioReceiver == nullptr) { 343 LOG(ERROR) << __func__ 344 << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started"; 345 return false; 346 } 347 bt_status_t status = do_in_main_thread( 348 FROM_HERE, 349 base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend, 350 base::Unretained(localAudioReceiver), stop_audio_ticks)); 351 if (status != BT_STATUS_SUCCESS) { 352 LOG(ERROR) << __func__ 353 << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err=" 354 << status; 355 return false; 356 } 357 return true; 358 } 359 } // namespace 360 361 void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, 362 HearingAidAudioReceiver* audioReceiver, 363 uint16_t remote_delay_ms) { 364 LOG(INFO) << __func__ << ": Hearing Aid Source Open"; 365 366 bit_rate = codecConfiguration.bit_rate; 367 sample_rate = codecConfiguration.sample_rate; 368 data_interval_ms = codecConfiguration.data_interval_ms; 369 370 stats.Reset(); 371 372 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) { 373 bluetooth::audio::hearing_aid::start_session(); 374 bluetooth::audio::hearing_aid::set_remote_delay(remote_delay_ms); 375 } 376 localAudioReceiver = audioReceiver; 377 } 378 379 void HearingAidAudioSource::Stop() { 380 LOG(INFO) << __func__ << ": Hearing Aid Source Close"; 381 382 localAudioReceiver = nullptr; 383 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) { 384 bluetooth::audio::hearing_aid::end_session(); 385 } 386 387 stop_audio_ticks(); 388 } 389 390 void HearingAidAudioSource::Initialize() { 391 auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{ 392 .on_resume_ = hearing_aid_on_resume_req, 393 .on_suspend_ = hearing_aid_on_suspend_req, 394 }; 395 if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) { 396 LOG(WARNING) << __func__ << ": Using legacy HAL"; 397 uipc_hearing_aid = UIPC_Init(); 398 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH); 399 } 400 } 401 402 void HearingAidAudioSource::CleanUp() { 403 if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) { 404 bluetooth::audio::hearing_aid::cleanup(); 405 } else { 406 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL); 407 uipc_hearing_aid = nullptr; 408 } 409 } 410 411 void HearingAidAudioSource::DebugDump(int fd) { 412 uint64_t now_us = bluetooth::common::time_get_os_boottime_us(); 413 std::stringstream stream; 414 stream << " Hearing Aid Audio HAL:" 415 << "\n Counts (underflow) : " 416 << stats.media_read_total_underflow_count 417 << "\n Bytes (underflow) : " 418 << stats.media_read_total_underflow_bytes 419 << "\n Last update time ago in ms (underflow) : " 420 << (stats.media_read_last_underflow_us > 0 421 ? (unsigned long long)(now_us - 422 stats.media_read_last_underflow_us) / 423 1000 424 : 0) 425 << std::endl; 426 dprintf(fd, "%s", stream.str().c_str()); 427 } 428