• 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 <cstdint>
21 #include <memory>
22 #include <sstream>
23 #include <vector>
24 
25 #include "audio_hal_interface/hearing_aid_software_encoding.h"
26 #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
27 #include "bta/include/bta_hearing_aid_api.h"
28 #include "common/repeating_timer.h"
29 #include "common/time_util.h"
30 #include "osi/include/wakelock.h"
31 #include "stack/include/btu.h"  // get_main_thread
32 #include "udrv/include/uipc.h"
33 
34 using base::FilePath;
35 
36 namespace {
37 #define CASE_RETURN_STR(const) \
38   case const:                  \
39     return #const;
40 
audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event)41 const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
42   switch (event) {
43     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
44     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
45     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
46     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
47     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
48     CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
49     CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
50     CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
51     CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
52     default:
53       break;
54   }
55 
56   return "UNKNOWN HEARING_AID_CTRL_CMD";
57 }
58 
59 int bit_rate = -1;
60 int sample_rate = -1;
61 int data_interval_ms = -1;
62 int num_channels = 2;
63 bluetooth::common::RepeatingTimer audio_timer;
64 HearingAidAudioReceiver* localAudioReceiver = nullptr;
65 std::unique_ptr<tUIPC_STATE> uipc_hearing_aid = nullptr;
66 
67 struct AudioHalStats {
68   size_t media_read_total_underflow_bytes;
69   size_t media_read_total_underflow_count;
70   uint64_t media_read_last_underflow_us;
71 
AudioHalStats__anon5f7db97f0111::AudioHalStats72   AudioHalStats() { Reset(); }
73 
Reset__anon5f7db97f0111::AudioHalStats74   void Reset() {
75     media_read_total_underflow_bytes = 0;
76     media_read_total_underflow_count = 0;
77     media_read_last_underflow_us = 0;
78   }
79 };
80 
81 AudioHalStats stats;
82 
83 bool hearing_aid_on_resume_req(bool start_media_task);
84 bool hearing_aid_on_suspend_req();
85 
send_audio_data()86 void send_audio_data() {
87   uint32_t bytes_per_tick =
88       (num_channels * sample_rate * data_interval_ms * (bit_rate / 8)) / 1000;
89 
90   uint16_t event;
91   uint8_t p_buf[bytes_per_tick];
92 
93   uint32_t bytes_read;
94   if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
95     bytes_read = bluetooth::audio::hearing_aid::read(p_buf, bytes_per_tick);
96   } else {
97     bytes_read = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, &event,
98                            p_buf, bytes_per_tick);
99   }
100 
101   VLOG(2) << "bytes_read: " << bytes_read;
102   if (bytes_read < bytes_per_tick) {
103     stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read;
104     stats.media_read_total_underflow_count++;
105     stats.media_read_last_underflow_us =
106         bluetooth::common::time_get_os_boottime_us();
107   }
108 
109   std::vector<uint8_t> data(p_buf, p_buf + bytes_read);
110 
111   if (localAudioReceiver != nullptr) {
112     localAudioReceiver->OnAudioDataReady(data);
113   }
114 }
115 
hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status)116 void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) {
117   uint8_t ack = status;
118   DVLOG(2) << "Hearing Aid audio ctrl ack: " << status;
119   UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
120 }
121 
start_audio_ticks()122 void start_audio_ticks() {
123   if (data_interval_ms != HA_INTERVAL_10_MS &&
124       data_interval_ms != HA_INTERVAL_20_MS) {
125     LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
126   }
127 
128   wakelock_acquire();
129   audio_timer.SchedulePeriodic(
130       get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
131       base::TimeDelta::FromMilliseconds(data_interval_ms));
132   LOG(INFO) << __func__ << ": running with data interval: " << data_interval_ms;
133 }
134 
stop_audio_ticks()135 void stop_audio_ticks() {
136   LOG(INFO) << __func__ << ": stopped";
137   audio_timer.CancelAndWait();
138   wakelock_release();
139 }
140 
hearing_aid_data_cb(tUIPC_CH_ID,tUIPC_EVENT event)141 void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
142   DVLOG(2) << "Hearing Aid audio data event: " << event;
143   switch (event) {
144     case UIPC_OPEN_EVT:
145       LOG(INFO) << __func__ << ": UIPC_OPEN_EVT";
146       /*
147        * Read directly from media task from here on (keep callback for
148        * connection events.
149        */
150       UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO,
151                  UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
152       UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
153                  reinterpret_cast<void*>(0));
154 
155       do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks));
156       break;
157     case UIPC_CLOSE_EVT:
158       LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT";
159       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
160       do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks));
161       break;
162     default:
163       LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event;
164   }
165 }
166 
hearing_aid_recv_ctrl_data()167 void hearing_aid_recv_ctrl_data() {
168   tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE;
169   int n;
170 
171   uint8_t read_cmd = 0; /* The read command size is one octet */
172   n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, NULL, &read_cmd, 1);
173   cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd);
174 
175   /* detach on ctrl channel means audioflinger process was terminated */
176   if (n == 0) {
177     LOG(WARNING) << __func__ << "CTRL CH DETACHED";
178     UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL);
179     return;
180   }
181 
182   LOG(INFO) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd);
183   //  a2dp_cmd_pending = cmd;
184 
185   tHEARING_AID_CTRL_ACK ctrl_ack_status;
186 
187   switch (cmd) {
188     case HEARING_AID_CTRL_CMD_CHECK_READY:
189       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
190       break;
191 
192     case HEARING_AID_CTRL_CMD_START:
193       ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
194       // timer is restarted in UIPC_Open
195       if (!hearing_aid_on_resume_req(false)) {
196         ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
197       } else {
198         UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb,
199                   HEARING_AID_DATA_PATH);
200       }
201       hearing_aid_send_ack(ctrl_ack_status);
202       break;
203 
204     case HEARING_AID_CTRL_CMD_STOP:
205       if (!hearing_aid_on_suspend_req()) {
206         LOG(INFO) << __func__ << ":HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but ignored.";
207       }
208       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
209       break;
210 
211     case HEARING_AID_CTRL_CMD_SUSPEND:
212       ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
213       if (!hearing_aid_on_suspend_req()) {
214         ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
215       }
216       hearing_aid_send_ack(ctrl_ack_status);
217       break;
218 
219     case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: {
220       btav_a2dp_codec_config_t codec_config;
221       btav_a2dp_codec_config_t codec_capability;
222       if (sample_rate == 16000) {
223         codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
224         codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
225       } else if (sample_rate == 24000) {
226         codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
227         codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
228       } else {
229         LOG(FATAL) << "unsupported sample rate: " << sample_rate;
230       }
231 
232       codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
233       codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
234 
235       codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
236       codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
237 
238       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
239       // Send the current codec config
240       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
241                 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
242                 sizeof(btav_a2dp_codec_sample_rate_t));
243       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
244                 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
245                 sizeof(btav_a2dp_codec_bits_per_sample_t));
246       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
247                 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
248                 sizeof(btav_a2dp_codec_channel_mode_t));
249       // Send the current codec capability
250       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
251                 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
252                 sizeof(btav_a2dp_codec_sample_rate_t));
253       UIPC_Send(
254           *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
255           reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
256           sizeof(btav_a2dp_codec_bits_per_sample_t));
257       UIPC_Send(
258           *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
259           reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
260           sizeof(btav_a2dp_codec_channel_mode_t));
261       break;
262     }
263 
264     case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: {
265       // TODO: we only support one config for now!
266       btav_a2dp_codec_config_t codec_config;
267       codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
268       codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
269       codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
270 
271       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
272       // Send the current codec config
273       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
274                     reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
275                     sizeof(btav_a2dp_codec_sample_rate_t)) !=
276           sizeof(btav_a2dp_codec_sample_rate_t)) {
277         LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL";
278         break;
279       }
280       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
281                     reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
282                     sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
283           sizeof(btav_a2dp_codec_bits_per_sample_t)) {
284         LOG(ERROR) << __func__
285                    << "Error reading bits per sample from audio HAL";
286 
287         break;
288       }
289       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
290                     reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
291                     sizeof(btav_a2dp_codec_channel_mode_t)) !=
292           sizeof(btav_a2dp_codec_channel_mode_t)) {
293         LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL";
294 
295         break;
296       }
297       LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
298                 << "sample_rate=" << codec_config.sample_rate
299                 << "bits_per_sample=" << codec_config.bits_per_sample
300                 << "channel_mode=" << codec_config.channel_mode;
301       break;
302     }
303 
304     default:
305       LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd;
306       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE);
307       break;
308   }
309   LOG(INFO) << __func__
310             << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd)
311             << " DONE";
312 }
313 
hearing_aid_ctrl_cb(tUIPC_CH_ID,tUIPC_EVENT event)314 void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
315   VLOG(2) << "Hearing Aid audio ctrl event: " << event;
316   switch (event) {
317     case UIPC_OPEN_EVT:
318       break;
319     case UIPC_CLOSE_EVT:
320       /* restart ctrl server unless we are shutting down */
321       if (HearingAid::IsHearingAidRunning()) {
322         UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb,
323                   HEARING_AID_CTRL_PATH);
324       }
325       break;
326     case UIPC_RX_DATA_READY_EVT:
327       hearing_aid_recv_ctrl_data();
328       break;
329     default:
330       LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event;
331   }
332 }
333 
hearing_aid_on_resume_req(bool start_media_task)334 bool hearing_aid_on_resume_req(bool start_media_task) {
335   if (localAudioReceiver == nullptr) {
336     LOG(ERROR) << __func__
337                << ": HEARING_AID_CTRL_CMD_START: audio receiver not started";
338     return false;
339   }
340   bt_status_t status;
341   if (start_media_task) {
342     status = do_in_main_thread(
343         FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
344                                   base::Unretained(localAudioReceiver),
345                                   start_audio_ticks));
346   } else {
347     auto start_dummy_ticks = []() {
348       LOG(INFO) << "start_audio_ticks: waiting for data path opened";
349     };
350     status = do_in_main_thread(
351         FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
352                                   base::Unretained(localAudioReceiver),
353                                   start_dummy_ticks));
354   }
355   if (status != BT_STATUS_SUCCESS) {
356     LOG(ERROR) << __func__
357                << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
358                << 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) << __func__
367                << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started";
368     return false;
369   }
370   bt_status_t status = do_in_main_thread(
371       FROM_HERE,
372       base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
373                      base::Unretained(localAudioReceiver), stop_audio_ticks));
374   if (status != BT_STATUS_SUCCESS) {
375     LOG(ERROR) << __func__
376                << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
377                << 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) << __func__ << ": 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_2_0_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) << __func__ << ": Hearing Aid Source Close";
404 
405   localAudioReceiver = nullptr;
406   if (bluetooth::audio::hearing_aid::is_hal_2_0_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(WARNING) << __func__ << ": 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_2_0_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