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)39 OperatorConfig OperatorConfigLoader::LoadOperatorConfig(int32_t slotId)
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     operatorConfigCache_->LoadOperatorConfig(slotId, opc);
54     TELEPHONY_LOGI("LoadOperatorConfig %{public}zu", opc.configValue.size());
55     return opc;
56 }
57 
LoadOpKeyOnMccMnc(int32_t slotId)58 std::string OperatorConfigLoader::LoadOpKeyOnMccMnc(int32_t slotId)
59 {
60     SimState simState = SimState::SIM_STATE_UNKNOWN;
61     CoreManagerInner::GetInstance().GetSimState(slotId, simState);
62     std::shared_ptr<SimFileManager> simFileManager = simFileManager_.lock();
63     if (simFileManager == nullptr ||
64         !(simState == SimState::SIM_STATE_READY || simState == SimState::SIM_STATE_LOADED)) {
65         TELEPHONY_LOGE("LoadOpKeyOnMccMnc simState not ready");
66         return DEFAULT_OPERATOR_KEY;
67     }
68     Uri uri(OPKEY_INFO_URI);
69     std::vector<std::string> colume;
70     DataShare::DataSharePredicates predicates;
71     std::shared_ptr<DataShare::DataShareResultSet> resultSet;
72     std::shared_ptr<DataShare::DataShareHelper> helper = CreateOpKeyHelper();
73     if (helper == nullptr) {
74         TELEPHONY_LOGE("helper is nullptr");
75         return DEFAULT_OPERATOR_KEY;
76     }
77     std::string mccmncFromSim = Str16ToStr8(simFileManager->GetSimOperatorNumeric());
78     if (TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_) {
79         TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_(slotId, mccmncFromSim);
80     }
81     predicates.EqualTo(MCCMNC, mccmncFromSim);
82     resultSet = helper->Query(uri, predicates, colume);
83     if (resultSet != nullptr) {
84         std::string opkey = GetOpKey(resultSet, slotId);
85         helper->Release();
86         return opkey;
87     }
88     helper->Release();
89     return DEFAULT_OPERATOR_KEY;
90 }
91 
InsertOpkeyToSimDb(std::string opKeyValue)92 int OperatorConfigLoader::InsertOpkeyToSimDb(std::string opKeyValue)
93 {
94     if (opKeyValue.empty() || iccidFromSim_.empty()) {
95         TELEPHONY_LOGE("opKeyValue or imsi is null");
96         return Telephony::TELEPHONY_ERR_ARGUMENT_NULL;
97     }
98     std::shared_ptr<DataShare::DataShareHelper> helper = CreateSimHelper();
99     if (helper == nullptr) {
100         TELEPHONY_LOGE("helper is nullptr");
101         return Telephony::TELEPHONY_ERR_LOCAL_PTR_NULL;
102     }
103     DataShare::DataShareValuesBucket values;
104     DataShare::DataShareValueObject valueObj(opKeyValue);
105     values.Put(SimData::OPKEY, valueObj);
106     DataShare::DataSharePredicates predicates;
107     predicates.EqualTo(SimData::ICC_ID, iccidFromSim_);
108     predicates.And();
109     predicates.EqualTo(SimData::IMSI, imsiFromSim_);
110     Uri simUri(SIM_INFO_URI);
111     std::vector<std::string> colume;
112     auto resultSet = helper->Query(simUri, predicates, colume);
113     int rowCount = 0;
114     if (resultSet != nullptr) {
115         resultSet->GetRowCount(rowCount);
116     }
117     int result = 0;
118     if (rowCount > 0) {
119         result = helper->Update(simUri, predicates, values);
120     }
121     helper->Release();
122     return result;
123 }
124 
GetOpKey(std::shared_ptr<DataShare::DataShareResultSet> resultSet,int32_t slotId)125 std::string OperatorConfigLoader::GetOpKey(std::shared_ptr<DataShare::DataShareResultSet> resultSet, int32_t slotId)
126 {
127     if (resultSet == nullptr) {
128         TELEPHONY_LOGE("GetOpKey resultSet is nullptr");
129         return DEFAULT_OPERATOR_KEY;
130     }
131     std::shared_ptr<SimFileManager> simFileManager = simFileManager_.lock();
132     if (simFileManager == nullptr) {
133         TELEPHONY_LOGE("GetOpKey simFileManager is nullptr");
134         return DEFAULT_OPERATOR_KEY;
135     }
136     iccidFromSim_ = Str16ToStr8(simFileManager->GetSimDecIccId());
137     imsiFromSim_ = Str16ToStr8(simFileManager->GetIMSI());
138     spnFromSim_ = Str16ToStr8(simFileManager->GetSimSpn());
139     gid1FromSim_ = Str16ToStr8(simFileManager->GetSimGid1());
140     gid2FromSim_ = Str16ToStr8(simFileManager->GetSimGid2());
141     mccmncFromSim_ = Str16ToStr8(simFileManager->GetSimOperatorNumeric());
142     if (TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_ && TELEPHONY_EXT_WRAPPER.getRoamingBrokerImsi_) {
143         TELEPHONY_EXT_WRAPPER.getRoamingBrokerNumeric_(slotId, mccmncFromSim_);
144         TELEPHONY_EXT_WRAPPER.getRoamingBrokerImsi_(slotId, imsiFromSim_);
145     }
146     std::string opKeyVal = mccmncFromSim_;
147     std::string opNameVal = "COMMON";
148     std::string opKeyExtVal = "";
149     int count;
150     resultSet->GetRowCount(count);
151     TELEPHONY_LOGI("GetOpKey count: %{public}d", count);
152     if (count <= 0) {
153         TELEPHONY_LOGE("GetOpKey count: %{public}d, use MccMnc as opkey, COMMON as opname", count);
154         resultSet->Close();
155         SetMatchResultToSimFileManager(opKeyVal, opNameVal, opKeyExtVal, slotId, simFileManager);
156         return opKeyVal;
157     }
158     int columnIndex;
159     for (int row = 0; row < count; row++) {
160         if (MatchOperatorRule(resultSet, row)) {
161             resultSet->GetColumnIndex(OPKEY, columnIndex);
162             resultSet->GetString(columnIndex, opKeyVal);
163             resultSet->GetColumnIndex(OPNAME, columnIndex);
164             resultSet->GetString(columnIndex, opNameVal);
165             resultSet->GetColumnIndex(OPKEY_EXT, columnIndex);
166             resultSet->GetString(columnIndex, opKeyExtVal);
167         }
168     }
169     resultSet->Close();
170     SetMatchResultToSimFileManager(opKeyVal, opNameVal, opKeyExtVal, slotId, simFileManager);
171     InsertOpkeyToSimDb(opKeyVal);
172     return opKeyVal;
173 }
174 
SetMatchResultToSimFileManager(std::string opKeyVal,std::string opNameVal,std::string opKeyExtVal,int32_t slotId,std::shared_ptr<SimFileManager> simFileManager)175 void OperatorConfigLoader::SetMatchResultToSimFileManager(std::string opKeyVal, std::string opNameVal,
176     std::string opKeyExtVal, int32_t slotId, std::shared_ptr<SimFileManager> simFileManager)
177 {
178     std::string key;
179     SetParameter(key.append(OPKEY_PROP_PREFIX).append(std::to_string(slotId)).c_str(), opKeyVal.c_str());
180     key.shrink_to_fit();
181     simFileManager->SetOpKey(opKeyVal);
182     simFileManager->SetOpName(opNameVal);
183     simFileManager->SetOpKeyExt(opKeyExtVal);
184 }
185 
MatchOperatorRule(std::shared_ptr<DataShare::DataShareResultSet> & resultSet,int row)186 bool OperatorConfigLoader::MatchOperatorRule(std::shared_ptr<DataShare::DataShareResultSet> &resultSet, int row)
187 {
188     if (resultSet == nullptr) {
189         TELEPHONY_LOGE("resultSet is nullptr");
190         return false;
191     }
192     bool isAllRuleMatch = true;
193     int columnIndex;
194     std::string strVal;
195     resultSet->GoToRow(row);
196     resultSet->GetColumnIndex(ICCID, columnIndex);
197     resultSet->GetString(columnIndex, strVal);
198     if (!strVal.empty()) {
199         isAllRuleMatch = OperatorMatchingRule::IccidRegexMatch(iccidFromSim_, strVal);
200     }
201     if (!isAllRuleMatch) {
202         return false;
203     }
204     resultSet->GetColumnIndex(IMSI, columnIndex);
205     resultSet->GetString(columnIndex, strVal);
206     if (!strVal.empty()) {
207         isAllRuleMatch = OperatorMatchingRule::ImsiRegexMatch(imsiFromSim_, strVal);
208     }
209     if (!isAllRuleMatch) {
210         return false;
211     }
212     resultSet->GetColumnIndex(SPN, columnIndex);
213     resultSet->GetString(columnIndex, strVal);
214     if (!strVal.empty()) {
215         isAllRuleMatch = OperatorMatchingRule::SpnRegexMatch(spnFromSim_, strVal);
216     }
217     if (!isAllRuleMatch) {
218         return false;
219     }
220     resultSet->GetColumnIndex(GID1, columnIndex);
221     resultSet->GetString(columnIndex, strVal);
222     if (!strVal.empty()) {
223         isAllRuleMatch = OperatorMatchingRule::PrefixMatch(gid1FromSim_, strVal);
224     }
225     if (!isAllRuleMatch) {
226         return false;
227     }
228     resultSet->GetColumnIndex(GID2, columnIndex);
229     resultSet->GetString(columnIndex, strVal);
230     if (!strVal.empty()) {
231         isAllRuleMatch = OperatorMatchingRule::PrefixMatch(gid2FromSim_, strVal);
232     }
233     return isAllRuleMatch;
234 }
235 
CreateOpKeyHelper() const236 std::shared_ptr<DataShare::DataShareHelper> OperatorConfigLoader::CreateOpKeyHelper() const
237 {
238     TELEPHONY_LOGI("OperatorConfigLoader::CreateOpKeyHelper");
239     auto helper = TelephonyDataHelper::GetInstance();
240     if (helper == nullptr) {
241         TELEPHONY_LOGE("get CreateOpKeyHelper Failed.");
242         return nullptr;
243     }
244     return helper->CreateOpKeyHelper();
245 }
246 
CreateSimHelper() const247 std::shared_ptr<DataShare::DataShareHelper> OperatorConfigLoader::CreateSimHelper() const
248 {
249     TELEPHONY_LOGI("OperatorConfigLoader::CreateSimHelper");
250     auto helper = TelephonyDataHelper::GetInstance();
251     if (helper == nullptr) {
252         TELEPHONY_LOGE("get CreateSimHelper Failed.");
253         return nullptr;
254     }
255     return helper->CreateSimHelper();
256 }
257 } // namespace Telephony
258 } // namespace OHOS
259