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 "hril_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 UpdateNetworkInfo(event);
214 std::vector<std::shared_ptr<CellularDataStateMachine>> retryDataConnection;
215 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap =
216 connectManager_.GetActiveConnection();
217 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>>& it : idActiveConnectionMap) {
218 bool isPush = true;
219 if (it.second == nullptr) {
220 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first);
221 continue;
222 }
223 int32_t cid = it.second->GetCid();
224 for (size_t i = 0; i < infos->dcList.size(); ++i) {
225 if (infos->dcList[i].cid == cid && infos->dcList[i].active > 0) {
226 isPush = false;
227 break;
228 }
229 }
230 if (isPush) {
231 TELEPHONY_LOGI("cid:%{public}d add to retry", it.first);
232 retryDataConnection.push_back(it.second);
233 }
234 }
235 for (std::shared_ptr<CellularDataStateMachine> &it : retryDataConnection) {
236 if (it == nullptr) {
237 TELEPHONY_LOGI(" retryDataConnection is null");
238 continue;
239 }
240 AppExecFwk::InnerEvent::Pointer event =
241 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LOST_CONNECTION);
242 it->SendEvent(event);
243 }
244 }
245
RadioLinkCapabilityChanged(const AppExecFwk::InnerEvent::Pointer & event)246 void CcmDefaultState::RadioLinkCapabilityChanged(const AppExecFwk::InnerEvent::Pointer &event)
247 {
248 std::shared_ptr<DataLinkCapability> linkCapability = event->GetSharedObject<DataLinkCapability>();
249 if (linkCapability == nullptr) {
250 TELEPHONY_LOGE("linkCapability is null");
251 return;
252 }
253 if (connectManager_.IsBandwidthSourceModem()) {
254 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap =
255 connectManager_.GetActiveConnection();
256 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>> &it : idActiveConnectionMap) {
257 if (it.second == nullptr) {
258 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first);
259 continue;
260 }
261 AppExecFwk::InnerEvent::Pointer smEvent =
262 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LINK_CAPABILITY_CHANGED, linkCapability);
263 it.second->SendEvent(smEvent);
264 }
265 }
266 }
267
UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer & event)268 void CcmDefaultState::UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer &event)
269 {
270 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>();
271 if (infos == nullptr) {
272 TELEPHONY_LOGE("dataCallResultList is null");
273 return;
274 }
275 for (SetupDataCallResultInfo &it : infos->dcList) {
276 std::shared_ptr<CellularDataStateMachine> dataConnect = connectManager_.GetActiveConnectionByCid(it.cid);
277 if (dataConnect == nullptr) {
278 TELEPHONY_LOGE("get active connection by cid is := %{public}d flag:= %{public}d ", it.cid, it.flag);
279 continue;
280 }
281 dataConnect->UpdateNetworkInfo(it);
282 }
283 }
284
BeginNetStatistics()285 void DataConnectionManager::BeginNetStatistics()
286 {
287 if (connectionMonitor_ != nullptr) {
288 connectionMonitor_->BeginNetStatistics();
289 }
290 }
291
EndNetStatistics()292 void DataConnectionManager::EndNetStatistics()
293 {
294 if (connectionMonitor_ != nullptr) {
295 connectionMonitor_->EndNetStatistics();
296 }
297 }
298
UpdateCallState(int32_t state)299 void DataConnectionManager::UpdateCallState(int32_t state)
300 {
301 if (connectionMonitor_ != nullptr) {
302 connectionMonitor_->UpdateCallState(state);
303 }
304 }
305
GetDataRecoveryState()306 int32_t DataConnectionManager::GetDataRecoveryState()
307 {
308 if (connectionMonitor_ != nullptr) {
309 return static_cast<int32_t>(connectionMonitor_->GetDataRecoveryState());
310 }
311 return -1;
312 }
313
GetSlotId() const314 int32_t DataConnectionManager::GetSlotId() const
315 {
316 return slotId_;
317 }
318
GetDataFlowType()319 int32_t DataConnectionManager::GetDataFlowType()
320 {
321 if (connectionMonitor_ == nullptr) {
322 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
323 return static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_NONE);
324 }
325 CellDataFlowType flowType = connectionMonitor_->GetDataFlowType();
326 return static_cast<int32_t>(flowType);
327 }
328
SetDataFlowType(CellDataFlowType dataFlowType)329 void DataConnectionManager::SetDataFlowType(CellDataFlowType dataFlowType)
330 {
331 if (connectionMonitor_ == nullptr) {
332 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
333 return;
334 }
335 connectionMonitor_->SetDataFlowType(dataFlowType);
336 }
337
GetDefaultBandWidthsConfig()338 void DataConnectionManager::GetDefaultBandWidthsConfig()
339 {
340 OperatorConfig operatorConfig;
341 CoreManagerInner::GetInstance().GetOperatorConfigs(slotId_, operatorConfig);
342 if (operatorConfig.boolValue.find(KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL) != operatorConfig.boolValue.end()) {
343 bandwidthSourceModem_ = operatorConfig.boolValue[KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL];
344 }
345 if (operatorConfig.boolValue.find(KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL) !=
346 operatorConfig.boolValue.end()) {
347 uplinkUseLte_ = operatorConfig.boolValue[KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL];
348 }
349 std::vector<std::string> linkBandwidthVec;
350 if (operatorConfig.stringArrayValue.find(KEY_BANDWIDTH_STRING_ARRAY) != operatorConfig.stringArrayValue.end()) {
351 linkBandwidthVec = operatorConfig.stringArrayValue[KEY_BANDWIDTH_STRING_ARRAY];
352 }
353 if (linkBandwidthVec.empty()) {
354 linkBandwidthVec = CellularDataUtils::Split(DEFAULT_BANDWIDTH_CONFIG, ";");
355 }
356 bandwidthConfigMap_.clear();
357 for (std::string temp : linkBandwidthVec) {
358 std::vector<std::string> linkBandwidths = CellularDataUtils::Split(temp, ":");
359 if (linkBandwidths.size() == VALID_VECTOR_SIZE) {
360 std::string key = linkBandwidths.front();
361 std::string linkUpDownBandwidth = linkBandwidths.back();
362 std::vector<std::string> upDownBandwidthValue = CellularDataUtils::Split(linkUpDownBandwidth, ",");
363 if (upDownBandwidthValue.size() == VALID_VECTOR_SIZE) {
364 LinkBandwidthInfo linkBandwidthInfo;
365 linkBandwidthInfo.downBandwidth = (atoi)(upDownBandwidthValue.front().c_str());
366 linkBandwidthInfo.upBandwidth = (atoi)(upDownBandwidthValue.back().c_str());
367 bandwidthConfigMap_.emplace(key, linkBandwidthInfo);
368 }
369 }
370 }
371 TELEPHONY_LOGI("Slot%{public}d: BANDWIDTH_CONFIG_MAP size is %{public}zu", slotId_, bandwidthConfigMap_.size());
372 UpdateBandWidthsUseLte();
373 }
374
UpdateBandWidthsUseLte()375 void DataConnectionManager::UpdateBandWidthsUseLte()
376 {
377 if (!uplinkUseLte_) {
378 return;
379 }
380 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find("LTE");
381 if (iter != bandwidthConfigMap_.end()) {
382 LinkBandwidthInfo lteLinkBandwidthInfo = iter->second;
383 TELEPHONY_LOGI("Slot%{public}d: name is %{public}s upBandwidth = %{public}u downBandwidth = %{public}u",
384 slotId_, iter->first.c_str(), lteLinkBandwidthInfo.upBandwidth, lteLinkBandwidthInfo.downBandwidth);
385 iter = bandwidthConfigMap_.find("NR_NSA");
386 if (iter != bandwidthConfigMap_.end()) {
387 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth;
388 }
389 iter = bandwidthConfigMap_.find("NR_NSA_MMWAVE");
390 if (iter != bandwidthConfigMap_.end()) {
391 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth;
392 }
393 }
394 }
395
GetDefaultTcpBufferConfig()396 void DataConnectionManager::GetDefaultTcpBufferConfig()
397 {
398 tcpBufferConfigMap_.clear();
399 char tcpBufferConfig[MAX_BUFFER_SIZE] = {0};
400 GetParameter(CONFIG_TCP_BUFFER, DEFAULT_TCP_BUFFER_CONFIG, tcpBufferConfig, MAX_BUFFER_SIZE);
401 std::vector<std::string> tcpBufferVec = CellularDataUtils::Split(tcpBufferConfig, ";");
402 for (std::string tcpBuffer : tcpBufferVec) {
403 std::vector<std::string> str = CellularDataUtils::Split(tcpBuffer, ":");
404 tcpBufferConfigMap_.emplace(str.front(), str.back());
405 }
406 TELEPHONY_LOGI("Slot%{public}d: TCP_BUFFER_CONFIG_MAP size is %{public}zu", slotId_, tcpBufferConfigMap_.size());
407 }
408
GetBandwidthsByRadioTech(const int32_t radioTech)409 LinkBandwidthInfo DataConnectionManager::GetBandwidthsByRadioTech(const int32_t radioTech)
410 {
411 LinkBandwidthInfo linkBandwidthInfo;
412 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
413 NrState nrState = coreInner.GetNrState(slotId_);
414 FrequencyType frequencyType = coreInner.GetFrequencyType(slotId_);
415 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
416 if (radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE &&
417 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
418 if (frequencyType == FrequencyType::FREQ_TYPE_MMWAVE) {
419 radioTechName = "NR_NSA_MMWAVE";
420 } else {
421 radioTechName = "NR_NSA";
422 }
423 }
424 if (radioTechName == "NR") {
425 radioTechName = "NR_SA";
426 }
427 TELEPHONY_LOGI("Slot%{public}d: accessRadioName is %{private}s", slotId_, radioTechName.c_str());
428 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find(radioTechName);
429 if (iter != bandwidthConfigMap_.end()) {
430 linkBandwidthInfo = iter->second;
431 TELEPHONY_LOGI("Slot%{public}d: name is %{private}s upBandwidth = %{public}u downBandwidth = %{public}u",
432 slotId_, iter->first.c_str(), linkBandwidthInfo.upBandwidth, linkBandwidthInfo.downBandwidth);
433 }
434 return linkBandwidthInfo;
435 }
436
GetTcpBufferByRadioTech(const int32_t radioTech)437 std::string DataConnectionManager::GetTcpBufferByRadioTech(const int32_t radioTech)
438 {
439 std::string tcpBuffer = "";
440 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
441 NrState nrState = coreInner.GetNrState(slotId_);
442 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
443 if ((radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE ||
444 radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE_CA) &&
445 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
446 radioTechName = "NR";
447 }
448 std::map<std::string, std::string>::iterator iter = tcpBufferConfigMap_.find(radioTechName);
449 if (iter != tcpBufferConfigMap_.end()) {
450 tcpBuffer = iter->second;
451 }
452 return tcpBuffer;
453 }
454
IsNeedDoRecovery(bool needDoRecovery) const455 void DataConnectionManager::IsNeedDoRecovery(bool needDoRecovery) const
456 {
457 if (connectionMonitor_ != nullptr) {
458 connectionMonitor_->IsNeedDoRecovery(needDoRecovery);
459 }
460 }
461 } // namespace Telephony
462 } // namespace OHOS
463