Use device capabilities to identify radio band (#104)

This commit is contained in:
RockyMandayam2
2022-10-13 19:05:05 -07:00
committed by GitHub
parent 8171cc74ae
commit 6df81b7fef
19 changed files with 602 additions and 125 deletions

View File

@@ -22,7 +22,7 @@ public final class UCentralConstants {
public static final String BAND_2G = "2G";
/** String of the 5 GHz band */
public static final String BAND_5G = "5G";
/** List of all bands */
/** List of all bands ordered from lowest to highest */
public static final List<String> BANDS = Collections
.unmodifiableList(Arrays.asList(BAND_2G, BAND_5G));

View File

@@ -63,6 +63,8 @@ public class UCentralUtils {
Arrays.asList(36, 40, 44, 48, 149, 153, 157, 161, 165)
)
);
// NOTE: later, we may want to support channels 12, 13, and/or 14, if
// the AP supports it and OWF vendors will use them
bandToChannelsMap.put(
UCentralConstants.BAND_2G,
Collections.unmodifiableList(
@@ -416,23 +418,6 @@ public class UCentralUtils {
return bssidMap;
}
/**
* Converts channel number to that channel's center frequency in MHz.
*
* @param channel channel number
* @return the center frequency of the given channel in MHz
*/
public static int channelToFrequencyMHz(int channel) {
// TODO fixme
if (channel <= 14) {
// 2.4 GHz
return 2407 + 5 * channel;
} else {
// 5 GHz
return 5000 + channel;
}
}
/**
* Determines if the given channel is in the given band.
*
@@ -444,20 +429,13 @@ public class UCentralUtils {
return AVAILABLE_CHANNELS_BAND.get(band).contains(channel);
}
/**
* Given the channel, gets the band by checking lower bound and upper bound
* of each band
*
* @param channel channel number
* @return band if the channel can be mapped to a valid band; null otherwise
*/
public static String getBandFromChannel(int channel) {
for (String band : UCentralConstants.BANDS) {
if (isChannelInBand(channel, band)) {
return band;
}
/** Return which band contains the given frequency (MHz). */
public static String freqToBand(int freqMHz) {
if (2412 <= freqMHz && freqMHz <= 2484) {
return "2G";
} else {
return "5G";
}
return null;
}
/**

View File

@@ -30,6 +30,9 @@ import com.facebook.openwifi.cloudsdk.models.ap.State.Interface.SSID.Association
import com.facebook.openwifi.rrm.aggregators.Aggregator;
import com.facebook.openwifi.rrm.aggregators.MeanAggregator;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
/**
* Modeler utilities.
@@ -555,4 +558,28 @@ public class ModelerUtils {
station
);
}
/** Return the radio's band, or null if band cannot be found */
public static String getBand(
State.Radio radio,
JsonObject deviceCapability
) {
if (radio.phy == null) {
return null;
}
JsonElement radioCapabilityElement = deviceCapability.get(radio.phy);
if (radioCapabilityElement == null) {
return null;
}
JsonObject radioCapability = radioCapabilityElement.getAsJsonObject();
JsonElement bandsElement = radioCapability.get("band");
if (bandsElement == null) {
return null;
}
JsonArray bands = bandsElement.getAsJsonArray();
if (bands.isEmpty()) {
return null;
}
return bands.get(0).getAsString();
}
}

View File

@@ -28,6 +28,8 @@ import com.facebook.openwifi.rrm.DeviceConfig;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.ConfigManager;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.google.gson.JsonObject;
/**
* Channel optimizer base class.
@@ -298,25 +300,28 @@ public abstract class ChannelOptimizer {
List<WifiScanEntry> scanRespsFiltered =
new ArrayList<WifiScanEntry>();
for (WifiScanEntry entry : scanResps) {
if (UCentralUtils.isChannelInBand(entry.channel, band)) {
int channelWidth = getChannelWidthFromWiFiScan(
final String entryBand = UCentralUtils
.freqToBand(entry.frequency);
if (entryBand == null || !entryBand.equals(band)) {
continue;
}
int channelWidth = getChannelWidthFromWiFiScan(
entry.channel,
entry.ht_oper,
entry.vht_oper
);
int primaryChannel =
getPrimaryChannel(entry.channel, channelWidth);
List<Integer> coveredChannels =
getCoveredChannels(
entry.channel,
entry.ht_oper,
entry.vht_oper
primaryChannel,
channelWidth
);
int primaryChannel =
getPrimaryChannel(entry.channel, channelWidth);
List<Integer> coveredChannels =
getCoveredChannels(
entry.channel,
primaryChannel,
channelWidth
);
for (Integer newChannel : coveredChannels) {
WifiScanEntry newEntry = new WifiScanEntry(entry);
newEntry.channel = newChannel;
scanRespsFiltered.add(newEntry);
}
for (Integer newChannel : coveredChannels) {
WifiScanEntry newEntry = new WifiScanEntry(entry);
newEntry.channel = newChannel;
scanRespsFiltered.add(newEntry);
}
}
@@ -344,6 +349,7 @@ public abstract class ChannelOptimizer {
* @param band the operational band (e.g., "2G")
* @param serialNumber the device's serial number
* @param state the latest state of all the devices
* @param latestDeviceCapabilities latest device capabilities
* @return the current channel and channel width (MHz) of the device in the
* given band; returns a current channel of 0 if no channel in the given
* band is found.
@@ -351,7 +357,8 @@ public abstract class ChannelOptimizer {
protected static int[] getCurrentChannel(
String band,
String serialNumber,
State state
State state,
Map<String, JsonObject> latestDeviceCapabilities
) {
int currentChannel = 0;
int currentChannelWidth = MIN_CHANNEL_WIDTH;
@@ -361,27 +368,40 @@ public abstract class ChannelOptimizer {
radioIndex < state.radios.length;
radioIndex++
) {
int tempChannel = state.radios[radioIndex].channel;
if (UCentralUtils.isChannelInBand(tempChannel, band)) {
currentChannel = tempChannel;
// treat as two separate 80MHz channel and only assign to one
// TODO: support 80p80 properly
Integer parsedChannelWidth = UCentralUtils
.parseChannelWidth(
state.radios[radioIndex].channel_width,
true
);
if (parsedChannelWidth != null) {
currentChannelWidth = parsedChannelWidth;
break;
}
logger.error(
"Invalid channel width {}",
state.radios[radioIndex].channel_width
);
State.Radio radio = state.radios[radioIndex];
// check if radio is in band of interest
JsonObject deviceCapability =
latestDeviceCapabilities.get(serialNumber);
if (deviceCapability == null) {
continue;
}
final String radioBand = ModelerUtils.getBand(
radio,
deviceCapability
);
if (radioBand == null || !radioBand.equals(band)) {
continue;
}
int tempChannel = radio.channel;
currentChannel = tempChannel;
// treat as two separate 80MHz channel and only assign to one
// TODO: support 80p80 properly
Integer parsedChannelWidth = UCentralUtils
.parseChannelWidth(
radio.channel_width,
true
);
if (parsedChannelWidth != null) {
currentChannelWidth = parsedChannelWidth;
break;
}
logger.error(
"Invalid channel width {}",
radio.channel_width
);
continue;
}
return new int[] { currentChannel, currentChannelWidth };
}

View File

@@ -393,7 +393,12 @@ public class LeastUsedChannelOptimizer extends ChannelOptimizer {
continue;
}
int[] currentChannelInfo =
getCurrentChannel(band, serialNumber, state);
getCurrentChannel(
band,
serialNumber,
state,
model.latestDeviceCapabilities
);
int currentChannel = currentChannelInfo[0];
// Filter out APs if the radios in the state do not contain a
// channel in a band given by the state. This can happen when

View File

@@ -23,8 +23,8 @@ import com.facebook.openwifi.cloudsdk.UCentralUtils;
import com.facebook.openwifi.cloudsdk.WifiScanEntry;
import com.facebook.openwifi.cloudsdk.models.ap.State;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
/**
* Random channel initializer.
@@ -204,7 +204,12 @@ public class RandomChannelInitializer extends ChannelOptimizer {
continue;
}
int[] currentChannelInfo =
getCurrentChannel(band, serialNumber, state);
getCurrentChannel(
band,
serialNumber,
state,
model.latestDeviceCapabilities
);
int currentChannel = currentChannelInfo[0];
int currentChannelWidth = currentChannelInfo[1];
if (currentChannel == 0) {

View File

@@ -18,12 +18,11 @@ import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.facebook.openwifi.cloudsdk.UCentralUtils;
import com.facebook.openwifi.cloudsdk.models.ap.State;
import com.facebook.openwifi.rrm.DeviceConfig;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
/**
* Location-based optimal TPC algorithm.
@@ -153,6 +152,7 @@ public class LocationBasedOptimalTPC extends TPC {
/**
* Calculate new tx powers for the given band.
*
* @param band band (e.g., "2G")
* @param channel channel
* @param serialNumbers The serial numbers of the APs with the channel
* @param txPowerMap this map from serial number to band to new tx power
@@ -160,13 +160,13 @@ public class LocationBasedOptimalTPC extends TPC {
* this method with the new tx powers.
*/
private void buildTxPowerMapForChannel(
String band,
int channel,
List<String> serialNumbers,
Map<String, Map<String, Integer>> txPowerMap
) {
int numOfAPs = 0;
int boundary = 100;
String band = UCentralUtils.getBandFromChannel(channel);
Map<String, Integer> validAPs = new TreeMap<>();
List<Double> apLocX = new ArrayList<>();
List<Double> apLocY = new ArrayList<>();
@@ -283,9 +283,27 @@ public class LocationBasedOptimalTPC extends TPC {
@Override
public Map<String, Map<String, Integer>> computeTxPowerMap() {
Map<String, Map<String, Integer>> txPowerMap = new TreeMap<>();
Map<Integer, List<String>> apsPerChannel = getApsPerChannel();
for (Map.Entry<Integer, List<String>> e : apsPerChannel.entrySet()) {
buildTxPowerMapForChannel(e.getKey(), e.getValue(), txPowerMap);
Map<String, Map<Integer, List<String>>> bandToChannelToAps =
getApsPerChannel();
for (
Map.Entry<String, Map<Integer, List<String>>> bandEntry : bandToChannelToAps
.entrySet()
) {
final String band = bandEntry.getKey();
Map<Integer, List<String>> channelToAps = bandEntry.getValue();
for (
Map.Entry<Integer, List<String>> channelEntry : channelToAps
.entrySet()
) {
final int channel = channelEntry.getKey();
List<String> serialNumbers = channelEntry.getValue();
buildTxPowerMapForChannel(
band,
channel,
serialNumbers,
txPowerMap
);
}
}
return txPowerMap;
}

View File

@@ -25,6 +25,8 @@ import com.facebook.openwifi.cloudsdk.WifiScanEntry;
import com.facebook.openwifi.cloudsdk.models.ap.State;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.google.gson.JsonObject;
/**
* Measurement-based AP-AP TPC algorithm.
@@ -217,7 +219,14 @@ public class MeasurementBasedApApTPC extends TPC {
// At a given AP, if we receive a signal from ap_2, then it gets added to the rssi list for ap_2
latestScan.stream()
.filter(entry -> (managedBSSIDs.contains(entry.bssid) && UCentralUtils.isChannelInBand(entry.channel, band)))
.filter((entry) -> {
if (!managedBSSIDs.contains(entry.bssid)) {
return false;
}
String entryBand = UCentralUtils
.freqToBand(entry.frequency);
return entryBand != null && entryBand.equals(band);
})
.forEach(
entry -> {
bssidToRssiValues.get(entry.bssid).add(entry.signal);
@@ -296,17 +305,18 @@ public class MeasurementBasedApApTPC extends TPC {
/**
* Calculate new tx powers for the given channel on the given APs .
*
* @param band band (e.g., "2G")
* @param channel channel
* @param serialNumbers the serial numbers of the APs with the channel
* @param txPowerMap this maps from serial number to band to new tx power (dBm)
* and is updated by this method with the new tx powers.
*/
protected void buildTxPowerMapForChannel(
String band,
int channel,
List<String> serialNumbers,
Map<String, Map<String, Integer>> txPowerMap
) {
String band = UCentralUtils.getBandFromChannel(channel);
Set<String> managedBSSIDs = getManagedBSSIDs(model);
Map<String, List<Integer>> bssidToRssiValues =
buildRssiMap(managedBSSIDs, model.latestWifiScans, band);
@@ -363,9 +373,16 @@ public class MeasurementBasedApApTPC extends TPC {
State.Radio radio = state.radios[idx];
// this specific SSID is not on the band of interest
if (
!UCentralUtils.isChannelInBand(radio.channel, band)
) {
JsonObject deviceCapability = model.latestDeviceCapabilities
.get(serialNumber);
if (deviceCapability == null) {
continue;
}
final String radioBand = ModelerUtils.getBand(
radio,
deviceCapability
);
if (radioBand == null || !radioBand.equals(band)) {
continue;
}
@@ -409,9 +426,27 @@ public class MeasurementBasedApApTPC extends TPC {
@Override
public Map<String, Map<String, Integer>> computeTxPowerMap() {
Map<String, Map<String, Integer>> txPowerMap = new TreeMap<>();
Map<Integer, List<String>> apsPerChannel = getApsPerChannel();
for (Map.Entry<Integer, List<String>> e : apsPerChannel.entrySet()) {
buildTxPowerMapForChannel(e.getKey(), e.getValue(), txPowerMap);
Map<String, Map<Integer, List<String>>> bandToChannelToAps =
getApsPerChannel();
for (
Map.Entry<String, Map<Integer, List<String>>> bandEntry : bandToChannelToAps
.entrySet()
) {
final String band = bandEntry.getKey();
Map<Integer, List<String>> channelToAps = bandEntry.getValue();
for (
Map.Entry<Integer, List<String>> channelEntry : channelToAps
.entrySet()
) {
final int channel = channelEntry.getKey();
List<String> serialNumbers = channelEntry.getValue();
buildTxPowerMapForChannel(
band,
channel,
serialNumbers,
txPowerMap
);
}
}
return txPowerMap;
}

View File

@@ -15,13 +15,15 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.facebook.openwifi.cloudsdk.UCentralUtils;
import com.facebook.openwifi.cloudsdk.models.ap.State;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.google.gson.JsonObject;
/**
* Measurement-based AP-client algorithm.
@@ -305,8 +307,15 @@ public class MeasurementBasedApClientTPC extends TPC {
Map<String, Integer> radioMap = new TreeMap<>();
for (State.Radio radio : state.radios) {
int currentChannel = radio.channel;
String band = UCentralUtils.getBandFromChannel(currentChannel);
JsonObject deviceCapability = model.latestDeviceCapabilities
.get(serialNumber);
if (deviceCapability == null) {
continue;
}
final String band = ModelerUtils.getBand(
radio,
deviceCapability
);
if (band == null) {
continue;
}

View File

@@ -18,7 +18,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.facebook.openwifi.cloudsdk.UCentralConstants;
import com.facebook.openwifi.cloudsdk.UCentralUtils;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
@@ -137,36 +136,44 @@ public class RandomTxPowerInitializer extends TPC {
logger.info("Default power: {}", defaultTxPower);
}
Map<Integer, List<String>> apsPerChannel = getApsPerChannel();
Map<String, Map<Integer, List<String>>> bandToChannelToAps =
getApsPerChannel();
Map<String, Map<String, Integer>> txPowerMap = new TreeMap<>();
for (Map.Entry<Integer, List<String>> e : apsPerChannel.entrySet()) {
int channel = e.getKey();
List<String> serialNumbers = e.getValue();
String band = UCentralUtils.getBandFromChannel(channel);
for (String serialNumber : serialNumbers) {
int txPower = defaultTxPower;
if (setDifferentTxPowerPerAp) {
List<Integer> curTxPowerChoices = updateTxPowerChoices(
band,
for (
Map.Entry<String, Map<Integer, List<String>>> bandEntry : bandToChannelToAps
.entrySet()
) {
final String band = bandEntry.getKey();
Map<Integer, List<String>> channelToAps = bandEntry.getValue();
for (
Map.Entry<Integer, List<String>> channelEntry : channelToAps
.entrySet()
) {
List<String> serialNumbers = channelEntry.getValue();
for (String serialNumber : serialNumbers) {
int txPower = defaultTxPower;
if (setDifferentTxPowerPerAp) {
List<Integer> curTxPowerChoices = updateTxPowerChoices(
band,
serialNumber,
DEFAULT_TX_POWER_CHOICES
);
txPower = curTxPowerChoices
.get(rng.nextInt(curTxPowerChoices.size()));
}
txPowerMap
.computeIfAbsent(serialNumber, k -> new TreeMap<>())
.put(band, txPower);
logger.info(
"Device {} band {}: Assigning tx power = {}",
serialNumber,
DEFAULT_TX_POWER_CHOICES
band,
txPower
);
txPower = curTxPowerChoices
.get(rng.nextInt(curTxPowerChoices.size()));
}
txPowerMap.computeIfAbsent(serialNumber, k -> new TreeMap<>())
.put(band, txPower);
logger.info(
"Device {} band {}: Assigning tx power = {}",
serialNumber,
band,
txPower
);
}
}
return txPowerMap;
}
}

View File

@@ -25,6 +25,8 @@ import com.facebook.openwifi.rrm.DeviceConfig;
import com.facebook.openwifi.rrm.DeviceDataManager;
import com.facebook.openwifi.rrm.modules.ConfigManager;
import com.facebook.openwifi.rrm.modules.Modeler.DataModel;
import com.facebook.openwifi.rrm.modules.ModelerUtils;
import com.google.gson.JsonObject;
/**
* TPC (Transmit Power Control) base class.
@@ -180,10 +182,10 @@ public abstract class TPC {
/**
* Get AP serial numbers per channel.
*
* @return the map from channel to the list of AP serial numbers
* @return map from band to channel to list of AP serial numbers
*/
protected Map<Integer, List<String>> getApsPerChannel() {
Map<Integer, List<String>> apsPerChannel = new TreeMap<>();
protected Map<String, Map<Integer, List<String>>> getApsPerChannel() {
Map<String, Map<Integer, List<String>>> apsPerChannel = new TreeMap<>();
for (Map.Entry<String, List<State>> e : model.latestStates.entrySet()) {
String serialNumber = e.getKey();
List<State> states = e.getValue();
@@ -202,7 +204,20 @@ public abstract class TPC {
if (currentChannel == 0) {
continue;
}
JsonObject deviceCapability =
model.latestDeviceCapabilities.get(serialNumber);
if (deviceCapability == null) {
continue;
}
final String band = ModelerUtils.getBand(
radio,
deviceCapability
);
if (band == null) {
continue;
}
apsPerChannel
.computeIfAbsent(band, k -> new TreeMap<>())
.computeIfAbsent(currentChannel, k -> new ArrayList<>())
.add(serialNumber);
}

View File

@@ -56,6 +56,45 @@ public class TestUtils {
return topology;
}
/**
* Given the channel, gets the lowest band that contains that channel (there
* may be multiple bands that contain the same channel number due to channel
* numbering schemes).
*
* @param channel channel number
* @return band lowest band containing the channel; null if no such band
*/
private static String channelToLowestMatchingBand(int channel) {
for (String band : UCentralConstants.BANDS) {
if (UCentralUtils.isChannelInBand(channel, band)) {
return band;
}
}
return null;
}
/**
* Converts channel number to that channel's center frequency in MHz. If,
* due to channel numbering schemes, the channel number appears in multiple
* bands, use the lowest such band.
*
* @param channel channel number
* @return the center frequency of the given channel in MHz
*/
private static int channelToFrequencyMHzInLowestMatchingBand(int channel) {
if (UCentralUtils.isChannelInBand(channel, UCentralConstants.BAND_2G)) {
if (channel <= 13) {
return 2407 + 5 * channel;
} else {
// special case
return 2484;
}
} else {
// 5G
return 5000 + channel;
}
}
/**
* Create a radio info object which forms one element of the list of radio
* info objects representing a device's status.
@@ -158,7 +197,7 @@ public class TestUtils {
JsonArray jsonList = new JsonArray();
jsonList.add(
createDeviceStatusRadioObject(
UCentralUtils.getBandFromChannel(channel),
channelToLowestMatchingBand(channel),
channel,
DEFAULT_CHANNEL_WIDTH,
txPower2G
@@ -201,7 +240,7 @@ public class TestUtils {
public static WifiScanEntry createWifiScanEntry(int channel) {
WifiScanEntry entry = new WifiScanEntry();
entry.channel = channel;
entry.frequency = UCentralUtils.channelToFrequencyMHz(channel);
entry.frequency = channelToFrequencyMHzInLowestMatchingBand(channel);
entry.signal = -60;
entry.unixTimeMs = TestUtils.DEFAULT_WIFISCANENTRY_TIME.toEpochMilli();
return entry;
@@ -262,7 +301,7 @@ public class TestUtils {
WifiScanEntry entry = new WifiScanEntry();
entry.bssid = bssid;
entry.channel = channel;
entry.frequency = UCentralUtils.channelToFrequencyMHz(channel);
entry.frequency = channelToFrequencyMHzInLowestMatchingBand(channel);
entry.signal = -60;
entry.ht_oper = htOper;
entry.vht_oper = vhtOper;
@@ -326,6 +365,21 @@ public class TestUtils {
return wifiScanList;
}
/**
* Generate the String for the "phy" field of a State's radio at a given
* index. This field also appears in the device capability object.
*
* @param index index of the radio in the state
* @return the String value for the "phy" field of the radio
*/
private static String generatePhyString(int index) {
String phyId = "platform/soc/c000000.wifi";
if (index > 0) {
phyId += String.format("+%d", index);
}
return phyId;
}
/**
* Create an uplink0 interface with one radio, to place in
* {@link State#interfaces}.
@@ -335,6 +389,7 @@ public class TestUtils {
* {@link State#interfaces}
*/
private static State.Interface createUpStateInterface(int index) {
final String phyId = generatePhyString(index);
// @formatter:off
return gson.fromJson(
String.format(
@@ -369,7 +424,7 @@ public class TestUtils {
" },\n" +
" \"iface\": \"wlan%d\",\n" +
" \"mode\": \"ap\",\n" +
" \"phy\": \"platform/soc/c000000.wifi\",\n" +
" \"phy\": \"%s\",\n" +
" \"radio\": {\n" +
" \"$ref\": \"#/radios/%d\"\n" +
" },\n" +
@@ -380,6 +435,7 @@ public class TestUtils {
index,
index,
index,
phyId,
index,
index
),
@@ -423,13 +479,13 @@ public class TestUtils {
// @formatter:on
}
/** Create an element of {@link State#radios}. */
private static State.Radio createStateRadio() {
/** Create an element of {@link State#radios} at a given index. */
private static State.Radio createStateRadio(int index) {
State.Radio radio = new State.Radio();
radio.active_ms = 564328;
radio.busy_ms = 36998;
radio.noise = 4294967193L;
radio.phy = "platform/soc/c000000.wifi";
radio.phy = generatePhyString(index);
radio.receive_ms = 28;
radio.transmit_ms = 4893;
return radio;
@@ -506,7 +562,7 @@ public class TestUtils {
state.interfaces[numRadios] = createDownStateInterface(numRadios);
state.radios = new State.Radio[numRadios];
for (int i = 0; i < numRadios; i++) {
state.radios[i] = createStateRadio();
state.radios[i] = createStateRadio(i);
state.radios[i].channel = channels[i];
state.radios[i].channel_width = Integer.toString(channelWidths[i]);
state.radios[i].tx_power = txPowers[i];
@@ -705,6 +761,44 @@ public class TestUtils {
);
}
/**
* Create a radio capability object which is part of the device capability.
*/
public static JsonObject createRadioCapability(String band) {
JsonObject radioCapability = new JsonObject();
JsonArray bandArray = new JsonArray();
bandArray.add(band);
radioCapability.add("band", bandArray);
// the following fields are present but unused so they are excluded here
// channels
// dfs_channels
// frequencies
// he_mac_capa
// he_phy_capa
// ht_capa
// htmode
// rx_ant
// tx_ant
// vht_capa
return radioCapability;
}
/** Create a device capability object with radios in the given bands. */
public static JsonObject createDeviceCapability(String[] bands) {
JsonObject deviceCapability = new JsonObject();
for (int i = 0; i < bands.length; i++) {
String phyId = generatePhyString(i);
JsonObject radioCapability = createRadioCapability(bands[i]);
deviceCapability.add(phyId, radioCapability);
}
return deviceCapability;
}
/** Create a device capability object with a radio in the given band. */
public static JsonObject createDeviceCapability(String band) {
return createDeviceCapability(new String[] { band });
}
/**
* Create an AggregatedState from given radio info.
*

View File

@@ -63,6 +63,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -85,6 +89,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(40, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -108,6 +116,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC))
@@ -155,6 +167,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -177,6 +193,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(6, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -195,6 +215,10 @@ public class LeastUsedChannelOptimizerTest {
deviceC,
Arrays.asList(TestUtils.createState(6, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(
@@ -251,6 +275,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -272,6 +300,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(40, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -294,6 +326,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC))
@@ -349,6 +385,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -372,6 +412,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(40, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -395,6 +439,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC))
@@ -444,6 +492,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -468,6 +520,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(40, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -491,6 +547,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC))
@@ -511,6 +571,10 @@ public class LeastUsedChannelOptimizerTest {
deviceD,
Arrays.asList(TestUtils.createState(40, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceD,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceD,
Arrays.asList(TestUtils.createWifiScanList(channelsD))
@@ -567,6 +631,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -589,6 +657,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(36, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -612,6 +684,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC))
@@ -634,6 +710,10 @@ public class LeastUsedChannelOptimizerTest {
deviceD,
Arrays.asList(TestUtils.createState(36, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceD,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceD,
Arrays.asList(TestUtils.createWifiScanList(channelsD))
@@ -662,6 +742,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceE,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceE,
Arrays.asList(
@@ -711,6 +795,10 @@ public class LeastUsedChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -732,6 +820,10 @@ public class LeastUsedChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(48, channelWidth, dummyBssid))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(
@@ -766,6 +858,10 @@ public class LeastUsedChannelOptimizerTest {
TestUtils.createState(149, channelWidth, dummyBssid)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC1))

View File

@@ -67,6 +67,14 @@ public class RandomChannelInitializerTest {
deviceB,
TestUtils.createDeviceStatus(band, 8)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
ChannelOptimizer optimizer = new RandomChannelInitializer(
dataModel,
@@ -116,6 +124,22 @@ public class RandomChannelInitializerTest {
deviceB,
TestUtils.createDeviceStatus(band, 8)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_2G }
)
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_2G }
)
);
ChannelOptimizer optimizer = new RandomChannelInitializer(
dataModel,

View File

@@ -65,6 +65,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, bssidA)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -89,6 +93,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(40, channelWidth, bssidB))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -123,6 +131,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
deviceC,
Arrays.asList(TestUtils.createState(149, channelWidth, bssidC))
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(TestUtils.createWifiScanList(channelsC, bssidsC))
@@ -173,6 +185,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
.createState(aExpectedChannel, channelWidth, bssidA)
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceA,
Arrays.asList(
@@ -195,6 +211,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
deviceB,
Arrays.asList(TestUtils.createState(6, channelWidth, bssidB))
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceB,
Arrays.asList(TestUtils.createWifiScanList(channelsB))
@@ -213,6 +233,10 @@ public class UnmanagedApAwareChannelOptimizerTest {
deviceC,
Arrays.asList(TestUtils.createState(6, channelWidth, bssidC))
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(band)
);
dataModel.latestWifiScans.put(
deviceC,
Arrays.asList(

View File

@@ -145,6 +145,14 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
}
Map<String, Map<String, Integer>> expected = new HashMap<>();
@@ -214,6 +222,14 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel2.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
}
dataModel2.latestDeviceStatusRadios
.put(
@@ -233,6 +249,10 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel2.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
Map<String, Map<String, Integer>> expected2 = new HashMap<>();
for (String band : UCentralConstants.BANDS) {
@@ -327,6 +347,14 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel2.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
}
Map<String, Map<String, Integer>> expected2 = new HashMap<>();
@@ -388,6 +416,14 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel3.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
}
Map<String, Map<String, Integer>> expected3 = new HashMap<>();
@@ -439,6 +475,14 @@ public class LocationBasedOptimalTPCTest {
)
)
);
dataModel4.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_2G }
)
);
}
Map<String, Map<String, Integer>> expected4 = new HashMap<>();

View File

@@ -108,6 +108,10 @@ public class MeasurementBasedApApTPCTest {
TestUtils
.createDeviceStatusSingleBand(channel, MAX_TX_POWER)
);
model.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(band)
);
}
return model;
@@ -157,6 +161,14 @@ public class MeasurementBasedApApTPCTest {
MAX_TX_POWER
)
);
model.latestDeviceCapabilities.put(
device,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
}
return model;
@@ -592,6 +604,10 @@ public class MeasurementBasedApApTPCTest {
MAX_TX_POWER
)
);
dataModel.latestDeviceCapabilities.put(
DEVICE_C,
TestUtils.createDeviceCapability(UCentralConstants.BAND_2G)
);
optimizer = new MeasurementBasedApApTPC(
dataModel,
TEST_ZONE,

View File

@@ -61,12 +61,20 @@ public class MeasurementBasedApClientTPCTest {
TestUtils.createState(36, 20, 20, null, new int[] {})
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceB,
Arrays.asList(
TestUtils.createState(36, 20, 20, "", new int[] { -65 })
)
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceC,
Arrays.asList(
@@ -79,18 +87,30 @@ public class MeasurementBasedApClientTPCTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceD,
Arrays.asList(
TestUtils.createState(36, 20, 22, null, new int[] { -80 })
)
);
dataModel.latestDeviceCapabilities.put(
deviceD,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceE,
Arrays.asList(
TestUtils.createState(36, 20, 23, null, new int[] { -45 })
)
);
dataModel.latestDeviceCapabilities.put(
deviceE,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
TPC optimizer = new MeasurementBasedApClientTPC(
dataModel,
@@ -158,6 +178,10 @@ public class MeasurementBasedApClientTPCTest {
TestUtils.createState(1, 20, 20, null, new int[] {})
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(UCentralConstants.BAND_2G)
);
// 5G only
dataModel.latestStates.put(
deviceB,
@@ -165,6 +189,10 @@ public class MeasurementBasedApClientTPCTest {
TestUtils.createState(36, 20, 20, null, new int[] {})
)
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
// 2G and 5G
dataModel.latestStates.put(
deviceC,
@@ -181,6 +209,14 @@ public class MeasurementBasedApClientTPCTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_2G,
UCentralConstants.BAND_5G }
)
);
// No valid bands in 2G or 5G
dataModel.latestStates.put(
deviceD,
@@ -248,12 +284,20 @@ public class MeasurementBasedApClientTPCTest {
TestUtils.createState(36, 20, 20, null, new int[] {})
)
);
dataModel.latestDeviceCapabilities.put(
deviceA,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceB,
Arrays.asList(
TestUtils.createState(36, 20, 20, "", new int[] { -65 })
)
);
dataModel.latestDeviceCapabilities.put(
deviceB,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
dataModel.latestStates.put(
deviceC,
Arrays.asList(
@@ -266,6 +310,10 @@ public class MeasurementBasedApClientTPCTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
deviceC,
TestUtils.createDeviceCapability(UCentralConstants.BAND_5G)
);
TPC optimizer = new MeasurementBasedApClientTPC(
dataModel,

View File

@@ -78,6 +78,14 @@ public class RandomTxPowerInitializerTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
DEVICE_A,
TestUtils.createDeviceCapability(
new String[] {
UCentralConstants.BAND_5G,
UCentralConstants.BAND_2G }
)
);
dataModel.latestStates.put(
DEVICE_B,
Arrays.asList(
@@ -89,6 +97,10 @@ public class RandomTxPowerInitializerTest {
)
)
);
dataModel.latestDeviceCapabilities.put(
DEVICE_B,
TestUtils.createDeviceCapability(UCentralConstants.BAND_2G)
);
return dataModel;
}