Home | History | Annotate | Download | only in wifi
      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 int mLastSource = SOURCE_UNKNOWN;
     33     private long mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
     34     private boolean mEnableConnectedMacRandomization = false;
     35 
     36     @Override
     37     public void reset() {
     38         super.reset();
     39         mLastSource = SOURCE_UNKNOWN;
     40         mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
     41         if (mEnableConnectedMacRandomization) {
     42             setMacAddress(DEFAULT_MAC_ADDRESS);
     43         }
     44     }
     45 
     46     /**
     47      * Updates the packet rates using link layer stats
     48      *
     49      * @param stats WifiLinkLayerStats
     50      * @param timeStamp time in milliseconds
     51      */
     52     public void updatePacketRates(@NonNull WifiLinkLayerStats stats, long timeStamp) {
     53         long txgood = stats.txmpdu_be + stats.txmpdu_bk + stats.txmpdu_vi + stats.txmpdu_vo;
     54         long txretries = stats.retries_be + stats.retries_bk + stats.retries_vi + stats.retries_vo;
     55         long txbad = stats.lostmpdu_be + stats.lostmpdu_bk + stats.lostmpdu_vi + stats.lostmpdu_vo;
     56         long rxgood = stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo;
     57         update(SOURCE_LLSTATS, txgood, txretries, txbad, rxgood, timeStamp);
     58     }
     59 
     60     /**
     61      * This function is less powerful and used if the WifiLinkLayerStats API is not implemented
     62      * at the Wifi HAL
     63      */
     64     public void updatePacketRates(long txPackets, long rxPackets, long timeStamp) {
     65         update(SOURCE_TRAFFIC_COUNTERS, txPackets, 0, 0, rxPackets, timeStamp);
     66     }
     67 
     68     private void update(int source, long txgood, long txretries, long txbad, long rxgood,
     69             long timeStamp) {
     70         if (source == mLastSource
     71                 && mLastPacketCountUpdateTimeStamp != RESET_TIME_STAMP
     72                 && mLastPacketCountUpdateTimeStamp < timeStamp
     73                 && txBad <= txbad
     74                 && txSuccess <= txgood
     75                 && rxSuccess <= rxgood
     76                 && txRetries <= txretries) {
     77             long timeDelta = timeStamp - mLastPacketCountUpdateTimeStamp;
     78             double lastSampleWeight = Math.exp(-1.0 * timeDelta / FILTER_TIME_CONSTANT);
     79             double currentSampleWeight = 1.0 - lastSampleWeight;
     80 
     81             txBadRate = txBadRate * lastSampleWeight
     82                     + (txbad - txBad) * 1000.0 / timeDelta
     83                     * currentSampleWeight;
     84             txSuccessRate = txSuccessRate * lastSampleWeight
     85                     + (txgood - txSuccess) * 1000.0 / timeDelta
     86                     * currentSampleWeight;
     87             rxSuccessRate = rxSuccessRate * lastSampleWeight
     88                     + (rxgood - rxSuccess) * 1000.0 / timeDelta
     89                     * currentSampleWeight;
     90             txRetriesRate = txRetriesRate * lastSampleWeight
     91                     + (txretries - txRetries) * 1000.0 / timeDelta
     92                     * currentSampleWeight;
     93         } else {
     94             txBadRate = 0;
     95             txSuccessRate = 0;
     96             rxSuccessRate = 0;
     97             txRetriesRate = 0;
     98             mLastSource = source;
     99         }
    100         txBad = txbad;
    101         txSuccess = txgood;
    102         rxSuccess = rxgood;
    103         txRetries = txretries;
    104         mLastPacketCountUpdateTimeStamp = timeStamp;
    105     }
    106 
    107     /**
    108      * Updates whether Connected MAC Randomization is enabled.
    109      *
    110      * @hide
    111      */
    112     public void setEnableConnectedMacRandomization(boolean enableConnectedMacRandomization) {
    113         mEnableConnectedMacRandomization = enableConnectedMacRandomization;
    114     }
    115 
    116 }
    117