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" 22namespace OHOS { 23namespace Telephony { 24namespace { 25 constexpr int32_t SYSTEM_UID = 1e4; 26 std::shared_mutex reqUidsMutex_; 27} 28const 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 37ApnHolder::ApnHolder(const std::string &apnType, const int32_t priority) : apnType_(apnType), priority_(priority) {} 38 39ApnHolder::~ApnHolder() = default; 40 41sptr<ApnItem> ApnHolder::GetNextRetryApn() const 42{ 43 return retryPolicy_.GetNextRetryApnItem(); 44} 45 46void ApnHolder::SetAllMatchedApns(std::vector<sptr<ApnItem>> &matchedApns) 47{ 48 retryPolicy_.SetMatchedApns(matchedApns); 49} 50 51int64_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 56void ApnHolder::SetCurrentApn(sptr<ApnItem> &apnItem) 57{ 58 apnItem_ = apnItem; 59} 60 61sptr<ApnItem> ApnHolder::GetCurrentApn() const 62{ 63 return apnItem_; 64} 65 66void 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 75void 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 85void 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 95ApnProfileState ApnHolder::GetApnState() const 96{ 97 return apnState_; 98} 99 100bool ApnHolder::IsDataCallEnabled() const 101{ 102 return dataCallEnabled_; 103} 104 105std::string ApnHolder::GetApnType() const 106{ 107 return apnType_; 108} 109 110void 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 128int32_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 138void ApnHolder::SetCellularDataStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine) 139{ 140 cellularDataStateMachine_ = stateMachine; 141} 142 143std::shared_ptr<CellularDataStateMachine> ApnHolder::GetCellularDataStateMachine() const 144{ 145 return cellularDataStateMachine_; 146} 147 148uint64_t ApnHolder::GetCapability() const 149{ 150 return capability_; 151} 152 153int32_t ApnHolder::GetPriority() const 154{ 155 return priority_; 156} 157 158HasSystemUse 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 169void 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 181bool 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 197void ApnHolder::ReleaseAllCellularData() 198{ 199 TELEPHONY_LOGI("clear all cellular data"); 200 netRequests_.clear(); 201 if (netRequests_.empty()) { 202 dataCallEnabled_ = false; 203 } 204} 205 206bool ApnHolder::IsEmergencyType() const 207{ 208 return apnType_ == DATA_CONTEXT_ROLE_EMERGENCY; 209} 210 211bool ApnHolder::IsMmsType() const 212{ 213 return apnType_ == DATA_CONTEXT_ROLE_MMS; 214} 215 216void ApnHolder::InitialApnRetryCount() 217{ 218 retryPolicy_.InitialRetryCountValue(); 219} 220 221bool 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 247bool 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 276bool 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 301void ApnHolder::MarkCurrentApnBad() 302{ 303 if (apnItem_ != nullptr) { 304 apnItem_->MarkBadApn(true); 305 } 306} 307 308void ApnHolder::ClearCurrentApnBad() 309{ 310 if (apnItem_ != nullptr) { 311 apnItem_->MarkBadApn(false); 312 } 313} 314} // namespace Telephony 315} // namespace OHOS