1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "a2dp_encoding_host.h"
18 
19 #include <bluetooth/log.h>
20 #include <grp.h>
21 #include <sys/stat.h>
22 
23 #include <memory>
24 #include <vector>
25 
26 #include "a2dp_encoding.h"
27 #include "btif/include/btif_a2dp_source.h"
28 #include "btif/include/btif_av.h"
29 #include "btif/include/btif_hf.h"
30 #include "stack/include/avdt_api.h"
31 #include "types/raw_address.h"
32 #include "udrv/include/uipc.h"
33 
34 #define A2DP_DATA_READ_POLL_MS 10
35 #define A2DP_HOST_DATA_PATH "/var/run/bluetooth/audio/.a2dp_data"
36 // TODO(b/198260375): Make A2DP data owner group configurable.
37 #define A2DP_HOST_DATA_GROUP "bluetooth-audio"
38 
39 typedef enum {
40   A2DP_CTRL_CMD_NONE,
41   A2DP_CTRL_CMD_CHECK_READY,
42   A2DP_CTRL_CMD_START,
43   A2DP_CTRL_CMD_STOP,
44   A2DP_CTRL_CMD_SUSPEND,
45   A2DP_CTRL_GET_INPUT_AUDIO_CONFIG,
46   A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
47   A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
48   A2DP_CTRL_GET_PRESENTATION_POSITION,
49 } tA2DP_CTRL_CMD;
50 
51 namespace std {
52 template <>
53 struct formatter<tUIPC_EVENT> : enum_formatter<tUIPC_EVENT> {};
54 template <>
55 struct formatter<tA2DP_CTRL_CMD> : enum_formatter<tA2DP_CTRL_CMD> {};
56 }  // namespace std
57 
58 namespace {
59 
60 std::unique_ptr<tUIPC_STATE> a2dp_uipc = nullptr;
61 
btif_a2dp_data_cb(tUIPC_CH_ID ch_id,tUIPC_EVENT event)62 static void btif_a2dp_data_cb([[maybe_unused]] tUIPC_CH_ID ch_id, tUIPC_EVENT event) {
63   bluetooth::log::warn("BTIF MEDIA (A2DP-DATA) EVENT {}", dump_uipc_event(event));
64 
65   switch (event) {
66     case UIPC_OPEN_EVT:
67       /*
68        * Read directly from media task from here on (keep callback for
69        * connection events.
70        */
71       UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
72       UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
73                  reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
74 
75       // Will start audio on btif_a2dp_on_started
76 
77       /* ACK back when media task is fully started */
78       break;
79 
80     case UIPC_CLOSE_EVT:
81       /* Post stop event and wait for audio path to stop */
82       btif_av_stream_stop(RawAddress::kEmpty);
83       break;
84 
85     default:
86       bluetooth::log::error("### A2DP-DATA EVENT {} NOT HANDLED ###", event);
87       break;
88   }
89 }
90 
91 // If A2DP_HOST_DATA_GROUP exists we expect audio server and BT both are
92 // in this group therefore have access to A2DP socket. Otherwise audio
93 // server should be in the same group that BT stack runs with to access
94 // A2DP socket.
a2dp_data_path_open()95 static void a2dp_data_path_open() {
96   UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb, A2DP_HOST_DATA_PATH);
97   struct group* grp = getgrnam(A2DP_HOST_DATA_GROUP);
98   chmod(A2DP_HOST_DATA_PATH, 0770);
99   if (grp) {
100     int res = chown(A2DP_HOST_DATA_PATH, -1, grp->gr_gid);
101     if (res == -1) {
102       bluetooth::log::error("failed: {}", strerror(errno));
103     }
104   }
105 }
106 
107 tA2DP_CTRL_CMD a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
108 uint64_t total_bytes_read_;
109 timespec data_position_;
110 uint16_t remote_delay_report_;
111 
112 }  // namespace
113 
114 namespace bluetooth {
115 namespace audio {
116 namespace a2dp {
117 
118 // Invoked by audio server to set audio config (PCM for now)
SetAudioConfig(AudioConfig config)119 bool SetAudioConfig(AudioConfig config) {
120   btav_a2dp_codec_config_t codec_config;
121   codec_config.sample_rate = config.sample_rate;
122   codec_config.bits_per_sample = config.bits_per_sample;
123   codec_config.channel_mode = config.channel_mode;
124   btif_a2dp_source_feeding_update_req(codec_config);
125   return true;
126 }
127 
128 // Invoked by audio server when it has audio data to stream.
StartRequest()129 bool StartRequest() {
130   // Reset total read bytes and timestamp to avoid confusing audio
131   // server at delay calculation.
132   total_bytes_read_ = 0;
133   data_position_ = {0, 0};
134 
135   // Check if a previous request is not finished
136   if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
137     log::info("A2DP_CTRL_CMD_START in progress");
138     return false;
139   } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
140     log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
141     return false;
142   }
143 
144   // Don't send START request to stack while we are in a call
145   if (!bluetooth::headset::IsCallIdle()) {
146     log::error("call state is busy");
147     return false;
148   }
149 
150   if (btif_av_stream_started_ready(A2dpType::kSource)) {
151     // Already started, ACK back immediately.
152     a2dp_data_path_open();
153     return true;
154   }
155   if (btif_av_stream_ready(A2dpType::kSource)) {
156     a2dp_data_path_open();
157     /*
158      * Post start event and wait for audio path to open.
159      * If we are the source, the ACK will be sent after the start
160      * procedure is completed.
161      */
162     a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
163     btif_av_stream_start(A2dpType::kSource);
164     if (btif_av_get_peer_sep(A2dpType::kSource) != AVDT_TSEP_SRC) {
165       log::info("accepted");
166       return true;  // NOTE: The request is placed, but could still fail.
167     }
168     a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
169     return true;
170   }
171   log::error("AV stream is not ready to start");
172   return false;
173 }
174 
175 // Invoked by audio server when audio streaming is done.
StopRequest()176 bool StopRequest() {
177   if (btif_av_get_peer_sep(A2dpType::kSource) == AVDT_TSEP_SNK &&
178       !btif_av_stream_started_ready(A2dpType::kSource)) {
179     btif_av_clear_remote_suspend_flag(A2dpType::kSource);
180     return true;
181   }
182   log::info("handling");
183   a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
184   btif_av_stream_stop(RawAddress::kEmpty);
185   return true;
186 }
187 
SuspendRequest()188 bool SuspendRequest() {
189   if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
190     log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
191     return false;
192   }
193   if (!btif_av_stream_started_ready(A2dpType::kSource)) {
194     log::warn("AV stream is not started");
195     return false;
196   }
197   log::info("handling");
198   a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
199   btif_av_stream_suspend();
200   return true;
201 }
202 
203 // Invoked by audio server to check audio presentation position periodically.
GetPresentationPosition()204 PresentationPosition GetPresentationPosition() {
205   PresentationPosition presentation_position{
206           .remote_delay_report_ns = remote_delay_report_ * 100000u,
207           .total_bytes_read = total_bytes_read_,
208           .data_position = data_position_,
209   };
210   return presentation_position;
211 }
212 
213 // delay reports from AVDTP is based on 1/10 ms (100us)
set_remote_delay(uint16_t delay_report)214 void set_remote_delay(uint16_t delay_report) { remote_delay_report_ = delay_report; }
215 
216 // Inform audio server about offloading codec; not used for now
update_codec_offloading_capabilities(const std::vector<btav_a2dp_codec_config_t> &,bool)217 bool update_codec_offloading_capabilities(
218         const std::vector<btav_a2dp_codec_config_t>& /*framework_preference*/,
219         bool /*supports_a2dp_hw_offload_v2*/) {
220   return false;
221 }
222 
223 // Checking if new bluetooth_audio is enabled
is_hal_enabled()224 bool is_hal_enabled() { return true; }
225 
226 // Check if new bluetooth_audio is running with offloading encoders
is_hal_offloading()227 bool is_hal_offloading() { return false; }
228 
229 static StreamCallbacks null_stream_callbacks_;
230 static StreamCallbacks const* stream_callbacks_ = &null_stream_callbacks_;
231 
232 // Initialize BluetoothAudio HAL: openProvider
init(bluetooth::common::MessageLoopThread *,StreamCallbacks const * strean_callbacks,bool)233 bool init(bluetooth::common::MessageLoopThread* /*message_loop*/,
234           StreamCallbacks const* strean_callbacks, bool /*offload_enabled*/) {
235   if (a2dp_uipc != nullptr) {
236     log::warn("Re-init-ing UIPC that is already running");
237     cleanup();
238   }
239   a2dp_uipc = UIPC_Init();
240   total_bytes_read_ = 0;
241   data_position_ = {};
242   remote_delay_report_ = 0;
243   stream_callbacks_ = strean_callbacks;
244 
245   return true;
246 }
247 
248 // Clean up BluetoothAudio HAL
cleanup()249 void cleanup() {
250   end_session();
251   stream_callbacks_ = &null_stream_callbacks_;
252 
253   if (a2dp_uipc != nullptr) {
254     UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
255     a2dp_uipc = nullptr;
256   }
257 }
258 
259 // Set up the codec into BluetoothAudio HAL
setup_codec(A2dpCodecConfig *,uint16_t,int)260 bool setup_codec(A2dpCodecConfig* /*a2dp_config*/, uint16_t /*peer_mtu*/,
261                  int /*preferred_encoding_interval_us*/) {
262   // TODO: setup codec
263   return true;
264 }
265 
start_session()266 void start_session() {
267   // TODO: Notify server; or do we handle it during connected?
268 }
269 
end_session()270 void end_session() {
271   // TODO: Notify server; or do we handle it during disconnected?
272 
273   // Reset remote delay. New value will be set when new session starts.
274   remote_delay_report_ = 0;
275 
276   a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
277 }
278 
set_audio_low_latency_mode_allowed(bool)279 void set_audio_low_latency_mode_allowed(bool /*allowed*/) {}
280 
ack_stream_started(Status)281 void ack_stream_started(Status /*ack*/) {
282   a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
283   // TODO: Notify server
284 }
285 
ack_stream_suspended(Status)286 void ack_stream_suspended(Status /*ack*/) {
287   a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
288   // TODO: Notify server
289 }
290 
291 // Read from the FMQ of BluetoothAudio HAL
read(uint8_t * p_buf,uint32_t len)292 size_t read(uint8_t* p_buf, uint32_t len) {
293   uint32_t bytes_read = 0;
294   if (a2dp_uipc == nullptr) {
295     return 0;
296   }
297   bytes_read = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len);
298   total_bytes_read_ += bytes_read;
299   // MONOTONIC_RAW isn't affected by NTP, audio stack rely on this
300   // to get precise delay calculation.
301   clock_gettime(CLOCK_MONOTONIC_RAW, &data_position_);
302   return bytes_read;
303 }
304 
305 // Check if OPUS codec is supported
is_opus_supported()306 bool is_opus_supported() { return true; }
307 
308 namespace provider {
309 
310 // Lookup the codec info in the list of supported offloaded sink codecs.
sink_codec_index(const uint8_t *)311 std::optional<btav_a2dp_codec_index_t> sink_codec_index(const uint8_t* /*p_codec_info*/) {
312   return std::nullopt;
313 }
314 
315 // Lookup the codec info in the list of supported offloaded source codecs.
source_codec_index(const uint8_t *)316 std::optional<btav_a2dp_codec_index_t> source_codec_index(const uint8_t* /*p_codec_info*/) {
317   return std::nullopt;
318 }
319 
320 // Return the name of the codec which is assigned to the input index.
321 // The codec index must be in the ranges
322 // BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
323 // BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
324 // Returns nullopt if the codec_index is not assigned or codec extensibility
325 // is not supported or enabled.
codec_index_str(btav_a2dp_codec_index_t)326 std::optional<const char*> codec_index_str(btav_a2dp_codec_index_t /*codec_index*/) {
327   return std::nullopt;
328 }
329 
330 // Return true if the codec is supported for the session type
331 // A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
supports_codec(btav_a2dp_codec_index_t)332 bool supports_codec(btav_a2dp_codec_index_t /*codec_index*/) { return false; }
333 
334 // Return the A2DP capabilities for the selected codec.
codec_info(btav_a2dp_codec_index_t,bluetooth::a2dp::CodecId *,uint8_t *,btav_a2dp_codec_config_t *)335 bool codec_info(btav_a2dp_codec_index_t /*codec_index*/, bluetooth::a2dp::CodecId* /*codec_id*/,
336                 uint8_t* /*codec_info*/, btav_a2dp_codec_config_t* /*codec_config*/) {
337   return false;
338 }
339 
340 // Query the codec selection fromt the audio HAL.
341 // The HAL is expected to pick the best audio configuration based on the
342 // discovered remote SEPs.
get_a2dp_configuration(RawAddress,std::vector<a2dp_remote_capabilities> const &,btav_a2dp_codec_config_t const &)343 std::optional<a2dp_configuration> get_a2dp_configuration(
344         RawAddress /*peer_address*/, std::vector<a2dp_remote_capabilities> const& /*remote_seps*/,
345         btav_a2dp_codec_config_t const& /*user_preferences*/) {
346   return std::nullopt;
347 }
348 
349 // Query the codec parameters from the audio HAL.
350 // The HAL performs a two part validation:
351 //  - check if the configuration is valid
352 //  - check if the configuration is supported by the audio provider
353 // In case any of these checks fails, the corresponding A2DP
354 // status is returned. If the configuration is valid and supported,
355 // A2DP_OK is returned.
parse_a2dp_configuration(btav_a2dp_codec_index_t,const uint8_t *,btav_a2dp_codec_config_t *,std::vector<uint8_t> *)356 tA2DP_STATUS parse_a2dp_configuration(btav_a2dp_codec_index_t /*codec_index*/,
357                                       const uint8_t* /*codec_info*/,
358                                       btav_a2dp_codec_config_t* /*codec_parameters*/,
359                                       std::vector<uint8_t>* /*vendor_specific_parameters*/) {
360   return A2DP_FAIL;
361 }
362 
363 }  // namespace provider
364 
365 }  // namespace a2dp
366 }  // namespace audio
367 }  // namespace bluetooth
368