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