• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "daudio_utils.h"
17 
18 #include <ctime>
19 
20 #include "daudio_constants.h"
21 #include "daudio_errcode.h"
22 #include "daudio_log.h"
23 
24 #undef DH_LOG_TAG
25 #define DH_LOG_TAG "DAudioUtils"
26 
27 namespace OHOS {
28 namespace DistributedHardware {
29 constexpr size_t INT32_SHORT_ID_LENGTH = 20;
30 constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
31 constexpr size_t INT32_MIN_ID_LENGTH = 3;
32 constexpr uint8_t MAX_KEY_DH_ID_LEN = 20;
33 
GetAnonyString(const std::string & value)34 std::string GetAnonyString(const std::string &value)
35 {
36     std::string res;
37     std::string tmpStr("******");
38     size_t strLen = value.length();
39     if (strLen < INT32_MIN_ID_LENGTH) {
40         return tmpStr;
41     }
42 
43     if (strLen <= INT32_SHORT_ID_LENGTH) {
44         res += value[0];
45         res += tmpStr;
46         res += value[strLen - 1];
47     } else {
48         res.append(value, 0, INT32_PLAINTEXT_LENGTH);
49         res += tmpStr;
50         res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
51     }
52 
53     return res;
54 }
55 
GetAudioParamStr(const std::string & params,const std::string & key,std::string & value)56 int32_t GetAudioParamStr(const std::string &params, const std::string &key, std::string &value)
57 {
58     size_t step = key.size();
59     if (step >= params.size()) {
60         return ERR_DH_AUDIO_HDF_FAIL;
61     }
62     size_t pos = params.find(key);
63     if (pos == params.npos || params.at(pos + step) != '=') {
64         return ERR_DH_AUDIO_COMMON_NOT_FOUND_KEY;
65     }
66     size_t splitPosEnd = params.find(';', pos);
67     if (splitPosEnd != params.npos) {
68         value = params.substr(pos + step + 1, splitPosEnd - pos - step - 1);
69     } else {
70         value = params.substr(pos + step + 1);
71     }
72     return DH_SUCCESS;
73 }
74 
GetAudioParamInt(const std::string & params,const std::string & key,int32_t & value)75 int32_t GetAudioParamInt(const std::string &params, const std::string &key, int32_t &value)
76 {
77     std::string val = "-1";
78     int32_t ret = GetAudioParamStr(params, key, val);
79     if (!CheckIsNum(val)) {
80         DHLOGE("String is not number. str:%s.", val.c_str());
81         return -1;
82     }
83     value = std::stoi(val);
84     return ret;
85 }
86 
CheckIsNum(const std::string & jsonString)87 bool CheckIsNum(const std::string &jsonString)
88 {
89     if (jsonString.empty() || jsonString.size() > MAX_KEY_DH_ID_LEN) {
90         DHLOGE("Json string size %d, is zero or too long.", jsonString.size());
91         return false;
92     }
93     for (char const &c : jsonString) {
94         if (!std::isdigit(c)) {
95             DHLOGE("Json string is not number.");
96             return false;
97         }
98     }
99     return true;
100 }
101 
GetAudioParamUInt(const std::string & params,const std::string & key,uint32_t & value)102 int32_t GetAudioParamUInt(const std::string &params, const std::string &key, uint32_t &value)
103 {
104     value = 0;
105     return DH_SUCCESS;
106 }
107 
GetAudioParamBool(const std::string & params,const std::string & key,bool & value)108 int32_t GetAudioParamBool(const std::string &params, const std::string &key, bool &value)
109 {
110     std::string val;
111     GetAudioParamStr(params, key, val);
112     value = (val != "0");
113     return DH_SUCCESS;
114 }
115 
SetAudioParamStr(std::string & params,const std::string & key,const std::string & value)116 int32_t SetAudioParamStr(std::string &params, const std::string &key, const std::string &value)
117 {
118     params = params + key + '=' + value + ';';
119     return DH_SUCCESS;
120 }
121 
GetDevTypeByDHId(int32_t dhId)122 int32_t GetDevTypeByDHId(int32_t dhId)
123 {
124     if ((uint32_t)dhId & 0x8000000) {
125         return AUDIO_DEVICE_TYPE_MIC;
126     } else if ((uint32_t)dhId & 0x7ffffff) {
127         return AUDIO_DEVICE_TYPE_SPEAKER;
128     }
129     return AUDIO_DEVICE_TYPE_UNKNOWN;
130 }
131 
GetNowTimeUs()132 int64_t GetNowTimeUs()
133 {
134     std::chrono::microseconds nowUs =
135         std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
136     return nowUs.count();
137 }
138 
CalculateFrameSize(uint32_t sampleRate,uint32_t channelCount,int32_t format,uint32_t timeInterval,bool isMMAP)139 uint32_t CalculateFrameSize(uint32_t sampleRate, uint32_t channelCount,
140     int32_t format, uint32_t timeInterval, bool isMMAP)
141 {
142     return isMMAP ? (sampleRate * channelCount * static_cast<uint32_t>(format) * timeInterval) /
143                      AUDIO_MS_PER_SECOND : DEFAULT_AUDIO_DATA_SIZE;
144 }
145 
CalculateSampleNum(uint32_t sampleRate,uint32_t timems)146 int32_t CalculateSampleNum(uint32_t sampleRate, uint32_t timems)
147 {
148     return (sampleRate * timems) / AUDIO_MS_PER_SECOND;
149 }
150 
GetCurNano()151 int64_t GetCurNano()
152 {
153     int64_t result = -1;
154     struct timespec time;
155     clockid_t clockId = CLOCK_MONOTONIC;
156     int ret = clock_gettime(clockId, &time);
157     if (ret < 0) {
158         return result;
159     }
160     result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
161     return result;
162 }
163 
AbsoluteSleep(int64_t nanoTime)164 int32_t AbsoluteSleep(int64_t nanoTime)
165 {
166     int32_t ret = -1;
167     if (nanoTime <= 0) {
168         return ret;
169     }
170     struct timespec time;
171     time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
172     time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND);
173 
174     clockid_t clockId = CLOCK_MONOTONIC;
175     ret = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
176     return ret;
177 }
178 
CalculateOffset(const int64_t frameIndex,const int64_t framePeriodNs,const int64_t startTime)179 int64_t CalculateOffset(const int64_t frameIndex, const int64_t framePeriodNs, const int64_t startTime)
180 {
181     int64_t totalOffset = GetCurNano() - startTime;
182     return totalOffset - frameIndex * framePeriodNs;
183 }
184 
UpdateTimeOffset(const int64_t frameIndex,const int64_t framePeriodNs,int64_t & startTime)185 int64_t UpdateTimeOffset(const int64_t frameIndex, const int64_t framePeriodNs, int64_t &startTime)
186 {
187     int64_t timeOffset = 0;
188     if (frameIndex == 0) {
189         startTime = GetCurNano();
190     } else if (frameIndex % AUDIO_OFFSET_FRAME_NUM == 0) {
191         timeOffset = CalculateOffset(frameIndex, framePeriodNs, startTime);
192     }
193     return timeOffset;
194 }
195 
IsOutDurationRange(int64_t startTime,int64_t endTime,int64_t lastStartTime)196 bool IsOutDurationRange(int64_t startTime, int64_t endTime, int64_t lastStartTime)
197 {
198     int64_t currentInterval = endTime - startTime;
199     int64_t twiceInterval = startTime - lastStartTime;
200     return (currentInterval > MAX_TIME_INTERVAL_US || twiceInterval > MAX_TIME_INTERVAL_US) ? true : false;
201 }
202 
SaveFile(std::string fileName,uint8_t * audioData,int32_t size)203 void SaveFile(std::string fileName, uint8_t *audioData, int32_t size)
204 {
205     std::ofstream ofs(fileName, std::ios::binary | std::ios::out | std::ios::app);
206     if (!ofs.is_open()) {
207         return;
208     }
209     ofs.write(reinterpret_cast<char *>(audioData), size);
210     ofs.close();
211 }
212 
WrapCJsonItem(const std::initializer_list<std::pair<std::string,std::string>> & keys,std::string & content)213 int32_t WrapCJsonItem(const std::initializer_list<std::pair<std::string, std::string>> &keys, std::string &content)
214 {
215     cJSON *jParam = cJSON_CreateObject();
216     if (jParam == nullptr) {
217         return ERR_DH_AUDIO_HDF_FAIL;
218     }
219     for (auto item : keys) {
220         cJSON_AddStringToObject(jParam, item.first.c_str(), item.second.c_str());
221     }
222     char *jsonData = cJSON_PrintUnformatted(jParam);
223     if (jsonData == nullptr) {
224         cJSON_Delete(jParam);
225         return ERR_DH_AUDIO_HDF_FAIL;
226     }
227     content = std::string(jsonData);
228     cJSON_Delete(jParam);
229     cJSON_free(jsonData);
230     return DH_SUCCESS;
231 }
232 
IsString(const cJSON * jsonObj,const std::string & key)233 static bool IsString(const cJSON *jsonObj, const std::string &key)
234 {
235     if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
236         DHLOGE("JSON parameter is invalid.");
237         return false;
238     }
239     cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
240     if (paramValue == nullptr) {
241         DHLOGE("paramValue is null");
242         return false;
243     }
244 
245     if (cJSON_IsString(paramValue)) {
246         return true;
247     }
248     return false;
249 }
250 
CJsonParamCheck(const cJSON * jsonObj,const std::initializer_list<std::string> & keys)251 bool CJsonParamCheck(const cJSON *jsonObj, const std::initializer_list<std::string> &keys)
252 {
253     if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
254         DHLOGE("JSON parameter is invalid.");
255         return false;
256     }
257 
258     for (auto it = keys.begin(); it != keys.end(); it++) {
259         cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, (*it).c_str());
260         if (paramValue == nullptr) {
261             DHLOGE("JSON parameter does not contain key: %s", (*it).c_str());
262             return false;
263         }
264         bool res = IsString(jsonObj, *it);
265         if (!res) {
266             DHLOGE("The key %s value format in JSON is illegal.", (*it).c_str());
267             return false;
268         }
269     }
270     return true;
271 }
272 
ParseStringFromArgs(const std::string & args,const char * key)273 std::string ParseStringFromArgs(const std::string &args, const char *key)
274 {
275     DHLOGD("ParseStringFrom Args : %s", args.c_str());
276     cJSON *jParam = cJSON_Parse(args.c_str());
277     if (jParam == nullptr) {
278         DHLOGE("Failed to parse JSON: %s", cJSON_GetErrorPtr());
279         cJSON_Delete(jParam);
280         return "Failed to parse JSON";
281     }
282     if (!CJsonParamCheck(jParam, { key })) {
283         DHLOGE("Not found the key : %s.", key);
284         cJSON_Delete(jParam);
285         return "Not found the key.";
286     }
287     cJSON *dhIdItem = cJSON_GetObjectItem(jParam, key);
288     if (dhIdItem == NULL || !cJSON_IsString(dhIdItem)) {
289         DHLOGE("Not found the value of the key : %s.", key);
290         cJSON_Delete(jParam);
291         return "Not found the value.";
292     }
293     std::string content(dhIdItem->valuestring);
294     cJSON_Delete(jParam);
295     DHLOGD("Parsed string is: %s.", content.c_str());
296     return content;
297 }
298 } // namespace DistributedHardware
299 } // namespace OHOS