• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "apn_utils.h"
17 
18 #include <algorithm>
19 #include "parameters.h"
20 #include "edm_errors.h"
21 #include "edm_log.h"
22 #include "pdp_profile_data.h"
23 #include "core_service_client.h"
24 #include "edm_sys_manager.h"
25 #include "system_ability_definition.h"
26 
27 namespace OHOS {
28 namespace EDM {
29 using namespace Telephony;
30 namespace {
31 constexpr const char *PDP_PROFILE_BASE_URI = "datashare:///com.ohos.pdpprofileability";
32 constexpr const char *PDP_PROFILE_URI = "datashare:///com.ohos.pdpprofileability/net/pdp_profile";
33 constexpr const char *PDP_PROFILE_PREFER_URI = "datashare:///com.ohos.pdpprofileability/net/pdp_profile/preferapn";
34 constexpr const char *OPKEY_BASE_URI = "datashare:///com.ohos.opkeyability";
35 constexpr const char *OPKEY_URI = "datashare:///com.ohos.opkeyability/opkey/opkey_info";
36 constexpr int32_t SIM_SLOT_ZERO = 0;
37 constexpr int32_t SIM_SLOT_ONE = 1;
38 }
39 
CreatePdpProfileAbilityHelper()40 std::shared_ptr<DataShare::DataShareHelper> ApnUtils::CreatePdpProfileAbilityHelper()
41 {
42     EDMLOGI("Create pdp profile ability helper");
43     sptr<IRemoteObject> remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(ENTERPRISE_DEVICE_MANAGER_SA_ID);
44     return DataShare::DataShareHelper::Creator(remoteObject, PDP_PROFILE_BASE_URI);
45 }
46 
CreateOpkeyAbilityHelper()47 std::shared_ptr<DataShare::DataShareHelper> ApnUtils::CreateOpkeyAbilityHelper()
48 {
49     EDMLOGI("Create opkey ability helper");
50     sptr<IRemoteObject> remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(ENTERPRISE_DEVICE_MANAGER_SA_ID);
51     return DataShare::DataShareHelper::Creator(remoteObject, OPKEY_BASE_URI);
52 }
53 
GetOpkey(const std::string & mccmnc,std::string & opkey)54 int32_t ApnUtils::GetOpkey(const std::string &mccmnc, std::string &opkey)
55 {
56     EDMLOGI("ApnUtils::GetOpkey start");
57     auto helper = CreateOpkeyAbilityHelper();
58     if (helper == nullptr) {
59         EDMLOGE("GetOpkey helper get failed");
60         return -1;
61     }
62     DataShare::DataSharePredicates predicates;
63     predicates.EqualTo(PdpProfileData::MCCMNC, mccmnc);
64     Uri uri((OPKEY_URI));
65     std::vector<std::string> columns;
66     std::shared_ptr<DataShare::DataShareResultSet> queryResult = helper->Query(uri, predicates, columns);
67     if (queryResult == nullptr) {
68         EDMLOGE("GetOpkey error");
69         return -1;
70     }
71 
72     if (queryResult->GoToRow(0) != DataShare::E_OK) {
73         EDMLOGE("GetOpkey GoToRow error");
74         queryResult->Close();
75         return -1;
76     }
77 
78     int32_t columnIndex = -1;
79     if (queryResult->GetColumnIndex("operator_key", columnIndex) != DataShare::E_OK ||
80         queryResult->GetString(columnIndex, opkey) != DataShare::E_OK) {
81         return -1;
82     }
83     EDMLOGI("ApnUtils::GetOpkey opkey=%{public}s", opkey.c_str());
84     return 0;
85 }
86 
ApnInsert(const std::map<std::string,std::string> & apnInfo,const ApnUtilsPassword & apnUtilsPassword)87 int32_t ApnUtils::ApnInsert(const std::map<std::string, std::string> &apnInfo,
88     const ApnUtilsPassword &apnUtilsPassword)
89 {
90     EDMLOGI("ApnUtils::ApnInsert start");
91     auto helper = CreatePdpProfileAbilityHelper();
92     if (helper == nullptr) {
93         EDMLOGE("ApnInsert helper get failed");
94         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
95     }
96     DataShare::DataShareValuesBucket values;
97     for (const auto & [key, value] : apnInfo) {
98         values.Put(key, value);
99     }
100     if (apnUtilsPassword.password != nullptr) {
101         values.Put("auth_pwd", std::string(apnUtilsPassword.password, apnUtilsPassword.passwordSize));
102     }
103     std::string mccmnc = apnInfo.at(PdpProfileData::MCC) + apnInfo.at(PdpProfileData::MNC);
104     values.Put(PdpProfileData::MCCMNC, mccmnc);
105     std::string opkey;
106     if (GetOpkey(mccmnc, opkey) == ERR_OK && !opkey.empty()) {
107         values.Put(PdpProfileData::OPKEY, opkey);
108     } else {
109         values.Put(PdpProfileData::OPKEY, mccmnc);
110     }
111     Uri uri((PDP_PROFILE_URI));
112     return helper->Insert(uri, values) >= DataShare::E_OK ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
113 }
114 
ApnDelete(const std::string & apnId)115 int32_t ApnUtils::ApnDelete(const std::string &apnId)
116 {
117     EDMLOGI("ApnUtils::ApnDelete start");
118     auto helper = CreatePdpProfileAbilityHelper();
119     if (helper == nullptr) {
120         EDMLOGE("ApnDelete helper get failed");
121         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
122     }
123     DataShare::DataSharePredicates predicates;
124     predicates.EqualTo(PdpProfileData::PROFILE_ID, apnId);
125     Uri uri((PDP_PROFILE_URI));
126     return helper->Delete(uri, predicates) == DataShare::E_OK ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
127 }
128 
ApnUpdate(const std::map<std::string,std::string> & apnInfo,const std::string & apnId,const ApnUtilsPassword & apnUtilsPassword)129 int32_t ApnUtils::ApnUpdate(const std::map<std::string, std::string> &apnInfo, const std::string &apnId,
130     const ApnUtilsPassword &apnUtilsPassword)
131 {
132     EDMLOGI("ApnUtils::ApnUpdate start");
133     auto helper = CreatePdpProfileAbilityHelper();
134     if (helper == nullptr) {
135         EDMLOGE("ApnUpdate helper get failed");
136         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
137     }
138 
139     DataShare::DataShareValuesBucket values;
140     for (const auto & [key, value] : apnInfo) {
141         values.Put(key, value);
142     }
143     if (apnUtilsPassword.password != nullptr) {
144         values.Put("auth_pwd", std::string(apnUtilsPassword.password, apnUtilsPassword.passwordSize));
145     }
146 
147     std::string mccmnc;
148     if (apnInfo.find(PdpProfileData::MCC) != apnInfo.end() && apnInfo.find(PdpProfileData::MNC) != apnInfo.end()) {
149         mccmnc = apnInfo.at(PdpProfileData::MCC) + apnInfo.at(PdpProfileData::MNC);
150     } else if (apnInfo.find(PdpProfileData::MCC) != apnInfo.end()) {
151         mccmnc = apnInfo.at(PdpProfileData::MCC) + ApnQuery(apnId)[PdpProfileData::MNC];
152     } else if (apnInfo.find(PdpProfileData::MNC) != apnInfo.end()) {
153         mccmnc = ApnQuery(apnId)[PdpProfileData::MCC] + apnInfo.at(PdpProfileData::MNC);
154     }
155 
156     if (apnInfo.find(PdpProfileData::MCC) != apnInfo.end() || apnInfo.find(PdpProfileData::MNC) != apnInfo.end()) {
157         values.Put(PdpProfileData::MCCMNC, mccmnc);
158         std::string opkey;
159         if (GetOpkey(mccmnc, opkey) == ERR_OK && !opkey.empty()) {
160             values.Put(PdpProfileData::OPKEY, opkey);
161         } else {
162             values.Put(PdpProfileData::OPKEY, mccmnc);
163         }
164     }
165     DataShare::DataSharePredicates predicates;
166     predicates.EqualTo(PdpProfileData::PROFILE_ID, apnId);
167     Uri uri((PDP_PROFILE_URI));
168     return helper->Update(uri, predicates, values) == DataShare::E_OK ? ERR_OK : EdmReturnErrCode::SYSTEM_ABNORMALLY;
169 }
170 
ApnQuery(const std::map<std::string,std::string> & apnInfo)171 std::vector<std::string> ApnUtils::ApnQuery(const std::map<std::string, std::string> &apnInfo)
172 {
173     EDMLOGI("ApnUtils::ApnQueryId start");
174     auto helper = CreatePdpProfileAbilityHelper();
175     std::vector<std::string> result;
176     ApnQueryVector(helper, apnInfo, result);
177     return result;
178 }
179 
ApnQueryVector(std::shared_ptr<DataShare::DataShareHelper> helper,const std::map<std::string,std::string> & apnInfo,std::vector<std::string> & result)180 void ApnUtils::ApnQueryVector(std::shared_ptr<DataShare::DataShareHelper> helper,
181     const std::map<std::string, std::string> &apnInfo, std::vector<std::string> &result)
182 {
183     if (helper == nullptr) {
184         EDMLOGE("ApnQueryVector helper get failed");
185         return;
186     }
187     std::vector<std::string> columns;
188     DataShare::DataSharePredicates predicates;
189     for (const auto & [key, value] : apnInfo) {
190         predicates.EqualTo(key, value);
191     }
192     Uri uri((PDP_PROFILE_URI));
193     std::shared_ptr<DataShare::DataShareResultSet> queryResult = helper->Query(uri, predicates, columns);
194     if (queryResult == nullptr) {
195         EDMLOGE("QueryApnId error");
196         return;
197     }
198     int32_t rowCnt = 0;
199     queryResult->GetRowCount(rowCnt);
200     for (int32_t rowIdx = 0; rowIdx < rowCnt; ++rowIdx) {
201         if (queryResult->GoToRow(rowIdx)) {
202             EDMLOGE("ApnQueryVector GoToRow error");
203             queryResult->Close();
204             return;
205         }
206         int32_t apnIdIdx = -1;
207         queryResult->GetColumnIndex(PdpProfileData::PROFILE_ID, apnIdIdx);
208         int32_t apnId = -1;
209         queryResult->GetInt(apnIdIdx, apnId);
210         bool needInsert = !std::any_of(result.begin(), result.end(), [apnId](const auto &ele) {
211             return ele == std::to_string(apnId);
212         });
213         if (needInsert) {
214             result.push_back(std::to_string(apnId));
215         }
216     }
217     queryResult->Close();
218 }
219 
ApnQuery(const std::string & apnId)220 std::map<std::string, std::string> ApnUtils::ApnQuery(const std::string &apnId)
221 {
222     EDMLOGI("ApnUtils::ApnQueryInfo start");
223     auto helper = CreatePdpProfileAbilityHelper();
224 
225     std::map<std::string, std::string> results;
226     int32_t queryResult = ApnQueryResultSet(helper, apnId, results);
227     if (queryResult < 0) {
228         EDMLOGE("QueryApnInfo error");
229         return {};
230     }
231 
232     return results;
233 }
234 
ApnQueryResultSet(std::shared_ptr<DataShare::DataShareHelper> helper,const std::string & apnId,std::map<std::string,std::string> & results)235 int32_t ApnUtils::ApnQueryResultSet(std::shared_ptr<DataShare::DataShareHelper> helper, const std::string &apnId,
236     std::map<std::string, std::string> &results)
237 {
238     if (helper == nullptr) {
239         EDMLOGE("ApnQueryResultSet helper get failed");
240         return -1;
241     }
242     std::vector<std::string> columns;
243     DataShare::DataSharePredicates predicates;
244     predicates.EqualTo(PdpProfileData::PROFILE_ID, apnId);
245     Uri uri((PDP_PROFILE_URI));
246     std::shared_ptr<DataShare::DataShareResultSet> queryResult = helper->Query(uri, predicates, columns);
247     if (queryResult == nullptr) {
248         EDMLOGE("QueryApnResultSet error");
249         return -1;
250     }
251 
252     int32_t rowCnt = 0;
253     queryResult->GetRowCount(rowCnt);
254     EDMLOGI("ApnQuery rowCnt: %{public}d", rowCnt);
255     if (rowCnt <= 0) {
256         queryResult->Close();
257         return ERR_OK;
258     }
259 
260     if (queryResult->GoToRow(0) != DataShare::E_OK) {
261         EDMLOGE("ApnQuery GoToRow error");
262         queryResult->Close();
263         return -1;
264     }
265     int32_t columnCnt = -1;
266     queryResult->GetColumnCount(columnCnt);
267     for (int32_t idx = 0; idx < columnCnt; ++idx) {
268         std::string columnName;
269         queryResult->GetColumnName(idx, columnName);
270         DataShare::DataType dataType;
271         queryResult->GetDataType(idx, dataType);
272         if (dataType == DataShare::DataType::TYPE_INTEGER) {
273             int32_t value;
274             queryResult->GetInt(idx, value);
275             results[columnName] = std::to_string(value);
276         } else if (dataType == DataShare::DataType::TYPE_STRING) {
277             queryResult->GetString(idx, results[columnName]);
278         }
279     }
280     queryResult->Close();
281     return ERR_OK;
282 }
283 
MatchValidSimId(const std::string & opkey,int32_t slotId)284 int32_t ApnUtils::MatchValidSimId(const std::string &opkey, int32_t slotId)
285 {
286     std::string sysOpkey = system::GetParameter(std::string("telephony.sim.opkey") + std::to_string(slotId), "");
287     if (opkey != sysOpkey) {
288         return -1;
289     }
290     if (!Telephony::CoreServiceClient::GetInstance().IsSimActive(slotId)) {
291         return -1;
292     }
293     int32_t simId = Telephony::CoreServiceClient::GetInstance().GetSimId(slotId);
294     if (simId <= 0) {
295         return -1;
296     }
297     return simId;
298 }
299 
GetValidSimId(const std::string & apnId)300 int32_t ApnUtils::GetValidSimId(const std::string &apnId)
301 {
302     std::string opkey;
303     if (GetOpkey(ApnQuery(apnId)[PdpProfileData::MCCMNC], opkey) != ERR_OK || opkey.empty()) {
304         return -1;
305     }
306 
307     int32_t slotId = Telephony::CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
308     int32_t simId = MatchValidSimId(opkey, slotId);
309     if (simId > 0) {
310         return simId;
311     }
312 
313     simId = MatchValidSimId(opkey, slotId == SIM_SLOT_ONE ? SIM_SLOT_ZERO : SIM_SLOT_ONE);
314     if (simId > 0) {
315         return simId;
316     }
317     return -1;
318 }
319 
ApnSetPrefer(const std::string & apnId)320 int32_t ApnUtils::ApnSetPrefer(const std::string &apnId)
321 {
322     EDMLOGI("ApnUtils::ApnSetPrefer start");
323 
324     auto helper = CreatePdpProfileAbilityHelper();
325     if (helper == nullptr) {
326         EDMLOGE("ApnSetPrefer helper get failed");
327         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
328     }
329 
330     int32_t simId = GetValidSimId(apnId);
331     if (simId < 0) {
332         EDMLOGE("ApnUtils::ApnSetPrefer get failed");
333         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
334     }
335 
336     char* pResult = nullptr;
337     const int32_t apnIdInt = static_cast<int32_t>(std::strtol(apnId.c_str(), &pResult, 10));
338     if (apnId.c_str() == pResult) {
339         EDMLOGE("ApnUtils::ApnSetPrefer failed to convert type");
340         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
341     }
342     DataShare::DataSharePredicates predicates;
343     DataShare::DataShareValuesBucket values;
344     double profileIdAsDouble = static_cast<double>(apnIdInt);
345     double simIdAsDouble = static_cast<double>(simId);
346     values.Put(PdpProfileData::PROFILE_ID, profileIdAsDouble);
347     values.Put(PdpProfileData::SIM_ID, simIdAsDouble);
348     Uri preferApnUri(PDP_PROFILE_PREFER_URI);
349     int32_t result = helper->Update(preferApnUri, predicates, values);
350     if (result < DataShare::E_OK) {
351         EDMLOGE("SetPreferApn fail! result:%{public}d", result);
352         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
353     }
354     EDMLOGI("SetPreferApn result:%{public}d", result);
355     return ERR_OK;
356 }
357 } // namespace EDM
358 } // namespace OHOS