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(const std::shared_ptr<AppExecFwk::EventRunner> & runner,int32_t slotId)30 DataConnectionManager::DataConnectionManager(const std::shared_ptr<AppExecFwk::EventRunner> &runner, int32_t slotId)
31 : StateMachine(runner), slotId_(slotId)
32 {
33 connectionMonitor_ = std::make_shared<DataConnectionMonitor>(runner, slotId);
34 ccmDefaultState_ = std::make_unique<CcmDefaultState>(*this, "CcmDefaultState").release();
35 if (connectionMonitor_ == nullptr || ccmDefaultState_ == nullptr) {
36 TELEPHONY_LOGE("Slot%{public}d: connectionMonitor_ or ccmDefaultState is null", slotId_);
37 return;
38 }
39 StateMachine::SetOriginalState(ccmDefaultState_);
40 StateMachine::Start();
41 }
42
~DataConnectionManager()43 DataConnectionManager::~DataConnectionManager()
44 {
45 if (connectionMonitor_ != nullptr) {
46 connectionMonitor_->RemoveAllEvents();
47 }
48 }
49
AddConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> & stateMachine)50 void DataConnectionManager::AddConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
51 {
52 std::lock_guard<std::mutex> lock(stateMachineMutex_);
53 if (stateMachine != nullptr) {
54 stateMachines_.push_back(stateMachine);
55 }
56 }
57
RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> & stateMachine)58 void DataConnectionManager::RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
59 {
60 if (stateMachine == nullptr) {
61 TELEPHONY_LOGE("Slot%{public}d: stateMachine is null", slotId_);
62 return;
63 }
64 std::lock_guard<std::mutex> lock(stateMachineMutex_);
65 for (std::vector<std::shared_ptr<CellularDataStateMachine>>::const_iterator iter =
66 stateMachines_.begin(); iter != stateMachines_.end(); iter++) {
67 if (*iter.base() == stateMachine) {
68 stateMachines_.erase(iter);
69 break;
70 }
71 }
72 }
73
GetAllConnectionMachine()74 std::vector<std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetAllConnectionMachine()
75 {
76 std::lock_guard<std::mutex> lock(stateMachineMutex_);
77 return stateMachines_;
78 }
79
AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> & stateMachine)80 void DataConnectionManager::AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
81 {
82 std::lock_guard<std::mutex> lock(activeConnectionMutex_);
83 if (stateMachine != nullptr) {
84 cidActiveConnectionMap_[stateMachine->GetCid()] = stateMachine;
85 }
86 }
87
GetActiveConnectionByCid(int32_t cid)88 std::shared_ptr<CellularDataStateMachine> DataConnectionManager::GetActiveConnectionByCid(int32_t cid)
89 {
90 std::lock_guard<std::mutex> lock(activeConnectionMutex_);
91 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>>::const_iterator it = cidActiveConnectionMap_.find(cid);
92 if (it != cidActiveConnectionMap_.end()) {
93 return it->second;
94 }
95 return nullptr;
96 }
97
GetActiveConnection()98 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetActiveConnection()
99 {
100 std::lock_guard<std::mutex> lock(activeConnectionMutex_);
101 return cidActiveConnectionMap_;
102 }
103
IsBandwidthSourceModem() const104 bool DataConnectionManager::IsBandwidthSourceModem() const
105 {
106 return bandwidthSourceModem_;
107 }
108
isNoActiveConnection()109 bool DataConnectionManager::isNoActiveConnection()
110 {
111 std::lock_guard<std::mutex> lock(activeConnectionMutex_);
112 if (cidActiveConnectionMap_.empty()) {
113 return true;
114 }
115 return false;
116 }
117
RemoveActiveConnectionByCid(int32_t cid)118 void DataConnectionManager::RemoveActiveConnectionByCid(int32_t cid)
119 {
120 std::lock_guard<std::mutex> lock(activeConnectionMutex_);
121 if (cidActiveConnectionMap_.find(cid) != cidActiveConnectionMap_.end()) {
122 cidActiveConnectionMap_.erase(cid);
123 }
124 }
125
StartStallDetectionTimer()126 void DataConnectionManager::StartStallDetectionTimer()
127 {
128 if (connectionMonitor_ != nullptr) {
129 connectionMonitor_->StartStallDetectionTimer();
130 }
131 }
132
StopStallDetectionTimer()133 void DataConnectionManager::StopStallDetectionTimer()
134 {
135 if (connectionMonitor_ != nullptr) {
136 connectionMonitor_->StopStallDetectionTimer();
137 }
138 }
139
RegisterRadioObserver()140 void DataConnectionManager::RegisterRadioObserver()
141 {
142 if (stateMachineEventHandler_ == nullptr) {
143 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr!");
144 return;
145 }
146 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
147 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED, nullptr);
148 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_DATA_CALL_LIST_CHANGED, nullptr);
149 coreInner.RegisterCoreNotify(
150 slotId_, stateMachineEventHandler_, RadioEvent::RADIO_LINK_CAPABILITY_CHANGED, nullptr);
151 }
152
UnRegisterRadioObserver() const153 void DataConnectionManager::UnRegisterRadioObserver() const
154 {
155 if (stateMachineEventHandler_ == nullptr) {
156 TELEPHONY_LOGE("stateMachineEventHandler_ is nullptr!");
157 return;
158 }
159 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
160 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED);
161 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_DATA_CALL_LIST_CHANGED);
162 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_LINK_CAPABILITY_CHANGED);
163 }
164
StateBegin()165 void CcmDefaultState::StateBegin()
166 {
167 connectManager_.RegisterRadioObserver();
168 }
169
StateEnd()170 void CcmDefaultState::StateEnd()
171 {
172 connectManager_.UnRegisterRadioObserver();
173 }
174
StateProcess(const AppExecFwk::InnerEvent::Pointer & event)175 bool CcmDefaultState::StateProcess(const AppExecFwk::InnerEvent::Pointer &event)
176 {
177 if (event == nullptr) {
178 TELEPHONY_LOGE("event is null");
179 return false;
180 }
181 int32_t id = event->GetInnerEventId();
182 switch (id) {
183 case RadioEvent::RADIO_CONNECTED:
184 TELEPHONY_LOGI("Radio is connected");
185 break;
186 case RadioEvent::RADIO_DATA_CALL_LIST_CHANGED:
187 RadioDataCallListChanged(event);
188 break;
189 case RadioEvent::RADIO_LINK_CAPABILITY_CHANGED:
190 RadioLinkCapabilityChanged(event);
191 break;
192 default:
193 TELEPHONY_LOGE("StateProcess handle nothing!");
194 return false;
195 }
196 return true;
197 }
198
RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer & event)199 void CcmDefaultState::RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer &event)
200 {
201 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>();
202 if (infos == nullptr) {
203 TELEPHONY_LOGE("setupDataCallResultInfo is null");
204 return;
205 }
206 UpdateNetworkInfo(event);
207 std::vector<std::shared_ptr<CellularDataStateMachine>> retryDataConnection;
208 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap =
209 connectManager_.GetActiveConnection();
210 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>>& it : idActiveConnectionMap) {
211 bool isPush = true;
212 if (it.second == nullptr) {
213 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first);
214 continue;
215 }
216 int32_t cid = it.second->GetCid();
217 for (size_t i = 0; i < infos->dcList.size(); ++i) {
218 if (infos->dcList[i].cid == cid && infos->dcList[i].active > 0) {
219 isPush = false;
220 break;
221 }
222 }
223 if (isPush) {
224 TELEPHONY_LOGI("cid:%{public}d add to retry", it.first);
225 retryDataConnection.push_back(it.second);
226 }
227 }
228 for (std::shared_ptr<CellularDataStateMachine> &it : retryDataConnection) {
229 if (it == nullptr) {
230 TELEPHONY_LOGI(" retryDataConnection is null");
231 continue;
232 }
233 AppExecFwk::InnerEvent::Pointer event =
234 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LOST_CONNECTION);
235 it->SendEvent(event);
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->UpdateNetworkInfo(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
GetSlotId() const292 int32_t DataConnectionManager::GetSlotId() const
293 {
294 return slotId_;
295 }
296
GetDataFlowType()297 int32_t DataConnectionManager::GetDataFlowType()
298 {
299 if (connectionMonitor_ == nullptr) {
300 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
301 return static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_NONE);
302 }
303 CellDataFlowType flowType = connectionMonitor_->GetDataFlowType();
304 return static_cast<int32_t>(flowType);
305 }
306
SetDataFlowType(CellDataFlowType dataFlowType)307 void DataConnectionManager::SetDataFlowType(CellDataFlowType dataFlowType)
308 {
309 if (connectionMonitor_ == nullptr) {
310 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
311 return;
312 }
313 connectionMonitor_->SetDataFlowType(dataFlowType);
314 }
315
GetDefaultBandWidthsConfig()316 void DataConnectionManager::GetDefaultBandWidthsConfig()
317 {
318 OperatorConfig operatorConfig;
319 CoreManagerInner::GetInstance().GetOperatorConfigs(slotId_, operatorConfig);
320 if (operatorConfig.boolValue.find(KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL) != operatorConfig.boolValue.end()) {
321 bandwidthSourceModem_ = operatorConfig.boolValue[KEY_BANDWIDTH_SOURCE_USE_MODEM_BOOL];
322 }
323 if (operatorConfig.boolValue.find(KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL) !=
324 operatorConfig.boolValue.end()) {
325 uplinkUseLte_ = operatorConfig.boolValue[KEY_UPLINK_BANDWIDTH_NR_NSA_USE_LTE_VALUE_BOOL];
326 }
327 std::vector<std::string> linkBandwidthVec;
328 if (operatorConfig.stringArrayValue.find(KEY_BANDWIDTH_STRING_ARRAY) != operatorConfig.stringArrayValue.end()) {
329 linkBandwidthVec = operatorConfig.stringArrayValue[KEY_BANDWIDTH_STRING_ARRAY];
330 }
331 if (linkBandwidthVec.empty()) {
332 linkBandwidthVec = CellularDataUtils::Split(DEFAULT_BANDWIDTH_CONFIG, ";");
333 }
334 bandwidthConfigMap_.clear();
335 for (std::string temp : linkBandwidthVec) {
336 std::vector<std::string> linkBandwidths = CellularDataUtils::Split(temp, ":");
337 if (linkBandwidths.size() == VALID_VECTOR_SIZE) {
338 std::string key = linkBandwidths.front();
339 std::string linkUpDownBandwidth = linkBandwidths.back();
340 std::vector<std::string> upDownBandwidthValue = CellularDataUtils::Split(linkUpDownBandwidth, ",");
341 if (upDownBandwidthValue.size() == VALID_VECTOR_SIZE) {
342 LinkBandwidthInfo linkBandwidthInfo;
343 linkBandwidthInfo.downBandwidth = (atoi)(upDownBandwidthValue.front().c_str());
344 linkBandwidthInfo.upBandwidth = (atoi)(upDownBandwidthValue.back().c_str());
345 bandwidthConfigMap_.emplace(key, linkBandwidthInfo);
346 }
347 }
348 }
349 TELEPHONY_LOGI("Slot%{public}d: BANDWIDTH_CONFIG_MAP size is %{public}zu", slotId_, bandwidthConfigMap_.size());
350 UpdateBandWidthsUseLte();
351 }
352
UpdateBandWidthsUseLte()353 void DataConnectionManager::UpdateBandWidthsUseLte()
354 {
355 if (!uplinkUseLte_) {
356 return;
357 }
358 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find("LTE");
359 if (iter != bandwidthConfigMap_.end()) {
360 LinkBandwidthInfo lteLinkBandwidthInfo = iter->second;
361 TELEPHONY_LOGI("Slot%{public}d: name is %{public}s upBandwidth = %{public}u downBandwidth = %{public}u",
362 slotId_, iter->first.c_str(), lteLinkBandwidthInfo.upBandwidth, lteLinkBandwidthInfo.downBandwidth);
363 iter = bandwidthConfigMap_.find("NR_NSA");
364 if (iter != bandwidthConfigMap_.end()) {
365 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth;
366 }
367 iter = bandwidthConfigMap_.find("NR_NSA_MMWAVE");
368 if (iter != bandwidthConfigMap_.end()) {
369 iter->second.upBandwidth = lteLinkBandwidthInfo.upBandwidth;
370 }
371 }
372 }
373
GetDefaultTcpBufferConfig()374 void DataConnectionManager::GetDefaultTcpBufferConfig()
375 {
376 tcpBufferConfigMap_.clear();
377 char tcpBufferConfig[MAX_BUFFER_SIZE] = {0};
378 GetParameter(CONFIG_TCP_BUFFER, DEFAULT_TCP_BUFFER_CONFIG, tcpBufferConfig, MAX_BUFFER_SIZE);
379 std::vector<std::string> tcpBufferVec = CellularDataUtils::Split(tcpBufferConfig, ";");
380 for (std::string tcpBuffer : tcpBufferVec) {
381 std::vector<std::string> str = CellularDataUtils::Split(tcpBuffer, ":");
382 tcpBufferConfigMap_.emplace(str.front(), str.back());
383 }
384 TELEPHONY_LOGI("Slot%{public}d: TCP_BUFFER_CONFIG_MAP size is %{public}zu", slotId_, tcpBufferConfigMap_.size());
385 }
386
GetBandwidthsByRadioTech(const int32_t radioTech)387 LinkBandwidthInfo DataConnectionManager::GetBandwidthsByRadioTech(const int32_t radioTech)
388 {
389 LinkBandwidthInfo linkBandwidthInfo;
390 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
391 NrState nrState = coreInner.GetNrState(slotId_);
392 FrequencyType frequencyType = coreInner.GetFrequencyType(slotId_);
393 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
394 if (radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE &&
395 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
396 if (frequencyType == FrequencyType::FREQ_TYPE_MMWAVE) {
397 radioTechName = "NR_NSA_MMWAVE";
398 } else {
399 radioTechName = "NR_NSA";
400 }
401 }
402 if (radioTechName == "NR") {
403 radioTechName = "NR_SA";
404 }
405 TELEPHONY_LOGI("Slot%{public}d: accessRadioName is %{public}s", slotId_, radioTechName.c_str());
406 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find(radioTechName);
407 if (iter != bandwidthConfigMap_.end()) {
408 linkBandwidthInfo = iter->second;
409 TELEPHONY_LOGI("Slot%{public}d: name is %{public}s upBandwidth = %{public}u downBandwidth = %{public}u",
410 slotId_, iter->first.c_str(), linkBandwidthInfo.upBandwidth, linkBandwidthInfo.downBandwidth);
411 }
412 return linkBandwidthInfo;
413 }
414
GetTcpBufferByRadioTech(const int32_t radioTech)415 std::string DataConnectionManager::GetTcpBufferByRadioTech(const int32_t radioTech)
416 {
417 std::string tcpBuffer = "";
418 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
419 NrState nrState = coreInner.GetNrState(slotId_);
420 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
421 if ((radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE ||
422 radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE_CA) &&
423 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
424 radioTechName = "NR";
425 }
426 std::map<std::string, std::string>::iterator iter = tcpBufferConfigMap_.find(radioTechName);
427 if (iter != tcpBufferConfigMap_.end()) {
428 tcpBuffer = iter->second;
429 }
430 return tcpBuffer;
431 }
432 } // namespace Telephony
433 } // namespace OHOS
434