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