1 /*
2  * Copyright (C) 2022 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.Log;
20 
21 import java.util.HashMap;
22 import java.util.Map;
23 
24 /**
25  * A class representing signal poll results collected over multiple links.
26  */
27 public class WifiSignalPollResults {
28     public static String TAG = "WifiSignalPollResults";
29     public static final int MIN_RSSI = -127;
30     /* Maximum of 15 entries possible. */
31     public static final int MAX_ENTRIES = 15;
32 
WifiSignalPollResults()33     WifiSignalPollResults() {
34         mEntries = new HashMap();
35         mBestLinkId = 0;
36         mDefault = new SignalPollResult(0, MIN_RSSI, 0, 0, 0);
37     }
38     static class SignalPollResult {
SignalPollResult(int linkId, int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, int frequencyMHz)39         SignalPollResult(int linkId, int currentRssiDbm, int txBitrateMbps,
40                 int rxBitrateMbps, int frequencyMHz) {
41             this.linkId = linkId;
42             this.currentRssiDbm = currentRssiDbm;
43             this.txBitrateMbps = txBitrateMbps;
44             this.rxBitrateMbps = rxBitrateMbps;
45             this.frequencyMHz = frequencyMHz;
46         }
47 
48         /**
49          * Link identifier.
50          */
51         public final int linkId;
52 
53         /**
54          * RSSI value in dBM.
55          */
56         public final int currentRssiDbm;
57 
58         /**
59          * Last transmitted bit rate in Mbps.
60          */
61         public final int txBitrateMbps;
62 
63         /**
64          * Last received packet bit rate in Mbps.
65          */
66         public final int rxBitrateMbps;
67 
68         /**
69          * Frequency in MHz.
70          */
71         public final int frequencyMHz;
72     }
73 
74     /* Signal poll result entries. Maps linkId to SignalPollResult. */
75     private Map<Integer, SignalPollResult> mEntries;
76     /* Link id of the best link. */
77     private int mBestLinkId;
78     /* Default entry with default values. */
79     private SignalPollResult mDefault;
80 
81     /**
82      * Add a new entry of signal poll result.
83      *
84      * @param linkId         Identifier of the link (0 - 14).
85      * @param currentRssiDbm Current RSSI in dBm.
86      * @param txBitRateMbps  Transmit bit rate of the link.
87      * @param rxBitRateMbps  Receive bit rate of the link.
88      * @param frequencyMHz   Frequency of the link.
89      */
addEntry(int linkId, int currentRssiDbm, int txBitRateMbps, int rxBitRateMbps, int frequencyMHz)90     public void addEntry(int linkId, int currentRssiDbm, int txBitRateMbps, int rxBitRateMbps,
91             int frequencyMHz) {
92         if (mEntries.size() > MAX_ENTRIES) {
93             Log.e(TAG, "addEntry: failed, reached maximum entries " + MAX_ENTRIES);
94             return;
95         }
96         // Update the best link id.
97         if (mEntries.size() == 0 || currentRssiDbm > mEntries.get(
98                 mBestLinkId).currentRssiDbm) {
99             mBestLinkId = linkId;
100         }
101         // Add a new Entry.
102         mEntries.put(linkId,
103                 new SignalPollResult(linkId, currentRssiDbm, txBitRateMbps, rxBitRateMbps,
104                         frequencyMHz));
105 
106     }
107 
108     /**
109      * Get current RSSI. In case of multi links, return the maximum RSSI (best link).
110      *
111      * @return rssi in dBm or {@link WifiSignalPollResults#MIN_RSSI} if no poll results.
112      */
getRssi()113     public int getRssi() {
114         return mEntries.getOrDefault(mBestLinkId, mDefault).currentRssiDbm;
115     }
116 
117     /**
118      * Get current RSSI of the link.
119      *
120      * @param linkId Identifier of the link.
121      * @return rssi in dBm or {@link WifiSignalPollResults#MIN_RSSI} if link is not present.
122      */
getRssi(int linkId)123     public int getRssi(int linkId) {
124         return mEntries.getOrDefault(linkId, mDefault).currentRssiDbm;
125     }
126 
127     /**
128      * Get transmit link speed in Mbps. In case of multi links, return the rate of the best link.
129      *
130      * @return tx link speed in Mpbs or 0 if no poll results.
131      */
getTxLinkSpeed()132     public int getTxLinkSpeed() {
133         return mEntries.getOrDefault(mBestLinkId, mDefault).txBitrateMbps;
134     }
135 
136     /**
137      * Get transmit link speed in Mbps of the link.
138      *
139      * @param linkId Identifier of the link.
140      * @return tx link speed in Mpbs or 0 if no poll results.
141      */
getTxLinkSpeed(int linkId)142     public int getTxLinkSpeed(int linkId) {
143         return mEntries.getOrDefault(linkId, mDefault).txBitrateMbps;
144     }
145 
146     /**
147      * Get receive link speed in Mbps. In case of multi links, return the rate of the best link.
148      *
149      * @return rx link speed in Mpbs or 0 if no poll results.
150      */
getRxLinkSpeed()151     public int getRxLinkSpeed() {
152         return mEntries.getOrDefault(mBestLinkId, mDefault).rxBitrateMbps;
153     }
154 
155     /**
156      * Get receive link speed in Mbps of the link.
157      *
158      * @param linkId Identifier of the link.
159      * @return rx link speed in Mpbs or 0 if no poll results.
160      */
getRxLinkSpeed(int linkId)161     public int getRxLinkSpeed(int linkId) {
162         return mEntries.getOrDefault(linkId, mDefault).rxBitrateMbps;
163     }
164 
165     /**
166      * Get frequency. In case of multi links, return frequency of the best link.
167      *
168      * @return frequency in MHz or 0 if no poll results.
169      */
getFrequency()170     public int getFrequency() {
171         return mEntries.getOrDefault(mBestLinkId, mDefault).frequencyMHz;
172     }
173 
174     /**
175      * Get frequency of the link.
176      *
177      * @param linkId Identifier of the link.
178      * @return frequency in MHz or 0 if no poll results.
179      */
getFrequency(int linkId)180     public int getFrequency(int linkId) {
181         return mEntries.getOrDefault(linkId, mDefault).frequencyMHz;
182     }
183 
184     /**
185      * Return whether the poll results available for the specific link.
186      *
187      * @param linkId Identifier of the link.
188      * @return true if available, otherwise false
189      */
isAvailable(int linkId)190     public boolean isAvailable(int linkId) {
191         return mEntries.containsKey(linkId);
192     }
193 }
194