1 /*
2  * Copyright 2019 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 #pragma once
18 
19 #include <iomanip>
20 #include <sstream>
21 #include <vector>
22 
23 #include "a2dp_error_codes.h"
24 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
25 #include "avdt_api.h"
26 #include "common/message_loop_thread.h"
27 
28 namespace bluetooth {
29 namespace audio {
30 namespace a2dp {
31 
32 bool update_codec_offloading_capabilities(
33     const std::vector<btav_a2dp_codec_config_t>& framework_preference,
34     bool supports_a2dp_hw_offload_v2);
35 
36 // Check if new bluetooth_audio is enabled
37 bool is_hal_enabled();
38 
39 // Check if new bluetooth_audio is running with offloading encoders
40 bool is_hal_offloading();
41 
42 // Initialize BluetoothAudio HAL: openProvider
43 bool init(bluetooth::common::MessageLoopThread* message_loop);
44 
45 // Clean up BluetoothAudio HAL
46 void cleanup();
47 
48 // Set up the codec into BluetoothAudio HAL
49 bool setup_codec();
50 
51 // Set low latency buffer mode allowed or disallowed
52 void set_audio_low_latency_mode_allowed(bool allowed);
53 
54 // Send command to the BluetoothAudio HAL: StartSession, EndSession,
55 // StreamStarted, StreamSuspended
56 void start_session();
57 void end_session();
58 void ack_stream_started(const tA2DP_CTRL_ACK& status);
59 void ack_stream_suspended(const tA2DP_CTRL_ACK& status);
60 
61 // Read from the FMQ of BluetoothAudio HAL
62 size_t read(uint8_t* p_buf, uint32_t len);
63 
64 // Update A2DP delay report to BluetoothAudio HAL
65 void set_remote_delay(uint16_t delay_report);
66 
67 // Check whether OPUS is supported
68 bool is_opus_supported();
69 
70 // Definitions for A2DP hardware offload codec extensibility.
71 namespace provider {
72 
73 // Lookup the codec info in the list of supported offloaded sink codecs.
74 std::optional<btav_a2dp_codec_index_t> sink_codec_index(
75     const uint8_t* p_codec_info);
76 
77 // Lookup the codec info in the list of supported offloaded source codecs.
78 std::optional<btav_a2dp_codec_index_t> source_codec_index(
79     const uint8_t* p_codec_info);
80 
81 // Return the name of the codec which is assigned to the input index.
82 // The codec index must be in the ranges
83 // BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
84 // BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
85 // Returns nullopt if the codec_index is not assigned or codec extensibility
86 // is not supported or enabled.
87 std::optional<const char*> codec_index_str(btav_a2dp_codec_index_t codec_index);
88 
89 // Return true if the codec is supported for the session type
90 // A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
91 bool supports_codec(btav_a2dp_codec_index_t codec_index);
92 
93 // Return the A2DP capabilities for the selected codec.
94 // `codec_info` returns the OTA codec capabilities, `codec_config`
95 // returns the supported capabilities in a generic format.
96 bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
97                 uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config);
98 
99 struct a2dp_configuration {
100   int remote_seid;
101   uint8_t codec_config[AVDT_CODEC_SIZE];
102   btav_a2dp_codec_config_t codec_parameters;
103   std::vector<uint8_t> vendor_specific_parameters;
104 
toStringa2dp_configuration105   inline std::string toString() const {
106     std::ostringstream os;
107     os << "A2dpConfiguration{";
108     os << "remote_seid: " << remote_seid;
109     os << ", codec_index: " << codec_parameters.codec_type;
110     os << ", codec_config: {";
111     for (int i = 0; i < AVDT_CODEC_SIZE; i++) {
112       os << "0x" << std::hex << std::setw(2) << std::setfill('0')
113          << static_cast<int>(codec_config[i]);
114       if (i != AVDT_CODEC_SIZE - 1) os << ",";
115     }
116     os << "}";
117     os << "}";
118     return os.str();
119   }
120 };
121 
122 struct a2dp_remote_capabilities {
123   int seid;
124   uint8_t const* capabilities;
125 
toStringa2dp_remote_capabilities126   inline std::string toString() const {
127     std::ostringstream os;
128     os << "A2dpRemoteCapabilities{";
129     os << "seid: " << seid;
130     os << ", capabilities: {";
131     if (capabilities != nullptr) {
132       for (int i = 0; i < AVDT_CODEC_SIZE; i++) {
133         os << "0x" << std::hex << std::setw(2) << std::setfill('0')
134            << static_cast<int>(capabilities[i]);
135         if (i != AVDT_CODEC_SIZE - 1) os << ",";
136       }
137     }
138     os << "}";
139     os << "}";
140     return os.str();
141   }
142 };
143 
144 // Query the codec selection fromt the audio HAL.
145 // The HAL is expected to pick the best audio configuration based on the
146 // discovered remote SEPs.
147 std::optional<a2dp_configuration> get_a2dp_configuration(
148     RawAddress peer_address,
149     std::vector<a2dp_remote_capabilities> const& remote_seps,
150     btav_a2dp_codec_config_t const& user_preferences);
151 
152 // Query the codec parameters from the audio HAL.
153 // The HAL is expected to parse the codec configuration
154 // received from the peer and decide whether accept
155 // the it or not.
156 tA2DP_STATUS parse_a2dp_configuration(
157     btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
158     btav_a2dp_codec_config_t* codec_parameters,
159     std::vector<uint8_t>* vendor_specific_parameters);
160 
161 }  // namespace provider
162 }  // namespace a2dp
163 }  // namespace audio
164 }  // namespace bluetooth
165