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