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