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 #ifdef __cplusplus
25 extern "C" {
26 #endif
ReleaseAllCellularDataForInternet()27 void ReleaseAllCellularDataForInternet()
28 {
29     using namespace OHOS::Telephony;
30     OHOS::sptr<ApnManager> apnManager = std::make_unique<ApnManager>().release();
31     if (!apnManager) {
32         TELEPHONY_LOGE("Get Apn manager failed");
33         return;
34     }
35     apnManager->InitApnHolders();
36     int32_t id = ApnManager::FindApnIdByCapability(OHOS::NetManagerStandard::NET_CAPABILITY_INTERNET);
37     OHOS::sptr<ApnHolder> apnHolder = apnManager->FindApnHolderById(id);
38     apnHolder->ReleaseAllCellularData();
39     TELEPHONY_LOGI("Release all cellular data");
40 }
41 #ifdef __cplusplus
42 }
43 #endif
44 
45 const std::map<std::string, int32_t> ApnHolder::apnTypeDataProfileMap_ {
46     {DATA_CONTEXT_ROLE_DEFAULT, DATA_PROFILE_DEFAULT},
47     {DATA_CONTEXT_ROLE_MMS, DATA_PROFILE_MMS},
48     {DATA_CONTEXT_ROLE_SUPL, DATA_PROFILE_SUPL},
49     {DATA_CONTEXT_ROLE_DUN, DATA_PROFILE_DUN},
50     {DATA_CONTEXT_ROLE_IA, DATA_PROFILE_IA},
51     {DATA_CONTEXT_ROLE_XCAP, DATA_PROFILE_XCAP}
52 };
53 
ApnHolder(const std::string & apnType,const int32_t priority)54 ApnHolder::ApnHolder(const std::string &apnType, const int32_t priority) : apnType_(apnType), priority_(priority) {}
55 
56 ApnHolder::~ApnHolder() = default;
57 
GetNextRetryApn() const58 sptr<ApnItem> ApnHolder::GetNextRetryApn() const
59 {
60     return retryPolicy_.GetNextRetryApnItem();
61 }
62 
SetAllMatchedApns(std::vector<sptr<ApnItem>> & matchedApns)63 void ApnHolder::SetAllMatchedApns(std::vector<sptr<ApnItem>> &matchedApns)
64 {
65     retryPolicy_.SetMatchedApns(matchedApns);
66 }
67 
GetRetryDelay() const68 int64_t ApnHolder::GetRetryDelay() const
69 {
70     return retryPolicy_.GetNextRetryDelay();
71 }
72 
SetCurrentApn(sptr<ApnItem> & apnItem)73 void ApnHolder::SetCurrentApn(sptr<ApnItem> &apnItem)
74 {
75     apnItem_ = apnItem;
76 }
77 
GetCurrentApn() const78 sptr<ApnItem> ApnHolder::GetCurrentApn() const
79 {
80     return apnItem_;
81 }
82 
SetApnState(ApnProfileState state)83 void ApnHolder::SetApnState(ApnProfileState state)
84 {
85     if (apnState_ != state) {
86         apnState_ = state;
87     }
88     if (apnState_ == PROFILE_STATE_FAILED) {
89         retryPolicy_.ClearRetryApns();
90     }
91 }
92 
GetApnState() const93 ApnProfileState ApnHolder::GetApnState() const
94 {
95     return apnState_;
96 }
97 
IsDataCallEnabled() const98 bool ApnHolder::IsDataCallEnabled() const
99 {
100     return dataCallEnabled_;
101 }
102 
GetApnType() const103 std::string ApnHolder::GetApnType() const
104 {
105     return apnType_;
106 }
107 
ReleaseDataConnection()108 void ApnHolder::ReleaseDataConnection()
109 {
110     if (cellularDataStateMachine_ == nullptr) {
111         TELEPHONY_LOGE("cellularDataStateMachine_ is null");
112         return;
113     }
114     std::unique_ptr<DataDisconnectParams> object =
115         std::make_unique<DataDisconnectParams>(apnType_, DisConnectionReason::REASON_CLEAR_CONNECTION);
116     if (object == nullptr) {
117         TELEPHONY_LOGE("ClearConnection fail, object is null");
118         return;
119     }
120     apnState_ = PROFILE_STATE_DISCONNECTING;
121     AppExecFwk::InnerEvent::Pointer event =
122         AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_DISCONNECT, object);
123     cellularDataStateMachine_->SendEvent(event);
124     cellularDataStateMachine_ = nullptr;
125 }
126 
GetProfileId(const std::string & apnType) const127 int32_t ApnHolder::GetProfileId(const std::string &apnType) const
128 {
129     std::map<std::string, int32_t>::const_iterator it = apnTypeDataProfileMap_.find(apnType);
130     if (it != apnTypeDataProfileMap_.end()) {
131         return it->second;
132     }
133     TELEPHONY_LOGI("this apnType is not in apnTypeDataProfileMap.");
134     return DATA_PROFILE_DEFAULT;
135 }
136 
SetCellularDataStateMachine(const std::shared_ptr<CellularDataStateMachine> & stateMachine)137 void ApnHolder::SetCellularDataStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
138 {
139     cellularDataStateMachine_ = stateMachine;
140 }
141 
GetCellularDataStateMachine() const142 std::shared_ptr<CellularDataStateMachine> ApnHolder::GetCellularDataStateMachine() const
143 {
144     return cellularDataStateMachine_;
145 }
146 
GetCapability() const147 uint64_t ApnHolder::GetCapability() const
148 {
149     return capability_;
150 }
151 
GetPriority() const152 int32_t ApnHolder::GetPriority() const
153 {
154     return priority_;
155 }
156 
RequestCellularData(const NetRequest & netRequest)157 void ApnHolder::RequestCellularData(const NetRequest &netRequest)
158 {
159     for (const NetRequest &request : netRequests_) {
160         if ((netRequest.capability == request.capability) && (netRequest.ident == request.ident)) {
161             return;
162         }
163     }
164     netRequests_.push_back(netRequest);
165     capability_ = netRequest.capability;
166     dataCallEnabled_ = true;
167 }
168 
ReleaseCellularData(const NetRequest & netRequest)169 void ApnHolder::ReleaseCellularData(const NetRequest &netRequest)
170 {
171     for (std::vector<NetRequest>::const_iterator it = netRequests_.begin(); it != netRequests_.end(); it++) {
172         if ((netRequest.capability == it->capability) && (netRequest.ident == it->ident)) {
173             netRequests_.erase(it);
174             if (netRequests_.empty()) {
175                 dataCallEnabled_ = false;
176             }
177             return;
178         }
179     }
180 }
181 
ReleaseAllCellularData()182 void ApnHolder::ReleaseAllCellularData()
183 {
184     TELEPHONY_LOGI("clear all cellular data");
185     netRequests_.clear();
186     if (netRequests_.empty()) {
187         dataCallEnabled_ = false;
188     }
189 }
190 
IsEmergencyType() const191 bool ApnHolder::IsEmergencyType() const
192 {
193     return apnType_ == DATA_CONTEXT_ROLE_EMERGENCY;
194 }
195 
IsMmsType() const196 bool ApnHolder::IsMmsType() const
197 {
198     return apnType_ == DATA_CONTEXT_ROLE_MMS;
199 }
200 
InitialApnRetryCount()201 void ApnHolder::InitialApnRetryCount()
202 {
203     retryPolicy_.InitialRetryCountValue();
204 }
205 
IsSameMatchedApns(std::vector<sptr<ApnItem>> newMatchedApns,bool roamingState)206 bool ApnHolder::IsSameMatchedApns(std::vector<sptr<ApnItem>> newMatchedApns, bool roamingState)
207 {
208     std::vector<sptr<ApnItem>> currentMatchedApns = retryPolicy_.GetMatchedApns();
209     if (currentMatchedApns.empty() || newMatchedApns.empty()) {
210         TELEPHONY_LOGE("newMatchedApns or oldMatchedApns is empty");
211         return false;
212     }
213     if (currentMatchedApns.size() != newMatchedApns.size()) {
214         TELEPHONY_LOGI("newMatchedApns and oldMatchedApns are not equal in size");
215         return false;
216     }
217     for (const sptr<ApnItem> &newApnItem : newMatchedApns) {
218         bool canHandle = false;
219         for (const sptr<ApnItem> &oldApnItem : currentMatchedApns) {
220             if (IsSameApnItem(newApnItem, oldApnItem, roamingState)) {
221                 canHandle = true;
222                 break;
223             }
224         }
225         if (!canHandle) {
226             return false;
227         }
228     }
229     return true;
230 }
231 
IsSameApnItem(const sptr<ApnItem> & newApnItem,const sptr<ApnItem> & oldApnItem,bool roamingState)232 bool ApnHolder::IsSameApnItem(const sptr<ApnItem> &newApnItem,
233                               const sptr<ApnItem> &oldApnItem,
234                               bool roamingState)
235 {
236     if (newApnItem == nullptr || oldApnItem == nullptr) {
237         TELEPHONY_LOGE("newApnItem or oldApnItem is null");
238         return false;
239     }
240     bool isSameProtocol = false;
241     if (roamingState) {
242         isSameProtocol = std::strcmp(newApnItem->attr_.roamingProtocol_, oldApnItem->attr_.roamingProtocol_) == 0;
243     } else {
244         isSameProtocol = std::strcmp(newApnItem->attr_.protocol_, oldApnItem->attr_.protocol_) == 0;
245     }
246     return isSameProtocol && newApnItem->attr_.profileId_ == oldApnItem->attr_.profileId_ &&
247         newApnItem->attr_.authType_ == oldApnItem->attr_.authType_ &&
248         newApnItem->attr_.isRoamingApn_ == oldApnItem->attr_.isRoamingApn_ &&
249         newApnItem->attr_.isEdited_ == oldApnItem->attr_.isEdited_ &&
250         std::strcmp(newApnItem->attr_.types_, oldApnItem->attr_.types_) == 0 &&
251         std::strcmp(newApnItem->attr_.numeric_, oldApnItem->attr_.numeric_) == 0 &&
252         std::strcmp(newApnItem->attr_.apn_, oldApnItem->attr_.apn_) == 0 &&
253         std::strcmp(newApnItem->attr_.apnName_, oldApnItem->attr_.apnName_) == 0 &&
254         std::strcmp(newApnItem->attr_.user_, oldApnItem->attr_.user_) == 0 &&
255         std::strcmp(newApnItem->attr_.password_, oldApnItem->attr_.password_) == 0 &&
256         std::strcmp(newApnItem->attr_.homeUrl_, oldApnItem->attr_.homeUrl_) == 0 &&
257         std::strcmp(newApnItem->attr_.proxyIpAddress_, oldApnItem->attr_.proxyIpAddress_) == 0 &&
258         std::strcmp(newApnItem->attr_.mmsIpAddress_, oldApnItem->attr_.mmsIpAddress_) == 0;
259 }
260 
IsCompatibleApnItem(const sptr<ApnItem> & newApnItem,const sptr<ApnItem> & oldApnItem,bool roamingState)261 bool ApnHolder::IsCompatibleApnItem(const sptr<ApnItem> &newApnItem, const sptr<ApnItem> &oldApnItem,
262     bool roamingState)
263 {
264     if (newApnItem == nullptr || oldApnItem == nullptr) {
265         TELEPHONY_LOGE("newApnItem or oldApnItem is null");
266         return false;
267     }
268     bool isSameProtocol = false;
269     if (roamingState) {
270         isSameProtocol = std::strcmp(newApnItem->attr_.roamingProtocol_, oldApnItem->attr_.roamingProtocol_) == 0;
271     } else {
272         isSameProtocol = std::strcmp(newApnItem->attr_.protocol_, oldApnItem->attr_.protocol_) == 0;
273     }
274     return isSameProtocol && newApnItem->attr_.profileId_ == oldApnItem->attr_.profileId_ &&
275         newApnItem->attr_.authType_ == oldApnItem->attr_.authType_ &&
276         std::strcmp(newApnItem->attr_.types_, oldApnItem->attr_.types_) == 0 &&
277         std::strcmp(newApnItem->attr_.numeric_, oldApnItem->attr_.numeric_) == 0 &&
278         std::strcmp(newApnItem->attr_.apn_, oldApnItem->attr_.apn_) == 0 &&
279         std::strcmp(newApnItem->attr_.apnName_, oldApnItem->attr_.apnName_) == 0 &&
280         std::strcmp(newApnItem->attr_.user_, oldApnItem->attr_.user_) == 0 &&
281         std::strcmp(newApnItem->attr_.password_, oldApnItem->attr_.password_) == 0 &&
282         std::strcmp(newApnItem->attr_.proxyIpAddress_, oldApnItem->attr_.proxyIpAddress_) == 0 &&
283         std::strcmp(newApnItem->attr_.mmsIpAddress_, oldApnItem->attr_.mmsIpAddress_) == 0;
284 }
285 } // namespace Telephony
286 } // namespace OHOS