• 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 
~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