1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import android.content.Context;
20 import android.provider.Settings;
21 
22 import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent;
23 
24 /**
25  * Looks for Wifi data stalls
26  */
27 public class WifiDataStall {
28 
29     // Default minimum number of txBadDelta to trigger data stall
30     public static final int MIN_TX_BAD_DEFAULT = 1;
31     // Default minimum number of txSuccessDelta to trigger data stall
32     // when rxSuccessDelta is 0
33     public static final int MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT = 50;
34     // Maximum time gap between two WifiLinkLayerStats to trigger a data stall
35     public static final long MAX_MS_DELTA_FOR_DATA_STALL = 60 * 1000; // 1 minute
36 
37     private final Context mContext;
38     private final FrameworkFacade mFacade;
39     private final WifiMetrics mWifiMetrics;
40 
41     private int mMinTxBad;
42     private int mMinTxSuccessWithoutRx;
43 
WifiDataStall(Context context, FrameworkFacade facade, WifiMetrics wifiMetrics)44     public WifiDataStall(Context context, FrameworkFacade facade, WifiMetrics wifiMetrics) {
45         mContext = context;
46         mFacade = facade;
47         mWifiMetrics = wifiMetrics;
48         loadSettings();
49     }
50 
51     /**
52      * Load setting values related to wifi data stall.
53      */
loadSettings()54     public void loadSettings() {
55         mMinTxBad = mFacade.getIntegerSetting(
56                 mContext, Settings.Global.WIFI_DATA_STALL_MIN_TX_BAD, MIN_TX_BAD_DEFAULT);
57         mMinTxSuccessWithoutRx = mFacade.getIntegerSetting(
58                 mContext, Settings.Global.WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX,
59                 MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT);
60         mWifiMetrics.setWifiDataStallMinTxBad(mMinTxBad);
61         mWifiMetrics.setWifiDataStallMinRxWithoutTx(mMinTxSuccessWithoutRx);
62     }
63 
64     /**
65      * Checks for data stall by looking at tx/rx packet counts
66      * @param oldStats second most recent WifiLinkLayerStats
67      * @param newStats most recent WifiLinkLayerStats
68      * @return trigger type of WifiIsUnusableEvent
69      */
checkForDataStall(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats)70     public int checkForDataStall(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats) {
71         if (oldStats == null || newStats == null) {
72             mWifiMetrics.resetWifiIsUnusableLinkLayerStats();
73             return WifiIsUnusableEvent.TYPE_UNKNOWN;
74         }
75 
76         long txSuccessDelta = (newStats.txmpdu_be + newStats.txmpdu_bk
77                 + newStats.txmpdu_vi + newStats.txmpdu_vo)
78                 - (oldStats.txmpdu_be + oldStats.txmpdu_bk
79                 + oldStats.txmpdu_vi + oldStats.txmpdu_vo);
80         long txRetriesDelta = (newStats.retries_be + newStats.retries_bk
81                 + newStats.retries_vi + newStats.retries_vo)
82                 - (oldStats.retries_be + oldStats.retries_bk
83                 + oldStats.retries_vi + oldStats.retries_vo);
84         long txBadDelta = (newStats.lostmpdu_be + newStats.lostmpdu_bk
85                 + newStats.lostmpdu_vi + newStats.lostmpdu_vo)
86                 - (oldStats.lostmpdu_be + oldStats.lostmpdu_bk
87                 + oldStats.lostmpdu_vi + oldStats.lostmpdu_vo);
88         long rxSuccessDelta = (newStats.rxmpdu_be + newStats.rxmpdu_bk
89                 + newStats.rxmpdu_vi + newStats.rxmpdu_vo)
90                 - (oldStats.rxmpdu_be + oldStats.rxmpdu_bk
91                 + oldStats.rxmpdu_vi + oldStats.rxmpdu_vo);
92         long timeMsDelta = newStats.timeStampInMs - oldStats.timeStampInMs;
93 
94         if (timeMsDelta < 0
95                 || txSuccessDelta < 0
96                 || txRetriesDelta < 0
97                 || txBadDelta < 0
98                 || rxSuccessDelta < 0) {
99             // There was a reset in WifiLinkLayerStats
100             mWifiMetrics.resetWifiIsUnusableLinkLayerStats();
101             return WifiIsUnusableEvent.TYPE_UNKNOWN;
102         }
103 
104         mWifiMetrics.updateWifiIsUnusableLinkLayerStats(txSuccessDelta, txRetriesDelta,
105                 txBadDelta, rxSuccessDelta, timeMsDelta);
106         if (timeMsDelta < MAX_MS_DELTA_FOR_DATA_STALL) {
107             // There is a data stall if there are too many tx failures
108             // or if we are not receiving any packets despite many tx successes
109             boolean dataStallBadTx = (txBadDelta >= mMinTxBad);
110             boolean dataStallTxSuccessWithoutRx =
111                     (rxSuccessDelta == 0 && txSuccessDelta >= mMinTxSuccessWithoutRx);
112             if (dataStallBadTx && dataStallTxSuccessWithoutRx) {
113                 mWifiMetrics.logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH);
114                 return WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH;
115             } else if (dataStallBadTx) {
116                 mWifiMetrics.logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX);
117                 return WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX;
118             } else if (dataStallTxSuccessWithoutRx) {
119                 mWifiMetrics.logWifiIsUnusableEvent(
120                         WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX);
121                 return WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX;
122             }
123         }
124 
125         return WifiIsUnusableEvent.TYPE_UNKNOWN;
126     }
127 }
128