• 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 "locale_config.h"
27 #include "locale_info.h"
28 #include "memory"
29 #include "parameter.h"
30 #include "telephony_errors.h"
31 #include "telephony_log_wrapper.h"
32 
33 namespace OHOS {
34 namespace Telephony {
35 OperatorNameUtils OperatorNameUtils::operatorNameUtils_;
36 const char *PATH = "/etc/telephony/operator_name.json";
37 const char *ITEM_OPERATOR_NAMES = "operator_names";
38 const char *ITEM_PLMN = "mcc_mnc_array";
39 const char *ITEM_ZH_CN = "zh_CN";
40 const char *ITEM_EN_US = "en_US";
41 const char *ITEM_ZH_TW = "zh_TW";
42 const char *ITEM_ZH_HK = "zh_HK";
43 const char *ITEM_ZH_HANS = "zh_Hans";
44 const char *ITEM_ZH_HANT = "zh_Hant";
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_LOGD("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     cJSON *root = cJSON_Parse(content);
89     free(content);
90     content = nullptr;
91     if (root == nullptr) {
92         TELEPHONY_LOGE("json root is error!");
93         return TELEPHONY_ERR_READ_DATA_FAIL;
94     }
95 
96     cJSON *itemRoots = cJSON_GetObjectItem(root, ITEM_OPERATOR_NAMES);
97     if (itemRoots == nullptr || !cJSON_IsArray(itemRoots) || cJSON_GetArraySize(itemRoots) == 0) {
98         TELEPHONY_LOGE("operator name itemRoots is invalid");
99         cJSON_Delete(root);
100         itemRoots = nullptr;
101         root = nullptr;
102         return TELEPHONY_ERR_READ_DATA_FAIL;
103     }
104     ParserOperatorNames(vec, itemRoots);
105     cJSON_Delete(root);
106     itemRoots = nullptr;
107     root = nullptr;
108     return TELEPHONY_SUCCESS;
109 }
110 
LoaderJsonFile(char * & content,const char * path) const111 int32_t OperatorNameUtils::LoaderJsonFile(char *&content, const char *path) const
112 {
113     long len = 0;
114     char realPath[PATH_MAX] = { 0x00 };
115     if (realpath(path, realPath) == nullptr) {
116         return TELEPHONY_ERR_READ_DATA_FAIL;
117     }
118     FILE *f = fopen(realPath, "rb");
119     if (f == nullptr) {
120         return TELEPHONY_ERR_READ_DATA_FAIL;
121     }
122     int ret_seek_end = fseek(f, 0, SEEK_END);
123     if (ret_seek_end != 0) {
124         TELEPHONY_LOGE("ret_seek_end != 0!");
125         CloseFile(f);
126         return TELEPHONY_ERR_READ_DATA_FAIL;
127     }
128     len = ftell(f);
129     int ret_seek_set = fseek(f, 0, SEEK_SET);
130     if (ret_seek_set != 0) {
131         CloseFile(f);
132         return TELEPHONY_ERR_READ_DATA_FAIL;
133     }
134     if (len == 0 || len > static_cast<long>(MAX_BYTE_LEN)) {
135         TELEPHONY_LOGE("len is valid!");
136         CloseFile(f);
137         return TELEPHONY_ERR_READ_DATA_FAIL;
138     }
139     content = static_cast<char *>(malloc(len + 1));
140     if (content == nullptr) {
141         CloseFile(f);
142         return TELEPHONY_ERR_READ_DATA_FAIL;
143     }
144     if (memset_s(content, len + 1, 0, len + 1) != EOK) {
145         TELEPHONY_LOGE("memset_s failed");
146         free(content);
147         content = nullptr;
148         CloseFile(f);
149         return TELEPHONY_ERR_READ_DATA_FAIL;
150     }
151     size_t ret_read = fread(content, 1, len, f);
152     if (ret_read != static_cast<size_t>(len)) {
153         free(content);
154         content = nullptr;
155         CloseFile(f);
156         return TELEPHONY_ERR_READ_DATA_FAIL;
157     }
158     return CloseFile(f);
159 }
160 
ParserOperatorNames(std::vector<OperatorNameCust> & vec,cJSON * itemRoots)161 void OperatorNameUtils::ParserOperatorNames(std::vector<OperatorNameCust> &vec, cJSON *itemRoots)
162 {
163     cJSON *itemRoot = nullptr;
164     cJSON *plmnArray = nullptr;
165     cJSON *arrValue = nullptr;
166     for (int32_t i = 0; i < cJSON_GetArraySize(itemRoots); i++) {
167         itemRoot = cJSON_GetArrayItem(itemRoots, i);
168         if (itemRoot == nullptr) {
169             continue;
170         }
171         OperatorNameCust nameCust;
172         plmnArray = cJSON_GetObjectItem(itemRoot, ITEM_PLMN);
173         if (plmnArray == nullptr || !cJSON_IsArray(plmnArray)) {
174             continue;
175         }
176         for (int32_t j = 0; j < cJSON_GetArraySize(plmnArray); j++) {
177             arrValue = cJSON_GetArrayItem(plmnArray, j);
178             if (arrValue != nullptr && cJSON_IsNumber(arrValue)) {
179                 nameCust.mccMnc.push_back(std::to_string(static_cast<int32_t>(cJSON_GetNumberValue(arrValue))));
180             }
181         }
182 
183         nameCust.zhCN = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_ZH_CN));
184         nameCust.enUS = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_EN_US));
185         nameCust.zhTW = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_ZH_TW));
186         nameCust.zhHK = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_ZH_HK));
187         nameCust.zhHans = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_ZH_HANS));
188         nameCust.zhHant = ParseString(cJSON_GetObjectItem(itemRoot, ITEM_ZH_HANT));
189         vec.push_back(nameCust);
190     }
191     itemRoot = nullptr;
192     plmnArray = nullptr;
193     arrValue = nullptr;
194 }
195 
ParseString(cJSON * value)196 std::string OperatorNameUtils::ParseString(cJSON *value)
197 {
198     if (value != nullptr && value->type == cJSON_String && value->valuestring != nullptr) {
199         return value->valuestring;
200     }
201     return "";
202 }
203 
CloseFile(FILE * f) const204 int32_t OperatorNameUtils::CloseFile(FILE *f) const
205 {
206     int ret_close = fclose(f);
207     if (ret_close != 0) {
208         TELEPHONY_LOGE("ret_close != 0!");
209         return TELEPHONY_ERR_READ_DATA_FAIL;
210     }
211     return TELEPHONY_SUCCESS;
212 }
213 
GetNameByLocale(OperatorNameCust & value)214 std::string OperatorNameUtils::GetNameByLocale(OperatorNameCust &value)
215 {
216     std::string locale = OHOS::Global::I18n::LocaleConfig::GetSystemLocale();
217     OHOS::Global::I18n::LocaleInfo localeInfo(locale);
218     std::string languageCode = localeInfo.GetLanguage() + "_" + localeInfo.GetRegion();
219     std::string countryCodeTempScript = "";
220     if (!(localeInfo.GetScript().empty())) {
221         countryCodeTempScript = localeInfo.GetLanguage() + "_" + localeInfo.GetScript();
222     }
223     TELEPHONY_LOGD("locale is %{public}s, languageCode is %{public}s, countryCodeTempScript is %{public}s",
224         locale.c_str(), languageCode.c_str(), countryCodeTempScript.c_str());
225     if (countryCodeTempScript == std::string(ITEM_ZH_HANS)) {
226         languageCode = std::string(ITEM_ZH_HANS);
227     }
228     if (countryCodeTempScript == std::string(ITEM_ZH_HANT)) {
229         languageCode = std::string(ITEM_ZH_HANT);
230     }
231     if (languageCode == std::string(ITEM_ZH_CN)) {
232         return value.zhCN;
233     }
234     if (languageCode == std::string(ITEM_ZH_TW)) {
235         return value.zhTW;
236     }
237     if (languageCode == std::string(ITEM_ZH_HK)) {
238         return value.zhHK;
239     }
240     if (languageCode == std::string(ITEM_ZH_HANS)) {
241         return value.zhHans;
242     }
243     if (languageCode == std::string(ITEM_ZH_HANT)) {
244         return value.zhHant;
245     }
246     if (languageCode == std::string(ITEM_EN_US)) {
247         return value.enUS;
248     }
249     return value.enUS;
250 }
251 
GetCustomName(const std::string & numeric)252 std::string OperatorNameUtils::GetCustomName(const std::string &numeric)
253 {
254     if (!IsInit()) {
255         Init();
256     }
257     TELEPHONY_LOGD("Start");
258     std::unique_lock<std::mutex> lock(mutex_);
259     if (nameArray_.empty()) {
260         TELEPHONY_LOGE("nameArray_ is empty");
261         return "";
262     }
263     for (OperatorNameCust &value : nameArray_) {
264         auto obj = std::find(value.mccMnc.begin(), value.mccMnc.end(), numeric);
265         if (obj != value.mccMnc.end()) {
266             std::string name = GetNameByLocale(value);
267             TELEPHONY_LOGD("Name is %{public}s", name.c_str());
268             return name;
269         }
270     }
271     TELEPHONY_LOGD("Not found name %{public}s", numeric.c_str());
272     return "";
273 }
274 } // namespace Telephony
275 } // namespace OHOS
276