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