1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef A2DP_CODEC_CONFIG_H
17 #define A2DP_CODEC_CONFIG_H
18 
19 #include <cstdint>
20 #include <string>
21 
22 #include "a2dp_codec_constant.h"
23 
24 namespace OHOS {
25 namespace bluetooth {
26 struct A2dpCodecCapability {
27     A2dpCodecIndex codecIndex_;
28     A2dpCodecPriority codecPriority_;
29     A2dpCodecPriority defaultPriority_;
30     uint32_t sampleRate_;
31     uint32_t bitsPerSample;
32     uint8_t channelMode_;
33     uint64_t codecSpecific1;
34     uint64_t codecSpecific2;
35     uint64_t codecSpecific3;
36     uint64_t codecSpecific4;
37 
ToStringA2dpCodecCapability38     std::string ToString() const
39     {
40         std::string codecNameStr;
41 
42         switch (codecIndex_) {
43             case A2DP_SOURCE_CODEC_INDEX_SBC:
44                 codecNameStr = "SBC";
45                 break;
46             case A2DP_SOURCE_CODEC_INDEX_AAC:
47                 codecNameStr = "AAC";
48                 break;
49             case A2DP_SINK_CODEC_INDEX_SBC:
50                 codecNameStr = "SBC (Sink)";
51                 break;
52             case A2DP_SINK_CODEC_INDEX_AAC:
53                 codecNameStr = "AAC (Sink)";
54                 break;
55             default:
56                 codecNameStr = "invalid";
57                 break;
58         }
59 
60         std::string sampleRateStr;
61         AppendCapability(sampleRateStr, (sampleRate_ == A2DP_SAMPLE_RATE_NONE), "NONE");
62         AppendCapability(sampleRateStr, (sampleRate_ & A2DP_SBC_SAMPLE_RATE_44100), "44100");
63         AppendCapability(sampleRateStr, (sampleRate_ & A2DP_SBC_SAMPLE_RATE_48000), "48000");
64         AppendCapability(sampleRateStr, (sampleRate_ & A2DP_SBC_SAMPLE_RATE_32000), "32000");
65         AppendCapability(sampleRateStr, (sampleRate_ & A2DP_SBC_SAMPLE_RATE_16000), "16000");
66 
67         std::string bitsPerSampleStr;
68         AppendCapability(bitsPerSampleStr, (bitsPerSample == A2DP_SAMPLE_BITS_NONE), "NONE");
69         AppendCapability(bitsPerSampleStr, (bitsPerSample & A2DP_SAMPLE_BITS_16), "16");
70         AppendCapability(bitsPerSampleStr, (bitsPerSample & A2DP_SAMPLE_BITS_24), "24");
71         AppendCapability(bitsPerSampleStr, (bitsPerSample & A2DP_SAMPLE_BITS_32), "32");
72 
73         std::string channelModeStr;
74         AppendCapability(channelModeStr, (channelMode_ == A2DP_CHANNEL_MODE_NONE), "NONE");
75         AppendCapability(channelModeStr, (channelMode_ & A2DP_SBC_CHANNEL_MODE_MONO), "A2DP_SBC_CHANNEL_MODE_MONO");
76         AppendCapability(channelModeStr, (channelMode_ & A2DP_SBC_CHANNEL_MODE_STEREO), "A2DP_SBC_CHANNEL_MODE_STEREO");
77 
78         return "codec: " + codecNameStr + " priority: " + std::to_string(codecPriority_) +
79                " sampleRate_: " + sampleRateStr + " bitsPerSample: " + bitsPerSampleStr +
80                " channelMode_: " + channelModeStr + " codec_specific_1: " + std::to_string(codecSpecific1) +
81                " codec_specific_2: " + std::to_string(codecSpecific2) +
82                " codec_specific_3: " + std::to_string(codecSpecific3) +
83                " codec_specific_4: " + std::to_string(codecSpecific4);
84     }
85 
86 private:
AppendCapabilityA2dpCodecCapability87     static std::string AppendCapability(std::string &result, bool append, const std::string &name)
88     {
89         if (!append) {
90             return result;
91         }
92 
93         if (!result.empty()) {
94             result += "|";
95         }
96         result += name;
97         return result;
98     }
99 };
100 
101 class A2dpCodecConfig {
102 public:
103     explicit A2dpCodecConfig(A2dpCodecIndex index = A2dpCodecIndex::A2DP_SOURCE_CODEC_INDEX_SBC,
104         A2dpCodecPriority priority = A2dpCodecPriority::A2DP_CODEC_PRIORITY_DEFAULT);
105     virtual ~A2dpCodecConfig() = default;
106 
107     /**
108      * @brief A function to create codec elements.
109      *
110      * @param[in] codecIndex The index of the codec elements.
111      * @param[in] codecPriority The priority of the codec elements.
112      * @return A2DP_SUCCESS: Successful; otherwise failed to call avdtp api.
113      * @since 6.0
114      */
115     static A2dpCodecConfig *CreateCodec(A2dpCodecIndex codecIndex, A2dpCodecPriority codecPriority);
116     A2dpCodecIndex GetCodecIndex() const;
117     A2dpCodecPriority GetCodecPriority() const;
118     A2dpCodecCapability GetCodecLocalCapability() const;
119     A2dpCodecCapability GetCodecConfig() const;
120     A2dpCodecCapability GetUserConfig() const;
121     A2dpCodecCapability GetAudioCodecConfig() const;
122     uint32_t GetAudioBitsPerSample() const;
123     bool CopyOutOtaCodecConfig(uint8_t *codecInfo) const;
124     const std::string &Name() const;
125 
126     void SetCodecPriority(A2dpCodecPriority codecPriority);
127     void SetDefaultCodecPriority();
128     bool SetCodecUserConfig(const A2dpCodecCapability &userConfig, const A2dpCodecCapability &audioConfig,
129         const uint8_t *peerCodeInfo, uint8_t *resultCodecInfo, bool *restartConfig);
130     virtual bool SetCodecConfig(const uint8_t *peerCodeInfo, uint8_t *resultCodecInfo) = 0;
131     virtual bool SetPeerCodecCapabilities(const uint8_t *peerCapabilities) = 0;
132 
133 protected:
134     A2dpCodecCapability codecConfig_ {};
135     A2dpCodecCapability userCodecConfig_ {};
136     A2dpCodecCapability savedCodecUserConfig_ {};
137     A2dpCodecCapability audioCodecConfig_ {};
138     A2dpCodecCapability codecSelectableCap_ {};
139     A2dpCodecCapability codecLocalCap_ {};
140     A2dpCodecCapability codecCap_ {};
141     A2dpCodecCapability savedCodecCapability_ {};
142     A2dpCodecCapability savedCodecConfig_ {};
143     A2dpCodecCapability savedCodecSelectableCapability {};
144     A2dpCodecIndex codecIndex_ {};
145     A2dpCodecPriority codecPriority_ {};
146     A2dpCodecPriority defaultPriority_ {};
147     uint8_t otaCodecConfig_[A2DP_CODEC_SIZE] {};
148     uint8_t otaCodecPeerCapability_[A2DP_CODEC_SIZE] {};
149     uint8_t savedOtaCodecPeerCapability[A2DP_CODEC_SIZE] {};
150     uint8_t otaCodecPeerConfig_[A2DP_CODEC_SIZE] {};
151     uint8_t savedOtaCodecConfig_[A2DP_CODEC_SIZE] {};
152     std::string name_ = "";
153 };
154 
155 /**
156  * @brief A function to get the codec type.
157  *
158  * @param[in] codecInfo The information about the codec Capabilities.
159  * @return the codec type.
160  * @since 6.0
161  */
162 A2dpCodecType GetCodecType(const uint8_t *codecInfo);
163 
164 /**
165  * @brief A function to check codec capabilities conntain valid peer source codec.
166  *
167  * @param[in] codecInfo The information about the codec.
168  * @return TRUE: is valid, otherwise not valid.
169  * @since 6.0
170  */
171 bool IsPeerSourceCodecValid(const uint8_t *codecInfo);
172 
173 /**
174  * @brief A function to check codec capabilities conntain valid peer sink codec.
175  *
176  * @param[in] codecInfo The information about the codec.
177  * @return TRUE: is valid, otherwise not valid.
178  * @since 6.0
179  */
180 bool IsPeerSinkCodecValid(const uint8_t *codecInfo);
181 
182 /**
183  * @brief A function to get the source codec index.
184  *
185  * @param[in] codecInfo The information about the codec.
186  * @return the index of the codec.
187  * @since 6.0
188  */
189 A2dpCodecIndex GetSourceCodecIndex(const uint8_t *codecInfo);
190 
191 /**
192  * @brief A function to get the sink codec index.
193  *
194  * @param[in] codecInfo The information about the codec.
195  * @return the index of the codec.
196  * @since 6.0
197  */
198 A2dpCodecIndex GetSinkCodecIndex(const uint8_t *codecInfo);
199 
200 /**
201  * @brief A function to get the codec name
202  *
203  * @param[in] codecInfo The information about the codec Capabilities.
204  * @return the codec type.
205  * @since 6.0
206  */
207 bool IsConfigChanged(const uint8_t (&lastCodecInfo)[A2DP_CODEC_SIZE], const uint8_t *newCodecInfo);
208 }  // namespace bluetooth
209 }  // namespace OHOS
210 #endif  // !A2DP_CODEC_CONFIG_H