1 /*
2 * Copyright (C) 2021 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_holder.h"
17
18 #include "cellular_data_event_code.h"
19 #include "cellular_data_state_machine.h"
20 #include "data_disconnect_params.h"
21 #include "apn_manager.h"
22 namespace OHOS {
23 namespace Telephony {
24 namespace {
25 constexpr int32_t SYSTEM_UID = 1e4;
26 std::shared_mutex reqUidsMutex_;
27 }
28 const std::map<std::string, int32_t> ApnHolder::apnTypeDataProfileMap_ {
29 {DATA_CONTEXT_ROLE_DEFAULT, DATA_PROFILE_DEFAULT},
30 {DATA_CONTEXT_ROLE_MMS, DATA_PROFILE_MMS},
31 {DATA_CONTEXT_ROLE_SUPL, DATA_PROFILE_SUPL},
32 {DATA_CONTEXT_ROLE_DUN, DATA_PROFILE_DUN},
33 {DATA_CONTEXT_ROLE_IA, DATA_PROFILE_IA},
34 {DATA_CONTEXT_ROLE_XCAP, DATA_PROFILE_XCAP}
35 };
36
ApnHolder(const std::string &apnType, const int32_t priority)37 ApnHolder::ApnHolder(const std::string &apnType, const int32_t priority) : apnType_(apnType), priority_(priority) {}
38
39 ApnHolder::~ApnHolder() = default;
40
GetNextRetryApn() const41 sptr<ApnItem> ApnHolder::GetNextRetryApn() const
42 {
43 return retryPolicy_.GetNextRetryApnItem();
44 }
45
SetAllMatchedApns(std::vector<sptr<ApnItem>> &matchedApns)46 void ApnHolder::SetAllMatchedApns(std::vector<sptr<ApnItem>> &matchedApns)
47 {
48 retryPolicy_.SetMatchedApns(matchedApns);
49 }
50
GetRetryDelay(int32_t cause, int32_t suggestTime, RetryScene scene, int32_t slotId)51 int64_t ApnHolder::GetRetryDelay(int32_t cause, int32_t suggestTime, RetryScene scene, int32_t slotId)
52 {
53 return retryPolicy_.GetNextRetryDelay(apnType_, cause, suggestTime, scene, slotId);
54 }
55
SetCurrentApn(sptr<ApnItem> &apnItem)56 void ApnHolder::SetCurrentApn(sptr<ApnItem> &apnItem)
57 {
58 apnItem_ = apnItem;
59 }
60
GetCurrentApn() const61 sptr<ApnItem> ApnHolder::GetCurrentApn() const
62 {
63 return apnItem_;
64 }
65
AddUid(uint32_t uid)66 void ApnHolder::AddUid(uint32_t uid)
67 {
68 std::unique_lock<std::shared_mutex> lock(reqUidsMutex_);
69 if (reqUids_.find(uid) != reqUids_.end()) {
70 return;
71 }
72 reqUids_.insert(uid);
73 }
74
RemoveUid(uint32_t uid)75 void ApnHolder::RemoveUid(uint32_t uid)
76 {
77 std::unique_lock<std::shared_mutex> lock(reqUidsMutex_);
78 auto it = reqUids_.find(uid);
79 if (it != reqUids_.end()) {
80 reqUids_.erase(it);
81 return;
82 }
83 }
84
SetApnState(ApnProfileState state)85 void ApnHolder::SetApnState(ApnProfileState state)
86 {
87 if (apnState_ != state) {
88 apnState_ = state;
89 }
90 if (apnState_ == PROFILE_STATE_FAILED) {
91 retryPolicy_.ClearRetryApns();
92 }
93 }
94
GetApnState() const95 ApnProfileState ApnHolder::GetApnState() const
96 {
97 return apnState_;
98 }
99
IsDataCallEnabled() const100 bool ApnHolder::IsDataCallEnabled() const
101 {
102 return dataCallEnabled_;
103 }
104
GetApnType() const105 std::string ApnHolder::GetApnType() const
106 {
107 return apnType_;
108 }
109
ReleaseDataConnection()110 void ApnHolder::ReleaseDataConnection()
111 {
112 if (cellularDataStateMachine_ == nullptr) {
113 TELEPHONY_LOGE("cellularDataStateMachine_ is null");
114 return;
115 }
116 std::unique_ptr<DataDisconnectParams> object =
117 std::make_unique<DataDisconnectParams>(apnType_, DisConnectionReason::REASON_CLEAR_CONNECTION);
118 if (object == nullptr) {
119 TELEPHONY_LOGE("ClearConnection fail, object is null");
120 return;
121 }
122 apnState_ = PROFILE_STATE_DISCONNECTING;
123 AppExecFwk::InnerEvent::Pointer event =
124 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_DISCONNECT, object);
125 cellularDataStateMachine_->SendEvent(event);
126 }
127
GetProfileId(const std::string &apnType) const128 int32_t ApnHolder::GetProfileId(const std::string &apnType) const
129 {
130 std::map<std::string, int32_t>::const_iterator it = apnTypeDataProfileMap_.find(apnType);
131 if (it != apnTypeDataProfileMap_.end()) {
132 return it->second;
133 }
134 TELEPHONY_LOGI("this apnType is not in apnTypeDataProfileMap.");
135 return DATA_PROFILE_DEFAULT;
136 }
137
SetCellularDataStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)138 void ApnHolder::SetCellularDataStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
139 {
140 cellularDataStateMachine_ = stateMachine;
141 }
142
GetCellularDataStateMachine() const143 std::shared_ptr<CellularDataStateMachine> ApnHolder::GetCellularDataStateMachine() const
144 {
145 return cellularDataStateMachine_;
146 }
147
GetCapability() const148 uint64_t ApnHolder::GetCapability() const
149 {
150 return capability_;
151 }
152
GetPriority() const153 int32_t ApnHolder::GetPriority() const
154 {
155 return priority_;
156 }
157
GetUidStatus() const158 HasSystemUse ApnHolder::GetUidStatus() const
159 {
160 std::unique_lock<std::shared_mutex> lock(reqUidsMutex_);
161 for (auto item : reqUids_) {
162 if (item < SYSTEM_UID) {
163 return HasSystemUse::HAS;
164 }
165 }
166 return HasSystemUse::NOT_HAS;
167 }
168
RequestCellularData(const NetRequest &netRequest)169 void ApnHolder::RequestCellularData(const NetRequest &netRequest)
170 {
171 for (const NetRequest &request : netRequests_) {
172 if ((netRequest.capability == request.capability) && (netRequest.ident == request.ident)) {
173 return;
174 }
175 }
176 netRequests_.push_back(netRequest);
177 capability_ = netRequest.capability;
178 dataCallEnabled_ = true;
179 }
180
ReleaseCellularData(const NetRequest &netRequest)181 bool ApnHolder::ReleaseCellularData(const NetRequest &netRequest)
182 {
183 for (std::vector<NetRequest>::const_iterator it = netRequests_.begin(); it != netRequests_.end();) {
184 if ((netRequest.capability == it->capability) && (netRequest.ident == it->ident)) {
185 it = netRequests_.erase(it);
186 if (netRequests_.empty()) {
187 dataCallEnabled_ = false;
188 return true;
189 }
190 } else {
191 it++;
192 }
193 }
194 return false;
195 }
196
ReleaseAllCellularData()197 void ApnHolder::ReleaseAllCellularData()
198 {
199 TELEPHONY_LOGI("clear all cellular data");
200 netRequests_.clear();
201 if (netRequests_.empty()) {
202 dataCallEnabled_ = false;
203 }
204 }
205
IsEmergencyType() const206 bool ApnHolder::IsEmergencyType() const
207 {
208 return apnType_ == DATA_CONTEXT_ROLE_EMERGENCY;
209 }
210
IsMmsType() const211 bool ApnHolder::IsMmsType() const
212 {
213 return apnType_ == DATA_CONTEXT_ROLE_MMS;
214 }
215
InitialApnRetryCount()216 void ApnHolder::InitialApnRetryCount()
217 {
218 retryPolicy_.InitialRetryCountValue();
219 }
220
IsSameMatchedApns(std::vector<sptr<ApnItem>> newMatchedApns, bool roamingState)221 bool ApnHolder::IsSameMatchedApns(std::vector<sptr<ApnItem>> newMatchedApns, bool roamingState)
222 {
223 std::vector<sptr<ApnItem>> currentMatchedApns = retryPolicy_.GetMatchedApns();
224 if (currentMatchedApns.empty() || newMatchedApns.empty()) {
225 TELEPHONY_LOGE("newMatchedApns or oldMatchedApns is empty");
226 return false;
227 }
228 if (currentMatchedApns.size() != newMatchedApns.size()) {
229 TELEPHONY_LOGI("newMatchedApns and oldMatchedApns are not equal in size");
230 return false;
231 }
232 for (const sptr<ApnItem> &newApnItem : newMatchedApns) {
233 bool canHandle = false;
234 for (const sptr<ApnItem> &oldApnItem : currentMatchedApns) {
235 if (IsSameApnItem(newApnItem, oldApnItem, roamingState)) {
236 canHandle = true;
237 break;
238 }
239 }
240 if (!canHandle) {
241 return false;
242 }
243 }
244 return true;
245 }
246
IsSameApnItem(const sptr<ApnItem> &newApnItem, const sptr<ApnItem> &oldApnItem, bool roamingState)247 bool ApnHolder::IsSameApnItem(const sptr<ApnItem> &newApnItem,
248 const sptr<ApnItem> &oldApnItem,
249 bool roamingState)
250 {
251 if (newApnItem == nullptr || oldApnItem == nullptr) {
252 TELEPHONY_LOGE("newApnItem or oldApnItem is null");
253 return false;
254 }
255 bool isSameProtocol = false;
256 if (roamingState) {
257 isSameProtocol = std::strcmp(newApnItem->attr_.roamingProtocol_, oldApnItem->attr_.roamingProtocol_) == 0;
258 } else {
259 isSameProtocol = std::strcmp(newApnItem->attr_.protocol_, oldApnItem->attr_.protocol_) == 0;
260 }
261 return isSameProtocol && newApnItem->attr_.profileId_ == oldApnItem->attr_.profileId_ &&
262 newApnItem->attr_.authType_ == oldApnItem->attr_.authType_ &&
263 newApnItem->attr_.isRoamingApn_ == oldApnItem->attr_.isRoamingApn_ &&
264 newApnItem->attr_.isEdited_ == oldApnItem->attr_.isEdited_ &&
265 std::strcmp(newApnItem->attr_.types_, oldApnItem->attr_.types_) == 0 &&
266 std::strcmp(newApnItem->attr_.numeric_, oldApnItem->attr_.numeric_) == 0 &&
267 std::strcmp(newApnItem->attr_.apn_, oldApnItem->attr_.apn_) == 0 &&
268 std::strcmp(newApnItem->attr_.apnName_, oldApnItem->attr_.apnName_) == 0 &&
269 std::strcmp(newApnItem->attr_.user_, oldApnItem->attr_.user_) == 0 &&
270 std::strcmp(newApnItem->attr_.password_, oldApnItem->attr_.password_) == 0 &&
271 std::strcmp(newApnItem->attr_.homeUrl_, oldApnItem->attr_.homeUrl_) == 0 &&
272 std::strcmp(newApnItem->attr_.proxyIpAddress_, oldApnItem->attr_.proxyIpAddress_) == 0 &&
273 std::strcmp(newApnItem->attr_.mmsIpAddress_, oldApnItem->attr_.mmsIpAddress_) == 0;
274 }
275
IsCompatibleApnItem(const sptr<ApnItem> &newApnItem, const sptr<ApnItem> &oldApnItem, bool roamingState)276 bool ApnHolder::IsCompatibleApnItem(const sptr<ApnItem> &newApnItem, const sptr<ApnItem> &oldApnItem,
277 bool roamingState)
278 {
279 if (newApnItem == nullptr || oldApnItem == nullptr) {
280 TELEPHONY_LOGE("newApnItem or oldApnItem is null");
281 return false;
282 }
283 bool isSameProtocol = false;
284 if (roamingState) {
285 isSameProtocol = std::strcmp(newApnItem->attr_.roamingProtocol_, oldApnItem->attr_.roamingProtocol_) == 0;
286 } else {
287 isSameProtocol = std::strcmp(newApnItem->attr_.protocol_, oldApnItem->attr_.protocol_) == 0;
288 }
289 return isSameProtocol && newApnItem->attr_.profileId_ == oldApnItem->attr_.profileId_ &&
290 newApnItem->attr_.authType_ == oldApnItem->attr_.authType_ &&
291 std::strcmp(newApnItem->attr_.types_, oldApnItem->attr_.types_) == 0 &&
292 std::strcmp(newApnItem->attr_.numeric_, oldApnItem->attr_.numeric_) == 0 &&
293 std::strcmp(newApnItem->attr_.apn_, oldApnItem->attr_.apn_) == 0 &&
294 std::strcmp(newApnItem->attr_.apnName_, oldApnItem->attr_.apnName_) == 0 &&
295 std::strcmp(newApnItem->attr_.user_, oldApnItem->attr_.user_) == 0 &&
296 std::strcmp(newApnItem->attr_.password_, oldApnItem->attr_.password_) == 0 &&
297 std::strcmp(newApnItem->attr_.proxyIpAddress_, oldApnItem->attr_.proxyIpAddress_) == 0 &&
298 std::strcmp(newApnItem->attr_.mmsIpAddress_, oldApnItem->attr_.mmsIpAddress_) == 0;
299 }
300
MarkCurrentApnBad()301 void ApnHolder::MarkCurrentApnBad()
302 {
303 if (apnItem_ != nullptr) {
304 apnItem_->MarkBadApn(true);
305 }
306 }
307
ClearCurrentApnBad()308 void ApnHolder::ClearCurrentApnBad()
309 {
310 if (apnItem_ != nullptr) {
311 apnItem_->MarkBadApn(false);
312 }
313 }
314 } // namespace Telephony
315 } // namespace OHOS