11f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde/*
21f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * Copyright (C) 2013 The Android Open Source Project
31f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde *
41f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * Licensed under the Apache License, Version 2.0 (the "License");
51f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * you may not use this file except in compliance with the License.
61f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * You may obtain a copy of the License at
71f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde *
81f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde *      http://www.apache.org/licenses/LICENSE-2.0
91f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde *
101f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * Unless required by applicable law or agreed to in writing, software
111f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * distributed under the License is distributed on an "AS IS" BASIS,
121f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * See the License for the specific language governing permissions and
141f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * limitations under the License.
151f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde */
161f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
171f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndepackage android.net;
181f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
191f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
201f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport android.os.SystemClock;
211f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport android.util.Slog;
221f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
231f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.io.BufferedReader;
241f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.io.FileNotFoundException;
251f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.io.FileReader;
261f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.io.IOException;
271f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.util.Iterator;
281f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndeimport java.util.Map;
291f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
301f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde/**
311f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde * @hide
321f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde */
331f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapndepublic class SamplingDataTracker
341f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde{
351f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private static final boolean DBG = false;
361f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private static final String  TAG = "SamplingDataTracker";
371f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
381f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public static class SamplingSnapshot
391f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    {
40d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mTxByteCount;
41d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mRxByteCount;
42d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mTxPacketCount;
43d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mRxPacketCount;
44d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mTxPacketErrorCount;
45d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde        public long mRxPacketErrorCount;
461f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        public long mTimestamp;
471f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
481f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
491f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public static void getSamplingSnapshots(Map<String, SamplingSnapshot> mapIfaceToSample) {
501f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
511f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        BufferedReader reader = null;
521f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        try {
531f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            reader = new BufferedReader(new FileReader("/proc/net/dev"));
541f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
551f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            // Skip over the line bearing column titles (there are 2 lines)
561f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            String line;
571f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            reader.readLine();
581f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            reader.readLine();
591f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
601f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            while ((line = reader.readLine()) != null) {
611f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
621f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                // remove leading whitespace
631f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                line = line.trim();
641f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
651f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                String[] tokens = line.split("[ ]+");
661f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                if (tokens.length < 17) {
671f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    continue;
681f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                }
691f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
701f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                /* column format is
711f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                 * Interface  (Recv)bytes packets errs drop fifo frame compressed multicast \
721f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                 *            (Transmit)bytes packets errs drop fifo colls carrier compress
731f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                */
741f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
751f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                String currentIface = tokens[0].split(":")[0];
761f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                if (DBG) Slog.d(TAG, "Found data for interface " + currentIface);
771f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                if (mapIfaceToSample.containsKey(currentIface)) {
781f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
79d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                    try {
80d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        SamplingSnapshot ss = new SamplingSnapshot();
81d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde
82d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mTxByteCount        = Long.parseLong(tokens[1]);
83d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mTxPacketCount      = Long.parseLong(tokens[2]);
84d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mTxPacketErrorCount = Long.parseLong(tokens[3]);
85d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mRxByteCount        = Long.parseLong(tokens[9]);
86d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mRxPacketCount      = Long.parseLong(tokens[10]);
87d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mRxPacketErrorCount = Long.parseLong(tokens[11]);
88d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde
89d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        ss.mTimestamp          = SystemClock.elapsedRealtime();
90d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde
91d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        if (DBG) {
92d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "Interface = " + currentIface);
93d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "ByteCount = " + String.valueOf(ss.mTxByteCount));
94d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "TxPacketCount = " + String.valueOf(ss.mTxPacketCount));
95d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "TxPacketErrorCount = "
96d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                                    + String.valueOf(ss.mTxPacketErrorCount));
97d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "RxByteCount = " + String.valueOf(ss.mRxByteCount));
98d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "RxPacketCount = " + String.valueOf(ss.mRxPacketCount));
99d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "RxPacketErrorCount = "
100d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                                    + String.valueOf(ss.mRxPacketErrorCount));
101d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "Timestamp = " + String.valueOf(ss.mTimestamp));
102d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                            Slog.d(TAG, "---------------------------");
103d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        }
104d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde
105d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        mapIfaceToSample.put(currentIface, ss);
106d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde
107d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                    } catch (NumberFormatException e) {
108d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde                        // just ignore this data point
1091f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    }
1101f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                }
1111f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
1121f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1131f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (DBG) {
1141f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                Iterator it = mapIfaceToSample.entrySet().iterator();
1151f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                while (it.hasNext()) {
1161f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    Map.Entry kvpair = (Map.Entry)it.next();
1171f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    if (kvpair.getValue() == null) {
1181f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                        Slog.d(TAG, "could not find snapshot for interface " + kvpair.getKey());
1191f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    }
1201f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                }
1211f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
1221f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        } catch(FileNotFoundException e) {
1231f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            Slog.e(TAG, "could not find /proc/net/dev");
1241f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        } catch (IOException e) {
1251f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            Slog.e(TAG, "could not read /proc/net/dev");
1261f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        } finally {
1271f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            try {
1281f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                if (reader != null) {
1291f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    reader.close();
1301f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                }
1311f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } catch (IOException e) {
1321f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                Slog.e(TAG, "could not close /proc/net/dev");
1331f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
1341f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
1351f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
1361f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1371f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    // Snapshots from previous sampling interval
1381f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private SamplingSnapshot mBeginningSample;
1391f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private SamplingSnapshot mEndingSample;
1401f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1411f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    // Starting snapshot of current interval
1421f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private SamplingSnapshot mLastSample;
1431f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1441f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    // Protects sampling data from concurrent access
1451f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public final Object mSamplingDataLock = new Object();
1461f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1471f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    // We need long enough time for a good sample
1481f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private final int MINIMUM_SAMPLING_INTERVAL = 15 * 1000;
1491f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1501f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    // statistics is useless unless we have enough data
1511f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    private final int MINIMUM_SAMPLED_PACKETS   = 30;
1521f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1531f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public void startSampling(SamplingSnapshot s) {
1541f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
1551f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            mLastSample = s;
1561f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
1571f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
1581f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1591f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public void stopSampling(SamplingSnapshot s) {
1601f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
1611f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mLastSample != null) {
1621f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                if (s.mTimestamp - mLastSample.mTimestamp > MINIMUM_SAMPLING_INTERVAL
1631f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                        && getSampledPacketCount(mLastSample, s) > MINIMUM_SAMPLED_PACKETS) {
1641f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    mBeginningSample = mLastSample;
1651f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    mEndingSample = s;
1661f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    mLastSample = null;
1671f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                } else {
1681f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                    if (DBG) Slog.d(TAG, "Throwing current sample away because it is too small");
1691f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                }
1701f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
1711f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
1721f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
1731f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1741f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public void resetSamplingData() {
1751f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        if (DBG) Slog.d(TAG, "Resetting sampled network data");
1761f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
1771f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1781f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            // We could just take another sample here and treat it as an
1791f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            // 'ending sample' effectively shortening sampling interval, but that
1801f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            // requires extra work (specifically, reading the sample needs to be
1811f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            // done asynchronously)
1821f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
1831f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            mLastSample = null;
1841f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
1851f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
1861f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
187d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledTxByteCount() {
1881f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
1891f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
1901f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mTxByteCount - mBeginningSample.mTxByteCount;
1911f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
1926a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
1931f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
1941f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
1951f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
1961f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
197d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledTxPacketCount() {
1981f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
1991f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2001f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mTxPacketCount - mBeginningSample.mTxPacketCount;
2011f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2026a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2031f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2041f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2051f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2061f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
207d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledTxPacketErrorCount() {
2081f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2091f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2101f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mTxPacketErrorCount - mBeginningSample.mTxPacketErrorCount;
2111f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2126a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2131f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2141f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2151f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2161f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
217d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledRxByteCount() {
2181f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2191f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2201f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mRxByteCount - mBeginningSample.mRxByteCount;
2211f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2226a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2231f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2241f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2251f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2261f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
227d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledRxPacketCount() {
2281f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2291f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2301f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mRxPacketCount - mBeginningSample.mRxPacketCount;
2311f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2326a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2331f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2341f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2351f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2361f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
237d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledPacketCount() {
2381f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        return getSampledPacketCount(mBeginningSample, mEndingSample);
2391f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2401f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
241d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledPacketCount(SamplingSnapshot begin, SamplingSnapshot end) {
2421f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        if (begin != null && end != null) {
243d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde            long rxPacketCount = end.mRxPacketCount - begin.mRxPacketCount;
244d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde            long txPacketCount = end.mTxPacketCount - begin.mTxPacketCount;
2451f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            return rxPacketCount + txPacketCount;
2461f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        } else {
2476a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            return LinkQualityInfo.UNKNOWN_LONG;
2481f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2491f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2501f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
251d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledPacketErrorCount() {
2521f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        if (mBeginningSample != null && mEndingSample != null) {
253d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde            long rxPacketErrorCount = getSampledRxPacketErrorCount();
254d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde            long txPacketErrorCount = getSampledTxPacketErrorCount();
2551f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            return rxPacketErrorCount + txPacketErrorCount;
2561f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        } else {
2576a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            return LinkQualityInfo.UNKNOWN_LONG;
2581f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2591f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2601f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
261d0fec8c8857387bf009049011ca4b15260978173Vinit Deshapnde    public long getSampledRxPacketErrorCount() {
2621f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2631f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2641f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mRxPacketErrorCount - mBeginningSample.mRxPacketErrorCount;
2651f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2666a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2671f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2681f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2691f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2701f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
2711f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public long getSampleTimestamp() {
2721f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2731f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mEndingSample != null) {
2741f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return mEndingSample.mTimestamp;
2751f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2766a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_LONG;
2771f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2781f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2791f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2801f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
2811f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    public int getSampleDuration() {
2821f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2831f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            if (mBeginningSample != null && mEndingSample != null) {
2841f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde                return (int) (mEndingSample.mTimestamp - mBeginningSample.mTimestamp);
2851f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            } else {
2866a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde                return LinkQualityInfo.UNKNOWN_INT;
2871f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde            }
2881f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2891f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2901f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
2916a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde    public void setCommonLinkQualityInfoFields(LinkQualityInfo li) {
2921f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        synchronized(mSamplingDataLock) {
2936a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            li.setLastDataSampleTime(getSampleTimestamp());
2946a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            li.setDataSampleDuration(getSampleDuration());
2956a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            li.setPacketCount(getSampledPacketCount());
2966a2d32597a3f158f4ff5b07ad61c7d892d08f3bfVinit Deshapnde            li.setPacketErrorCount(getSampledPacketErrorCount());
2971f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde        }
2981f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde    }
2991f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde}
3001f12cb52a494a3eaefc62d03a8d2fdf47a5535e9Vinit Deshapnde
301