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