• 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_monitor.h"
17 
18 #include "core_manager_inner.h"
19 #include "radio_event.h"
20 #include "telephony_log_wrapper.h"
21 
22 #include "cellular_data_event_code.h"
23 #include "cellular_data_hisysevent.h"
24 #include "cellular_data_service.h"
25 #include "cellular_data_types.h"
26 #include "cellular_data_constant.h"
27 #include "data_service_ext_wrapper.h"
28 
29 #ifdef ABILITY_POWER_SUPPORT
30 #include "power_mgr_client.h"
31 #endif
32 
33 namespace OHOS {
34 namespace Telephony {
DataConnectionMonitor(int32_t slotId)35 DataConnectionMonitor::DataConnectionMonitor(int32_t slotId) : TelEventHandler("DataConnectionMonitor"), slotId_(slotId)
36 {
37     trafficManager_ = std::make_unique<TrafficManagement>(slotId);
38     stallDetectionTrafficManager_ = std::make_unique<TrafficManagement>(slotId);
39     if (trafficManager_ == nullptr || stallDetectionTrafficManager_ == nullptr) {
40         TELEPHONY_LOGE("TrafficManager or stallDetectionTrafficManager init failed");
41     }
42 }
43 
IsAggressiveRecovery()44 bool DataConnectionMonitor::IsAggressiveRecovery()
45 {
46     return (dataRecoveryState_ == RecoveryState::STATE_CLEANUP_CONNECTIONS) ||
47         (dataRecoveryState_ == RecoveryState::STATE_REREGISTER_NETWORK) ||
48         (dataRecoveryState_ == RecoveryState::STATE_RADIO_STATUS_RESTART);
49 }
50 
IsScreenOn()51 bool DataConnectionMonitor::IsScreenOn()
52 {
53     bool isScreenOn = false;
54 #ifdef ABILITY_POWER_SUPPORT
55     isScreenOn = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
56 #endif
57     TELEPHONY_LOGI("isScreenOn = %{public}d.", isScreenOn);
58     return isScreenOn;
59 }
60 
GetStallDetectionPeriod()61 int32_t DataConnectionMonitor::GetStallDetectionPeriod()
62 {
63     if (IsScreenOn() || IsAggressiveRecovery()) {
64         return DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT;
65     }
66     return DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT;
67 }
68 
StartStallDetectionTimer()69 void DataConnectionMonitor::StartStallDetectionTimer()
70 {
71     TELEPHONY_LOGI("Slot%{public}d: start stall detection", slotId_);
72     stallDetectionEnabled = true;
73     int32_t stallDetectionPeriod = GetStallDetectionPeriod();
74     TELEPHONY_LOGI("stallDetectionPeriod = %{public}d", stallDetectionPeriod);
75     if (!HasInnerEvent(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID)) {
76         AppExecFwk::InnerEvent::Pointer event =
77             AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID);
78         SendEvent(event, stallDetectionPeriod, Priority::LOW);
79     }
80 }
81 
OnStallDetectionTimer()82 void DataConnectionMonitor::OnStallDetectionTimer()
83 {
84     TELEPHONY_LOGD("Slot%{public}d: on stall detection", slotId_);
85 #ifdef OHOS_BUILD_ENABLE_DATA_SERVICE_EXT
86     if (DATA_SERVICE_EXT_WRAPPER.requestTcpAndDnsPackets_) {
87         DATA_SERVICE_EXT_WRAPPER.requestTcpAndDnsPackets_();
88         return;
89     }
90 #endif
91     UpdateFlowInfo();
92     if (noRecvPackets_ > RECOVERY_TRIGGER_PACKET) {
93         HandleRecovery();
94         noRecvPackets_ = 0;
95     }
96     int32_t stallDetectionPeriod = GetStallDetectionPeriod();
97     TELEPHONY_LOGI("stallDetectionPeriod = %{public}d", stallDetectionPeriod);
98     if (!HasInnerEvent(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID) && stallDetectionEnabled) {
99         AppExecFwk::InnerEvent::Pointer event =
100             AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID);
101         SendEvent(event, stallDetectionPeriod, Priority::LOW);
102     }
103 }
104 
StopStallDetectionTimer()105 void DataConnectionMonitor::StopStallDetectionTimer()
106 {
107     TELEPHONY_LOGI("Slot%{public}d: stop stall detection", slotId_);
108     stallDetectionEnabled = false;
109     RemoveEvent(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID);
110 }
111 
UpdateFlowInfo()112 void DataConnectionMonitor::UpdateFlowInfo()
113 {
114     if (stallDetectionTrafficManager_ == nullptr) {
115         TELEPHONY_LOGE("Slot%{public}d: stallDetectionTrafficManager_ is null", slotId_);
116         return;
117     }
118     int64_t previousSentPackets = 0;
119     int64_t previousRecvPackets = 0;
120     int64_t currentSentPackets = 0;
121     int64_t currentRecvPackets = 0;
122     stallDetectionTrafficManager_->GetPacketData(previousSentPackets, previousRecvPackets);
123     stallDetectionTrafficManager_->UpdatePacketData();
124     stallDetectionTrafficManager_->GetPacketData(currentSentPackets, currentRecvPackets);
125     int64_t sentPackets = currentSentPackets - previousSentPackets;
126     int64_t recvPackets = currentRecvPackets - previousRecvPackets;
127     if (sentPackets > 0 && recvPackets == 0) {
128         noRecvPackets_ += sentPackets;
129     } else if ((sentPackets > 0 && recvPackets > 0) || (sentPackets == 0 && recvPackets > 0)) {
130         noRecvPackets_ = 0;
131         dataRecoveryState_ = RecoveryState::STATE_REQUEST_CONTEXT_LIST;
132     } else {
133         TELEPHONY_LOGD("Slot%{public}d: Update Flow Info nothing to do", slotId_);
134     }
135 }
136 
HandleRecovery()137 void DataConnectionMonitor::HandleRecovery()
138 {
139     if (callState_ != static_cast<int32_t>(TelCallStatus::CALL_STATUS_IDLE) &&
140         callState_ != static_cast<int32_t>(TelCallStatus::CALL_STATUS_DISCONNECTED)) {
141         TELEPHONY_LOGI("Slot%{public}d: Stop recovery while call is busy", slotId_);
142         dataRecoveryState_ = RecoveryState::STATE_REQUEST_CONTEXT_LIST;
143         return;
144     }
145     switch (dataRecoveryState_) {
146         case RecoveryState::STATE_REQUEST_CONTEXT_LIST: {
147             TELEPHONY_LOGI("Slot%{public}d: Handle Recovery: get data call list", slotId_);
148             dataRecoveryState_ = RecoveryState::STATE_CLEANUP_CONNECTIONS;
149             GetPdpContextList();
150             CellularDataHiSysEvent::WriteDataDeactiveBehaviorEvent(slotId_, DataDisconnectCause::ON_THE_NETWORK_SIDE);
151             break;
152         }
153         case RecoveryState::STATE_CLEANUP_CONNECTIONS: {
154             TELEPHONY_LOGI("Slot%{public}d: Handle Recovery: cleanup connections", slotId_);
155             dataRecoveryState_ = RecoveryState::STATE_REREGISTER_NETWORK;
156             int32_t ret = DelayedRefSingleton<CellularDataService>::GetInstance().ClearAllConnections(
157                 slotId_, DisConnectionReason::REASON_RETRY_CONNECTION);
158             if (ret != static_cast<int32_t>(RequestNetCode::REQUEST_SUCCESS)) {
159                 TELEPHONY_LOGE("Slot%{public}d: Handle Recovery: cleanup connections failed", slotId_);
160             }
161             break;
162         }
163         case RecoveryState::STATE_REREGISTER_NETWORK: {
164             TELEPHONY_LOGI("Slot%{public}d: Handle Recovery: re-register network", slotId_);
165             dataRecoveryState_ = RecoveryState::STATE_RADIO_STATUS_RESTART;
166             GetPreferredNetworkPara();
167             break;
168         }
169         case RecoveryState::STATE_RADIO_STATUS_RESTART: {
170             TELEPHONY_LOGI("Slot%{public}d: Handle Recovery: radio restart", slotId_);
171             dataRecoveryState_ = RecoveryState::STATE_REQUEST_CONTEXT_LIST;
172             int32_t ret = DelayedRefSingleton<CellularDataService>::GetInstance().ClearAllConnections(
173                 slotId_, DisConnectionReason::REASON_RETRY_CONNECTION);
174             if (ret != static_cast<int32_t>(RequestNetCode::REQUEST_SUCCESS)) {
175                 TELEPHONY_LOGE("Slot%{public}d: Handle Recovery: radio restart cleanup connections failed", slotId_);
176             }
177             SetRadioState(CORE_SERVICE_POWER_OFF, RadioEvent::RADIO_OFF);
178             break;
179         }
180         default: {
181             TELEPHONY_LOGE("Slot%{public}d: Handle Recovery is falsie", slotId_);
182             break;
183         }
184     }
185 }
186 
BeginNetStatistics()187 void DataConnectionMonitor::BeginNetStatistics()
188 {
189     updateNetStat_ = true;
190     UpdateNetTrafficState();
191 }
192 
UpdateCallState(int32_t state)193 void DataConnectionMonitor::UpdateCallState(int32_t state)
194 {
195     callState_ = state;
196 }
197 
EndNetStatistics()198 void DataConnectionMonitor::EndNetStatistics()
199 {
200     RemoveEvent(CellularDataEventCode::MSG_RUN_MONITOR_TASK);
201     updateNetStat_ = false;
202     if (dataFlowType_ != CellDataFlowType::DATA_FLOW_TYPE_NONE) {
203         dataFlowType_ = CellDataFlowType::DATA_FLOW_TYPE_NONE;
204         StateNotification::GetInstance().OnUpDataFlowtype(slotId_, dataFlowType_);
205     }
206 }
207 
UpdateNetTrafficState()208 void DataConnectionMonitor::UpdateNetTrafficState()
209 {
210     if (!HasInnerEvent(CellularDataEventCode::MSG_RUN_MONITOR_TASK) && updateNetStat_) {
211         UpdateDataFlowType();
212         AppExecFwk::InnerEvent::Pointer event =
213             AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_RUN_MONITOR_TASK);
214         SendEvent(event, DEFAULT_NET_STATISTICS_PERIOD);
215     }
216 }
217 
GetPdpContextList()218 void DataConnectionMonitor::GetPdpContextList()
219 {
220     CoreManagerInner::GetInstance().GetPdpContextList(slotId_,
221         RadioEvent::RADIO_DATA_CALL_LIST_CHANGED, shared_from_this());
222 }
223 
SetRadioState(const int32_t & radioState,const int32_t & eventCode)224 void DataConnectionMonitor::SetRadioState(const int32_t &radioState, const int32_t &eventCode)
225 {
226     CoreManagerInner::GetInstance().SetRadioState(slotId_, eventCode, radioState, 0, shared_from_this());
227 }
228 
GetPreferredNetworkPara()229 void DataConnectionMonitor::GetPreferredNetworkPara()
230 {
231     CoreManagerInner::GetInstance().GetPreferredNetworkPara(slotId_,
232         RadioEvent::RADIO_GET_PREFERRED_NETWORK_MODE, shared_from_this());
233 }
234 
SetPreferredNetworkPara(const AppExecFwk::InnerEvent::Pointer & event)235 void DataConnectionMonitor::SetPreferredNetworkPara(const AppExecFwk::InnerEvent::Pointer &event)
236 {
237     std::shared_ptr<PreferredNetworkTypeInfo> preferredNetworkInfo = event->GetSharedObject<PreferredNetworkTypeInfo>();
238     if (preferredNetworkInfo == nullptr) {
239         TELEPHONY_LOGE("preferredNetworkInfo is null");
240         return;
241     }
242     int32_t networkType = preferredNetworkInfo->preferredNetworkType;
243     CoreManagerInner::GetInstance().SetPreferredNetworkPara(slotId_,
244         RadioEvent::RADIO_SET_PREFERRED_NETWORK_MODE, networkType, shared_from_this());
245 }
246 
GetDataRecoveryState()247 RecoveryState DataConnectionMonitor::GetDataRecoveryState()
248 {
249     return dataRecoveryState_;
250 }
251 
UpdateDataFlowType()252 void DataConnectionMonitor::UpdateDataFlowType()
253 {
254     if (trafficManager_ == nullptr) {
255         TELEPHONY_LOGE("Slot%{public}d: trafficManager is null", slotId_);
256         return;
257     }
258     int64_t previousSentPackets = 0;
259     int64_t previousRecvPackets = 0;
260     int64_t currentSentPackets = 0;
261     int64_t currentRecvPackets = 0;
262     trafficManager_->GetPacketData(previousSentPackets, previousRecvPackets);
263     trafficManager_->UpdatePacketData();
264     trafficManager_->GetPacketData(currentSentPackets, currentRecvPackets);
265     int64_t sentPackets = currentSentPackets - previousSentPackets;
266     int64_t recvPackets = currentRecvPackets - previousRecvPackets;
267     CellDataFlowType previousDataFlowType = dataFlowType_;
268     if (previousSentPackets != 0 || previousRecvPackets != 0) {
269         if (sentPackets > 0 && recvPackets == 0) {
270             dataFlowType_ = CellDataFlowType::DATA_FLOW_TYPE_UP;
271         } else if (sentPackets == 0 && recvPackets > 0) {
272             dataFlowType_ = CellDataFlowType::DATA_FLOW_TYPE_DOWN;
273         } else if (sentPackets > 0 && recvPackets > 0) {
274             dataFlowType_ = CellDataFlowType::DATA_FLOW_TYPE_UP_DOWN;
275         } else {
276             dataFlowType_ = CellDataFlowType::DATA_FLOW_TYPE_NONE;
277         }
278     }
279     if (previousDataFlowType != dataFlowType_) {
280         StateNotification::GetInstance().OnUpDataFlowtype(slotId_, dataFlowType_);
281     }
282 }
283 
GetDataFlowType()284 CellDataFlowType DataConnectionMonitor::GetDataFlowType()
285 {
286     return dataFlowType_;
287 }
288 
SetDataFlowType(CellDataFlowType dataFlowType)289 void DataConnectionMonitor::SetDataFlowType(CellDataFlowType dataFlowType)
290 {
291     if (dataFlowType_ != dataFlowType) {
292         dataFlowType_ = dataFlowType;
293         StateNotification::GetInstance().OnUpDataFlowtype(slotId_, dataFlowType_);
294     }
295 }
296 
IsNeedDoRecovery(bool needDoRecovery)297 void DataConnectionMonitor::IsNeedDoRecovery(bool needDoRecovery)
298 {
299     if (needDoRecovery) {
300         HandleRecovery();
301     } else {
302         dataRecoveryState_ = RecoveryState::STATE_REQUEST_CONTEXT_LIST;
303     }
304     int32_t stallDetectionPeriod = GetStallDetectionPeriod();
305     TELEPHONY_LOGI("stallDetectionPeriod = %{public}d", stallDetectionPeriod);
306     if (!HasInnerEvent(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID) && stallDetectionEnabled) {
307         AppExecFwk::InnerEvent::Pointer event =
308             AppExecFwk::InnerEvent::Get(CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID);
309         SendEvent(event, stallDetectionPeriod, Priority::LOW);
310     }
311 }
312 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)313 void DataConnectionMonitor::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
314 {
315     if (event == nullptr) {
316         TELEPHONY_LOGE("Slot%{public}d: event is null", slotId_);
317         return;
318     }
319     uint32_t eventID = event->GetInnerEventId();
320     switch (eventID) {
321         case CellularDataEventCode::MSG_RUN_MONITOR_TASK: {
322             UpdateNetTrafficState();
323             break;
324         }
325         case CellularDataEventCode::MSG_STALL_DETECTION_EVENT_ID:
326             OnStallDetectionTimer();
327             break;
328         case RadioEvent::RADIO_DATA_CALL_LIST_CHANGED:
329             TELEPHONY_LOGI("Slot%{public}d: radio call list changed complete", slotId_);
330             break;
331         case RadioEvent::RADIO_GET_PREFERRED_NETWORK_MODE:
332             SetPreferredNetworkPara(event);
333             break;
334         case RadioEvent::RADIO_SET_PREFERRED_NETWORK_MODE:
335             TELEPHONY_LOGI("Slot%{public}d: set preferred network mode complete", slotId_);
336             break;
337         case RadioEvent::RADIO_OFF:
338             SetRadioState(CORE_SERVICE_POWER_ON, RadioEvent::RADIO_ON);
339             break;
340         case RadioEvent::RADIO_ON:
341             TELEPHONY_LOGI("Slot%{public}d: set radio state on complete", slotId_);
342             break;
343         default:
344             TELEPHONY_LOGI("Slot%{public}d: connection monitor ProcessEvent code = %{public}u", slotId_, eventID);
345             break;
346     }
347 }
348 } // namespace Telephony
349 } // namespace OHOS
350