• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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.annotation.NonNull;
20 import android.net.wifi.WifiInfo;
21 
22 /**
23  * Extends WifiInfo with the methods for computing the averaged packet rates
24  */
25 public class ExtendedWifiInfo extends WifiInfo {
26     private static final long RESET_TIME_STAMP = Long.MIN_VALUE;
27     private static final double FILTER_TIME_CONSTANT = 3000.0;
28     private static final int SOURCE_UNKNOWN = 0;
29     private static final int SOURCE_TRAFFIC_COUNTERS = 1;
30     private static final int SOURCE_LLSTATS = 2;
31 
32     private final WifiGlobals mWifiGlobals;
33     private final String mIfaceName;
34 
35     private int mLastSource = SOURCE_UNKNOWN;
36     private long mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
37 
ExtendedWifiInfo(WifiGlobals wifiGlobals, String ifaceName)38     ExtendedWifiInfo(WifiGlobals wifiGlobals, String ifaceName) {
39         mWifiGlobals = wifiGlobals;
40         mIfaceName = ifaceName;
41     }
42 
43     @Override
reset()44     public void reset() {
45         super.reset();
46         mLastSource = SOURCE_UNKNOWN;
47         mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
48         if (mWifiGlobals.isConnectedMacRandomizationEnabled()) {
49             setMacAddress(DEFAULT_MAC_ADDRESS);
50         }
51     }
52 
53     /**
54      * Updates the packet rates using link layer stats
55      *
56      * @param stats WifiLinkLayerStats
57      * @param timeStamp time in milliseconds
58      */
updatePacketRates(@onNull WifiLinkLayerStats stats, long timeStamp)59     public void updatePacketRates(@NonNull WifiLinkLayerStats stats, long timeStamp) {
60         long txgood = stats.txmpdu_be + stats.txmpdu_bk + stats.txmpdu_vi + stats.txmpdu_vo;
61         long txretries = stats.retries_be + stats.retries_bk + stats.retries_vi + stats.retries_vo;
62         long txbad = stats.lostmpdu_be + stats.lostmpdu_bk + stats.lostmpdu_vi + stats.lostmpdu_vo;
63         long rxgood = stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo;
64         update(SOURCE_LLSTATS, txgood, txretries, txbad, rxgood, timeStamp);
65     }
66 
67     /**
68      * This function is less powerful and used if the WifiLinkLayerStats API is not implemented
69      * at the Wifi HAL
70      */
updatePacketRates(long txPackets, long rxPackets, long timeStamp)71     public void updatePacketRates(long txPackets, long rxPackets, long timeStamp) {
72         update(SOURCE_TRAFFIC_COUNTERS, txPackets, 0, 0, rxPackets, timeStamp);
73     }
74 
update(int source, long txgood, long txretries, long txbad, long rxgood, long timeStamp)75     private void update(int source, long txgood, long txretries, long txbad, long rxgood,
76             long timeStamp) {
77         if (source == mLastSource
78                 && mLastPacketCountUpdateTimeStamp != RESET_TIME_STAMP
79                 && mLastPacketCountUpdateTimeStamp < timeStamp
80                 && txBad <= txbad
81                 && txSuccess <= txgood
82                 && rxSuccess <= rxgood
83                 && txRetries <= txretries) {
84             long timeDelta = timeStamp - mLastPacketCountUpdateTimeStamp;
85             double lastSampleWeight = Math.exp(-1.0 * timeDelta / FILTER_TIME_CONSTANT);
86             double currentSampleWeight = 1.0 - lastSampleWeight;
87 
88             setLostTxPacketsPerSecond(getLostTxPacketsPerSecond() * lastSampleWeight
89                     + (txbad - txBad) * 1000.0 / timeDelta
90                     * currentSampleWeight);
91             setSuccessfulTxPacketsPerSecond(getSuccessfulTxPacketsPerSecond() * lastSampleWeight
92                     + (txgood - txSuccess) * 1000.0 / timeDelta
93                     * currentSampleWeight);
94             setSuccessfulRxPacketsPerSecond(getSuccessfulRxPacketsPerSecond() * lastSampleWeight
95                     + (rxgood - rxSuccess) * 1000.0 / timeDelta
96                     * currentSampleWeight);
97             setRetriedTxPacketsRate(getRetriedTxPacketsPerSecond() * lastSampleWeight
98                     + (txretries - txRetries) * 1000.0 / timeDelta
99                     * currentSampleWeight);
100         } else {
101             setLostTxPacketsPerSecond(0);
102             setSuccessfulTxPacketsPerSecond(0);
103             setSuccessfulRxPacketsPerSecond(0);
104             setRetriedTxPacketsRate(0);
105             mLastSource = source;
106         }
107         txBad = txbad;
108         txSuccess = txgood;
109         rxSuccess = rxgood;
110         txRetries = txretries;
111         mLastPacketCountUpdateTimeStamp = timeStamp;
112     }
113 
getIfaceName()114     public String getIfaceName() {
115         return mIfaceName;
116     }
117 }
118