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