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 
28 namespace OHOS {
29 namespace Telephony {
DataConnectionManager(int32_t slotId)30 DataConnectionManager::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 
~DataConnectionManager()39 DataConnectionManager::~DataConnectionManager()
40 {
41     if (connectionMonitor_ != nullptr) {
42         connectionMonitor_->RemoveAllEvents();
43     }
44 }
45 
Init()46 void 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 
AddConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)57 void 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 
RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)65 void 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 
GetAllConnectionMachine()81 std::vector<std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetAllConnectionMachine()
82 {
83     std::lock_guard<std::mutex> lock(stateMachineMutex_);
84     return stateMachines_;
85 }
86 
AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> &stateMachine)87 void 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 
GetActiveConnectionByCid(int32_t cid)95 std::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 
GetActiveConnection()105 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetActiveConnection()
106 {
107     std::lock_guard<std::mutex> lock(activeConnectionMutex_);
108     return cidActiveConnectionMap_;
109 }
110 
IsBandwidthSourceModem() const111 bool DataConnectionManager::IsBandwidthSourceModem() const
112 {
113     return bandwidthSourceModem_;
114 }
115 
isNoActiveConnection()116 bool DataConnectionManager::isNoActiveConnection()
117 {
118     std::lock_guard<std::mutex> lock(activeConnectionMutex_);
119     if (cidActiveConnectionMap_.empty()) {
120         return true;
121     }
122     return false;
123 }
124 
RemoveActiveConnectionByCid(int32_t cid)125 void 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 
StartStallDetectionTimer()133 void DataConnectionManager::StartStallDetectionTimer()
134 {
135     if (connectionMonitor_ != nullptr) {
136         connectionMonitor_->StartStallDetectionTimer();
137     }
138 }
139 
StopStallDetectionTimer()140 void DataConnectionManager::StopStallDetectionTimer()
141 {
142     if (connectionMonitor_ != nullptr) {
143         connectionMonitor_->StopStallDetectionTimer();
144     }
145 }
146 
RegisterRadioObserver()147 void 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 
UnRegisterRadioObserver() const160 void 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 
StateBegin()172 void CcmDefaultState::StateBegin()
173 {
174     connectManager_.RegisterRadioObserver();
175 }
176 
StateEnd()177 void CcmDefaultState::StateEnd()
178 {
179     connectManager_.UnRegisterRadioObserver();
180 }
181 
StateProcess(const AppExecFwk::InnerEvent::Pointer &event)182 bool 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 
RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer &event)206 void 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 
RadioLinkCapabilityChanged(const AppExecFwk::InnerEvent::Pointer &event)239 void 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 
UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer &event)261 void 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 
BeginNetStatistics()278 void DataConnectionManager::BeginNetStatistics()
279 {
280     if (connectionMonitor_ != nullptr) {
281         connectionMonitor_->BeginNetStatistics();
282     }
283 }
284 
EndNetStatistics()285 void DataConnectionManager::EndNetStatistics()
286 {
287     if (connectionMonitor_ != nullptr) {
288         connectionMonitor_->EndNetStatistics();
289     }
290 }
291 
UpdateCallState(int32_t state)292 void DataConnectionManager::UpdateCallState(int32_t state)
293 {
294     if (connectionMonitor_ != nullptr) {
295         connectionMonitor_->UpdateCallState(state);
296     }
297 }
298 
GetDataRecoveryState()299 int32_t DataConnectionManager::GetDataRecoveryState()
300 {
301     if (connectionMonitor_ != nullptr) {
302         return static_cast<int32_t>(connectionMonitor_->GetDataRecoveryState());
303     }
304     return -1;
305 }
306 
GetSlotId() const307 int32_t DataConnectionManager::GetSlotId() const
308 {
309     return slotId_;
310 }
311 
GetDataFlowType()312 int32_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 
SetDataFlowType(CellDataFlowType dataFlowType)322 void 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 
GetDefaultBandWidthsConfig()331 void 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 
UpdateBandWidthsUseLte()369 void 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 
GetDefaultTcpBufferConfig()390 void 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 
GetBandwidthsByRadioTech(const int32_t radioTech)404 LinkBandwidthInfo 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 
GetTcpBufferByRadioTech(const int32_t radioTech)433 std::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 
IsNeedDoRecovery(bool needDoRecovery) const452 void DataConnectionManager::IsNeedDoRecovery(bool needDoRecovery) const
453 {
454     if (connectionMonitor_ != nullptr) {
455         connectionMonitor_->IsNeedDoRecovery(needDoRecovery);
456     }
457 }
458 
HandleScreenStateChanged(bool isScreenOn) const459 void 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