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