1 /*
2 * Copyright (C) 2023 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_name_utils.h"
17
18 #include <securec.h>
19
20 #include "config_policy_utils.h"
21 #include "cstdint"
22 #include "cstdio"
23 #include "cstdlib"
24 #include "cstring"
25 #include "iosfwd"
26 #include "json/config.h"
27 #include "json/reader.h"
28 #include "json/value.h"
29 #include "locale_config.h"
30 #include "memory"
31 #include "parameter.h"
32 #include "telephony_errors.h"
33 #include "telephony_log_wrapper.h"
34
35 namespace OHOS {
36 namespace Telephony {
37 OperatorNameUtils OperatorNameUtils::operatorNameUtils_;
38 const char *PATH = "/etc/telephony/operator_name.json";
39 const char *ITEM_OPERATOR_NAMES = "operator_names";
40 const char *ITEM_PLMN = "mcc_mnc_array";
41 const char *ITEM_ZH_HANS_CN = "zh-Hans-CN";
42 const char *ITEM_EN_LATN_US = "en-Latn-US";
43 const char *ITEM_ZH_HANT_TW = "zh-Hant-TW";
44 const char *ITEM_ZH_HANT_HK = "zh-Hant-HK";
45 const int MAX_BYTE_LEN = 10 * 1024 * 1024;
46
GetInstance()47 OperatorNameUtils &OperatorNameUtils::GetInstance()
48 {
49 return operatorNameUtils_;
50 }
51
Init()52 void OperatorNameUtils::Init()
53 {
54 std::unique_lock<std::mutex> lock(mutex_);
55 if (isInit_) {
56 TELEPHONY_LOGI("has init");
57 return;
58 }
59 nameArray_.clear();
60 ParserOperatorNameCustJson(nameArray_);
61 TELEPHONY_LOGI("init success");
62 isInit_ = true;
63 }
64
IsInit()65 bool OperatorNameUtils::IsInit()
66 {
67 TELEPHONY_LOGI("is init %{public}d nameArray_ size %{public}zu", isInit_, nameArray_.size());
68 return isInit_;
69 }
70
ParserOperatorNameCustJson(std::vector<OperatorNameCust> & vec)71 int32_t OperatorNameUtils::ParserOperatorNameCustJson(std::vector<OperatorNameCust> &vec)
72 {
73 char *content = nullptr;
74 char buf[MAX_PATH_LEN];
75 char *path = GetOneCfgFile(PATH, buf, MAX_PATH_LEN);
76 int32_t ret = TELEPHONY_SUCCESS;
77 if (path && *path != '\0') {
78 ret = LoaderJsonFile(content, path);
79 }
80 if (ret != TELEPHONY_SUCCESS) {
81 TELEPHONY_LOGE("load fail!");
82 return ret;
83 }
84 if (content == nullptr) {
85 TELEPHONY_LOGE("content is nullptr!");
86 return TELEPHONY_ERR_READ_DATA_FAIL;
87 }
88 const int contentLength = strlen(content);
89 const std::string rawJson(content);
90 free(content);
91 content = nullptr;
92 JSONCPP_STRING err;
93 Json::Value root;
94 Json::CharReaderBuilder builder;
95 Json::CharReader *reader(builder.newCharReader());
96 if (!reader->parse(rawJson.c_str(), rawJson.c_str() + contentLength, &root, &err)) {
97 TELEPHONY_LOGE("reader is error!");
98 delete reader;
99 return TELEPHONY_ERR_READ_DATA_FAIL;
100 }
101 delete reader;
102 reader = nullptr;
103 Json::Value itemRoots = root[ITEM_OPERATOR_NAMES];
104 if (itemRoots.size() == 0) {
105 TELEPHONY_LOGE("itemRoots size == 0!");
106 return TELEPHONY_ERR_READ_DATA_FAIL;
107 }
108 ParserOperatorNames(vec, itemRoots);
109 return TELEPHONY_SUCCESS;
110 }
111
LoaderJsonFile(char * & content,const char * path) const112 int32_t OperatorNameUtils::LoaderJsonFile(char *&content, const char *path) const
113 {
114 long len = 0;
115 char realPath[PATH_MAX] = { 0x00 };
116 if (realpath(path, realPath) == nullptr) {
117 TELEPHONY_LOGE("realpath fail! #PATH: %{public}s", path);
118 return TELEPHONY_ERR_READ_DATA_FAIL;
119 }
120 FILE *f = fopen(realPath, "rb");
121 if (f == nullptr) {
122 return TELEPHONY_ERR_READ_DATA_FAIL;
123 }
124 int ret_seek_end = fseek(f, 0, SEEK_END);
125 if (ret_seek_end != 0) {
126 TELEPHONY_LOGE("ret_seek_end != 0!");
127 CloseFile(f);
128 return TELEPHONY_ERR_READ_DATA_FAIL;
129 }
130 len = ftell(f);
131 int ret_seek_set = fseek(f, 0, SEEK_SET);
132 if (ret_seek_set != 0) {
133 CloseFile(f);
134 return TELEPHONY_ERR_READ_DATA_FAIL;
135 }
136 if (len == 0 || len > static_cast<long>(MAX_BYTE_LEN)) {
137 TELEPHONY_LOGE("len is valid!");
138 CloseFile(f);
139 return TELEPHONY_ERR_READ_DATA_FAIL;
140 }
141 content = static_cast<char *>(malloc(len + 1));
142 if (content == nullptr) {
143 CloseFile(f);
144 return TELEPHONY_ERR_READ_DATA_FAIL;
145 }
146 if (memset_s(content, len + 1, 0, len + 1) != EOK) {
147 TELEPHONY_LOGE("memset_s failed");
148 free(content);
149 content = nullptr;
150 CloseFile(f);
151 return TELEPHONY_ERR_READ_DATA_FAIL;
152 }
153 size_t ret_read = fread(content, 1, len, f);
154 if (ret_read != static_cast<size_t>(len)) {
155 free(content);
156 content = nullptr;
157 CloseFile(f);
158 return TELEPHONY_ERR_READ_DATA_FAIL;
159 }
160 return CloseFile(f);
161 }
162
ParserOperatorNames(std::vector<OperatorNameCust> & vec,Json::Value & root)163 void OperatorNameUtils::ParserOperatorNames(std::vector<OperatorNameCust> &vec, Json::Value &root)
164 {
165 for (int32_t i = 0; i < static_cast<int32_t>(root.size()); i++) {
166 Json::Value itemRoot = root[i];
167 OperatorNameCust nameCust;
168 if (itemRoot[ITEM_PLMN].isArray()) {
169 for (auto value : itemRoot[ITEM_PLMN]) {
170 nameCust.mccMnc.push_back(value.asString());
171 }
172 }
173 if (itemRoot[ITEM_ZH_HANS_CN].isString()) {
174 nameCust.zhHansCN = itemRoot[ITEM_ZH_HANS_CN].asString();
175 }
176 if (itemRoot[ITEM_EN_LATN_US].isString()) {
177 nameCust.enLatnUS = itemRoot[ITEM_EN_LATN_US].asString();
178 }
179 if (itemRoot[ITEM_ZH_HANT_TW].isString()) {
180 nameCust.zhHantTW = itemRoot[ITEM_ZH_HANT_TW].asString();
181 }
182 if (itemRoot[ITEM_ZH_HANT_HK].isString()) {
183 nameCust.zhHantHK = itemRoot[ITEM_ZH_HANT_HK].asString();
184 }
185 vec.push_back(nameCust);
186 }
187 }
188
CloseFile(FILE * f) const189 int32_t OperatorNameUtils::CloseFile(FILE *f) const
190 {
191 int ret_close = fclose(f);
192 if (ret_close != 0) {
193 TELEPHONY_LOGE("ret_close != 0!");
194 return TELEPHONY_ERR_READ_DATA_FAIL;
195 }
196 return TELEPHONY_SUCCESS;
197 }
198
GetNameByLocale(OperatorNameCust & value)199 std::string OperatorNameUtils::GetNameByLocale(OperatorNameCust &value)
200 {
201 std::string locale = OHOS::Global::I18n::LocaleConfig::GetSystemLocale();
202 TELEPHONY_LOGD("locale is %{public}s", locale.c_str());
203 if (locale == std::string(ITEM_ZH_HANS_CN)) {
204 return value.zhHansCN;
205 }
206 if (locale == std::string(ITEM_ZH_HANT_TW)) {
207 return value.zhHantTW;
208 }
209 if (locale == std::string(ITEM_ZH_HANT_HK)) {
210 return value.zhHantHK;
211 }
212 return value.enLatnUS;
213 }
214
GetCustomName(const std::string & numeric)215 std::string OperatorNameUtils::GetCustomName(const std::string &numeric)
216 {
217 if (!IsInit()) {
218 Init();
219 }
220 TELEPHONY_LOGD("Start");
221 std::unique_lock<std::mutex> lock(mutex_);
222 if (nameArray_.empty()) {
223 TELEPHONY_LOGE("nameArray_ is empty");
224 return "";
225 }
226 for (OperatorNameCust &value : nameArray_) {
227 auto obj = std::find(value.mccMnc.begin(), value.mccMnc.end(), numeric);
228 if (obj != value.mccMnc.end()) {
229 std::string name = GetNameByLocale(value);
230 TELEPHONY_LOGD("Name is %{public}s", name.c_str());
231 return name;
232 }
233 }
234 TELEPHONY_LOGD("Not found name %{public}s", numeric.c_str());
235 return "";
236 }
237 } // namespace Telephony
238 } // namespace OHOS
239