1/*
2 * Copyright (C) 2014 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
17package android.net.wifi;
18
19import android.os.Parcelable;
20import android.os.Parcel;
21
22import java.util.Arrays;
23
24/**
25 * A class representing link layer statistics collected over a Wifi Interface.
26 */
27/** {@hide} */
28public class WifiLinkLayerStats implements Parcelable {
29    private static final String TAG = "WifiLinkLayerStats";
30
31    /**
32     * The current status of this network configuration entry.
33     * @see Status
34     */
35    /** {@hide} */
36    public int status;
37
38    /**
39     * The network's SSID. Can either be an ASCII string,
40     * which must be enclosed in double quotation marks
41     * (e.g., {@code "MyNetwork"}, or a string of
42     * hex digits,which are not enclosed in quotes
43     * (e.g., {@code 01a243f405}).
44     */
45    /** {@hide} */
46    public String SSID;
47    /**
48     * When set. this is the BSSID the radio is currently associated with.
49     * The value is a string in the format of an Ethernet MAC address, e.g.,
50     * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
51     */
52    /** {@hide} */
53    public String BSSID;
54
55    /* number beacons received from our own AP */
56    /** {@hide} */
57    public int beacon_rx;
58
59    /* RSSI taken on management frames */
60    /** {@hide} */
61    public int rssi_mgmt;
62
63    /* packets counters */
64    /** {@hide} */
65    /* WME Best Effort Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries)*/
66    public long rxmpdu_be;
67    /** {@hide} */
68    public long txmpdu_be;
69    /** {@hide} */
70    public long lostmpdu_be;
71    /** {@hide} */
72    public long retries_be;
73    /** {@hide} */
74    /* WME Background Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
75    public long rxmpdu_bk;
76    /** {@hide} */
77    public long txmpdu_bk;
78    /** {@hide} */
79    public long lostmpdu_bk;
80    /** {@hide} */
81    public long retries_bk;
82    /** {@hide} */
83    /* WME Video Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
84    public long rxmpdu_vi;
85    /** {@hide} */
86    public long txmpdu_vi;
87    /** {@hide} */
88    public long lostmpdu_vi;
89    /** {@hide} */
90    public long retries_vi;
91    /** {@hide} */
92    /* WME Voice Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
93    public long rxmpdu_vo;
94    /** {@hide} */
95    public long txmpdu_vo;
96    /** {@hide} */
97    public long lostmpdu_vo;
98    /** {@hide} */
99    public long retries_vo;
100
101    /** {@hide} */
102    public int on_time;
103    /** {@hide} */
104    public int tx_time;
105    /** {@hide} */
106    public int[] tx_time_per_level;
107    /** {@hide} */
108    public int rx_time;
109    /** {@hide} */
110    public int on_time_scan;
111
112    /** {@hide} */
113    public WifiLinkLayerStats() {
114    }
115
116    @Override
117    /** {@hide} */
118    public String toString() {
119        StringBuilder sbuf = new StringBuilder();
120        sbuf.append(" WifiLinkLayerStats: ").append('\n');
121
122        if (this.SSID != null) {
123            sbuf.append(" SSID: ").append(this.SSID).append('\n');
124        }
125        if (this.BSSID != null) {
126            sbuf.append(" BSSID: ").append(this.BSSID).append('\n');
127        }
128
129        sbuf.append(" my bss beacon rx: ").append(Integer.toString(this.beacon_rx)).append('\n');
130        sbuf.append(" RSSI mgmt: ").append(Integer.toString(this.rssi_mgmt)).append('\n');
131        sbuf.append(" BE : ").append(" rx=").append(Long.toString(this.rxmpdu_be))
132                .append(" tx=").append(Long.toString(this.txmpdu_be))
133                .append(" lost=").append(Long.toString(this.lostmpdu_be))
134                .append(" retries=").append(Long.toString(this.retries_be)).append('\n');
135        sbuf.append(" BK : ").append(" rx=").append(Long.toString(this.rxmpdu_bk))
136                .append(" tx=").append(Long.toString(this.txmpdu_bk))
137                .append(" lost=").append(Long.toString(this.lostmpdu_bk))
138                .append(" retries=").append(Long.toString(this.retries_bk)).append('\n');
139        sbuf.append(" VI : ").append(" rx=").append(Long.toString(this.rxmpdu_vi))
140                .append(" tx=").append(Long.toString(this.txmpdu_vi))
141                .append(" lost=").append(Long.toString(this.lostmpdu_vi))
142                .append(" retries=").append(Long.toString(this.retries_vi)).append('\n');
143        sbuf.append(" VO : ").append(" rx=").append(Long.toString(this.rxmpdu_vo))
144                .append(" tx=").append(Long.toString(this.txmpdu_vo))
145                .append(" lost=").append(Long.toString(this.lostmpdu_vo))
146                .append(" retries=").append(Long.toString(this.retries_vo)).append('\n');
147        sbuf.append(" on_time : ").append(Integer.toString(this.on_time))
148                .append(" rx_time=").append(Integer.toString(this.rx_time))
149                .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n')
150                .append(" tx_time=").append(Integer.toString(this.tx_time))
151                .append(" tx_time_per_level=" + Arrays.toString(tx_time_per_level));
152        return sbuf.toString();
153    }
154
155    /** Implement the Parcelable interface {@hide} */
156    public int describeContents() {
157        return 0;
158    }
159
160    /** {@hide} */
161    public String getPrintableSsid() {
162        if (SSID == null) return "";
163        final int length = SSID.length();
164        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
165            return SSID.substring(1, length - 1);
166        }
167
168        /** The ascii-encoded string format is P"<ascii-encoded-string>"
169         * The decoding is implemented in the supplicant for a newly configured
170         * network.
171         */
172        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
173                (SSID.charAt(length-1) == '"')) {
174            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
175                    SSID.substring(2, length - 1));
176            return wifiSsid.toString();
177        }
178        return SSID;
179    }
180
181    /** Implement the Parcelable interface {@hide} */
182    public void writeToParcel(Parcel dest, int flags) {
183        dest.writeString(SSID);
184        dest.writeString(BSSID);
185        dest.writeInt(on_time);
186        dest.writeInt(tx_time);
187        dest.writeIntArray(tx_time_per_level);
188        dest.writeInt(rx_time);
189        dest.writeInt(on_time_scan);
190    }
191
192    /** Implement the Parcelable interface {@hide} */
193    public static final Creator<WifiLinkLayerStats> CREATOR =
194        new Creator<WifiLinkLayerStats>() {
195            public WifiLinkLayerStats createFromParcel(Parcel in) {
196                WifiLinkLayerStats stats = new WifiLinkLayerStats();
197                stats.SSID = in.readString();
198                stats.BSSID = in.readString();
199                stats.on_time = in.readInt();
200                stats.tx_time = in.readInt();
201                stats.tx_time_per_level = in.createIntArray();
202                stats.rx_time = in.readInt();
203                stats.on_time_scan = in.readInt();
204                return stats;
205            };
206            public WifiLinkLayerStats[] newArray(int size) {
207                return new WifiLinkLayerStats[size];
208            }
209
210        };
211}
212