• 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 "devicestatus_data_parse.h"
17 
18 #include <fcntl.h>
19 #include <unistd.h>
20 
21 #include <sys/stat.h>
22 
23 #include "devicestatus_data_define.h"
24 #include "devicestatus_errors.h"
25 #include "fi_log.h"
26 #include "utility.h"
27 
28 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace {
32 constexpr ::OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DeviceStatusDataParse" };
33 constexpr int32_t FILE_SIZE_MAX { 0x5000 };
34 constexpr int32_t READ_DATA_BUFF_SIZE { 256 };
35 constexpr int32_t INVALID_FILE_SIZE { -1 };
36 const std::string MSDP_DATA_PATH { "/data/msdp/device_status_data.json" };
37 const std::string MSDP_DATA_DIR { "/data/msdp" };
38 } // namespace
39 
40 std::vector<int32_t> DeviceStatusDataParse::tempcount_ =
41     std::vector<int32_t> (static_cast<int32_t>(Type::TYPE_MAX), static_cast<int32_t>(TypeValue::INVALID));
42 
CreateJsonFile()43 int32_t DeviceStatusDataParse::CreateJsonFile()
44 {
45     int32_t fd = open(MSDP_DATA_PATH.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
46     if (fd < 0) {
47         FI_HILOGE("open failed");
48         return DEVICESTATUS_FAILED;
49     }
50     if (close(fd) < 0) {
51         FI_HILOGE("Close fd failed, error:%{public}s, fd:%{public}d", strerror(errno), fd);
52     }
53 
54     struct stat buf;
55     if (stat(MSDP_DATA_DIR.c_str(), &buf) != 0) {
56         FI_HILOGE("stat folder path is invalid %{public}d", errno);
57         return DEVICESTATUS_FAILED;
58     }
59     if (chown(MSDP_DATA_PATH.c_str(), buf.st_uid, buf.st_gid) != 0) {
60         FI_HILOGE("chown failed, errno is %{public}d", errno);
61         return DEVICESTATUS_FAILED;
62     }
63 
64     return DEVICESTATUS_OK;
65 }
66 
ParseDeviceStatusData(Type type,Data & data)67 bool DeviceStatusDataParse::ParseDeviceStatusData(Type type, Data& data)
68 {
69     std::string jsonBuf = ReadJsonFile(MSDP_DATA_PATH.c_str());
70     if (jsonBuf.empty()) {
71         FI_HILOGE("Read json failed, errno is %{public}d", errno);
72         data.type = type;
73         data.value = OnChangedValue::VALUE_INVALID;
74         return false;
75     }
76     return DeviceStatusDataInit(jsonBuf, true, type, data);
77 }
78 
DeviceStatusDataInit(const std::string & fileData,bool logStatus,Type & type,Data & data)79 bool DeviceStatusDataParse::DeviceStatusDataInit(const std::string& fileData, bool logStatus, Type& type,
80     Data& data)
81 {
82     CALL_DEBUG_ENTER;
83     JsonParser parser;
84     parser.json = cJSON_Parse(fileData.c_str());
85     data.type = type;
86     data.value = OnChangedValue::VALUE_INVALID;
87     if (cJSON_IsArray(parser.json)) {
88         FI_HILOGE("parser is array");
89         return false;
90     }
91 
92     if (type < Type::TYPE_ABSOLUTE_STILL || type >= Type::TYPE_MAX) {
93         FI_HILOGE("Type error");
94         return false;
95     }
96 
97     cJSON* mockarray = cJSON_GetObjectItem(parser.json, DeviceStatusJson[type].json.c_str());
98     if (!cJSON_IsArray(mockarray)) {
99         FI_HILOGE("mockarray is not array");
100         return false;
101     }
102     int32_t jsonsize = cJSON_GetArraySize(mockarray);
103     if (jsonsize == 0) {
104         FI_HILOGE("Json size is zero");
105         return false;
106     }
107     tempcount_[type] = tempcount_[type] % jsonsize;
108     cJSON* mockvalue = cJSON_GetArrayItem(mockarray, tempcount_[type]);
109     tempcount_[type]++;
110     data.type = type;
111     if (mockvalue == nullptr || !cJSON_IsNumber(mockvalue)) {
112         FI_HILOGE("Json parser number is failed");
113         return false;
114     }
115     data.value = static_cast<OnChangedValue>(mockvalue->valueint);
116     FI_HILOGD("type:%{public}d, status:%{public}d", data.type, data.value);
117     return true;
118 }
119 
DisableCount(const Type type)120 bool DeviceStatusDataParse::DisableCount(const Type type)
121 {
122     CALL_DEBUG_ENTER;
123     tempcount_[static_cast<int32_t>(type)] = static_cast<int32_t>(TypeValue::INVALID);
124     return true;
125 }
126 
ReadJsonFile(const std::string & filePath)127 std::string DeviceStatusDataParse::ReadJsonFile(const std::string &filePath)
128 {
129     if (filePath.empty()) {
130         FI_HILOGE("Path is empty");
131         return {};
132     }
133     char realPath[PATH_MAX] = {};
134     if (realpath(filePath.c_str(), realPath) == nullptr) {
135         FI_HILOGE("Path is error, %{public}d", errno);
136         return {};
137     }
138     if (!CheckFileDir(realPath, MSDP_DATA_DIR)) {
139         FI_HILOGE("File dir is invalid");
140         return {};
141     }
142     if (!CheckFileExtendName(realPath, "json")) {
143         FI_HILOGE("Unable to parse files other than json format");
144         return {};
145     }
146     if (!Utility::DoesFileExist(filePath.c_str())) {
147         FI_HILOGE("File not exist");
148         return {};
149     }
150     if (!CheckFileSize(filePath)) {
151         FI_HILOGE("File size out of read range");
152         return {};
153     }
154     return ReadFile(realPath);
155 }
156 
GetFileSize(const std::string & filePath)157 int32_t DeviceStatusDataParse::GetFileSize(const std::string& filePath)
158 {
159     struct stat statbuf = { 0 };
160     if (stat(filePath.c_str(), &statbuf) != 0) {
161         FI_HILOGE("Get file size error");
162         return INVALID_FILE_SIZE;
163     }
164     return statbuf.st_size;
165 }
166 
CheckFileDir(const std::string & filePath,const std::string & dir)167 bool DeviceStatusDataParse::CheckFileDir(const std::string& filePath, const std::string& dir)
168 {
169     if (filePath.compare(0, MSDP_DATA_DIR.size(), MSDP_DATA_DIR) != 0) {
170         FI_HILOGE("FilePath dir is invalid");
171         return false;
172     }
173     return true;
174 }
175 
CheckFileSize(const std::string & filePath)176 bool DeviceStatusDataParse::CheckFileSize(const std::string& filePath)
177 {
178     int32_t fileSize = GetFileSize(filePath);
179     if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
180         FI_HILOGE("File size out of read range");
181         return false;
182     }
183     return true;
184 }
185 
CheckFileExtendName(const std::string & filePath,const std::string & checkExtension)186 bool DeviceStatusDataParse::CheckFileExtendName(const std::string& filePath, const std::string& checkExtension)
187 {
188     std::string::size_type pos = filePath.find_last_of('.');
189     if (pos == std::string::npos) {
190         FI_HILOGE("File is not find extension");
191         return false;
192     }
193     return (filePath.substr(pos + 1, filePath.npos) == checkExtension);
194 }
195 
ReadFile(const std::string & filePath)196 std::string DeviceStatusDataParse::ReadFile(const std::string &filePath)
197 {
198     CALL_DEBUG_ENTER;
199     FILE* fp = fopen(filePath.c_str(), "r");
200     if (fp == nullptr) {
201         FI_HILOGE("Open failed");
202         return {};
203     }
204     std::string dataStr;
205     char buf[READ_DATA_BUFF_SIZE] = {};
206     while (fgets(buf, sizeof(buf), fp) != nullptr) {
207         dataStr += buf;
208     }
209     if (fclose(fp) != 0) {
210         FI_HILOGW("Close file failed");
211     }
212     return dataStr;
213 }
214 } // namespace DeviceStatus
215 } // namespace Msdp
216 } // namespace OHOS
217