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 "data_connection_manager.h" 17 18#include "cellular_data_event_code.h" 19#include "cellular_data_handler.h" 20#include "cellular_data_state_machine.h" 21#include "cellular_data_utils.h" 22#include "core_manager_inner.h" 23#include "tel_ril_data_parcel.h" 24#include "operator_config_types.h" 25#include "radio_event.h" 26#include "telephony_log_wrapper.h" 27 28namespace OHOS { 29namespace Telephony { 30DataConnectionManager::DataConnectionManager(int32_t slotId) : StateMachine("DataConnectionManager"), slotId_(slotId) 31{ 32 connectionMonitor_ = std::make_shared<DataConnectionMonitor>(slotId); 33 if (connectionMonitor_ == nullptr) { 34 TELEPHONY_LOGE("Slot%{public}d: connectionMonitor_ is null", slotId_); 35 return; 36 } 37} 38 39DataConnectionManager::~DataConnectionManager() 40{ 41 if (connectionMonitor_ != nullptr) { 42 connectionMonitor_->RemoveAllEvents(); 43 } 44} 45 46void DataConnectionManager::Init() 47{ 48 ccmDefaultState_ = std::make_unique<CcmDefaultState>(*this, "CcmDefaultState").release(); 49 if (ccmDefaultState_ == nullptr) { 50 TELEPHONY_LOGE("Slot%{public}d: ccmDefaultState_ is null", slotId_); 51 return; 52 } 53 StateMachine::SetOriginalState(ccmDefaultState_); 54 StateMachine::Start(); 55} 56 57void DataConnectionManager::AddConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine) 58{ 59 std::lock_guard<std::mutex> lock(stateMachineMutex_); 60 if (stateMachine != nullptr) { 61 stateMachines_.push_back(stateMachine); 62 } 63} 64 65void DataConnectionManager::RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine) 66{ 67 if (stateMachine == nullptr) { 68 TELEPHONY_LOGE("Slot%{public}d: stateMachine is null", slotId_); 69 return; 70 } 71 std::lock_guard<std::mutex> lock(stateMachineMutex_); 72 for (std::vector<std::shared_ptr<CellularDataStateMachine>>::const_iterator iter = 73 stateMachines_.begin(); iter != stateMachines_.end(); iter++) { 74 if (*iter.base() == stateMachine) { 75 stateMachines_.erase(iter); 76 break; 77 } 78 } 79} 80 81std::vector<std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetAllConnectionMachine() 82{ 83 std::lock_guard<std::mutex> lock(stateMachineMutex_); 84 return stateMachines_; 85} 86 87void DataConnectionManager::AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> &stateMachine) 88{ 89 std::lock_guard<std::mutex> lock(activeConnectionMutex_); 90 if (stateMachine != nullptr) { 91 cidActiveConnectionMap_[stateMachine->GetCid()] = stateMachine; 92 } 93} 94 95std::shared_ptr<CellularDataStateMachine> DataConnectionManager::GetActiveConnectionByCid(int32_t cid) 96{ 97 std::lock_guard<std::mutex> lock(activeConnectionMutex_); 98 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>>::const_iterator it = cidActiveConnectionMap_.find(cid); 99 if (it != cidActiveConnectionMap_.end()) { 100 return it->second; 101 } 102 return nullptr; 103} 104 105std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetActiveConnection() 106{ 107 std::lock_guard<std::mutex> lock(activeConnectionMutex_); 108 return cidActiveConnectionMap_; 109} 110 111bool DataConnectionManager::IsBandwidthSourceModem() const 112{ 113 return bandwidthSourceModem_; 114} 115 116bool DataConnectionManager::isNoActiveConnection() 117{ 118 std::lock_guard<std::mutex> lock(activeConnectionMutex_); 119 if (cidActiveConnectionMap_.empty()) { 120 return true; 121 } 122 return false; 123} 124 125void DataConnectionManager::RemoveActiveConnectionByCid(int32_t cid) 126{ 127 std::lock_guard<std::mutex> lock(activeConnectionMutex_); 128 if (cidActiveConnectionMap_.find(cid) != cidActiveConnectionMap_.end()) { 129 cidActiveConnectionMap_.erase(cid); 130 } 131} 132 133void DataConnectionManager::StartStallDetectionTimer() 134{ 135 if (connectionMonitor_ != nullptr) { 136 connectionMonitor_->StartStallDetectionTimer(); 137 } 138} 139 140void DataConnectionManager::StopStallDetectionTimer() 141{ 142 if (connectionMonitor_ != nullptr) { 143 connectionMonitor_->StopStallDetectionTimer(); 144 } 145} 146 147void DataConnectionManager::RegisterRadioObserver() 148{ 149 if (stateMachineEventHandler_ == nullptr) { 150 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr!"); 151 return; 152 } 153 CoreManagerInner &coreInner = CoreManagerInner::GetInstance(); 154 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED, nullptr); 155 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_DATA_CALL_LIST_CHANGED, nullptr); 156 coreInner.RegisterCoreNotify( 157 slotId_, stateMachineEventHandler_, RadioEvent::RADIO_LINK_CAPABILITY_CHANGED, nullptr); 158} 159 160void DataConnectionManager::UnRegisterRadioObserver() const 161{ 162 if (stateMachineEventHandler_ == nullptr) { 163 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr!"); 164 return; 165 } 166 CoreManagerInner &coreInner = CoreManagerInner::GetInstance(); 167 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED); 168 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_DATA_CALL_LIST_CHANGED); 169 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_LINK_CAPABILITY_CHANGED); 170} 171 172void CcmDefaultState::StateBegin() 173{ 174 connectManager_.RegisterRadioObserver(); 175} 176 177void CcmDefaultState::StateEnd() 178{ 179 connectManager_.UnRegisterRadioObserver(); 180} 181 182bool CcmDefaultState::StateProcess(const AppExecFwk::InnerEvent::Pointer &event) 183{ 184 if (event == nullptr) { 185 TELEPHONY_LOGE("event is null"); 186 return false; 187 } 188 int32_t id = event->GetInnerEventId(); 189 switch (id) { 190 case RadioEvent::RADIO_CONNECTED: 191 TELEPHONY_LOGI("Radio is connected"); 192 break; 193 case RadioEvent::RADIO_DATA_CALL_LIST_CHANGED: 194 RadioDataCallListChanged(event); 195 break; 196 case RadioEvent::RADIO_LINK_CAPABILITY_CHANGED: 197 RadioLinkCapabilityChanged(event); 198 break; 199 default: 200 TELEPHONY_LOGE("handle nothing!"); 201 return false; 202 } 203 return true; 204} 205 206void CcmDefaultState::RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer &event) 207{ 208 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>(); 209 if (infos == nullptr) { 210 TELEPHONY_LOGE("setupDataCallResultInfo is null"); 211 return; 212 } 213 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap = 214 connectManager_.GetActiveConnection(); 215 UpdateNetworkInfo(event); 216 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>>& it : idActiveConnectionMap) { 217 if (it.second == nullptr) { 218 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first); 219 continue; 220 } 221 int32_t cid = it.second->GetCid(); 222 for (size_t i = 0; i < infos->dcList.size(); ++i) { 223 if (infos->dcList[i].cid == cid && infos->dcList[i].active <= 0) { 224 auto object = std::make_shared<SetupDataCallResultInfo>(); 225 object->cid = cid; 226 object->reason = infos->dcList[i].reason; 227 object->retryTime = infos->dcList[i].retryTime; 228 object->retryScene = static_cast<int32_t>(RetryScene::RETRY_SCENE_MODEM_DEACTIVATE); 229 TELEPHONY_LOGI("add to retry (modem dend): cid=%{public}d, cause=%{public}d", cid, object->reason); 230 AppExecFwk::InnerEvent::Pointer event = 231 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LOST_CONNECTION, object); 232 it.second->SendEvent(event); 233 break; 234 } 235 } 236 } 237} 238 239void CcmDefaultState::RadioLinkCapabilityChanged(const AppExecFwk::InnerEvent::Pointer &event) 240{ 241 std::shared_ptr<DataLinkCapability> linkCapability = event->GetSharedObject<DataLinkCapability>(); 242 if (linkCapability == nullptr) { 243 TELEPHONY_LOGE("linkCapability is null"); 244 return; 245 } 246 if (connectManager_.IsBandwidthSourceModem()) { 247 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap = 248 connectManager_.GetActiveConnection(); 249 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>> &it : idActiveConnectionMap) { 250 if (it.second == nullptr) { 251 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first); 252 continue; 253 } 254 AppExecFwk::InnerEvent::Pointer smEvent = 255 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LINK_CAPABILITY_CHANGED, linkCapability); 256 it.second->SendEvent(smEvent); 257 } 258 } 259} 260 261void CcmDefaultState::UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer &event) 262{ 263 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>(); 264 if (infos == nullptr) { 265 TELEPHONY_LOGE("dataCallResultList is null"); 266 return; 267 } 268 for (SetupDataCallResultInfo &it : infos->dcList) { 269 std::shared_ptr<CellularDataStateMachine> dataConnect = connectManager_.GetActiveConnectionByCid(it.cid); 270 if (dataConnect == nullptr) { 271 TELEPHONY_LOGE("get active connection by cid is := %{public}d flag:= %{public}d ", it.cid, it.flag); 272 continue; 273 } 274 dataConnect->UpdateNetworkInfoIfInActive(it); 275 } 276} 277 278void DataConnectionManager::BeginNetStatistics() 279{ 280 if (connectionMonitor_ != nullptr) { 281 connectionMonitor_->BeginNetStatistics(); 282 } 283} 284 285void DataConnectionManager::EndNetStatistics() 286{ 287 if (connectionMonitor_ != nullptr) { 288 connectionMonitor_->EndNetStatistics(); 289 } 290} 291 292void DataConnectionManager::UpdateCallState(int32_t state) 293{ 294 if (connectionMonitor_ != nullptr) { 295 connectionMonitor_->UpdateCallState(state); 296 } 297} 298 299int32_t DataConnectionManager::GetDataRecoveryState() 300{ 301 if (connectionMonitor_ != nullptr) { 302 return static_cast<int32_t>(connectionMonitor_->GetDataRecoveryState()); 303 } 304 return -1; 305} 306 307int32_t DataConnectionManager::GetSlotId() const 308{ 309 return slotId_; 310} 311 312int32_t DataConnectionManager::GetDataFlowType() 313{ 314 if (connectionMonitor_ == nullptr) { 315 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_); 316 return static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_NONE); 317 } 318 CellDataFlowType flowType = connectionMonitor_->GetDataFlowType(); 319 return static_cast<int32_t>(flowType); 320} 321 322void DataConnectionManager::SetDataFlowType(CellDataFlowType dataFlowType) 323{ 324 if (connectionMonitor_ == nullptr) { 325 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_); 326 return; 327 } 328 connectionMonitor_->SetDataFlowType(dataFlowType); 329} 330 331void DataConnectionManager::GetDefaultBandWidthsConfig() 332{ 333 OperatorConfig operatorConfig; 334 CoreManagerInner::GetInstance().GetOperatorConfigs(slotId_, operatorConfig); 335 if (operatorConfig.boolValue.find(KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL) != operatorConfig.boolValue.end()) { 336 bandwidthSourceModem_ = operatorConfig.boolValue[KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL]; 337 } 338 if (operatorConfig.boolValue.find(KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL) != 339 operatorConfig.boolValue.end()) { 340 uplinkUseLte_ = operatorConfig.boolValue[KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL]; 341 } 342 std::vector<std::string> linkBandwidthVec; 343 if (operatorConfig.stringArrayValue.find(KEY_BANDWIDTH_STRING_ARRAY) != operatorConfig.stringArrayValue.end()) { 344 linkBandwidthVec = operatorConfig.stringArrayValue[KEY_BANDWIDTH_STRING_ARRAY]; 345 } 346 if (linkBandwidthVec.empty()) { 347 linkBandwidthVec = CellularDataUtils::Split(DEFAULT_BANDWIDTH_CONFIG, ";"); 348 } 349 std::lock_guard<std::mutex> lock(bandwidthConfigMutex_); 350 bandwidthConfigMap_.clear(); 351 for (std::string temp : linkBandwidthVec) { 352 std::vector<std::string> linkBandwidths = CellularDataUtils::Split(temp, ":"); 353 if (linkBandwidths.size() == VALID_VECTOR_SIZE) { 354 std::string key = linkBandwidths.front(); 355 std::string linkUpDownBandwidth = linkBandwidths.back(); 356 std::vector<std::string> upDownBandwidthValue = CellularDataUtils::Split(linkUpDownBandwidth, ","); 357 if (upDownBandwidthValue.size() == VALID_VECTOR_SIZE) { 358 LinkBandwidthInfo linkBandwidthInfo; 359 linkBandwidthInfo.downBandwidth = (atoi)(upDownBandwidthValue.front().c_str()); 360 linkBandwidthInfo.upBandwidth = (atoi)(upDownBandwidthValue.back().c_str()); 361 bandwidthConfigMap_.emplace(key, linkBandwidthInfo); 362 } 363 } 364 } 365 TELEPHONY_LOGI("Slot%{public}d: BANDWIDTH_CONFIG_MAP size is %{public}zu", slotId_, bandwidthConfigMap_.size()); 366 UpdateBandWidthsUseLte(); 367} 368 369void DataConnectionManager::UpdateBandWidthsUseLte() 370{ 371 if (!uplinkUseLte_) { 372 return; 373 } 374 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find("LTE"); 375 if (iter != bandwidthConfigMap_.end()) { 376 LinkBandwidthInfo lteLinkBandwidthInfo = iter->second; 377 TELEPHONY_LOGI("Slot%{public}d: name is %{public}s upBandwidth = %{public}u downBandwidth = %{public}u", 378 slotId_, iter->first.c_str(), lteLinkBandwidthInfo.upBandwidth, lteLinkBandwidthInfo.downBandwidth); 379 iter = bandwidthConfigMap_.find("NR_NSA"); 380 if (iter != bandwidthConfigMap_.end()) { 381 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth; 382 } 383 iter = bandwidthConfigMap_.find("NR_NSA_MMWAVE"); 384 if (iter != bandwidthConfigMap_.end()) { 385 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth; 386 } 387 } 388} 389 390void DataConnectionManager::GetDefaultTcpBufferConfig() 391{ 392 char tcpBufferConfig[MAX_BUFFER_SIZE] = {0}; 393 GetParameter(CONFIG_TCP_BUFFER, DEFAULT_TCP_BUFFER_CONFIG, tcpBufferConfig, MAX_BUFFER_SIZE); 394 std::vector<std::string> tcpBufferVec = CellularDataUtils::Split(tcpBufferConfig, ";"); 395 std::lock_guard<std::mutex> lock(tcpBufferConfigMutex_); 396 tcpBufferConfigMap_.clear(); 397 for (std::string tcpBuffer : tcpBufferVec) { 398 std::vector<std::string> str = CellularDataUtils::Split(tcpBuffer, ":"); 399 tcpBufferConfigMap_.emplace(str.front(), str.back()); 400 } 401 TELEPHONY_LOGI("Slot%{public}d: TCP_BUFFER_CONFIG_MAP size is %{public}zu", slotId_, tcpBufferConfigMap_.size()); 402} 403 404LinkBandwidthInfo DataConnectionManager::GetBandwidthsByRadioTech(const int32_t radioTech) 405{ 406 LinkBandwidthInfo linkBandwidthInfo; 407 CoreManagerInner &coreInner = CoreManagerInner::GetInstance(); 408 NrState nrState = coreInner.GetNrState(slotId_); 409 FrequencyType frequencyType = coreInner.GetFrequencyType(slotId_); 410 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech); 411 if (radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE && 412 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) { 413 if (frequencyType == FrequencyType::FREQ_TYPE_MMWAVE) { 414 radioTechName = "NR_NSA_MMWAVE"; 415 } else { 416 radioTechName = "NR_NSA"; 417 } 418 } 419 if (radioTechName == "NR") { 420 radioTechName = "NR_SA"; 421 } 422 TELEPHONY_LOGI("Slot%{public}d: accessRadioName is %{private}s", slotId_, radioTechName.c_str()); 423 std::lock_guard<std::mutex> lock(bandwidthConfigMutex_); 424 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find(radioTechName); 425 if (iter != bandwidthConfigMap_.end()) { 426 linkBandwidthInfo = iter->second; 427 TELEPHONY_LOGI("Slot%{public}d: name is %{private}s upBandwidth = %{public}u downBandwidth = %{public}u", 428 slotId_, iter->first.c_str(), linkBandwidthInfo.upBandwidth, linkBandwidthInfo.downBandwidth); 429 } 430 return linkBandwidthInfo; 431} 432 433std::string DataConnectionManager::GetTcpBufferByRadioTech(const int32_t radioTech) 434{ 435 std::string tcpBuffer = ""; 436 CoreManagerInner &coreInner = CoreManagerInner::GetInstance(); 437 NrState nrState = coreInner.GetNrState(slotId_); 438 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech); 439 if ((radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE || 440 radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE_CA) && 441 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) { 442 radioTechName = "NR"; 443 } 444 std::lock_guard<std::mutex> lock(tcpBufferConfigMutex_); 445 std::map<std::string, std::string>::iterator iter = tcpBufferConfigMap_.find(radioTechName); 446 if (iter != tcpBufferConfigMap_.end()) { 447 tcpBuffer = iter->second; 448 } 449 return tcpBuffer; 450} 451 452void DataConnectionManager::IsNeedDoRecovery(bool needDoRecovery) const 453{ 454 if (connectionMonitor_ != nullptr) { 455 connectionMonitor_->IsNeedDoRecovery(needDoRecovery); 456 } 457} 458 459void DataConnectionManager::HandleScreenStateChanged(bool isScreenOn) const 460{ 461 if (connectionMonitor_ == nullptr) { 462 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_); 463 return; 464 } 465 connectionMonitor_->HandleScreenStateChanged(isScreenOn); 466} 467} // namespace Telephony 468} // namespace OHOS 469