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 "core_manager_inner.h"
19 #include "hril_data_parcel.h"
20 #include "radio_event.h"
21 #include "telephony_log_wrapper.h"
22
23 #include "cellular_data_event_code.h"
24 #include "cellular_data_handler.h"
25 #include "cellular_data_state_machine.h"
26 #include "cellular_data_utils.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 if (stateMachine != nullptr) {
53 stateMachines_.push_back(stateMachine);
54 }
55 }
56
RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> & stateMachine)57 void DataConnectionManager::RemoveConnectionStateMachine(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
58 {
59 if (stateMachine == nullptr) {
60 TELEPHONY_LOGE("Slot%{public}d: stateMachine is null", slotId_);
61 return;
62 }
63 for (std::vector<std::shared_ptr<CellularDataStateMachine>>::const_iterator iter =
64 stateMachines_.begin(); iter != stateMachines_.end(); iter++) {
65 if (*iter.base() == stateMachine) {
66 stateMachines_.erase(iter);
67 break;
68 }
69 }
70 }
71
GetAllConnectionMachine()72 std::vector<std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetAllConnectionMachine()
73 {
74 return stateMachines_;
75 }
76
AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> & stateMachine)77 void DataConnectionManager::AddActiveConnectionByCid(const std::shared_ptr<CellularDataStateMachine> &stateMachine)
78 {
79 if (stateMachine != nullptr) {
80 cidActiveConnectionMap_[stateMachine->GetCid()] = stateMachine;
81 }
82 }
83
GetActiveConnectionByCid(int32_t cid) const84 std::shared_ptr<CellularDataStateMachine> DataConnectionManager::GetActiveConnectionByCid(int32_t cid) const
85 {
86 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>>::const_iterator it = cidActiveConnectionMap_.find(cid);
87 if (it != cidActiveConnectionMap_.end()) {
88 return it->second;
89 }
90 return nullptr;
91 }
92
GetActiveConnection() const93 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> DataConnectionManager::GetActiveConnection() const
94 {
95 return cidActiveConnectionMap_;
96 }
97
isNoActiveConnection() const98 bool DataConnectionManager::isNoActiveConnection() const
99 {
100 if (cidActiveConnectionMap_.empty()) {
101 return true;
102 }
103 return false;
104 }
105
RemoveActiveConnectionByCid(int32_t cid)106 void DataConnectionManager::RemoveActiveConnectionByCid(int32_t cid)
107 {
108 if (cidActiveConnectionMap_.find(cid) != cidActiveConnectionMap_.end()) {
109 cidActiveConnectionMap_.erase(cid);
110 }
111 }
112
StartStallDetectionTimer()113 void DataConnectionManager::StartStallDetectionTimer()
114 {
115 if (connectionMonitor_ != nullptr) {
116 connectionMonitor_->StartStallDetectionTimer();
117 }
118 }
119
StopStallDetectionTimer()120 void DataConnectionManager::StopStallDetectionTimer()
121 {
122 if (connectionMonitor_ != nullptr) {
123 connectionMonitor_->StopStallDetectionTimer();
124 }
125 }
126
RegisterRadioObserver()127 void DataConnectionManager::RegisterRadioObserver()
128 {
129 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
130 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED, nullptr);
131 coreInner.RegisterCoreNotify(slotId_, stateMachineEventHandler_,
132 RadioEvent::RADIO_DATA_CALL_LIST_CHANGED, nullptr);
133 }
134
UnRegisterRadioObserver() const135 void DataConnectionManager::UnRegisterRadioObserver() const
136 {
137 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
138 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_CONNECTED);
139 coreInner.UnRegisterCoreNotify(slotId_, stateMachineEventHandler_, RadioEvent::RADIO_DATA_CALL_LIST_CHANGED);
140 }
141
StateBegin()142 void CcmDefaultState::StateBegin()
143 {
144 connectManager_.RegisterRadioObserver();
145 }
146
StateEnd()147 void CcmDefaultState::StateEnd()
148 {
149 connectManager_.UnRegisterRadioObserver();
150 }
151
StateProcess(const AppExecFwk::InnerEvent::Pointer & event)152 bool CcmDefaultState::StateProcess(const AppExecFwk::InnerEvent::Pointer &event)
153 {
154 if (event == nullptr) {
155 TELEPHONY_LOGE("event is null");
156 return false;
157 }
158 int32_t id = event->GetInnerEventId();
159 switch (id) {
160 case RadioEvent::RADIO_CONNECTED:
161 TELEPHONY_LOGI("Radio is connected");
162 break;
163 case RadioEvent::RADIO_DATA_CALL_LIST_CHANGED:
164 RadioDataCallListChanged(event);
165 break;
166 default:
167 TELEPHONY_LOGE("StateProcess handle nothing!");
168 return false;
169 }
170 return true;
171 }
172
RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer & event)173 void CcmDefaultState::RadioDataCallListChanged(const AppExecFwk::InnerEvent::Pointer &event)
174 {
175 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>();
176 if (infos == nullptr) {
177 TELEPHONY_LOGE("setupDataCallResultInfo is null");
178 return;
179 }
180 UpdateNetworkInfo(event);
181 std::vector<std::shared_ptr<CellularDataStateMachine>> retryDataConnection;
182 std::map<int32_t, std::shared_ptr<CellularDataStateMachine>> idActiveConnectionMap =
183 connectManager_.GetActiveConnection();
184 for (const std::pair<const int32_t, std::shared_ptr<CellularDataStateMachine>>& it : idActiveConnectionMap) {
185 bool isPush = true;
186 if (it.second == nullptr) {
187 TELEPHONY_LOGI("The activation item is null(%{public}d)", it.first);
188 continue;
189 }
190 int32_t cid = it.second->GetCid();
191 for (size_t i = 0; i < infos->dcList.size(); ++i) {
192 if (infos->dcList[i].cid == cid) {
193 isPush = false;
194 break;
195 }
196 }
197 if (isPush) {
198 TELEPHONY_LOGI("cid:%{public}d add to retry", it.first);
199 retryDataConnection.push_back(it.second);
200 }
201 }
202 for (std::shared_ptr<CellularDataStateMachine> &it : retryDataConnection) {
203 if (it == nullptr) {
204 TELEPHONY_LOGI(" retryDataConnection is null");
205 continue;
206 }
207 AppExecFwk::InnerEvent::Pointer event =
208 AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_SM_LOST_CONNECTION);
209 it->SendEvent(event);
210 }
211 }
212
UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer & event)213 void CcmDefaultState::UpdateNetworkInfo(const AppExecFwk::InnerEvent::Pointer &event)
214 {
215 std::shared_ptr<DataCallResultList> infos = event->GetSharedObject<DataCallResultList>();
216 if (infos == nullptr) {
217 TELEPHONY_LOGE("dataCallResultList is null");
218 return;
219 }
220 for (SetupDataCallResultInfo &it : infos->dcList) {
221 std::shared_ptr<CellularDataStateMachine> dataConnect = connectManager_.GetActiveConnectionByCid(it.cid);
222 if (dataConnect == nullptr) {
223 TELEPHONY_LOGE("get active connection by cid is := %{public}d flag:= %{public}d ", it.cid, it.flag);
224 continue;
225 }
226 dataConnect->UpdateNetworkInfo(it);
227 }
228 }
229
BeginNetStatistics()230 void DataConnectionManager::BeginNetStatistics()
231 {
232 if (connectionMonitor_ != nullptr) {
233 connectionMonitor_->BeginNetStatistics();
234 }
235 }
236
EndNetStatistics()237 void DataConnectionManager::EndNetStatistics()
238 {
239 if (connectionMonitor_ != nullptr) {
240 connectionMonitor_->EndNetStatistics();
241 }
242 }
243
GetSlotId() const244 int32_t DataConnectionManager::GetSlotId() const
245 {
246 return slotId_;
247 }
248
GetDataFlowType()249 int32_t DataConnectionManager::GetDataFlowType()
250 {
251 if (connectionMonitor_ == nullptr) {
252 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
253 return static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_NONE);
254 }
255 CellDataFlowType flowType = connectionMonitor_->GetDataFlowType();
256 return static_cast<int32_t>(flowType);
257 }
258
SetDataFlowType(CellDataFlowType dataFlowType)259 void DataConnectionManager::SetDataFlowType(CellDataFlowType dataFlowType)
260 {
261 if (connectionMonitor_ == nullptr) {
262 TELEPHONY_LOGE("Slot%{public}d: connection monitor is null", slotId_);
263 return;
264 }
265 connectionMonitor_->SetDataFlowType(dataFlowType);
266 }
267
GetDefaultBandWidthsConfig()268 std::string DataConnectionManager::GetDefaultBandWidthsConfig()
269 {
270 bandwidthConfigMap_.clear();
271 char bandWidthBuffer[MAX_BUFFER_SIZE] = {0};
272 GetParameter(CONFIG_BANDWIDTH, DEFAULT_BANDWIDTH_CONFIG, bandWidthBuffer, MAX_BUFFER_SIZE);
273 std::vector<std::string> linkBandwidthVec = CellularDataUtils::Split(bandWidthBuffer, ";");
274 for (std::string temp : linkBandwidthVec) {
275 std::vector<std::string> linkBandwidths = CellularDataUtils::Split(temp, ":");
276 if (linkBandwidths.size() == VALID_VECTOR_SIZE) {
277 std::string key = linkBandwidths.front();
278 std::string linkUpDownBandwidth = linkBandwidths.back();
279 std::vector<std::string> upDownBandwidthValue = CellularDataUtils::Split(linkUpDownBandwidth, ",");
280 if (upDownBandwidthValue.size() == VALID_VECTOR_SIZE) {
281 LinkBandwidthInfo linkBandwidthInfo;
282 linkBandwidthInfo.upBandwidth = (atoi)(upDownBandwidthValue.front().c_str());
283 linkBandwidthInfo.downBandwidth = (atoi)(upDownBandwidthValue.back().c_str());
284 bandwidthConfigMap_.emplace(key, linkBandwidthInfo);
285 }
286 }
287 }
288 TELEPHONY_LOGI("Slot%{public}d: BANDWIDTH_CONFIG_MAP size is %{public}zu", slotId_, bandwidthConfigMap_.size());
289 return "bandWidth";
290 }
291
GetDefaultTcpBufferConfig()292 std::string DataConnectionManager::GetDefaultTcpBufferConfig()
293 {
294 tcpBufferConfigMap_.clear();
295 char tcpBufferConfig[MAX_BUFFER_SIZE] = {0};
296 GetParameter(CONFIG_TCP_BUFFER, DEFAULT_TCP_BUFFER_CONFIG, tcpBufferConfig, MAX_BUFFER_SIZE);
297 std::vector<std::string> tcpBufferVec = CellularDataUtils::Split(tcpBufferConfig, ";");
298 for (std::string tcpBuffer : tcpBufferVec) {
299 std::vector<std::string> str = CellularDataUtils::Split(tcpBuffer, ":");
300 tcpBufferConfigMap_.emplace(str.front(), str.back());
301 }
302 TELEPHONY_LOGI("Slot%{public}d: TCP_BUFFER_CONFIG_MAP size is %{public}zu", slotId_, tcpBufferConfigMap_.size());
303 return tcpBufferConfig;
304 }
305
GetBandwidthsByRadioTech(const int32_t radioTech)306 LinkBandwidthInfo DataConnectionManager::GetBandwidthsByRadioTech(const int32_t radioTech)
307 {
308 LinkBandwidthInfo linkBandwidthInfo;
309 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
310 NrState nrState = coreInner.GetNrState(slotId_);
311 FrequencyType frequencyType = coreInner.GetFrequencyType(slotId_);
312 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
313 if (radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE &&
314 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
315 if (frequencyType == FrequencyType::FREQ_TYPE_MMWAVE) {
316 radioTechName = "NR_NSA_MMWAVE";
317 } else {
318 radioTechName = "NR_NSA";
319 }
320 }
321 if (radioTechName == "NR") {
322 radioTechName = "NR_SA";
323 }
324 TELEPHONY_LOGI("Slot%{public}d: accessRadioName is %{public}s", slotId_, radioTechName.c_str());
325 std::map<std::string, LinkBandwidthInfo>::iterator iter = bandwidthConfigMap_.find(radioTechName);
326 if (iter != bandwidthConfigMap_.end()) {
327 linkBandwidthInfo = iter->second;
328 TELEPHONY_LOGI("Slot%{public}d: name is %{public}s upBandwidth = %{public}u downBandwidth = %{public}u",
329 slotId_, iter->first.c_str(), linkBandwidthInfo.upBandwidth, linkBandwidthInfo.downBandwidth);
330 }
331 return linkBandwidthInfo;
332 }
333
GetTcpBufferByRadioTech(const int32_t radioTech)334 std::string DataConnectionManager::GetTcpBufferByRadioTech(const int32_t radioTech)
335 {
336 std::string tcpBuffer = "";
337 CoreManagerInner &coreInner = CoreManagerInner::GetInstance();
338 NrState nrState = coreInner.GetNrState(slotId_);
339 std::string radioTechName = CellularDataUtils::ConvertRadioTechToRadioName(radioTech);
340 if ((radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE ||
341 radioTech == (int32_t)RadioTech::RADIO_TECHNOLOGY_LTE_CA) &&
342 (nrState == NrState::NR_NSA_STATE_DUAL_CONNECTED || nrState == NrState::NR_NSA_STATE_CONNECTED_DETECT)) {
343 radioTechName = "NR";
344 }
345 std::map<std::string, std::string>::iterator iter = tcpBufferConfigMap_.find(radioTechName);
346 if (iter != tcpBufferConfigMap_.end()) {
347 tcpBuffer = iter->second;
348 }
349 return tcpBuffer;
350 }
351 } // namespace Telephony
352 } // namespace OHOS
353