• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 
17 package com.android.server.wifi;
18 
19 import android.util.SparseArray;
20 
21 import java.util.Arrays;
22 
23 /**
24  * A class representing link layer statistics collected over a Wifi Interface.
25  */
26 
27 /**
28  * {@hide}
29  */
30 public class WifiLinkLayerStats {
31     public static final String V1_0 = "V1_0";
32     public static final String V1_3 = "V1_3";
33     public static final String V1_5 = "V1_5";
34 
35     /** The version of hal StaLinkLayerStats **/
36     public String version;
37 
38     /** Number of beacons received from our own AP */
39     public int beacon_rx;
40 
41     /** RSSI of management frames */
42     public int rssi_mgmt;
43 
44     /* Packet counters and contention time stats */
45 
46     /** WME Best Effort Access Category received mpdu */
47     public long rxmpdu_be;
48     /** WME Best Effort Access Category transmitted mpdu */
49     public long txmpdu_be;
50     /** WME Best Effort Access Category lost mpdu */
51     public long lostmpdu_be;
52     /** WME Best Effort Access Category number of transmission retries */
53     public long retries_be;
54     /** WME Best Effort Access Category data packet min contention time in microseconds */
55     public long contentionTimeMinBeInUsec;
56     /** WME Best Effort Access Category data packet max contention time in microseconds */
57     public long contentionTimeMaxBeInUsec;
58     /** WME Best Effort Access Category data packet average contention time in microseconds */
59     public long contentionTimeAvgBeInUsec;
60     /**
61      * WME Best Effort Access Category number of data packets used for deriving the min, the max,
62      * and the average contention time
63      */
64     public long contentionNumSamplesBe;
65 
66     /** WME Background Access Category received mpdu */
67     public long rxmpdu_bk;
68     /** WME Background Access Category transmitted mpdu */
69     public long txmpdu_bk;
70     /** WME Background Access Category lost mpdu */
71     public long lostmpdu_bk;
72     /** WME Background Access Category number of transmission retries */
73     public long retries_bk;
74     /** WME Background Access Category data packet min contention time in microseconds */
75     public long contentionTimeMinBkInUsec;
76     /** WME Background Access Category data packet max contention time in microseconds */
77     public long contentionTimeMaxBkInUsec;
78     /** WME Background Access Category data packet average contention time in microseconds */
79     public long contentionTimeAvgBkInUsec;
80     /**
81      * WME Background Access Category number of data packets used for deriving the min, the max,
82      * and the average contention time
83      */
84     public long contentionNumSamplesBk;
85 
86     /** WME Video Access Category received mpdu */
87     public long rxmpdu_vi;
88     /** WME Video Access Category transmitted mpdu */
89     public long txmpdu_vi;
90     /** WME Video Access Category lost mpdu */
91     public long lostmpdu_vi;
92     /** WME Video Access Category number of transmission retries */
93     public long retries_vi;
94     /** WME Video Access Category data packet min contention time in microseconds */
95     public long contentionTimeMinViInUsec;
96     /** WME Video Access Category data packet max contention time in microseconds */
97     public long contentionTimeMaxViInUsec;
98     /** WME Video Access Category data packet average contention time in microseconds */
99     public long contentionTimeAvgViInUsec;
100     /**
101      * WME Video Access Category number of data packets used for deriving the min, the max, and
102      * the average contention time
103      */
104     public long contentionNumSamplesVi;
105 
106     /** WME Voice Access Category received mpdu */
107     public long rxmpdu_vo;
108     /** WME Voice Access Category transmitted mpdu */
109     public long txmpdu_vo;
110     /** WME Voice Access Category lost mpdu */
111     public long lostmpdu_vo;
112     /** WME Voice Access Category number of transmission retries */
113     public long retries_vo;
114     /** WME Voice Access Category data packet min contention time in microseconds */
115     public long contentionTimeMinVoInUsec;
116     /** WME Voice Access Category data packet max contention time in microseconds */
117     public long contentionTimeMaxVoInUsec;
118     /** WME Voice Access Category data packet average contention time in microseconds */
119     public long contentionTimeAvgVoInUsec;
120     /**
121      * WME Voice Access Category number of data packets used for deriving the min, the max, and
122      * the average contention time
123      */
124     public long contentionNumSamplesVo;
125 
126     /**
127      * Cumulative milliseconds when radio is awake
128      */
129     public int on_time;
130     /**
131      * Cumulative milliseconds of active transmission
132      */
133     public int tx_time;
134     /**
135      * Cumulative milliseconds per radio transmit power level of active transmission
136      */
137     public int[] tx_time_per_level;
138     /**
139      * Cumulative milliseconds of active receive
140      */
141     public int rx_time;
142     /**
143      * Cumulative milliseconds when radio is awake due to scan
144      */
145     public int on_time_scan;
146     /**
147      * Cumulative milliseconds when radio is awake due to nan scan
148      */
149     public int on_time_nan_scan;
150     /**
151      * Cumulative milliseconds when radio is awake due to background scan
152      */
153     public int on_time_background_scan;
154     /**
155      * Cumulative milliseconds when radio is awake due to roam scan
156      */
157     public int on_time_roam_scan;
158     /**
159      * Cumulative milliseconds when radio is awake due to pno scan
160      */
161     public int on_time_pno_scan;
162     /**
163      * Cumulative milliseconds when radio is awake due to hotspot 2.0 scan amd GAS exchange
164      */
165     public int on_time_hs20_scan;
166     /**
167      * channel stats
168      */
169     public static class ChannelStats {
170         /**
171          * Channel frequency in MHz;
172          */
173         public int frequency;
174         /**
175          * Cumulative milliseconds radio is awake on this channel
176          */
177         public int radioOnTimeMs;
178         /**
179          * Cumulative milliseconds CCA is held busy on this channel
180          */
181         public int ccaBusyTimeMs;
182     }
183     /**
184      * Channel stats list
185      */
186     public final SparseArray<ChannelStats> channelStatsMap = new SparseArray<>();
187 
188     /**
189      * numRadios - Number of radios used for coalescing above radio stats.
190      */
191     public int numRadios;
192 
193     /**
194      * TimeStamp - absolute milliseconds from boot when these stats were sampled.
195      */
196     public long timeStampInMs;
197 
198     /**
199      * Duty cycle of the iface.
200      * if this iface is being served using time slicing on a radio with one or more ifaces
201      * (i.e MCC), then the duty cycle assigned to this iface in %.
202      * If not using time slicing (i.e SCC or DBS), set to 100.
203      */
204     public short timeSliceDutyCycleInPercent = -1;
205 
206     /**
207      * Per rate information and statistics.
208      */
209     public static class RateStat {
210         /**
211          * Preamble information. 0: OFDM, 1:CCK, 2:HT 3:VHT 4:HE 5..7 reserved.
212          */
213         public int preamble;
214         /**
215          * Number of spatial streams. 0:1x1, 1:2x2, 3:3x3, 4:4x4.
216          */
217         public int nss;
218         /**
219          * Bandwidth information. 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz.
220          */
221         public int bw;
222         /**
223          * MCS index. OFDM/CCK rate code would be as per IEEE std in the units of 0.5Mbps.
224          * HT/VHT/HE: it would be MCS index.
225          */
226         public int rateMcsIdx;
227         /**
228          * Bitrate in units of 100 Kbps.
229          */
230         public int bitRateInKbps;
231         /**
232          * Number of successfully transmitted data packets (ACK received).
233          */
234         public int txMpdu;
235         /**
236          * Number of received data packets.
237          */
238         public int rxMpdu;
239         /**
240          * Number of data packet losses (no ACK).
241          */
242         public int mpduLost;
243         /**
244          * Number of data packet retries.
245          */
246         public int retries;
247     }
248 
249     /**
250      * Per peer statistics.
251      */
252     public static class PeerInfo {
253         /**
254          * Station count.
255          */
256         public short staCount;
257         /**
258          * Channel utilization.
259          */
260         public short chanUtil;
261         /**
262          * Per rate statistics.
263          */
264         public RateStat[] rateStats;
265     }
266 
267     /**
268      * Peer statistics.
269      */
270     public PeerInfo[] peerInfo;
271 
272     /**
273      * Radio stats
274      */
275     public static class RadioStat {
276         /**
277          * Radio identifier
278          */
279         public int radio_id;
280         /**
281          * Cumulative milliseconds when radio is awake from the last radio chip reset
282          */
283         public int on_time;
284         /**
285          * Cumulative milliseconds of active transmission from the last radio chip reset
286          */
287         public int tx_time;
288         /**
289          * Cumulative milliseconds of active receive from the last radio chip reset
290          */
291         public int rx_time;
292         /**
293          * Cumulative milliseconds when radio is awake due to scan from the last radio chip reset
294          */
295         public int on_time_scan;
296         /**
297          * Cumulative milliseconds when radio is awake due to nan scan from the last radio chip
298          * reset
299          */
300         public int on_time_nan_scan;
301         /**
302          * Cumulative milliseconds when radio is awake due to background scan from the last radio
303          * chip reset
304          */
305         public int on_time_background_scan;
306         /**
307          * Cumulative milliseconds when radio is awake due to roam scan from the last radio chip
308          * reset
309          */
310         public int on_time_roam_scan;
311         /**
312          * Cumulative milliseconds when radio is awake due to pno scan from the last radio chip
313          * reset
314          */
315         public int on_time_pno_scan;
316         /**
317          * Cumulative milliseconds when radio is awake due to hotspot 2.0 scan amd GAS exchange
318          * from the last radio chip reset
319          */
320         public int on_time_hs20_scan;
321         /**
322          * Channel stats list
323          */
324         public final SparseArray<ChannelStats> channelStatsMap = new SparseArray<>();
325     }
326 
327     /**
328      * Radio stats of all the radios.
329      */
330     public RadioStat[] radioStats;
331 
332     @Override
toString()333     public String toString() {
334         StringBuilder sbuf = new StringBuilder();
335         sbuf.append(" WifiLinkLayerStats: ").append('\n');
336 
337         sbuf.append(" version of StaLinkLayerStats: ").append(version).append('\n');
338         sbuf.append(" my bss beacon rx: ").append(Integer.toString(this.beacon_rx)).append('\n');
339         sbuf.append(" RSSI mgmt: ").append(Integer.toString(this.rssi_mgmt)).append('\n');
340         sbuf.append(" BE : ").append(" rx=").append(Long.toString(this.rxmpdu_be))
341                 .append(" tx=").append(Long.toString(this.txmpdu_be))
342                 .append(" lost=").append(Long.toString(this.lostmpdu_be))
343                 .append(" retries=").append(Long.toString(this.retries_be)).append('\n')
344                 .append(" contention_time_min")
345                 .append(Long.toString(this.contentionTimeMinBeInUsec))
346                 .append(" contention_time_max")
347                 .append(Long.toString(this.contentionTimeMaxBeInUsec)).append('\n')
348                 .append(" contention_time_avg")
349                 .append(Long.toString(this.contentionTimeAvgBeInUsec))
350                 .append(" contention_num_samples")
351                 .append(Long.toString(this.contentionNumSamplesBe)).append('\n');
352         sbuf.append(" BK : ").append(" rx=").append(Long.toString(this.rxmpdu_bk))
353                 .append(" tx=").append(Long.toString(this.txmpdu_bk))
354                 .append(" lost=").append(Long.toString(this.lostmpdu_bk))
355                 .append(" retries=").append(Long.toString(this.retries_bk)).append('\n')
356                 .append(" contention_time_min")
357                 .append(Long.toString(this.contentionTimeMinBkInUsec))
358                 .append(" contention_time_max")
359                 .append(Long.toString(this.contentionTimeMaxBkInUsec)).append('\n')
360                 .append(" contention_time_avg")
361                 .append(Long.toString(this.contentionTimeAvgBkInUsec))
362                 .append(" contention_num_samples")
363                 .append(Long.toString(this.contentionNumSamplesBk)).append('\n');
364         sbuf.append(" VI : ").append(" rx=").append(Long.toString(this.rxmpdu_vi))
365                 .append(" tx=").append(Long.toString(this.txmpdu_vi))
366                 .append(" lost=").append(Long.toString(this.lostmpdu_vi))
367                 .append(" retries=").append(Long.toString(this.retries_vi)).append('\n')
368                 .append(" contention_time_min")
369                 .append(Long.toString(this.contentionTimeMinViInUsec))
370                 .append(" contention_time_max")
371                 .append(Long.toString(this.contentionTimeMaxViInUsec)).append('\n')
372                 .append(" contention_time_avg")
373                 .append(Long.toString(this.contentionTimeAvgViInUsec))
374                 .append(" contention_num_samples")
375                 .append(Long.toString(this.contentionNumSamplesVi)).append('\n');
376         sbuf.append(" VO : ").append(" rx=").append(Long.toString(this.rxmpdu_vo))
377                 .append(" tx=").append(Long.toString(this.txmpdu_vo))
378                 .append(" lost=").append(Long.toString(this.lostmpdu_vo))
379                 .append(" retries=").append(Long.toString(this.retries_vo)).append('\n')
380                 .append(" contention_time_min")
381                 .append(Long.toString(this.contentionTimeMinVoInUsec))
382                 .append(" contention_time_max")
383                 .append(Long.toString(this.contentionTimeMaxVoInUsec)).append('\n')
384                 .append(" contention_time_avg")
385                 .append(Long.toString(this.contentionTimeAvgVoInUsec))
386                 .append(" contention_num_samples")
387                 .append(Long.toString(this.contentionNumSamplesVo)).append('\n');
388         sbuf.append(" numRadios=" + numRadios)
389                 .append(" on_time= ").append(Integer.toString(this.on_time))
390                 .append(" tx_time=").append(Integer.toString(this.tx_time))
391                 .append(" rx_time=").append(Integer.toString(this.rx_time))
392                 .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n')
393                 .append(" nan_scan_time=")
394                 .append(Integer.toString(this.on_time_nan_scan)).append('\n')
395                 .append(" g_scan_time=")
396                 .append(Integer.toString(this.on_time_background_scan)).append('\n')
397                 .append(" roam_scan_time=")
398                 .append(Integer.toString(this.on_time_roam_scan)).append('\n')
399                 .append(" pno_scan_time=")
400                 .append(Integer.toString(this.on_time_pno_scan)).append('\n')
401                 .append(" hs2.0_scan_time=")
402                 .append(Integer.toString(this.on_time_hs20_scan)).append('\n')
403                 .append(" tx_time_per_level=" + Arrays.toString(tx_time_per_level)).append('\n');
404         int numChanStats = this.channelStatsMap.size();
405         sbuf.append(" Number of channel stats=").append(numChanStats).append('\n');
406         for (int i = 0; i < numChanStats; ++i) {
407             ChannelStats channelStatsEntry = this.channelStatsMap.valueAt(i);
408             sbuf.append(" Frequency=").append(channelStatsEntry.frequency)
409                     .append(" radioOnTimeMs=").append(channelStatsEntry.radioOnTimeMs)
410                     .append(" ccaBusyTimeMs=").append(channelStatsEntry.ccaBusyTimeMs).append('\n');
411         }
412         int numRadios = this.radioStats == null ? 0 : this.radioStats.length;
413         sbuf.append(" Individual radio stats: numRadios=").append(numRadios).append('\n');
414         for (int i = 0; i < numRadios; i++) {
415             RadioStat radio = this.radioStats[i];
416             sbuf.append(" radio_id=" + radio.radio_id)
417                     .append(" on_time=").append(Integer.toString(radio.on_time))
418                     .append(" tx_time=").append(Integer.toString(radio.tx_time))
419                     .append(" rx_time=").append(Integer.toString(radio.rx_time))
420                     .append(" scan_time=").append(Integer.toString(radio.on_time_scan)).append('\n')
421                     .append(" nan_scan_time=")
422                     .append(Integer.toString(radio.on_time_nan_scan)).append('\n')
423                     .append(" g_scan_time=")
424                     .append(Integer.toString(radio.on_time_background_scan)).append('\n')
425                     .append(" roam_scan_time=")
426                     .append(Integer.toString(radio.on_time_roam_scan)).append('\n')
427                     .append(" pno_scan_time=")
428                     .append(Integer.toString(radio.on_time_pno_scan)).append('\n')
429                     .append(" hs2.0_scan_time=")
430                     .append(Integer.toString(radio.on_time_hs20_scan)).append('\n');
431             int numRadioChanStats = radio.channelStatsMap.size();
432             sbuf.append(" Number of channel stats=").append(numRadioChanStats).append('\n');
433             for (int j = 0; j < numRadioChanStats; ++j) {
434                 ChannelStats channelStatsEntry = radio.channelStatsMap.valueAt(j);
435                 sbuf.append(" Frequency=").append(channelStatsEntry.frequency)
436                         .append(" radioOnTimeMs=").append(channelStatsEntry.radioOnTimeMs)
437                         .append(" ccaBusyTimeMs=").append(channelStatsEntry.ccaBusyTimeMs)
438                         .append('\n');
439             }
440         }
441         sbuf.append(" ts=" + timeStampInMs);
442         int numPeers = this.peerInfo == null ? 0 : this.peerInfo.length;
443         sbuf.append(" Number of peers=").append(numPeers).append('\n');
444         for (int i = 0; i < numPeers; i++) {
445             PeerInfo peer = this.peerInfo[i];
446             sbuf.append(" staCount=").append(peer.staCount)
447                     .append(" chanUtil=").append(peer.chanUtil).append('\n');
448             int numRateStats = peer.rateStats == null ? 0 : peer.rateStats.length;
449             for (int j = 0; j < numRateStats; j++) {
450                 RateStat rateStat = peer.rateStats[j];
451                 sbuf.append(" preamble=").append(rateStat.preamble)
452                         .append(" nss=").append(rateStat.nss)
453                         .append(" bw=").append(rateStat.bw)
454                         .append(" rateMcsIdx=").append(rateStat.rateMcsIdx)
455                         .append(" bitRateInKbps=").append(rateStat.bitRateInKbps).append('\n')
456                         .append(" txMpdu=").append(rateStat.txMpdu)
457                         .append(" rxMpdu=").append(rateStat.rxMpdu)
458                         .append(" mpduLost=").append(rateStat.mpduLost)
459                         .append(" retries=").append(rateStat.retries).append('\n');
460             }
461         }
462         return sbuf.toString();
463     }
464 
465 }
466