• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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