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