1 /*
2 * Copyright (c) 2022-2024 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_util.h"
17
18 #include <cstddef>
19 #include <ctime>
20 #include <iomanip>
21 #include <map>
22 #include <ostream>
23 #include <random>
24 #include <sstream>
25 #include <sstream>
26 #include <sys/time.h>
27
28 #include "softbus_bus_center.h"
29
30 #include "audio_event.h"
31 #include "daudio_constants.h"
32 #include "daudio_errorcode.h"
33 #include "daudio_log.h"
34 #include "parameter.h"
35
36 #undef DH_LOG_TAG
37 #define DH_LOG_TAG "DAudioUtil"
38
39 namespace OHOS {
40 namespace DistributedHardware {
41 using JsonTypeCheckFunc = bool (*)(const cJSON *jsonObj, const std::string &key);
42 constexpr int32_t WORD_WIDTH_8 = 8;
43 constexpr int32_t WORD_WIDTH_4 = 4;
44 constexpr size_t INT32_SHORT_ID_LENGTH = 20;
45 constexpr size_t INT32_MIN_ID_LENGTH = 3;
46 constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
47 constexpr uint8_t MAX_KEY_DH_ID_LEN = 20;
48
49 std::map<std::string, JsonTypeCheckFunc> typeCheckMap = {
50 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_TYPE, &DistributedHardware::IsInt32),
51 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_EVENT_CONTENT, &DistributedHardware::IsString),
52 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_DH_ID, &DistributedHardware::IsString),
53 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_REQID, &DistributedHardware::IsString),
54 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_VERSION, &DistributedHardware::IsString),
55 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_CHANGE_TYPE, &DistributedHardware::IsString),
56 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_DEV_ID, &DistributedHardware::IsString),
57 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_RESULT, &DistributedHardware::IsInt32),
58 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_EVENT_TYPE, &DistributedHardware::IsInt32),
59 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_AUDIO_PARAM, &DistributedHardware::IsAudioParam),
60 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_ATTRS, &DistributedHardware::IsString),
61 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_RANDOM_TASK_CODE, &DistributedHardware::IsString),
62 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_SAMPLING_RATE, &DistributedHardware::IsInt32),
63 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_CHANNELS, &DistributedHardware::IsInt32),
64 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_FORMAT, &DistributedHardware::IsInt32),
65 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_SOURCE_TYPE, &DistributedHardware::IsInt32),
66 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_CONTENT_TYPE, &DistributedHardware::IsInt32),
67 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_STREAM_USAGE, &DistributedHardware::IsInt32),
68 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_DATATYPE, &DistributedHardware::IsString),
69 std::map<std::string, JsonTypeCheckFunc>::value_type(KEY_CODEC_TYPE, &DistributedHardware::IsInt32),
70 };
71
72 std::map<int32_t, std::string> eventNameMap = {
73 std::make_pair(EVENT_UNKNOWN, "EVENT_UNKNOWN"),
74 std::make_pair(OPEN_CTRL, "OPEN_CTRL"),
75 std::make_pair(CLOSE_CTRL, "CLOSE_CTRL"),
76 std::make_pair(CTRL_OPENED, "CTRL_OPENED"),
77 std::make_pair(CTRL_CLOSED, "CTRL_CLOSED"),
78 std::make_pair(NOTIFY_OPEN_CTRL_RESULT, "NOTIFY_OPEN_CTRL_RESULT"),
79 std::make_pair(NOTIFY_CLOSE_CTRL_RESULT, "NOTIFY_CLOSE_CTRL_RESULT"),
80 std::make_pair(DATA_OPENED, "DATA_OPENED"),
81 std::make_pair(DATA_CLOSED, "DATA_CLOSED"),
82
83 std::make_pair(OPEN_SPEAKER, "OPEN_SPEAKER"),
84 std::make_pair(CLOSE_SPEAKER, "CLOSE_SPEAKER"),
85 std::make_pair(SPEAKER_OPENED, "SPEAKER_OPENED"),
86 std::make_pair(SPEAKER_CLOSED, "SPEAKER_CLOSED"),
87 std::make_pair(NOTIFY_OPEN_SPEAKER_RESULT, "NOTIFY_OPEN_SPEAKER_RESULT"),
88 std::make_pair(NOTIFY_CLOSE_SPEAKER_RESULT, "NOTIFY_CLOSE_SPEAKER_RESULT"),
89 std::make_pair(NOTIFY_HDF_SPK_DUMP, "NOTIFY_HDF_SPK_DUMP"),
90 std::make_pair(NOTIFY_HDF_MIC_DUMP, "NOTIFY_HDF_MIC_DUMP"),
91
92 std::make_pair(OPEN_MIC, "OPEN_MIC"),
93 std::make_pair(CLOSE_MIC, "CLOSE_MIC"),
94 std::make_pair(MIC_OPENED, "MIC_OPENED"),
95 std::make_pair(MIC_CLOSED, "MIC_CLOSED"),
96 std::make_pair(NOTIFY_OPEN_MIC_RESULT, "NOTIFY_OPEN_MIC_RESULT"),
97 std::make_pair(NOTIFY_CLOSE_MIC_RESULT, "NOTIFY_CLOSE_MIC_RESULT"),
98
99 std::make_pair(VOLUME_SET, "VOLUME_SET"),
100 std::make_pair(VOLUME_GET, "VOLUME_GET"),
101 std::make_pair(VOLUME_CHANGE, "VOLUME_CHANGE"),
102 std::make_pair(VOLUME_MIN_GET, "VOLUME_MIN_GET"),
103 std::make_pair(VOLUME_MAX_GET, "VOLUME_MAX_GET"),
104 std::make_pair(VOLUME_MUTE_SET, "VOLUME_MUTE_SET"),
105
106 std::make_pair(AUDIO_FOCUS_CHANGE, "AUDIO_FOCUS_CHANGE"),
107 std::make_pair(AUDIO_RENDER_STATE_CHANGE, "AUDIO_RENDER_STATE_CHANGE"),
108
109 std::make_pair(SET_PARAM, "SET_PARAM"),
110 std::make_pair(SEND_PARAM, "SEND_PARAM"),
111
112 std::make_pair(AUDIO_ENCODER_ERR, "AUDIO_ENCODER_ERR"),
113 std::make_pair(AUDIO_DECODER_ERR, "AUDIO_DECODER_ERR"),
114
115 std::make_pair(CHANGE_PLAY_STATUS, "CHANGE_PLAY_STATUS"),
116
117 std::make_pair(MMAP_SPK_START, "MMAP_SPK_START"),
118 std::make_pair(MMAP_SPK_STOP, "MMAP_SPK_STOP"),
119 std::make_pair(MMAP_MIC_START, "MMAP_MIC_START"),
120 std::make_pair(MMAP_MIC_STOP, "MMAP_MIC_STOP"),
121 std::make_pair(AUDIO_START, "AUDIO_START"),
122 std::make_pair(AUDIO_STOP, "AUDIO_STOP")
123 };
124
GetEventNameByType(const int32_t eventType)125 std::string GetEventNameByType(const int32_t eventType)
126 {
127 auto iter = eventNameMap.find(eventType);
128 if (iter == eventNameMap.end()) {
129 DHLOGE("Can't find matched eventname");
130 return "EVENT_UNKNOWN";
131 }
132 return iter->second;
133 }
134
GetLocalDeviceNetworkId(std::string & networkId)135 int32_t GetLocalDeviceNetworkId(std::string &networkId)
136 {
137 NodeBasicInfo basicInfo = { { 0 } };
138 int32_t ret = GetLocalNodeDeviceInfo(PKG_NAME.c_str(), &basicInfo);
139 if (ret != DH_SUCCESS) {
140 DHLOGE("Failed to obtain the network ID of the local device. ret: %{public}d", ret);
141 return ret;
142 }
143
144 networkId = std::string(basicInfo.networkId);
145 return DH_SUCCESS;
146 }
147
GetRandomID()148 std::string GetRandomID()
149 {
150 static std::random_device rd;
151 static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
152 uint64_t ab = dist(rd);
153 uint64_t cd = dist(rd);
154 uint32_t a, b, c, d;
155 std::stringstream ss;
156 ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
157 cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
158 a = (ab >> 32U);
159 b = (ab & 0xFFFFFFFFU);
160 c = (cd >> 32U);
161 d = (cd & 0xFFFFFFFFU);
162 ss << std::hex << std::nouppercase << std::setfill('0');
163 ss << std::setw(WORD_WIDTH_8) << (a);
164 ss << std::setw(WORD_WIDTH_4) << (b >> 16U);
165 ss << std::setw(WORD_WIDTH_4) << (b & 0xFFFFU);
166 ss << std::setw(WORD_WIDTH_4) << (c >> 16U);
167 ss << std::setw(WORD_WIDTH_4) << (c & 0xFFFFU);
168 ss << std::setw(WORD_WIDTH_8) << d;
169
170 return ss.str();
171 }
172
GetAnonyString(const std::string & value)173 std::string GetAnonyString(const std::string &value)
174 {
175 std::string res;
176 std::string tmpStr("******");
177 size_t strLen = value.length();
178 if (strLen < INT32_MIN_ID_LENGTH) {
179 return tmpStr;
180 }
181
182 if (strLen <= INT32_SHORT_ID_LENGTH) {
183 res += value[0];
184 res += tmpStr;
185 res += value[strLen - 1];
186 } else {
187 res.append(value, 0, INT32_PLAINTEXT_LENGTH);
188 res += tmpStr;
189 res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
190 }
191
192 return res;
193 }
194
GetDevTypeByDHId(int32_t dhId)195 int32_t GetDevTypeByDHId(int32_t dhId)
196 {
197 DHLOGD("Get dev type by dhId: %{public}d.", dhId);
198 if (static_cast<uint32_t>(dhId) & 0x8000000) {
199 return AUDIO_DEVICE_TYPE_MIC;
200 } else if (static_cast<uint32_t>(dhId) & 0x7ffffff) {
201 return AUDIO_DEVICE_TYPE_SPEAKER;
202 }
203 return AUDIO_DEVICE_TYPE_UNKNOWN;
204 }
205
GetCurrentTime(int64_t & tvSec,int64_t & tvNSec)206 void GetCurrentTime(int64_t &tvSec, int64_t &tvNSec)
207 {
208 struct timespec time;
209 if (clock_gettime(CLOCK_MONOTONIC, &time) < 0) {
210 DHLOGE("Get current time failed");
211 }
212 tvSec = time.tv_sec;
213 tvNSec = time.tv_nsec;
214 }
215
GetNowTimeUs()216 int64_t GetNowTimeUs()
217 {
218 std::chrono::microseconds nowUs =
219 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
220 return nowUs.count();
221 }
222
GetAudioParamStr(const std::string & params,const std::string & key,std::string & value)223 int32_t GetAudioParamStr(const std::string ¶ms, const std::string &key, std::string &value)
224 {
225 size_t step = key.size();
226 if (step >= params.size()) {
227 return ERR_DH_AUDIO_FAILED;
228 }
229 size_t pos = params.find(key);
230 if (pos == params.npos || params.at(pos + step) != '=') {
231 return ERR_DH_AUDIO_NOT_FOUND_KEY;
232 }
233 size_t splitPosEnd = params.find(';', pos);
234 if (splitPosEnd != params.npos) {
235 value = params.substr(pos + step + 1, splitPosEnd - pos - step - 1);
236 } else {
237 value = params.substr(pos + step + 1);
238 }
239 return DH_SUCCESS;
240 }
241
GetAudioParamBool(const std::string & params,const std::string & key,bool & value)242 int32_t GetAudioParamBool(const std::string ¶ms, const std::string &key, bool &value)
243 {
244 std::string val;
245 int32_t ret = GetAudioParamStr(params, key, val);
246 if (ret != DH_SUCCESS) {
247 DHLOGE("Get audio param string fail, error code %{public}d.", ret);
248 return ret;
249 }
250
251 value = (val != "0");
252 return DH_SUCCESS;
253 }
254
GetAudioParamInt(const std::string & params,const std::string & key,int32_t & value)255 int32_t GetAudioParamInt(const std::string ¶ms, const std::string &key, int32_t &value)
256 {
257 std::string val = "0";
258 int32_t ret = GetAudioParamStr(params, key, val);
259 if (ret != DH_SUCCESS) {
260 DHLOGE("Get audio param string fail, error code %{public}d.", ret);
261 return ret;
262 }
263 if (!CheckIsNum(val)) {
264 DHLOGE("String is not number. str:%{public}s.", val.c_str());
265 return ERR_DH_AUDIO_NOT_SUPPORT;
266 }
267 value = std::atoi(val.c_str());
268 return DH_SUCCESS;
269 }
270
IsString(const cJSON * jsonObj,const std::string & key)271 bool IsString(const cJSON *jsonObj, const std::string &key)
272 {
273 if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
274 DHLOGE("JSON parameter is invalid.");
275 return false;
276 }
277 cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
278 if (paramValue == nullptr) {
279 DHLOGE("paramValue is null");
280 return false;
281 }
282
283 if (cJSON_IsString(paramValue)) {
284 return true;
285 }
286 return false;
287 }
288
IsInt32(const cJSON * jsonObj,const std::string & key)289 bool IsInt32(const cJSON *jsonObj, const std::string &key)
290 {
291 if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
292 DHLOGE("JSON parameter is invalid.");
293 return false;
294 }
295 cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
296 if (paramValue == nullptr) {
297 DHLOGE("paramValue is null");
298 return false;
299 }
300
301 if (cJSON_IsNumber(paramValue)) {
302 int value = paramValue->valueint;
303 if (INT32_MIN <= value && value <= INT32_MAX) {
304 return true;
305 }
306 }
307 return false;
308 }
309
IsAudioParam(const cJSON * jsonObj,const std::string & key)310 bool IsAudioParam(const cJSON *jsonObj, const std::string &key)
311 {
312 if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
313 DHLOGE("JSON parameter is invalid.");
314 return false;
315 }
316 cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, key.c_str());
317 if (paramValue == nullptr || !cJSON_IsObject(paramValue)) {
318 DHLOGE("paramValue is null or is not object");
319 return false;
320 }
321
322 return CJsonParamCheck(paramValue,
323 { KEY_SAMPLING_RATE, KEY_CHANNELS, KEY_FORMAT, KEY_SOURCE_TYPE, KEY_CONTENT_TYPE, KEY_STREAM_USAGE });
324 }
325
CJsonParamCheck(const cJSON * jsonObj,const std::initializer_list<std::string> & keys)326 bool CJsonParamCheck(const cJSON *jsonObj, const std::initializer_list<std::string> &keys)
327 {
328 if (jsonObj == nullptr || !cJSON_IsObject(jsonObj)) {
329 DHLOGE("JSON parameter is invalid.");
330 return false;
331 }
332
333 for (auto it = keys.begin(); it != keys.end(); it++) {
334 cJSON *paramValue = cJSON_GetObjectItemCaseSensitive(jsonObj, (*it).c_str());
335 if (paramValue == nullptr) {
336 DHLOGE("JSON parameter does not contain key: %{public}s", (*it).c_str());
337 return false;
338 }
339 auto iter = typeCheckMap.find(*it);
340 if (iter == typeCheckMap.end()) {
341 DHLOGE("Check is not supported yet, key %{public}s.", (*it).c_str());
342 return false;
343 }
344 JsonTypeCheckFunc &func = iter->second;
345 bool res = (*func)(jsonObj, *it);
346 if (!res) {
347 DHLOGE("The key %{public}s value format in JSON is illegal.", (*it).c_str());
348 return false;
349 }
350 }
351 return true;
352 }
353
CalculateSampleNum(uint32_t sampleRate,uint32_t timems)354 int32_t CalculateSampleNum(uint32_t sampleRate, uint32_t timems)
355 {
356 return (sampleRate * timems) / AUDIO_MS_PER_SECOND;
357 }
358
GetCurNano()359 int64_t GetCurNano()
360 {
361 int64_t result = -1;
362 struct timespec time;
363 clockid_t clockId = CLOCK_MONOTONIC;
364 int ret = clock_gettime(clockId, &time);
365 if (ret < 0) {
366 DHLOGE("GetCurNanoTime fail, ret: %{public}d", ret);
367 return result;
368 }
369 result = (time.tv_sec * AUDIO_NS_PER_SECOND) + time.tv_nsec;
370 return result;
371 }
372
AbsoluteSleep(int64_t nanoTime)373 int32_t AbsoluteSleep(int64_t nanoTime)
374 {
375 int32_t ret = -1;
376 if (nanoTime <= 0) {
377 DHLOGE("AbsoluteSleep invalid sleep time : %{public}" PRId64" ns", nanoTime);
378 return ret;
379 }
380 struct timespec time;
381 time.tv_sec = nanoTime / AUDIO_NS_PER_SECOND;
382 time.tv_nsec = nanoTime - (time.tv_sec * AUDIO_NS_PER_SECOND);
383
384 clockid_t clockId = CLOCK_MONOTONIC;
385 ret = clock_nanosleep(clockId, TIMER_ABSTIME, &time, nullptr);
386 if (ret != 0) {
387 DHLOGE("AbsoluteSleep may failed, ret is : %{public}d", ret);
388 }
389 return ret;
390 }
391
CalculateOffset(const int64_t frameIndex,const int64_t framePeriodNs,const int64_t startTime)392 int64_t CalculateOffset(const int64_t frameIndex, const int64_t framePeriodNs, const int64_t startTime)
393 {
394 int64_t totalOffset = GetCurNano() - startTime;
395 return totalOffset - frameIndex * framePeriodNs;
396 }
397
UpdateTimeOffset(const int64_t frameIndex,const int64_t framePeriodNs,int64_t & startTime)398 int64_t UpdateTimeOffset(const int64_t frameIndex, const int64_t framePeriodNs, int64_t &startTime)
399 {
400 int64_t timeOffset = 0;
401 if (frameIndex == 0) {
402 startTime = GetCurNano();
403 } else if (frameIndex % AUDIO_OFFSET_FRAME_NUM == 0) {
404 timeOffset = CalculateOffset(frameIndex, framePeriodNs, startTime);
405 }
406 return timeOffset;
407 }
408
CheckIsNum(const std::string & jsonString)409 bool CheckIsNum(const std::string &jsonString)
410 {
411 if (jsonString.empty() || jsonString.size() > MAX_KEY_DH_ID_LEN) {
412 int32_t stringSize = static_cast<int32_t>(jsonString.size());
413 DHLOGE("Json string size %{public}d, is zero or too long.", stringSize);
414 return false;
415 }
416 for (char const &c : jsonString) {
417 if (!std::isdigit(c)) {
418 DHLOGE("Json string is not number.");
419 return false;
420 }
421 }
422 return true;
423 }
424
CheckDevIdIsLegal(const std::string & devId)425 bool CheckDevIdIsLegal(const std::string &devId)
426 {
427 if (devId.empty() || devId.size() > DAUDIO_MAX_DEVICE_ID_LEN) {
428 int32_t stringSize = static_cast<int32_t>(devId.size());
429 DHLOGE("DevId size %{public}d, is zero or too long.", stringSize);
430 return false;
431 }
432 for (char const &c : devId) {
433 if (!std::isalnum(c)) {
434 DHLOGE("DevId is not number or letter.");
435 return false;
436 }
437 }
438 return true;
439 }
440
IsOutDurationRange(int64_t startTime,int64_t endTime,int64_t lastStartTime)441 bool IsOutDurationRange(int64_t startTime, int64_t endTime, int64_t lastStartTime)
442 {
443 int64_t currentInterval = endTime - startTime;
444 int64_t twiceInterval = startTime - lastStartTime;
445 return (currentInterval > MAX_TIME_INTERVAL_US || twiceInterval > MAX_TIME_INTERVAL_US) ? true : false;
446 }
447
GetCJsonString(const char * key,const char * value)448 std::string GetCJsonString(const char *key, const char *value)
449 {
450 cJSON *jParam = cJSON_CreateObject();
451 if (jParam == nullptr) {
452 DHLOGE("Failed to create cJSON object.");
453 return "Failed to create cJSON object.";
454 }
455 cJSON_AddStringToObject(jParam, key, value);
456 char *jsonData = cJSON_PrintUnformatted(jParam);
457 if (jsonData == nullptr) {
458 DHLOGE("Failed to create JSON data.");
459 cJSON_Delete(jParam);
460 return "Failed to create JSON data.";
461 }
462 std::string content(jsonData);
463 cJSON_Delete(jParam);
464 cJSON_free(jsonData);
465 DHLOGD("create cJSON success : %{public}s", content.c_str());
466 return content;
467 }
468
ParseStringFromArgs(std::string args,const char * key)469 std::string ParseStringFromArgs(std::string args, const char *key)
470 {
471 DHLOGD("ParseStringFrom Args : %{public}s", args.c_str());
472 cJSON *jParam = cJSON_Parse(args.c_str());
473 if (jParam == nullptr) {
474 DHLOGE("Failed to parse JSON: %{public}s", cJSON_GetErrorPtr());
475 return "Failed to parse JSON";
476 }
477 if (!CJsonParamCheck(jParam, { key })) {
478 DHLOGE("Not found the key : %{public}s.", key);
479 cJSON_Delete(jParam);
480 return "Not found the key.";
481 }
482 cJSON *dhIdItem = cJSON_GetObjectItem(jParam, key);
483 if (dhIdItem == NULL || !cJSON_IsString(dhIdItem)) {
484 DHLOGE("Not found the value of the key : %{public}s.", key);
485 cJSON_Delete(jParam);
486 return "Not found the value.";
487 }
488 std::string content(dhIdItem->valuestring);
489 cJSON_Delete(jParam);
490 DHLOGD("Parsed string is: %{public}s.", content.c_str());
491 return content;
492 }
493
494 template <typename T>
GetSysPara(const char * key,T & value)495 bool GetSysPara(const char *key, T &value)
496 {
497 CHECK_AND_RETURN_RET_LOG(key == nullptr, false, "key is nullptr");
498 char paraValue[30] = {0}; // 30 for system parameter
499 auto res = GetParameter(key, "-1", paraValue, sizeof(paraValue));
500
501 CHECK_AND_RETURN_RET_LOG(res <= 0, false, "GetParameter fail, key:%{public}s res:%{public}d", key, res);
502 DHLOGI("GetSysPara key:%{public}s value:%{public}s", key, paraValue);
503 std::stringstream valueStr;
504 valueStr << paraValue;
505 valueStr >> value;
506 return true;
507 }
508
509 template bool GetSysPara(const char *key, int32_t &value);
510 template bool GetSysPara(const char *key, uint32_t &value);
511 template bool GetSysPara(const char *key, int64_t &value);
512 template bool GetSysPara(const char *key, std::string &value);
513
IsParamEnabled(const std::string & key,bool & isEnabled)514 bool IsParamEnabled(const std::string &key, bool &isEnabled)
515 {
516 // by default: old trans
517 int32_t policyFlag = 0;
518 if (GetSysPara(key.c_str(), policyFlag) && policyFlag == 1) {
519 isEnabled = true;
520 return true;
521 }
522 isEnabled = false;
523 return false;
524 }
525
SaveFile(const std::string fileName,uint8_t * audioData,int32_t size)526 void SaveFile(const std::string fileName, uint8_t *audioData, int32_t size)
527 {
528 char path[PATH_MAX + 1] = {0x00};
529 if (fileName.length() > PATH_MAX || realpath(fileName.c_str(), path) == nullptr) {
530 DHLOGE("The file path is invalid.");
531 return;
532 }
533 std::ofstream ofs(path, std::ios::binary | std::ios::out | std::ios::app);
534 if (!ofs.is_open()) {
535 DHLOGE("open file failed");
536 return;
537 }
538 ofs.write(reinterpret_cast<char*>(audioData), size);
539 ofs.close();
540 }
541
542 std::map<std::string, std::string> DumpFileUtil::g_lastPara = {};
543
OpenDumpFileInner(const std::string & para,const std::string & fileName)544 FILE *DumpFileUtil::OpenDumpFileInner(const std::string ¶, const std::string &fileName)
545 {
546 std::string filePath = DUMP_SERVICE_DIR + fileName;
547 std::string dumpPara;
548 FILE *dumpFile = nullptr;
549 bool res = GetSysPara(para.c_str(), dumpPara);
550 if (!res || dumpPara.empty()) {
551 DHLOGI("%{public}s is not set, dump dcamera is not required", para.c_str());
552 g_lastPara[para] = dumpPara;
553 return dumpFile;
554 }
555 DHLOGI("%{public}s = %{public}s, filePath: %{public}s", para.c_str(), dumpPara.c_str(), filePath.c_str());
556 if (dumpPara == "w") {
557 dumpFile = fopen(filePath.c_str(), "wb+");
558 CHECK_AND_RETURN_RET_LOG(dumpFile == nullptr, dumpFile, "Error opening dump file!");
559 } else if (dumpPara == "a") {
560 dumpFile = fopen(filePath.c_str(), "ab+");
561 CHECK_AND_RETURN_RET_LOG(dumpFile == nullptr, dumpFile, "Error opening dump file!");
562 }
563 g_lastPara[para] = dumpPara;
564 return dumpFile;
565 }
566
WriteDumpFile(FILE * dumpFile,void * buffer,size_t bufferSize)567 void DumpFileUtil::WriteDumpFile(FILE *dumpFile, void *buffer, size_t bufferSize)
568 {
569 if (dumpFile == nullptr) {
570 return;
571 }
572 CHECK_AND_RETURN_LOG(buffer == nullptr, "Invalid write param");
573 size_t writeResult = fwrite(buffer, 1, bufferSize, dumpFile);
574 CHECK_AND_RETURN_LOG(writeResult != bufferSize, "Failed to write the file.");
575 }
576
CloseDumpFile(FILE ** dumpFile)577 void DumpFileUtil::CloseDumpFile(FILE **dumpFile)
578 {
579 if (*dumpFile) {
580 fclose(*dumpFile);
581 *dumpFile = nullptr;
582 }
583 }
584
ChangeDumpFileState(const std::string & para,FILE ** dumpFile,const std::string & filePath)585 void DumpFileUtil::ChangeDumpFileState(const std::string ¶, FILE **dumpFile, const std::string &filePath)
586 {
587 CHECK_AND_RETURN_LOG(*dumpFile == nullptr, "Invalid file para");
588 CHECK_AND_RETURN_LOG(g_lastPara[para] != "w" || g_lastPara[para] != "a", "Invalid input para");
589 std::string dumpPara;
590 bool res = GetSysPara(para.c_str(), dumpPara);
591 if (!res || dumpPara.empty()) {
592 DHLOGE("get %{public}s fail", para.c_str());
593 }
594 if (g_lastPara[para] == "w" && dumpPara == "w") {
595 return;
596 }
597 CloseDumpFile(dumpFile);
598 OpenDumpFile(para, filePath, dumpFile);
599 }
600
OpenDumpFile(const std::string & para,const std::string & fileName,FILE ** file)601 void DumpFileUtil::OpenDumpFile(const std::string ¶, const std::string &fileName, FILE **file)
602 {
603 if (*file != nullptr) {
604 DumpFileUtil::ChangeDumpFileState(para, file, fileName);
605 return;
606 }
607
608 if (para == DUMP_SERVER_PARA) {
609 *file = DumpFileUtil::OpenDumpFileInner(para, fileName);
610 }
611 }
612 } // namespace DistributedHardware
613 } // namespace OHOS