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_config_loader.h"
17
18 #include <string_ex.h>
19 #include "sim_data.h"
20 #include "telephony_data_helper.h"
21 #include "core_manager_inner.h"
22 #include "operator_matching_rule.h"
23 #include "sim_state_type.h"
24 #include "telephony_types.h"
25 #include "telephony_errors.h"
26 #include "telephony_ext_wrapper.h"
27
28 namespace OHOS {
29 namespace Telephony {
OperatorConfigLoader(std::weak_ptr<SimFileManager> simFileManager,std::shared_ptr<OperatorConfigCache> operatorConfigCache)30 OperatorConfigLoader::OperatorConfigLoader(
31 std::weak_ptr<SimFileManager> simFileManager, std::shared_ptr<OperatorConfigCache> operatorConfigCache)
32 : simFileManager_(simFileManager), operatorConfigCache_(operatorConfigCache)
33 {
34 TELEPHONY_LOGI("OperatorConfigLoader construct");
35 }
36
~OperatorConfigLoader()37 OperatorConfigLoader::~OperatorConfigLoader() {}
38
LoadOperatorConfig(int32_t slotId,int32_t state)39 OperatorConfig OperatorConfigLoader::LoadOperatorConfig(int32_t slotId, int32_t state)
40 {
41 OperatorConfig opc;
42 if (operatorConfigCache_ == nullptr) {
43 TELEPHONY_LOGE("operatorConfigCache_ is nullptr");
44 return opc;
45 }
46 bool isNeedLoad = operatorConfigCache_->IsNeedOperatorLoad(slotId);
47 TELEPHONY_LOGI("LoadOperatorConfig slotId: %{public}d isNeedLoad: %{public}d", slotId, isNeedLoad);
48 if (!isNeedLoad) {
49 return opc;
50 }
51 TELEPHONY_LOGI("LoadOperatorConfig slotId %{public}d", slotId);
52 std::string opkey = LoadOpKeyOnMccMnc(slotId);
53 if (opkey == DEFAULT_OPERATOR_KEY) {
54 state = operatorConfigCache_->STATE_PARA_CLEAR;
55 }
56 operatorConfigCache_->LoadOperatorConfig(slotId, opc, state);
57 TELEPHONY_LOGI("LoadOperatorConfig %{public}zu, slotId: %{public}d, opkey: %{public}s, state: %{public}d",
58 opc.configValue.size(), slotId, opkey.data(), state);
59 return opc;
60 }
61
LoadOpKeyOnMccMnc(int32_t slotId)62 std::string OperatorConfigLoader::LoadOpKeyOnMccMnc(int32_t slotId)
63 {
64 SimState simState = SimState::SIM_STATE_UNKNOWN;
65 CoreManagerInner::GetInstance().GetSimState(slotId, simState);
66 std::shared_ptr<SimFileManager> simFileManager = simFileManager_.lock();
67 if (simFileManager == nullptr ||
68 !(simState == SimState::SIM_STATE_READY || simState == SimState::SIM_STATE_LOADED)) {
69 TELEPHONY_LOGE("LoadOpKeyOnMccMnc simState not ready");
70 return DEFAULT_OPERATOR_KEY;
71 }
72 Uri uri(OPKEY_INFO_URI);
73 std::vector<std::string> colume;
74 DataShare::DataSharePredicates predicates;
75 std::shared_ptr<DataShare::DataShareResultSet> resultSet;
76 std::shared_ptr<DataShare::DataShareHelper> helper = CreateOpKeyHelper();
77 if (helper == nullptr) {
78 TELEPHONY_LOGE("helper is nullptr");
79 return DEFAULT_OPERATOR_KEY;
80 }
81 std::string mccmncFromSim = Str16ToStr8(simFileManager->GetSimOperatorNumeric());
82 if (TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_) {
83 TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_(slotId, mccmncFromSim);
84 }
85 predicates.EqualTo(MCCMNC, mccmncFromSim);
86 resultSet = helper->Query(uri, predicates, colume);
87 if (resultSet != nullptr) {
88 std::string opkey = GetOpKey(resultSet, slotId);
89 helper->Release();
90 return opkey;
91 }
92 helper->Release();
93 return DEFAULT_OPERATOR_KEY;
94 }
95
InsertOpkeyToSimDb(std::string opKeyValue,std::string mccVal,std::string mncVal,std::string imsiVal)96 int OperatorConfigLoader::InsertOpkeyToSimDb(
97 std::string opKeyValue, std::string mccVal, std::string mncVal, std::string imsiVal)
98 {
99 if (opKeyValue.empty() || iccidFromSim_.empty()) {
100 TELEPHONY_LOGE("opKeyValue or iccid is null");
101 return Telephony::TELEPHONY_ERR_ARGUMENT_NULL;
102 }
103 std::shared_ptr<DataShare::DataShareHelper> helper = CreateSimHelper();
104 if (helper == nullptr) {
105 TELEPHONY_LOGE("helper is nullptr");
106 return Telephony::TELEPHONY_ERR_LOCAL_PTR_NULL;
107 }
108 DataShare::DataShareValuesBucket values;
109 DataShare::DataShareValueObject opkeyObj(opKeyValue);
110 DataShare::DataShareValueObject mccObj(mccVal);
111 DataShare::DataShareValueObject mncObj(mncVal);
112 DataShare::DataShareValueObject imsiObj(imsiVal);
113 values.Put(SimData::OPKEY, opkeyObj);
114 values.Put(SimData::MCC, mccObj);
115 values.Put(SimData::MNC, mncObj);
116 values.Put(SimData::IMSI, imsiObj);
117 DataShare::DataSharePredicates predicates;
118 predicates.EqualTo(SimData::ICC_ID, iccidFromSim_);
119 Uri simUri(SIM_INFO_URI);
120 std::vector<std::string> colume;
121 auto resultSet = helper->Query(simUri, predicates, colume);
122 int rowCount = 0;
123 if (resultSet != nullptr) {
124 resultSet->GetRowCount(rowCount);
125 }
126 int result = 0;
127 if (rowCount > 0) {
128 result = helper->Update(simUri, predicates, values);
129 }
130 helper->Release();
131 TELEPHONY_LOGI("InsertOpkeyToSimDb result is %{public}d, Opkey is: %{public}s", result, opKeyValue.data());
132 return result;
133 }
134
GetOpKey(std::shared_ptr<DataShare::DataShareResultSet> resultSet,int32_t slotId)135 std::string OperatorConfigLoader::GetOpKey(std::shared_ptr<DataShare::DataShareResultSet> resultSet, int32_t slotId)
136 {
137 if (resultSet == nullptr) {
138 TELEPHONY_LOGE("GetOpKey resultSet is nullptr");
139 return DEFAULT_OPERATOR_KEY;
140 }
141 std::shared_ptr<SimFileManager> simFileManager = simFileManager_.lock();
142 if (simFileManager == nullptr) {
143 TELEPHONY_LOGE("GetOpKey simFileManager is nullptr");
144 return DEFAULT_OPERATOR_KEY;
145 }
146 iccidFromSim_ = Str16ToStr8(simFileManager->GetSimDecIccId());
147 imsiFromSim_ = Str16ToStr8(simFileManager->GetIMSI());
148 spnFromSim_ = Str16ToStr8(simFileManager->GetSimSpn());
149 gid1FromSim_ = Str16ToStr8(simFileManager->GetSimGid1());
150 gid2FromSim_ = Str16ToStr8(simFileManager->GetSimGid2());
151 mccmncFromSim_ = Str16ToStr8(simFileManager->GetSimOperatorNumeric());
152 if (TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_ && TELEPHONY_EXT_WRAPPER.getRoamingBrokerImsi_) {
153 TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_(slotId, mccmncFromSim_);
154 TELEPHONY_EXT_WRAPPER.getRoamingBrokerImsi_(slotId, imsiFromSim_);
155 }
156 std::string opKeyVal = mccmncFromSim_;
157 std::string opNameVal = "COMMON";
158 std::string opKeyExtVal = "";
159 int count;
160 resultSet->GetRowCount(count);
161 TELEPHONY_LOGI("GetOpKey count: %{public}d", count);
162 if (count <= 0) {
163 TELEPHONY_LOGE("GetOpKey count: %{public}d, use MccMnc as opkey, COMMON as opname", count);
164 resultSet->Close();
165 SetMatchResultToSimFileManager(opKeyVal, opNameVal, opKeyExtVal, slotId, simFileManager);
166 InsertOpkeyToSimDb(opKeyVal, GetMccFromMccMnc(mccmncFromSim_), GetMncFromMccMnc(mccmncFromSim_), imsiFromSim_);
167 return opKeyVal;
168 }
169 int columnIndex;
170 for (int row = 0; row < count; row++) {
171 if (MatchOperatorRule(resultSet, row)) {
172 resultSet->GetColumnIndex(OPKEY, columnIndex);
173 resultSet->GetString(columnIndex, opKeyVal);
174 resultSet->GetColumnIndex(OPNAME, columnIndex);
175 resultSet->GetString(columnIndex, opNameVal);
176 resultSet->GetColumnIndex(OPKEY_EXT, columnIndex);
177 resultSet->GetString(columnIndex, opKeyExtVal);
178 }
179 }
180 resultSet->Close();
181 SetMatchResultToSimFileManager(opKeyVal, opNameVal, opKeyExtVal, slotId, simFileManager);
182 InsertOpkeyToSimDb(opKeyVal, GetMccFromMccMnc(mccmncFromSim_), GetMncFromMccMnc(mccmncFromSim_), imsiFromSim_);
183 return opKeyVal;
184 }
185
GetMccFromMccMnc(std::string mccmnc)186 std::string OperatorConfigLoader::GetMccFromMccMnc(std::string mccmnc)
187 {
188 if (static_cast<int>(mccmnc.size()) < MCCMNC_SHORT_LEN || static_cast<int>(mccmnc.size()) > MCCMNC_LONG_LEN) {
189 TELEPHONY_LOGE("invalid mccmnc, mccmnc is %{public}s", mccmnc.data());
190 return "";
191 }
192 return mccmnc.substr(0, MCC_LEN);
193 }
194
GetMncFromMccMnc(std::string mccmnc)195 std::string OperatorConfigLoader::GetMncFromMccMnc(std::string mccmnc)
196 {
197 if (static_cast<int>(mccmnc.size()) < MCCMNC_SHORT_LEN || static_cast<int>(mccmnc.size()) > MCCMNC_LONG_LEN) {
198 TELEPHONY_LOGE("invalid mccmnc, mccmnc is %{public}s", mccmnc.data());
199 return "";
200 }
201 return mccmnc.substr(MCC_LEN);
202 }
203
SetMatchResultToSimFileManager(std::string opKeyVal,std::string opNameVal,std::string opKeyExtVal,int32_t slotId,std::shared_ptr<SimFileManager> simFileManager)204 void OperatorConfigLoader::SetMatchResultToSimFileManager(std::string opKeyVal, std::string opNameVal,
205 std::string opKeyExtVal, int32_t slotId, std::shared_ptr<SimFileManager> simFileManager)
206 {
207 std::string key;
208 SetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), opKeyVal.c_str());
209 key.shrink_to_fit();
210 simFileManager->SetOpKey(opKeyVal);
211 simFileManager->SetOpName(opNameVal);
212 simFileManager->SetOpKeyExt(opKeyExtVal);
213 }
214
MatchOperatorRule(std::shared_ptr<DataShare::DataShareResultSet> & resultSet,int row)215 bool OperatorConfigLoader::MatchOperatorRule(std::shared_ptr<DataShare::DataShareResultSet> &resultSet, int row)
216 {
217 if (resultSet == nullptr) {
218 TELEPHONY_LOGE("resultSet is nullptr");
219 return false;
220 }
221 bool isAllRuleMatch = true;
222 int columnIndex;
223 std::string strVal;
224 resultSet->GoToRow(row);
225 resultSet->GetColumnIndex(ICCID, columnIndex);
226 resultSet->GetString(columnIndex, strVal);
227 if (!strVal.empty()) {
228 isAllRuleMatch = OperatorMatchingRule::IccidRegexMatch(iccidFromSim_, strVal);
229 }
230 if (!isAllRuleMatch) {
231 return false;
232 }
233 resultSet->GetColumnIndex(IMSI, columnIndex);
234 resultSet->GetString(columnIndex, strVal);
235 if (!strVal.empty()) {
236 isAllRuleMatch = OperatorMatchingRule::ImsiRegexMatch(imsiFromSim_, strVal);
237 }
238 if (!isAllRuleMatch) {
239 return false;
240 }
241 resultSet->GetColumnIndex(SPN, columnIndex);
242 resultSet->GetString(columnIndex, strVal);
243 if (!strVal.empty()) {
244 isAllRuleMatch = OperatorMatchingRule::SpnRegexMatch(spnFromSim_, strVal);
245 }
246 if (!isAllRuleMatch) {
247 return false;
248 }
249 resultSet->GetColumnIndex(GID1, columnIndex);
250 resultSet->GetString(columnIndex, strVal);
251 if (!strVal.empty()) {
252 isAllRuleMatch = OperatorMatchingRule::PrefixMatch(gid1FromSim_, strVal);
253 }
254 if (!isAllRuleMatch) {
255 return false;
256 }
257 resultSet->GetColumnIndex(GID2, columnIndex);
258 resultSet->GetString(columnIndex, strVal);
259 if (!strVal.empty()) {
260 isAllRuleMatch = OperatorMatchingRule::PrefixMatch(gid2FromSim_, strVal);
261 }
262 return isAllRuleMatch;
263 }
264
CreateOpKeyHelper() const265 std::shared_ptr<DataShare::DataShareHelper> OperatorConfigLoader::CreateOpKeyHelper() const
266 {
267 TELEPHONY_LOGI("OperatorConfigLoader::CreateOpKeyHelper");
268 auto helper = TelephonyDataHelper::GetInstance();
269 if (helper == nullptr) {
270 TELEPHONY_LOGE("get CreateOpKeyHelper Failed.");
271 return nullptr;
272 }
273 return helper->CreateOpKeyHelper(TelephonyDataHelper::DB_CONNECT_MAX_WAIT_TIME);
274 }
275
CreateSimHelper() const276 std::shared_ptr<DataShare::DataShareHelper> OperatorConfigLoader::CreateSimHelper() const
277 {
278 TELEPHONY_LOGI("OperatorConfigLoader::CreateSimHelper");
279 auto helper = TelephonyDataHelper::GetInstance();
280 if (helper == nullptr) {
281 TELEPHONY_LOGE("get CreateSimHelper Failed.");
282 return nullptr;
283 }
284 return helper->CreateSimHelper();
285 }
286 } // namespace Telephony
287 } // namespace OHOS
288