1 /*
2 * Copyright (C) 2022 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 "operator_file_parser.h"
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <climits>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <fstream>
23 #include <iterator>
24 #include <string_ex.h>
25 #include <unistd.h>
26 #include "config_policy_utils.h"
27 #include "sim_utils.h"
28 #include "telephony_types.h"
29
30 namespace OHOS {
31 namespace Telephony {
~OperatorFileParser()32 OperatorFileParser::~OperatorFileParser() {}
33
WriteOperatorConfigJson(std::string filename,const cJSON * root)34 bool OperatorFileParser::WriteOperatorConfigJson(std::string filename, const cJSON *root)
35 {
36 if (root == nullptr) {
37 TELEPHONY_LOGE("json is invalid");
38 return false;
39 }
40 if (!isCachePathExit()) {
41 if (mkdir(DEFAULT_OPERATE_CONFIG_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != SUCCESS) {
42 TELEPHONY_LOGE("CreateDirFailed");
43 return false;
44 }
45 }
46 FILE *file = nullptr;
47 file = fopen(GetOperatorConfigFilePath(filename).c_str(), "w");
48 if (file == nullptr) {
49 printf("OpenFileFailed");
50 return false;
51 }
52 char *cjValue = cJSON_Print(root);
53 int ret = fwrite(cjValue, sizeof(char), strlen(cjValue), file);
54 (void)fclose(file);
55 free(cjValue);
56 cjValue = nullptr;
57 file = nullptr;
58 if (ret == 0) {
59 printf("write json to file failed!");
60 return false;
61 }
62 return true;
63 }
64
ClearFilesCache()65 void OperatorFileParser::ClearFilesCache()
66 {
67 if (isCachePathExit()) {
68 TELEPHONY_LOGI("removeAllCache");
69 DeleteFiles();
70 }
71 }
72
DeleteFiles()73 void OperatorFileParser::DeleteFiles()
74 {
75 std::filesystem::path dirPath = std::string(DEFAULT_OPERATE_CONFIG_DIR);
76 std::error_code errorCode;
77 std::filesystem::remove_all(dirPath, errorCode);
78 if (errorCode.operator bool()) {
79 TELEPHONY_LOGE("delete fail, error code : %{public}d", errorCode.value());
80 } else {
81 TELEPHONY_LOGI("delete success");
82 }
83 }
84
isCachePathExit()85 bool OperatorFileParser::isCachePathExit()
86 {
87 return access(DEFAULT_OPERATE_CONFIG_DIR, F_OK) == SUCCESS;
88 }
89
GetOperatorConfigFilePath(std::string filename)90 std::string OperatorFileParser::GetOperatorConfigFilePath(std::string filename)
91 {
92 if (filename.empty()) {
93 TELEPHONY_LOGE("filename is empty");
94 return filename;
95 }
96 return std::string(DEFAULT_OPERATE_CONFIG_DIR) + "/" + filename;
97 }
98
ParseFromCustomSystem(int32_t slotId,OperatorConfig & opc,cJSON * root)99 bool OperatorFileParser::ParseFromCustomSystem(int32_t slotId, OperatorConfig &opc, cJSON *root)
100 {
101 int mode = MODE_SLOT_0;
102 if (slotId == SimSlotId::SIM_SLOT_1) {
103 mode = MODE_SLOT_1;
104 }
105 CfgFiles *cfgFiles = GetCfgFilesEx(DEFAULT_OPERATE_CONFIG_PATH, mode, nullptr);
106 if (cfgFiles == nullptr) {
107 TELEPHONY_LOGE("ParseFromCustomSystem cfgFiles is null");
108 return false;
109 }
110 char *filePath = nullptr;
111 cJSON *tempRoot = nullptr;
112 std::lock_guard<std::mutex> lock(mutex_);
113 tempConfig_.clear();
114 for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
115 filePath = cfgFiles->paths[i];
116 if (filePath && *filePath != '\0') {
117 bool ret = ParseOperatorConfigFromFile(opc, filePath, tempRoot, true);
118 if (!ret) {
119 TELEPHONY_LOGE("ParseFromCustomSystem failed");
120 continue;
121 }
122 }
123 }
124 CreateJsonFromOperatorConfig(root);
125 FreeCfgFiles(cfgFiles);
126 filePath = nullptr;
127 tempRoot = nullptr;
128 return true;
129 }
130
CreateJsonFromOperatorConfig(cJSON * root)131 void OperatorFileParser::CreateJsonFromOperatorConfig(cJSON *root)
132 {
133 for (auto it = tempConfig_.begin(); it != tempConfig_.end(); ++it) {
134 cJSON *jsontemp = cJSON_Parse(it->second.c_str());
135 if (jsontemp != nullptr) {
136 cJSON_AddItemToObject(root, it->first.c_str(), jsontemp);
137 }
138 }
139 tempConfig_.clear();
140 }
141
ParseOperatorConfigFromFile(OperatorConfig & opc,const std::string & path,cJSON * root,bool needSaveTempOpc)142 bool OperatorFileParser::ParseOperatorConfigFromFile(
143 OperatorConfig &opc, const std::string &path, cJSON *root, bool needSaveTempOpc)
144 {
145 char *content = nullptr;
146 int contentLength = LoaderJsonFile(content, path);
147 if (contentLength == LOADER_JSON_ERROR) {
148 TELEPHONY_LOGE("ParseOperatorConfigFromFile failed!");
149 return false;
150 }
151 root = cJSON_Parse(content);
152 free(content);
153 content = nullptr;
154 if (root == nullptr) {
155 TELEPHONY_LOGE("ParseOperatorConfigFromFile root is error!");
156 return false;
157 }
158 ParseOperatorConfigFromJson(root, opc, needSaveTempOpc);
159 cJSON_Delete(root);
160 return true;
161 }
162
ParseOperatorConfigFromJson(const cJSON * root,OperatorConfig & opc,bool needSaveTempOpc)163 void OperatorFileParser::ParseOperatorConfigFromJson(const cJSON *root, OperatorConfig &opc, bool needSaveTempOpc)
164 {
165 cJSON *value = root->child;
166 char *tempChar = nullptr;
167 std::map<std::u16string, std::u16string> &configValue = opc.configValue;
168 while (value) {
169 if (needSaveTempOpc) {
170 tempChar = cJSON_PrintUnformatted(value);
171 tempConfig_[value->string] = tempChar != nullptr ? tempChar : "";
172 if (tempChar != nullptr) {
173 free(tempChar);
174 }
175 }
176 tempChar = cJSON_Print(value);
177 configValue[Str8ToStr16(value->string)] = tempChar != nullptr ? Str8ToStr16(tempChar) : u"";
178 TELEPHONY_LOGI("ParseOperatorConfigFromFile key %{public}s value %{public}s", value->string,
179 Str16ToStr8(configValue[Str8ToStr16(value->string)]).c_str());
180 if (tempChar != nullptr) {
181 free(tempChar);
182 }
183 if (value->type == cJSON_Array) {
184 TELEPHONY_LOGD("parse type arrayValue");
185 if (cJSON_GetArraySize(value) > 0) {
186 ParseArray(value->string, value, opc);
187 }
188 } else if (value->type == cJSON_String) {
189 TELEPHONY_LOGD("parse type stringValue");
190 opc.stringValue[value->string] = value->valuestring;
191 configValue[Str8ToStr16(value->string)] = Str8ToStr16(value->valuestring);
192 } else if (value->type == cJSON_Number) {
193 TELEPHONY_LOGD("parse type initValue");
194 int64_t lValue = static_cast<int64_t>(cJSON_GetNumberValue(value));
195 configValue[Str8ToStr16(value->string)] = Str8ToStr16(std::to_string(lValue));
196 if (lValue > INT_MAX) {
197 TELEPHONY_LOGD("value is long");
198 opc.longValue[value->string] = lValue;
199 } else {
200 opc.intValue[value->string] = static_cast<int32_t>(lValue);
201 }
202 } else if (value->type == cJSON_True) {
203 TELEPHONY_LOGD("parse type booleanValue true");
204 opc.boolValue[value->string] = true;
205 configValue[Str8ToStr16(value->string)] = Str8ToStr16("true");
206 } else if (value->type == cJSON_False) {
207 opc.boolValue[value->string] = false;
208 configValue[Str8ToStr16(value->string)] = Str8ToStr16("false");
209 }
210 value = value->next;
211 }
212 tempChar = nullptr;
213 }
214
LoaderJsonFile(char * & content,const std::string & path)215 int32_t OperatorFileParser::LoaderJsonFile(char *&content, const std::string &path)
216 {
217 std::ifstream ifs;
218 ifs.open(path);
219 if (ifs.fail()) {
220 TELEPHONY_LOGE("LoaderJsonFile path failed");
221 return LOADER_JSON_ERROR;
222 }
223 ifs.seekg(0, std::ios::end);
224 uint64_t len = static_cast<uint64_t>(ifs.tellg());
225 if (len == 0 || len > MAX_BYTE_LEN) {
226 TELEPHONY_LOGE("LoaderJsonFile len <= 0 or len > MAX_BYTE_LEN!");
227 ifs.close();
228 return LOADER_JSON_ERROR;
229 }
230 content = static_cast<char *>(malloc(len + 1));
231 if (content == nullptr) {
232 TELEPHONY_LOGE("LoaderJsonFile malloc content fail!");
233 ifs.close();
234 return LOADER_JSON_ERROR;
235 }
236 if (memset_s(content, len + 1, 0, len + 1) != EOK) {
237 TELEPHONY_LOGE("LoaderJsonFile memset_s failed");
238 free(content);
239 content = nullptr;
240 ifs.close();
241 return LOADER_JSON_ERROR;
242 }
243 ifs.seekg(0, std::ios::beg);
244 ifs.read(content, len);
245 ifs.close();
246 return len;
247 }
248
CloseFile(FILE * f)249 bool OperatorFileParser::CloseFile(FILE *f)
250 {
251 int ret_close = fclose(f);
252 if (ret_close != 0) {
253 TELEPHONY_LOGE("LoaderJsonFile ret_close != 0!");
254 return false;
255 }
256 return true;
257 }
258
ParseArray(const std::string key,const cJSON * value,OperatorConfig & opc)259 void OperatorFileParser::ParseArray(const std::string key, const cJSON *value, OperatorConfig &opc)
260 {
261 if (value == nullptr || cJSON_GetArraySize(value) <= 0 || value->child == nullptr) {
262 return;
263 }
264 cJSON *arrayValue = value->child;
265 auto valueType = arrayValue->type;
266 if (valueType == cJSON_String) {
267 TELEPHONY_LOGI("parse string array");
268 if (opc.stringArrayValue.find(key) == opc.stringArrayValue.end()) {
269 opc.stringArrayValue[key] = std::vector<std::string>();
270 }
271 while (arrayValue) {
272 opc.stringArrayValue[key].push_back(arrayValue->valuestring);
273 arrayValue = arrayValue->next;
274 }
275 } else if (valueType == cJSON_Number && static_cast<int64_t>(cJSON_GetNumberValue(arrayValue)) > INT_MAX) {
276 TELEPHONY_LOGI("parse long array");
277 if (opc.longArrayValue.find(key) == opc.longArrayValue.end()) {
278 opc.longArrayValue[key] = std::vector<int64_t>();
279 }
280 while (arrayValue) {
281 opc.longArrayValue[key].push_back(static_cast<int64_t>(cJSON_GetNumberValue(arrayValue)));
282 arrayValue = arrayValue->next;
283 }
284 } else if (valueType == cJSON_Number) {
285 TELEPHONY_LOGI("parse int array");
286 if (opc.intArrayValue.find(key) == opc.intArrayValue.end()) {
287 opc.intArrayValue[key] = std::vector<int32_t>();
288 }
289 while (arrayValue) {
290 opc.intArrayValue[key].push_back(static_cast<int32_t>(cJSON_GetNumberValue(arrayValue)));
291 arrayValue = arrayValue->next;
292 }
293 }
294 arrayValue = nullptr;
295 }
296 } // namespace Telephony
297 } // namespace OHOS
298