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