• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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