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 Json::Value & root)34 bool OperatorFileParser::WriteOperatorConfigJson(std::string filename, const Json::Value &root)
35 {
36 if (!isCachePathExit()) {
37 if (mkdir(DEFAULT_OPERATE_CONFIG_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != SUCCESS) {
38 TELEPHONY_LOGE("CreateDirFailed");
39 return false;
40 }
41 }
42 std::fstream ofs;
43 ofs.open(GetOperatorConfigFilePath(filename).c_str(), std::ios::ate | std::ios::out);
44 if (!ofs.is_open()) {
45 TELEPHONY_LOGE("OpenFileFailed");
46 return false;
47 }
48 Json::StreamWriterBuilder jswBuilder;
49 jswBuilder["emitUTF8"] = true;
50 std::unique_ptr<Json::StreamWriter> jsWriter(jswBuilder.newStreamWriter());
51 std::ostringstream os;
52 jsWriter->write(root, &os);
53 ofs << os.str();
54 ofs.close();
55 return true;
56 }
57
ClearFilesCache()58 void OperatorFileParser::ClearFilesCache()
59 {
60 if (isCachePathExit()) {
61 TELEPHONY_LOGI("removeAllCache");
62 rmdir(DEFAULT_OPERATE_CONFIG_DIR);
63 }
64 }
65
isCachePathExit()66 bool OperatorFileParser::isCachePathExit()
67 {
68 return access(DEFAULT_OPERATE_CONFIG_DIR, F_OK) == SUCCESS;
69 }
70
GetOperatorConfigFilePath(std::string filename)71 std::string OperatorFileParser::GetOperatorConfigFilePath(std::string filename)
72 {
73 if (filename.empty()) {
74 TELEPHONY_LOGE("filename is empty");
75 return filename;
76 }
77 return std::string(DEFAULT_OPERATE_CONFIG_DIR) + "/" + filename;
78 }
79
ParseFromCustomSystem(int32_t slotId,OperatorConfig & opc,Json::Value & opcJson)80 bool OperatorFileParser::ParseFromCustomSystem(int32_t slotId, OperatorConfig &opc, Json::Value &opcJson)
81 {
82 int mode = MODE_SLOT_0;
83 if (slotId == SimSlotId::SIM_SLOT_1) {
84 mode = MODE_SLOT_1;
85 }
86 CfgFiles *cfgFiles = GetCfgFilesEx(DEFAULT_OPERATE_CONFIG_PATH, mode, nullptr);
87 if (cfgFiles == nullptr) {
88 TELEPHONY_LOGE("ParseFromCustomSystem cfgFiles is null");
89 return false;
90 }
91 char *filePath = nullptr;
92 for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
93 filePath = cfgFiles->paths[i];
94 if (filePath && *filePath != '\0') {
95 Json::Value temp;
96 bool ret = ParseOperatorConfigFromFile(opc, filePath, temp);
97 if (!ret) {
98 TELEPHONY_LOGE("ParseFromCustomSystem path %{public}s fail", filePath);
99 continue;
100 }
101 Json::Value::Members mem = temp.getMemberNames();
102 for (auto mem : temp.getMemberNames()) {
103 opcJson[std::string(mem)] = temp[mem];
104 }
105 }
106 }
107 FreeCfgFiles(cfgFiles);
108 return true;
109 }
110
ParseOperatorConfigFromFile(OperatorConfig & opc,const std::string & path,Json::Value & opcJson)111 bool OperatorFileParser::ParseOperatorConfigFromFile(OperatorConfig &opc, const std::string &path, Json::Value &opcJson)
112 {
113 char *content = nullptr;
114 int contentLength = LoaderJsonFile(content, path);
115 if (contentLength == LOADER_JSON_ERROR) {
116 TELEPHONY_LOGE("ParseOperatorConfigFromFile %{public}s is fail!", path.c_str());
117 return false;
118 }
119 const std::string rawJson(content);
120 free(content);
121 content = nullptr;
122 JSONCPP_STRING err;
123 Json::CharReaderBuilder builder;
124 Json::CharReader *reader(builder.newCharReader());
125 if (!reader->parse(rawJson.c_str(), rawJson.c_str() + contentLength, &opcJson, &err)) {
126 TELEPHONY_LOGE("ParseOperatorConfigFromFile reader is error!");
127 return false;
128 }
129 delete reader;
130 reader = nullptr;
131 ParseOperatorConfigFromJson(opcJson, opc);
132 return true;
133 }
134
ParseOperatorConfigFromJson(const Json::Value & root,OperatorConfig & opc)135 void OperatorFileParser::ParseOperatorConfigFromJson(const Json::Value &root, OperatorConfig &opc)
136 {
137 TELEPHONY_LOGD("ParseOperatorConfigFromJson");
138 Json::Value::Members mems = root.getMemberNames();
139 std::map<std::u16string, std::u16string> &configValue = opc.configValue;
140 for (auto mem : mems) {
141 auto keyStr8 = std::string(mem);
142 auto value = root[mem];
143 configValue[Str8ToStr16(keyStr8)] = Str8ToStr16(value.toStyledString());
144 TELEPHONY_LOGI("ParseOperatorConfigFromJson key %{public}s value %{public}s", keyStr8.c_str(),
145 value.toStyledString().c_str());
146 auto valueType = root[mem].type();
147 if (valueType == Json::arrayValue) {
148 TELEPHONY_LOGD("parse type arrayValue");
149 if (value.size() > 0) {
150 ParseArray(keyStr8, value, opc);
151 }
152 continue;
153 }
154 if (valueType == Json::stringValue) {
155 TELEPHONY_LOGD("parse type stringValue");
156 opc.stringValue[keyStr8] = value.asString();
157 configValue[Str8ToStr16(keyStr8)] = Str8ToStr16(value.asString());
158 continue;
159 }
160 if (valueType == Json::intValue) {
161 TELEPHONY_LOGD("parse type initValue");
162 int64_t lValue = static_cast<int64_t>(stoll(value.asString()));
163 configValue[Str8ToStr16(keyStr8)] = Str8ToStr16(value.asString());
164 if (value > INT_MAX) {
165 TELEPHONY_LOGD("value is long");
166 opc.longValue[keyStr8] = lValue;
167 } else {
168 TELEPHONY_LOGD("value is int");
169 opc.intValue[keyStr8] = static_cast<int32_t>(lValue);
170 }
171 continue;
172 }
173 if (valueType == Json::booleanValue) {
174 TELEPHONY_LOGD("parse type booleanValue");
175 opc.boolValue[keyStr8] = value.asBool();
176 configValue[Str8ToStr16(keyStr8)] = Str8ToStr16(value.asString());
177 continue;
178 }
179 }
180 }
181
LoaderJsonFile(char * & content,const std::string & path)182 int32_t OperatorFileParser::LoaderJsonFile(char *&content, const std::string &path)
183 {
184 std::ifstream ifs;
185 ifs.open(path);
186 if (ifs.fail()) {
187 TELEPHONY_LOGE("LoaderJsonFile path PATH: %{public}s failed", path.c_str());
188 return LOADER_JSON_ERROR;
189 }
190 ifs.seekg(0, std::ios::end);
191 uint64_t len = static_cast<uint64_t>(ifs.tellg());
192 if (len == 0 || len > MAX_BYTE_LEN) {
193 TELEPHONY_LOGE("LoaderJsonFile len <= 0 or len > MAX_BYTE_LEN!");
194 ifs.close();
195 return LOADER_JSON_ERROR;
196 }
197 content = static_cast<char *>(malloc(len + 1));
198 if (content == nullptr) {
199 TELEPHONY_LOGE("LoaderJsonFile malloc content fail!");
200 ifs.close();
201 return LOADER_JSON_ERROR;
202 }
203 if (memset_s(content, len + 1, 0, len + 1) != EOK) {
204 TELEPHONY_LOGE("LoaderJsonFile memset_s failed");
205 free(content);
206 content = nullptr;
207 ifs.close();
208 return LOADER_JSON_ERROR;
209 }
210 ifs.seekg(0, std::ios::beg);
211 ifs.read(content, len);
212 ifs.close();
213 return len;
214 }
215
CloseFile(FILE * f)216 bool OperatorFileParser::CloseFile(FILE *f)
217 {
218 int ret_close = fclose(f);
219 if (ret_close != 0) {
220 TELEPHONY_LOGE("LoaderJsonFile ret_close != 0!");
221 return false;
222 }
223 return true;
224 }
225
ParseArray(const std::string key,const Json::Value & arrayValue_,OperatorConfig & opc)226 void OperatorFileParser::ParseArray(const std::string key, const Json::Value &arrayValue_, OperatorConfig &opc)
227 {
228 if (arrayValue_.size() <= 0) {
229 return;
230 }
231 int32_t first = 0;
232 auto valueType = arrayValue_[first].type();
233 if (valueType == Json::stringValue) {
234 TELEPHONY_LOGI("parse string array");
235 if (opc.stringArrayValue.find(key) == opc.stringArrayValue.end()) {
236 opc.stringArrayValue[key] = std::vector<std::string>();
237 }
238 for (auto value : arrayValue_) {
239 opc.stringArrayValue[key].push_back(value.asString());
240 }
241 return;
242 }
243 if (valueType == Json::intValue && static_cast<int64_t>(stoll(arrayValue_[first].asString())) > INT_MAX) {
244 TELEPHONY_LOGI("parse long array");
245 if (opc.longArrayValue.find(key) == opc.longArrayValue.end()) {
246 opc.longArrayValue[key] = std::vector<int64_t>();
247 }
248 for (auto value : arrayValue_) {
249 opc.longArrayValue[key].push_back(static_cast<int64_t>(stoll(value.asString())));
250 }
251 return;
252 }
253 if (valueType == Json::intValue) {
254 TELEPHONY_LOGI("parse int array");
255 if (opc.intArrayValue.find(key) == opc.intArrayValue.end()) {
256 opc.intArrayValue[key] = std::vector<int32_t>();
257 }
258 for (auto value : arrayValue_) {
259 opc.intArrayValue[key].push_back(value.asInt());
260 }
261 return;
262 }
263 }
264 } // namespace Telephony
265 } // namespace OHOS
266