1 /*
2  * Copyright (C) 2021-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 "rdb_pdp_profile_helper.h"
17 
18 #include "data_storage_errors.h"
19 #include "data_storage_log_wrapper.h"
20 #include "parser_util.h"
21 #include "pdp_profile_data.h"
22 #include "preferences_util.h"
23 #include "rdb_errno.h"
24 #include "rdb_pdp_profile_callback.h"
25 #include "rdb_store_config.h"
26 #include "values_bucket.h"
27 #include "vector"
28 
29 namespace OHOS {
30 namespace Telephony {
RdbPdpProfileHelper()31 RdbPdpProfileHelper::RdbPdpProfileHelper() {}
32 
Init()33 int RdbPdpProfileHelper::Init()
34 {
35     int errCode = NativeRdb::E_OK;
36     NativeRdb::RdbStoreConfig config(dbPath_);
37     config.SetJournalMode(NativeRdb::JournalMode::MODE_TRUNCATE);
38     std::string pdpProfileStr;
39     CreatePdpProfileTableStr(pdpProfileStr, TABLE_PDP_PROFILE);
40     std::vector<std::string> createTableVec;
41     createTableVec.push_back(pdpProfileStr);
42     RdbPdpProfileCallback callback(createTableVec);
43     CreateRdbStore(config, VERSION, callback, errCode);
44     return errCode;
45 }
46 
UpdateDbPath(const std::string & path)47 void RdbPdpProfileHelper::UpdateDbPath(const std::string &path)
48 {
49     dbPath_ = path + DB_NAME;
50 }
51 
CreatePdpProfileTableStr(std::string & createTableStr,const std::string & tableName)52 void RdbPdpProfileHelper::CreatePdpProfileTableStr(std::string &createTableStr, const std::string &tableName)
53 {
54     createTableStr.append("CREATE TABLE IF NOT EXISTS ").append(tableName).append("(");
55     createTableStr.append(PdpProfileData::PROFILE_ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT, ");
56     createTableStr.append(PdpProfileData::PROFILE_NAME).append(" TEXT DEFAULT '', ");
57     createTableStr.append(PdpProfileData::MCC).append(" TEXT DEFAULT '', ");
58     createTableStr.append(PdpProfileData::MNC).append(" TEXT DEFAULT '', ");
59     createTableStr.append(PdpProfileData::MCCMNC).append(" TEXT DEFAULT '', ");
60     createTableStr.append(PdpProfileData::APN).append(" TEXT DEFAULT '', ");
61     createTableStr.append(PdpProfileData::AUTH_TYPE).append(" INTEGER, ");
62     createTableStr.append(PdpProfileData::AUTH_USER).append(" TEXT DEFAULT '', ");
63     createTableStr.append(PdpProfileData::AUTH_PWD).append(" TEXT DEFAULT '', ");
64     createTableStr.append(PdpProfileData::APN_TYPES).append(" TEXT DEFAULT '', ");
65     createTableStr.append(PdpProfileData::IS_ROAMING_APN).append(" INTEGER DEFAULT 1, ");
66     createTableStr.append(PdpProfileData::APN_PROTOCOL).append(" TEXT DEFAULT '', ");
67     createTableStr.append(PdpProfileData::APN_ROAM_PROTOCOL).append(" TEXT DEFAULT '', ");
68     createTableStr.append(PdpProfileData::HOME_URL).append(" TEXT DEFAULT '', ");
69     createTableStr.append(PdpProfileData::MMS_IP_ADDRESS).append(" TEXT DEFAULT '', ");
70     createTableStr.append(PdpProfileData::PROXY_IP_ADDRESS).append(" TEXT DEFAULT '', ");
71     createTableStr.append(PdpProfileData::BEARING_SYSTEM_TYPE).append(" INTEGER DEFAULT 0, ");
72     createTableStr.append(PdpProfileData::MVNO_TYPE).append(" TEXT DEFAULT '', ");
73     createTableStr.append(PdpProfileData::MVNO_MATCH_DATA).append(" TEXT DEFAULT '', ");
74     createTableStr.append(PdpProfileData::EDITED_STATUS).append(" INTEGER DEFAULT 0, ");
75     createTableStr.append(PdpProfileData::SERVER).append(" TEXT DEFAULT '', ");
76     createTableStr.append(PdpProfileData::OPKEY).append(" TEXT DEFAULT '', ");
77     createTableStr.append("UNIQUE (").append(PdpProfileData::MCC).append(", ");
78     createTableStr.append(PdpProfileData::MNC).append(", ");
79     createTableStr.append(PdpProfileData::OPKEY).append(", ");
80     createTableStr.append(PdpProfileData::MVNO_TYPE).append(", ");
81     createTableStr.append(PdpProfileData::MVNO_MATCH_DATA).append(", ");
82     createTableStr.append(PdpProfileData::APN).append(", ");
83     createTableStr.append(PdpProfileData::APN_TYPES).append(", ");
84     createTableStr.append(PdpProfileData::IS_ROAMING_APN).append(", ");
85     createTableStr.append(PdpProfileData::APN_PROTOCOL).append(", ");
86     createTableStr.append(PdpProfileData::APN_ROAM_PROTOCOL).append(", ");
87     createTableStr.append(PdpProfileData::HOME_URL).append(", ");
88     createTableStr.append(PdpProfileData::MMS_IP_ADDRESS).append(", ");
89     createTableStr.append(PdpProfileData::PROFILE_NAME).append(", ");
90     createTableStr.append(PdpProfileData::BEARING_SYSTEM_TYPE).append(", ");
91     createTableStr.append(PdpProfileData::AUTH_USER).append(", ");
92     createTableStr.append(PdpProfileData::AUTH_PWD).append(", ");
93     createTableStr.append(PdpProfileData::EDITED_STATUS).append(", ");
94     createTableStr.append(PdpProfileData::PROXY_IP_ADDRESS).append("))");
95 }
96 
ResetApn()97 int RdbPdpProfileHelper::ResetApn()
98 {
99     auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
100     if (preferencesUtil != nullptr) {
101         preferencesUtil->DeleteProfiles();
102     }
103     int ret = BeginTransaction();
104     if (ret != NativeRdb::E_OK) {
105         DATA_STORAGE_LOGE("RdbPdpProfileHelper::ResetApn BeginTransaction is error!");
106         return ret;
107     }
108     std::string pdpProfileStr;
109     CreatePdpProfileTableStr(pdpProfileStr, TEMP_TABLE_PDP_PROFILE);
110     ret = ExecuteSql(pdpProfileStr);
111     if (ret != NativeRdb::E_OK) {
112         DATA_STORAGE_LOGE("RdbPdpProfileHelper::ResetApn create table temp_pdp_profile ret = %{public}d", ret);
113         return ret;
114     }
115     DATA_STORAGE_LOGI("RdbPdpProfileHelper::ResetApn create table success");
116     ParserUtil util;
117     std::vector<PdpProfile> vec;
118     ret = util.ParserPdpProfileJson(vec);
119     if (ret != DATA_STORAGE_SUCCESS) {
120         RollBack();
121         return ret;
122     }
123     for (size_t i = 0; i < vec.size(); i++) {
124         NativeRdb::ValuesBucket value;
125         util.ParserPdpProfileToValuesBucket(value, vec[i]);
126         int64_t id;
127         Insert(id, value, TEMP_TABLE_PDP_PROFILE);
128     }
129     ret = ExecuteSql("drop table " + std::string(TABLE_PDP_PROFILE));
130     if (ret != NativeRdb::E_OK) {
131         DATA_STORAGE_LOGE("RdbPdpProfileHelper::ResetApn drop table ret = %{public}d", ret);
132         RollBack();
133         return ret;
134     }
135     DATA_STORAGE_LOGI("RdbPdpProfileHelper::ResetApn success");
136     std::string sql;
137     sql.append("alter table ").append(TEMP_TABLE_PDP_PROFILE).append(" rename to ").append(TABLE_PDP_PROFILE);
138     ret = ExecuteSql(sql);
139     if (ret != NativeRdb::E_OK) {
140         DATA_STORAGE_LOGE("RdbPdpProfileHelper::ResetApn alter table ret = %{public}d", ret);
141         RollBack();
142         return ret;
143     }
144     DATA_STORAGE_LOGI("RdbPdpProfileHelper::ResetApn alter table success");
145     ret = CommitTransactionAction();
146     return ret;
147 }
148 
CommitTransactionAction()149 int RdbPdpProfileHelper::CommitTransactionAction()
150 {
151     int result = Commit();
152     if (result != NativeRdb::E_OK) {
153         RollBack();
154     }
155     return result;
156 }
157 
InitAPNDatabase(int slotId,const std::string & opKey,bool isNeedCheckFile)158 int RdbPdpProfileHelper::InitAPNDatabase(int slotId, const std::string &opKey, bool isNeedCheckFile)
159 {
160     if (store_ == nullptr || opKey.empty() || strcmp(opKey.c_str(), INVALID_OPKEY) == 0) {
161         return NativeRdb::E_ERROR;
162     }
163     DATA_STORAGE_LOGD("InitAPNDatabase start");
164     ParserUtil util;
165     std::string path;
166     util.GetPdpProfilePath(slotId, path);
167     if (path.empty()) {
168         return NativeRdb::E_ERROR;
169     }
170     std::string checksum;
171     util.GetFileChecksum(path.c_str(), checksum);
172     if (checksum.empty()) {
173         DATA_STORAGE_LOGE("InitAPNDatabase fail! checksum is null!");
174         return NativeRdb::E_ERROR;
175     }
176     if (isNeedCheckFile && !IsApnDbUpdateNeeded(opKey, checksum)) {
177         DATA_STORAGE_LOGI("The file is not changed and does not need to be loaded again.");
178         return DATA_STORAGE_SUCCESS;
179     }
180     std::vector<PdpProfile> vec;
181     int resultCode = util.ParserPdpProfileJson(vec, path.c_str());
182     if (resultCode != DATA_STORAGE_SUCCESS) {
183         DATA_STORAGE_LOGE("InitAPNDatabase fail");
184         return DATA_STORAGE_ERROR;
185     }
186     int32_t result = store_->BeginTransaction();
187     if (result != NativeRdb::E_OK) {
188         DATA_STORAGE_LOGE("BeginTransaction error!");
189         return DATA_STORAGE_ERROR;
190     }
191     ClearData(opKey);
192     DATA_STORAGE_LOGD("InitAPNDatabase size = %{public}zu", vec.size());
193     for (size_t i = 0; i < vec.size(); i++) {
194         NativeRdb::ValuesBucket value;
195         util.ParserPdpProfileToValuesBucket(value, vec[i]);
196         value.PutString(PdpProfileData::OPKEY, opKey);
197         int64_t id;
198         store_->InsertWithConflictResolution(
199             id, TABLE_PDP_PROFILE, value, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
200     }
201     result = CommitTransactionAction();
202     if (result == NativeRdb::E_OK) {
203         SetPreferApnConfChecksum(opKey, checksum);
204     }
205     DATA_STORAGE_LOGD("InitAPNDatabase end");
206     return result;
207 }
208 
ClearData(const std::string & opKey)209 int RdbPdpProfileHelper::ClearData(const std::string &opKey)
210 {
211     int delRows = 0;
212     NativeRdb::AbsRdbPredicates *absRdbPredicates = (new NativeRdb::AbsRdbPredicates(TABLE_PDP_PROFILE))
213                                                         ->EqualTo(PdpProfileData::OPKEY, opKey)
214                                                         ->And()
215                                                         ->EqualTo(PdpProfileData::EDITED_STATUS, 0);
216     int result = Delete(delRows, *absRdbPredicates);
217     delete absRdbPredicates;
218     return result;
219 }
220 
IsApnDbUpdateNeeded(const std::string & opkey,std::string & checkSum)221 bool RdbPdpProfileHelper::IsApnDbUpdateNeeded(const std::string &opkey, std::string &checkSum)
222 {
223     auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
224     if (preferencesUtil != nullptr) {
225         std::string lastCheckSum = preferencesUtil->ObtainString(APN_CONF_CHECKSUM + opkey, "");
226         if (checkSum.compare(lastCheckSum) == 0) {
227             return false;
228         }
229     }
230     return true;
231 }
232 
SetPreferApnConfChecksum(const std::string & opkey,std::string & checkSum)233 int RdbPdpProfileHelper::SetPreferApnConfChecksum(const std::string &opkey, std::string &checkSum)
234 {
235     auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
236     if (preferencesUtil == nullptr) {
237         DATA_STORAGE_LOGE("preferencesUtil is nullptr!");
238         return NativePreferences::E_ERROR;
239     }
240     return preferencesUtil->SaveString(APN_CONF_CHECKSUM + opkey, checkSum);
241 }
242 } // namespace Telephony
243 } // namespace OHOS
244