• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "ip_qos_monitor.h"
17 #include "wifi_logger.h"
18 #include "wifi_config_center.h"
19 #include "wifi_global_func.h"
20 
21 static const int32_t MIN_DELTA_TCP_TX = 3;
22 static const int32_t QOS_TCP_TX_PKTS = 6;
23 static const int32_t QOS_TCP_RX_PKTS = 7;
24 static const int32_t QOS_MSG_FROM = 9;
25 static const int32_t MIN_PACKET_LEN = 7;
26 static const int32_t CMD_START_MONITOR = 10;
27 static const int32_t CMD_QUERY_PKTS = 15;
28 
29 namespace OHOS {
30 namespace Wifi {
31 DEFINE_WIFILOG_LABEL("IpQosMonitor");
32 
GetInstance()33 IpQosMonitor &IpQosMonitor::GetInstance()
34 {
35     static IpQosMonitor gIpQosMonitor;
36     return gIpQosMonitor;
37 }
38 
StartMonitor(int32_t arg)39 void IpQosMonitor::StartMonitor(int32_t arg)
40 {
41     WIFI_LOGD("enter %{public}s", __FUNCTION__);
42     WifiNetLink::GetInstance().SendQoeCmd(CMD_START_MONITOR, arg);
43 }
44 
QueryPackets(int32_t arg)45 void IpQosMonitor::QueryPackets(int32_t arg)
46 {
47     WIFI_LOGD("enter %{public}s", __FUNCTION__);
48     WifiNetLink::GetInstance().SendQoeCmd(CMD_QUERY_PKTS, arg);
49 }
50 
HandleTcpReportMsgComplete(const std::vector<int64_t> & elems,int32_t cmd)51 void IpQosMonitor::HandleTcpReportMsgComplete(const std::vector<int64_t> &elems, int32_t cmd)
52 {
53     WIFI_LOGD("enter %{public}s", __FUNCTION__);
54     ParseTcpReportMsg(elems, cmd);
55 }
56 
ParseTcpReportMsg(const std::vector<int64_t> & elems,int32_t cmd)57 void IpQosMonitor::ParseTcpReportMsg(const std::vector<int64_t> &elems, int32_t cmd)
58 {
59     if (elems.size() == 0) {
60         WIFI_LOGE("TcpReportMsg elems size is 0");
61         return;
62     }
63     if (cmd == CMD_QUERY_PKTS) {
64         HandleTcpPktsResp(elems);
65     }
66 }
67 
HandleTcpPktsResp(const std::vector<int64_t> & elems)68 void IpQosMonitor::HandleTcpPktsResp(const std::vector<int64_t> &elems)
69 {
70     WIFI_LOGD("enter %{public}s", __FUNCTION__);
71     std::unique_lock<std::mutex> locker(txRxStatusMtx_);
72     bool internetGood = ParseNetworkInternetGood(elems);
73     if (internetGood) {
74         if (!lastTxRxGood_) {
75             WIFI_LOGI("%{public}s: set tx_rx_good true", __FUNCTION__);
76             lastTxRxGood_ = true;
77         }
78         mInternetFailedCounter = 0;
79         mInternetSelfCureAllowed = true;
80         mHttpDetectedAllowed = true;
81         return;
82     }
83 
84     WifiLinkedInfo linkedInfo;
85     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
86     int32_t signalLevel = WifiSettings::GetInstance().GetSignalLevel(linkedInfo.rssi, linkedInfo.band, mInstId);
87     if (lastTxRxGood_) {
88         WIFI_LOGI("%{public}s: set tx_rx_good false", __FUNCTION__);
89         lastTxRxGood_ = false;
90     }
91     mInternetFailedCounter++;
92     WIFI_LOGI("%{public}s: mInternetFailedCounter = %{public}d", __FUNCTION__, mInternetFailedCounter);
93     if ((mInternetFailedCounter >= 1) && (linkedInfo.connState == ConnState::CONNECTED)) {
94         ISelfCureService *pSelfCureService = WifiServiceManager::GetInstance().GetSelfCureServiceInst(mInstId);
95         if (pSelfCureService == nullptr) {
96             WIFI_LOGE("%{public}s: pSelfCureService is null", __FUNCTION__);
97             return;
98         }
99         if (mHttpDetectedAllowed && signalLevel >= SIGNAL_LEVEL_2) {
100             WIFI_LOGI("%{public}s: start http detect", __FUNCTION__);
101             if (mNetWorkDetect == nullptr) {
102                 mNetWorkDetect = sptr<NetStateObserver>(new NetStateObserver());
103             }
104             if (mNetWorkDetect == nullptr) {
105                 WIFI_LOGE("%{public}s mNetWorkDetect is null", __func__);
106                 return;
107             }
108             mNetWorkDetect->StartWifiDetection();
109             mHttpDetectedAllowed = false;
110             return;
111         }
112     }
113 }
114 
AllowSelfCureNetwork(int32_t currentRssi)115 bool IpQosMonitor::AllowSelfCureNetwork(int32_t currentRssi)
116 {
117     ISelfCureService *pSelfCureService = WifiServiceManager::GetInstance().GetSelfCureServiceInst(mInstId);
118     if (pSelfCureService == nullptr) {
119         WIFI_LOGE("%{public}s: pSelfCureService is null.", __FUNCTION__);
120         return false;
121     }
122     if (mInternetSelfCureAllowed && currentRssi >= MIN_VAL_LEVEL_3_5 &&
123        (!pSelfCureService->IsSelfCureOnGoing())) {
124         return true;
125     }
126     return false;
127 }
128 
ParseNetworkInternetGood(const std::vector<int64_t> & elems)129 bool IpQosMonitor::ParseNetworkInternetGood(const std::vector<int64_t> &elems)
130 {
131     WIFI_LOGD("enter %{public}s", __FUNCTION__);
132     bool queryResp = (elems[QOS_MSG_FROM] == 0);
133     int32_t packetsLength = static_cast<int32_t>(elems.size());
134     if ((queryResp) && (packetsLength > MIN_PACKET_LEN)) {
135         int64_t tcpTxPkts = elems[QOS_TCP_TX_PKTS];
136         int64_t tcpRxPkts = elems[QOS_TCP_RX_PKTS];
137         WIFI_LOGD("tcpTxPkts = %{public}" PRId64 ", tcpRxPkts = %{public}" PRId64, tcpTxPkts, tcpRxPkts);
138         if ((mLastTcpTxCounter == 0) && (mLastTcpRxCounter == 0)) {
139             mLastTcpTxCounter = tcpTxPkts;
140             mLastTcpRxCounter = tcpRxPkts;
141             WIFI_LOGI("mLastTcpTxCounter = %{public}" PRId64 ", mLastTcpRxCounter = %{public}" PRId64,
142                 mLastTcpTxCounter, mLastTcpRxCounter);
143             return lastTxRxGood_;
144         }
145         int64_t deltaTcpTxPkts = tcpTxPkts - mLastTcpTxCounter;
146         int64_t deltaTcpRxPkts = tcpRxPkts - mLastTcpRxCounter;
147         WIFI_LOGI("deltaTcpTxPkts = %{public}" PRId64 ", deltaTcpRxPkts = %{public}" PRId64,
148             deltaTcpTxPkts, deltaTcpRxPkts);
149         mLastTcpTxCounter = tcpTxPkts;
150         mLastTcpRxCounter = tcpRxPkts;
151         if (deltaTcpRxPkts == 0) {
152             if (deltaTcpTxPkts < MIN_DELTA_TCP_TX) {
153                 WIFI_LOGD("%{public}s deltaTcpRxPkts 0, deltaTcpTxPkts less 3, return last tx rx status %{public}d",
154                     __FUNCTION__, lastTxRxGood_);
155                 return lastTxRxGood_;
156             }
157             if (deltaTcpTxPkts >= MIN_DELTA_TCP_TX) {
158                 WIFI_LOGI("%{public}s internetGood: false", __FUNCTION__);
159                 return false;
160             }
161         }
162     }
163     return true;
164 }
165 
GetCurrentTcpTxCounter()166 int64_t IpQosMonitor::GetCurrentTcpTxCounter()
167 {
168     return mLastTcpTxCounter;
169 }
170 
GetCurrentTcpRxCounter()171 int64_t IpQosMonitor::GetCurrentTcpRxCounter()
172 {
173     return mLastTcpRxCounter;
174 }
175 
ResetTxRxProperty()176 void IpQosMonitor::ResetTxRxProperty()
177 {
178     WIFI_LOGI("%{public}s: reset tx rx status", __FUNCTION__);
179     std::unique_lock<std::mutex> locker(txRxStatusMtx_);
180     lastTxRxGood_ = false;
181     mLastTcpTxCounter = 0;
182     mLastTcpRxCounter = 0;
183 }
184 
GetTxRxStatus()185 bool IpQosMonitor::GetTxRxStatus()
186 {
187     std::unique_lock<std::mutex> locker(txRxStatusMtx_);
188     return lastTxRxGood_;
189 }
190 
191 } // namespace Wifi
192 } // namespace OHOS
193