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 
AudioHalStats__anon0fb652380111::AudioHalStats49   AudioHalStats() { Reset(); }
50 
Reset__anon0fb652380111::AudioHalStats51   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 
send_audio_data()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 
hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status)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 
start_audio_ticks()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 
stop_audio_ticks()112 void stop_audio_ticks() {
113   LOG(INFO) << __func__ << ": stopped";
114   audio_timer.CancelAndWait();
115   wakelock_release();
116 }
117 
hearing_aid_data_cb(tUIPC_CH_ID,tUIPC_EVENT event)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 
hearing_aid_recv_ctrl_data()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 
hearing_aid_ctrl_cb(tUIPC_CH_ID,tUIPC_EVENT event)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 
hearing_aid_on_resume_req(bool start_media_task)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 
hearing_aid_on_suspend_req()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 
Start(const CodecConfiguration & codecConfiguration,HearingAidAudioReceiver * audioReceiver,uint16_t remote_delay_ms)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 
Stop()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 
Initialize()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 
CleanUp()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 
DebugDump(int fd)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