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