1f857971dSopenharmony_ci/* 2f857971dSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f857971dSopenharmony_ci * you may not use this file except in compliance with the License. 5f857971dSopenharmony_ci * You may obtain a copy of the License at 6f857971dSopenharmony_ci * 7f857971dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f857971dSopenharmony_ci * 9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f857971dSopenharmony_ci * See the License for the specific language governing permissions and 13f857971dSopenharmony_ci * limitations under the License. 14f857971dSopenharmony_ci */ 15f857971dSopenharmony_ci 16f857971dSopenharmony_ci#include "devicestatus_data_parse.h" 17f857971dSopenharmony_ci 18f857971dSopenharmony_ci#include <fcntl.h> 19f857971dSopenharmony_ci#include <unistd.h> 20f857971dSopenharmony_ci 21f857971dSopenharmony_ci#include <sys/stat.h> 22f857971dSopenharmony_ci 23f857971dSopenharmony_ci#include "devicestatus_data_define.h" 24f857971dSopenharmony_ci#include "devicestatus_errors.h" 25f857971dSopenharmony_ci#include "fi_log.h" 26f857971dSopenharmony_ci#include "json_parser.h" 27f857971dSopenharmony_ci#include "utility.h" 28f857971dSopenharmony_ci 29f857971dSopenharmony_ci#undef LOG_TAG 30f857971dSopenharmony_ci#define LOG_TAG "DeviceStatusDataParse" 31f857971dSopenharmony_ci 32f857971dSopenharmony_cinamespace OHOS { 33f857971dSopenharmony_cinamespace Msdp { 34f857971dSopenharmony_cinamespace DeviceStatus { 35f857971dSopenharmony_cinamespace { 36f857971dSopenharmony_ciconstexpr int32_t FILE_SIZE_MAX { 0x5000 }; 37f857971dSopenharmony_ciconstexpr int32_t READ_DATA_BUFF_SIZE { 256 }; 38f857971dSopenharmony_ciconst std::string MSDP_DATA_PATH { "/data/msdp/device_status_data.json" }; 39f857971dSopenharmony_ciconst std::string MSDP_DATA_DIR { "/data/msdp" }; 40f857971dSopenharmony_ci} // namespace 41f857971dSopenharmony_ci 42f857971dSopenharmony_cistd::vector<int32_t> DeviceStatusDataParse::tempcount_ = 43f857971dSopenharmony_ci std::vector<int32_t> (static_cast<int32_t>(Type::TYPE_MAX), static_cast<int32_t>(TypeValue::INVALID)); 44f857971dSopenharmony_ci 45f857971dSopenharmony_ciint32_t DeviceStatusDataParse::CreateJsonFile() 46f857971dSopenharmony_ci{ 47f857971dSopenharmony_ci int32_t fd = open(MSDP_DATA_PATH.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP); 48f857971dSopenharmony_ci if (fd < 0) { 49f857971dSopenharmony_ci FI_HILOGE("open failed"); 50f857971dSopenharmony_ci return DEVICESTATUS_FAILED; 51f857971dSopenharmony_ci } 52f857971dSopenharmony_ci if (close(fd) < 0) { 53f857971dSopenharmony_ci FI_HILOGE("close fd failed, error:%{public}s, fd:%{public}d", strerror(errno), fd); 54f857971dSopenharmony_ci } 55f857971dSopenharmony_ci 56f857971dSopenharmony_ci struct stat buf; 57f857971dSopenharmony_ci if (stat(MSDP_DATA_DIR.c_str(), &buf) != 0) { 58f857971dSopenharmony_ci FI_HILOGE("start folder path is invalid %{public}d", errno); 59f857971dSopenharmony_ci return DEVICESTATUS_FAILED; 60f857971dSopenharmony_ci } 61f857971dSopenharmony_ci if (chown(MSDP_DATA_PATH.c_str(), buf.st_uid, buf.st_gid) != 0) { 62f857971dSopenharmony_ci FI_HILOGE("chown failed, errno:%{public}d", errno); 63f857971dSopenharmony_ci return DEVICESTATUS_FAILED; 64f857971dSopenharmony_ci } 65f857971dSopenharmony_ci 66f857971dSopenharmony_ci return DEVICESTATUS_OK; 67f857971dSopenharmony_ci} 68f857971dSopenharmony_ci 69f857971dSopenharmony_cibool DeviceStatusDataParse::ParseDeviceStatusData(Type type, Data& data) 70f857971dSopenharmony_ci{ 71f857971dSopenharmony_ci std::string jsonBuf = ReadJsonFile(MSDP_DATA_PATH.c_str()); 72f857971dSopenharmony_ci if (jsonBuf.empty()) { 73f857971dSopenharmony_ci FI_HILOGE("Read json failed, errno:%{public}d", errno); 74f857971dSopenharmony_ci data.type = type; 75f857971dSopenharmony_ci data.value = OnChangedValue::VALUE_INVALID; 76f857971dSopenharmony_ci return false; 77f857971dSopenharmony_ci } 78f857971dSopenharmony_ci return DeviceStatusDataInit(jsonBuf, true, type, data); 79f857971dSopenharmony_ci} 80f857971dSopenharmony_ci 81f857971dSopenharmony_cibool DeviceStatusDataParse::DeviceStatusDataInit(const std::string& fileData, bool logStatus, Type& type, 82f857971dSopenharmony_ci Data& data) 83f857971dSopenharmony_ci{ 84f857971dSopenharmony_ci CALL_DEBUG_ENTER; 85f857971dSopenharmony_ci JsonParser parser; 86f857971dSopenharmony_ci parser.json = cJSON_Parse(fileData.c_str()); 87f857971dSopenharmony_ci data.type = type; 88f857971dSopenharmony_ci data.value = OnChangedValue::VALUE_INVALID; 89f857971dSopenharmony_ci if (cJSON_IsArray(parser.json)) { 90f857971dSopenharmony_ci FI_HILOGE("parser is array"); 91f857971dSopenharmony_ci return false; 92f857971dSopenharmony_ci } 93f857971dSopenharmony_ci 94f857971dSopenharmony_ci if (type < Type::TYPE_ABSOLUTE_STILL || type >= Type::TYPE_MAX) { 95f857971dSopenharmony_ci FI_HILOGE("type error"); 96f857971dSopenharmony_ci return false; 97f857971dSopenharmony_ci } 98f857971dSopenharmony_ci 99f857971dSopenharmony_ci cJSON* mockarray = cJSON_GetObjectItem(parser.json, DeviceStatusJson[type].json.c_str()); 100f857971dSopenharmony_ci if (!cJSON_IsArray(mockarray)) { 101f857971dSopenharmony_ci FI_HILOGE("mockarray is not array"); 102f857971dSopenharmony_ci return false; 103f857971dSopenharmony_ci } 104f857971dSopenharmony_ci int32_t jsonsize = cJSON_GetArraySize(mockarray); 105f857971dSopenharmony_ci if (jsonsize == 0) { 106f857971dSopenharmony_ci FI_HILOGE("Json size is zero"); 107f857971dSopenharmony_ci return false; 108f857971dSopenharmony_ci } 109f857971dSopenharmony_ci tempcount_[type] = tempcount_[type] % jsonsize; 110f857971dSopenharmony_ci cJSON* mockvalue = cJSON_GetArrayItem(mockarray, tempcount_[type]); 111f857971dSopenharmony_ci tempcount_[type]++; 112f857971dSopenharmony_ci data.type = type; 113f857971dSopenharmony_ci if (mockvalue == nullptr || !cJSON_IsNumber(mockvalue)) { 114f857971dSopenharmony_ci FI_HILOGE("Json parser number is failed"); 115f857971dSopenharmony_ci return false; 116f857971dSopenharmony_ci } 117f857971dSopenharmony_ci data.value = static_cast<OnChangedValue>(mockvalue->valueint); 118f857971dSopenharmony_ci FI_HILOGD("type:%{public}d, status:%{public}d", data.type, data.value); 119f857971dSopenharmony_ci return true; 120f857971dSopenharmony_ci} 121f857971dSopenharmony_ci 122f857971dSopenharmony_cibool DeviceStatusDataParse::DisableCount(const Type type) 123f857971dSopenharmony_ci{ 124f857971dSopenharmony_ci CALL_DEBUG_ENTER; 125f857971dSopenharmony_ci if (tempcount_.size() <= static_cast<size_t>(type)) { 126f857971dSopenharmony_ci FI_HILOGE("The index is out of bounds, size is %{public}zu", tempcount_.size()); 127f857971dSopenharmony_ci return false; 128f857971dSopenharmony_ci } 129f857971dSopenharmony_ci tempcount_[static_cast<int32_t>(type)] = static_cast<int32_t>(TypeValue::INVALID); 130f857971dSopenharmony_ci return true; 131f857971dSopenharmony_ci} 132f857971dSopenharmony_ci 133f857971dSopenharmony_cistd::string DeviceStatusDataParse::ReadJsonFile(const std::string &filePath) 134f857971dSopenharmony_ci{ 135f857971dSopenharmony_ci if (filePath.empty()) { 136f857971dSopenharmony_ci FI_HILOGE("Path is empty"); 137f857971dSopenharmony_ci return {}; 138f857971dSopenharmony_ci } 139f857971dSopenharmony_ci char realPath[PATH_MAX] = { 0 }; 140f857971dSopenharmony_ci if (realpath(filePath.c_str(), realPath) == nullptr) { 141f857971dSopenharmony_ci FI_HILOGE("Path is error, %{public}d", errno); 142f857971dSopenharmony_ci return {}; 143f857971dSopenharmony_ci } 144f857971dSopenharmony_ci if (!CheckFileDir(realPath, MSDP_DATA_DIR)) { 145f857971dSopenharmony_ci FI_HILOGE("File dir is invalid"); 146f857971dSopenharmony_ci return {}; 147f857971dSopenharmony_ci } 148f857971dSopenharmony_ci if (!CheckFileExtendName(realPath, "json")) { 149f857971dSopenharmony_ci FI_HILOGE("Unable to parse files other than json format"); 150f857971dSopenharmony_ci return {}; 151f857971dSopenharmony_ci } 152f857971dSopenharmony_ci if (!Utility::DoesFileExist(filePath.c_str())) { 153f857971dSopenharmony_ci FI_HILOGE("File not exist"); 154f857971dSopenharmony_ci return {}; 155f857971dSopenharmony_ci } 156f857971dSopenharmony_ci if (!CheckFileSize(filePath)) { 157f857971dSopenharmony_ci FI_HILOGE("File size out of read range"); 158f857971dSopenharmony_ci return {}; 159f857971dSopenharmony_ci } 160f857971dSopenharmony_ci return ReadFile(realPath); 161f857971dSopenharmony_ci} 162f857971dSopenharmony_ci 163f857971dSopenharmony_cibool DeviceStatusDataParse::CheckFileDir(const std::string& filePath, const std::string& dir) 164f857971dSopenharmony_ci{ 165f857971dSopenharmony_ci if (filePath.compare(0, MSDP_DATA_DIR.size(), MSDP_DATA_DIR) != 0) { 166f857971dSopenharmony_ci FI_HILOGE("FilePath dir is invalid"); 167f857971dSopenharmony_ci return false; 168f857971dSopenharmony_ci } 169f857971dSopenharmony_ci return true; 170f857971dSopenharmony_ci} 171f857971dSopenharmony_ci 172f857971dSopenharmony_cibool DeviceStatusDataParse::CheckFileSize(const std::string& filePath) 173f857971dSopenharmony_ci{ 174f857971dSopenharmony_ci int32_t fileSize = Utility::GetFileSize(filePath); 175f857971dSopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 176f857971dSopenharmony_ci FI_HILOGE("File size out of read range"); 177f857971dSopenharmony_ci return false; 178f857971dSopenharmony_ci } 179f857971dSopenharmony_ci return true; 180f857971dSopenharmony_ci} 181f857971dSopenharmony_ci 182f857971dSopenharmony_cibool DeviceStatusDataParse::CheckFileExtendName(const std::string& filePath, const std::string& checkExtension) 183f857971dSopenharmony_ci{ 184f857971dSopenharmony_ci std::string::size_type pos = filePath.find_last_of('.'); 185f857971dSopenharmony_ci if (pos == std::string::npos) { 186f857971dSopenharmony_ci FI_HILOGE("File is not find extension"); 187f857971dSopenharmony_ci return false; 188f857971dSopenharmony_ci } 189f857971dSopenharmony_ci return (filePath.substr(pos + 1, filePath.npos) == checkExtension); 190f857971dSopenharmony_ci} 191f857971dSopenharmony_ci 192f857971dSopenharmony_cistd::string DeviceStatusDataParse::ReadFile(const std::string &filePath) 193f857971dSopenharmony_ci{ 194f857971dSopenharmony_ci CALL_DEBUG_ENTER; 195f857971dSopenharmony_ci FILE* fp = fopen(filePath.c_str(), "r"); 196f857971dSopenharmony_ci if (fp == nullptr) { 197f857971dSopenharmony_ci FI_HILOGE("Open failed"); 198f857971dSopenharmony_ci return {}; 199f857971dSopenharmony_ci } 200f857971dSopenharmony_ci std::string dataStr; 201f857971dSopenharmony_ci char buf[READ_DATA_BUFF_SIZE] = { 0 }; 202f857971dSopenharmony_ci while (fgets(buf, sizeof(buf), fp) != nullptr) { 203f857971dSopenharmony_ci dataStr += buf; 204f857971dSopenharmony_ci } 205f857971dSopenharmony_ci if (fclose(fp) != 0) { 206f857971dSopenharmony_ci FI_HILOGW("Close file failed"); 207f857971dSopenharmony_ci } 208f857971dSopenharmony_ci return dataStr; 209f857971dSopenharmony_ci} 210f857971dSopenharmony_ci} // namespace DeviceStatus 211f857971dSopenharmony_ci} // namespace Msdp 212f857971dSopenharmony_ci} // namespace OHOS 213