1 /*
2 * Copyright (c) 2021-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 "dcamera_utils_tools.h"
17
18 #include <chrono>
19 #include <dlfcn.h>
20 #include <string>
21 #include <sstream>
22 #include <ostream>
23
24 #include "distributed_camera_constants.h"
25 #include "distributed_camera_errno.h"
26 #include "distributed_hardware_log.h"
27 #include "parameter.h"
28
29 #include "softbus_bus_center.h"
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 namespace {
34 const std::string YUV_LIB_PATH = "libyuv.z.so";
35 const std::string GET_IMAGE_CONVERTER_FUNC = "GetImageConverter";
36 }
37
38 #ifdef DCAMERA_MMAP_RESERVE
39 using GetImageConverterFunc = OHOS::OpenSourceLibyuv::ImageConverter (*)();
40 #endif
41
42 const uint32_t OFFSET2 = 2;
43 const uint32_t OFFSET4 = 4;
44 const uint32_t OFFSET6 = 6;
45 const uint8_t PARAM_FC = 0xfc;
46 const uint8_t PARAM_03 = 0x03;
47 const uint8_t PARAM_F0 = 0xf0;
48 const uint8_t PARAM_0F = 0x0f;
49 const uint8_t PARAM_C0 = 0xc0;
50 const uint8_t PARAM_3F = 0x3f;
51 const int INDEX_FIRST = 0;
52 const int INDEX_SECOND = 1;
53 const int INDEX_THIRD = 2;
54 const int INDEX_FORTH = 3;
GetLocalDeviceNetworkId(std::string & networkId)55 int32_t GetLocalDeviceNetworkId(std::string& networkId)
56 {
57 NodeBasicInfo basicInfo = { { 0 } };
58 int32_t ret = GetLocalNodeDeviceInfo(DCAMERA_PKG_NAME.c_str(), &basicInfo);
59 if (ret != DCAMERA_OK) {
60 DHLOGE("GetLocalNodeDeviceInfo failed ret: %{public}d", ret);
61 return ret;
62 }
63
64 networkId = std::string(basicInfo.networkId);
65 return DCAMERA_OK;
66 }
67
GetNowTimeStampMs()68 int64_t GetNowTimeStampMs()
69 {
70 std::chrono::milliseconds nowMs = std::chrono::duration_cast<std::chrono::milliseconds>(
71 std::chrono::system_clock::now().time_since_epoch());
72 return nowMs.count();
73 }
74
GetNowTimeStampUs()75 int64_t GetNowTimeStampUs()
76 {
77 std::chrono::microseconds nowUs = std::chrono::duration_cast<std::chrono::microseconds>(
78 std::chrono::system_clock::now().time_since_epoch());
79 return nowUs.count();
80 }
81
GetAlignedHeight(int32_t width)82 int32_t GetAlignedHeight(int32_t width)
83 {
84 int32_t alignedBits = 32;
85 int32_t alignedHeight = width;
86 if (alignedHeight % alignedBits != 0) {
87 alignedHeight = ((alignedHeight / alignedBits) + 1) * alignedBits;
88 }
89 return alignedHeight;
90 }
91
Base64Encode(const unsigned char * toEncode,unsigned int len)92 std::string Base64Encode(const unsigned char *toEncode, unsigned int len)
93 {
94 std::string ret = "";
95 if (len == 0 || toEncode == nullptr) {
96 DHLOGE("toEncode is null or len is zero.");
97 return ret;
98 }
99 int32_t length = static_cast<int32_t>(len);
100 uint32_t i = 0;
101 unsigned char charArray3[3];
102 unsigned char charArray4[4];
103
104 while (length--) {
105 charArray3[i++] = *(toEncode++);
106 if (i == sizeof(charArray3)) {
107 charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2;
108 charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) +
109 ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4);
110 charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) +
111 ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6);
112 charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F;
113 for (i = 0; i < sizeof(charArray4); i++) {
114 ret += BASE_64_CHARS[charArray4[i]];
115 }
116 i = 0;
117 }
118 }
119
120 if (i > 0) {
121 uint32_t j = 0;
122 for (j = i; j < sizeof(charArray3); j++) {
123 charArray3[j] = '\0';
124 }
125 charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2;
126 charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) +
127 ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4);
128 charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) +
129 ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6);
130 charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F;
131 for (j = 0; j < i + 1; j++) {
132 ret += BASE_64_CHARS[charArray4[j]];
133 }
134 while (i++ < sizeof(charArray3)) {
135 ret += '=';
136 }
137 }
138 return ret;
139 }
140
Base64Decode(const std::string & basicString)141 std::string Base64Decode(const std::string& basicString)
142 {
143 std::string ret = "";
144 if (basicString.empty()) {
145 DHLOGE("basicString is empty.");
146 return ret;
147 }
148 uint32_t i = 0;
149 int index = 0;
150 int len = static_cast<int>(basicString.size());
151 unsigned char charArray3[3];
152 unsigned char charArray4[4];
153
154 while (len-- && (basicString[index] != '=') && IsBase64(basicString[index])) {
155 charArray4[i++] = basicString[index];
156 index++;
157 if (i == sizeof(charArray4)) {
158 for (i = 0; i < sizeof(charArray4); i++) {
159 charArray4[i] = BASE_64_CHARS.find(charArray4[i]);
160 }
161 charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
162 ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
163 charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
164 ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
165 charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
166 for (i = 0; i < sizeof(charArray3); i++) {
167 ret += charArray3[i];
168 }
169 i = 0;
170 }
171 }
172
173 if (i > 0) {
174 uint32_t j = 0;
175 for (j = i; j < sizeof(charArray4); j++) {
176 charArray4[j] = 0;
177 }
178 for (j = 0; j < sizeof(charArray4); j++) {
179 charArray4[j] = BASE_64_CHARS.find(charArray4[j]);
180 }
181 charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) +
182 ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4);
183 charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) +
184 ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2);
185 charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH];
186 for (j = 0; j < i - 1; j++) {
187 ret += charArray3[j];
188 }
189 }
190 return ret;
191 }
192
IsBase64(unsigned char c)193 bool IsBase64(unsigned char c)
194 {
195 return (isalnum(c) || (c == '+') || (c == '/'));
196 }
197
DumpBufferToFile(const std::string fileName,uint8_t * buffer,size_t bufSize)198 void DumpBufferToFile(const std::string fileName, uint8_t *buffer, size_t bufSize)
199 {
200 if (fileName.empty() || buffer == nullptr) {
201 DHLOGE("dumpsaving : input param err.");
202 return;
203 }
204 char path[PATH_MAX + 1] = {0x00};
205 if (fileName.length() > PATH_MAX || realpath(fileName.c_str(), path) == nullptr) {
206 DHLOGE("The file path is invalid.");
207 return;
208 }
209 std::ofstream ofs(path, std::ios::binary | std::ios::out | std::ios::app);
210 if (!ofs.is_open()) {
211 DHLOGE("dumpsaving : open file failed.");
212 return;
213 }
214 ofs.write(reinterpret_cast<const char*>(buffer), bufSize);
215 ofs.close();
216 return;
217 }
218
IsUnderDumpMaxSize(const std::string fileName)219 int32_t IsUnderDumpMaxSize(const std::string fileName)
220 {
221 if (fileName.empty()) {
222 DHLOGE("dumpsaving : input fileName empty.");
223 return DCAMERA_INIT_ERR;
224 }
225 char path[PATH_MAX + 1] = {0x00};
226 if (fileName.length() > PATH_MAX || realpath(fileName.c_str(), path) == nullptr) {
227 DHLOGE("The file path is invalid.");
228 return DCAMERA_INIT_ERR;
229 }
230 std::ofstream ofs(path, std::ios::binary | std::ios::out | std::ios::app);
231 if (!ofs.is_open()) {
232 DHLOGE("dumpsaving : open file failed.");
233 return DCAMERA_INIT_ERR;
234 }
235 ofs.seekp(0, std::ios::end);
236 std::ofstream::pos_type fileSize = ofs.tellp();
237 if (fileSize < 0) {
238 DHLOGE("filesize get err");
239 fileSize = 0;
240 return DCAMERA_INIT_ERR;
241 }
242 ofs.close();
243 if (static_cast<int32_t>(fileSize) <= DUMP_FILE_MAX_SIZE) {
244 return DCAMERA_OK;
245 } else {
246 return DCAMERA_BAD_VALUE;
247 }
248 }
249
250 #ifdef DCAMERA_MMAP_RESERVE
251 IMPLEMENT_SINGLE_INSTANCE(ConverterHandle);
InitConverter()252 void ConverterHandle::InitConverter()
253 {
254 dlHandler_ = dlopen(YUV_LIB_PATH.c_str(), RTLD_LAZY | RTLD_NODELETE);
255 if (dlHandler_ == nullptr) {
256 DHLOGE("Dlopen failed.");
257 return;
258 }
259 GetImageConverterFunc getConverter = (GetImageConverterFunc)dlsym(dlHandler_, GET_IMAGE_CONVERTER_FUNC.c_str());
260 if (getConverter == nullptr) {
261 DHLOGE("Function of converter is null, failed reason: %s.", dlerror());
262 dlclose(dlHandler_);
263 dlHandler_ = nullptr;
264 return;
265 }
266 converter_ = getConverter();
267 isInited_.store(true);
268 DHLOGI("Initialize image converter success.");
269 }
270
DeInitConverter()271 void ConverterHandle::DeInitConverter()
272 {
273 if (dlHandler_) {
274 dlclose(dlHandler_);
275 dlHandler_ = nullptr;
276 }
277 isInited_.store(false);
278 }
279
GetHandle()280 const OHOS::OpenSourceLibyuv::ImageConverter& ConverterHandle::GetHandle()
281 {
282 if (!isInited_.load()) {
283 InitConverter();
284 }
285 return converter_;
286 }
287 #endif
288
289 template <typename T>
GetSysPara(const char * key,T & value)290 bool GetSysPara(const char *key, T &value)
291 {
292 CHECK_AND_RETURN_RET_LOG(key == nullptr, false, "key is nullptr");
293 char paraValue[30] = {0}; // 30 for system parameter
294 auto res = GetParameter(key, "-1", paraValue, sizeof(paraValue));
295
296 CHECK_AND_RETURN_RET_LOG(res <= 0, false, "GetParameter fail, key:%{public}s res:%{public}d", key, res);
297 DHLOGD("GetSysPara key:%{public}s value:%{public}s", key, paraValue);
298 std::stringstream valueStr;
299 valueStr << paraValue;
300 valueStr >> value;
301 return true;
302 }
303
304 template bool GetSysPara(const char *key, int32_t &value);
305 template bool GetSysPara(const char *key, uint32_t &value);
306 template bool GetSysPara(const char *key, int64_t &value);
307 template bool GetSysPara(const char *key, std::string &value);
308
309 std::map<std::string, std::string> DumpFileUtil::g_lastPara = {};
310
OpenDumpFileInner(std::string para,std::string fileName)311 FILE *DumpFileUtil::OpenDumpFileInner(std::string para, std::string fileName)
312 {
313 std::string filePath = DUMP_SERVICE_DIR + fileName;
314 std::string dumpPara;
315 FILE *dumpFile = nullptr;
316 char path[PATH_MAX + 1] = {0x00};
317 if (filePath.length() > PATH_MAX || realpath(filePath.c_str(), path) == nullptr) {
318 DHLOGE("The file path is invalid.");
319 return dumpFile;
320 }
321 bool res = GetSysPara(para.c_str(), dumpPara);
322 if (!res || dumpPara.empty()) {
323 DHLOGI("%{public}s is not set, dump dcamera is not required", para.c_str());
324 g_lastPara[para] = dumpPara;
325 return dumpFile;
326 }
327 DHLOGD("%{public}s = %{public}s, filePath: %{public}s", para.c_str(), dumpPara.c_str(), path);
328 if (dumpPara == "w") {
329 dumpFile = fopen(path, "wb+");
330 CHECK_AND_RETURN_RET_LOG(dumpFile == nullptr, dumpFile, "Error opening dump file!");
331 } else if (dumpPara == "a") {
332 dumpFile = fopen(path, "ab+");
333 CHECK_AND_RETURN_RET_LOG(dumpFile == nullptr, dumpFile, "Error opening dump file!");
334 }
335 g_lastPara[para] = dumpPara;
336 return dumpFile;
337 }
338
WriteDumpFile(FILE * dumpFile,void * buffer,size_t bufferSize)339 void DumpFileUtil::WriteDumpFile(FILE *dumpFile, void *buffer, size_t bufferSize)
340 {
341 if (dumpFile == nullptr) {
342 return;
343 }
344 CHECK_AND_RETURN_LOG(buffer == nullptr, "Invalid write param");
345 size_t writeResult = fwrite(buffer, 1, bufferSize, dumpFile);
346 CHECK_AND_RETURN_LOG(writeResult != bufferSize, "Failed to write the file.");
347 }
348
CloseDumpFile(FILE ** dumpFile)349 void DumpFileUtil::CloseDumpFile(FILE **dumpFile)
350 {
351 if (*dumpFile) {
352 fclose(*dumpFile);
353 *dumpFile = nullptr;
354 }
355 }
356
ChangeDumpFileState(std::string para,FILE ** dumpFile,std::string filePath)357 void DumpFileUtil::ChangeDumpFileState(std::string para, FILE **dumpFile, std::string filePath)
358 {
359 CHECK_AND_RETURN_LOG(*dumpFile == nullptr, "Invalid file para");
360 CHECK_AND_RETURN_LOG(g_lastPara[para] != "w" || g_lastPara[para] != "a", "Invalid input para");
361 std::string dumpPara;
362 bool res = GetSysPara(para.c_str(), dumpPara);
363 if (!res || dumpPara.empty()) {
364 DHLOGE("get %{public}s fail", para.c_str());
365 }
366 if (g_lastPara[para] == "w" && dumpPara == "w") {
367 return;
368 }
369 CloseDumpFile(dumpFile);
370 OpenDumpFile(para, filePath, dumpFile);
371 }
372
OpenDumpFile(std::string para,std::string fileName,FILE ** file)373 void DumpFileUtil::OpenDumpFile(std::string para, std::string fileName, FILE **file)
374 {
375 if (*file != nullptr) {
376 DumpFileUtil::ChangeDumpFileState(para, file, fileName);
377 return;
378 }
379
380 if (para == DUMP_SERVER_PARA) {
381 *file = DumpFileUtil::OpenDumpFileInner(para, fileName);
382 }
383 }
384 } // namespace DistributedHardware
385 } // namespace OHOS
386