• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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