mirror of
https://github.com/Telecominfraproject/wlan-cloud-rrm.git
synced 2025-10-30 18:17:58 +00:00
Compare commits
6 Commits
scale-test
...
v2.7.0-RC3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a25b28e7a7 | ||
|
|
c3b51aeafd | ||
|
|
bb4d3368a0 | ||
|
|
7d70bfd650 | ||
|
|
4373036d51 | ||
|
|
84b896f939 |
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owrrm:
|
owrrm:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owrrm
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owrrm
|
||||||
tag: main
|
tag: v2.7.0-RC3
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class Modeler implements Runnable {
|
|||||||
public Map<String, State> latestState = new ConcurrentHashMap<>();
|
public Map<String, State> latestState = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/** List of radio info per device. */
|
/** List of radio info per device. */
|
||||||
public Map<String, JsonArray> latestDeviceStatus =
|
public Map<String, JsonArray> latestDeviceStatusRadios =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/** List of capabilities per device. */
|
/** List of capabilities per device. */
|
||||||
@@ -379,7 +379,7 @@ public class Modeler implements Runnable {
|
|||||||
// Get old vs new radios info and store the new radios info
|
// Get old vs new radios info and store the new radios info
|
||||||
JsonArray newRadioList = config.getRadioConfigList();
|
JsonArray newRadioList = config.getRadioConfigList();
|
||||||
Set<String> newRadioBandsSet = config.getRadioBandsSet(newRadioList);
|
Set<String> newRadioBandsSet = config.getRadioBandsSet(newRadioList);
|
||||||
JsonArray oldRadioList = dataModel.latestDeviceStatus
|
JsonArray oldRadioList = dataModel.latestDeviceStatusRadios
|
||||||
.put(serialNumber, newRadioList);
|
.put(serialNumber, newRadioList);
|
||||||
Set<String> oldRadioBandsSet = config.getRadioBandsSet(oldRadioList);
|
Set<String> oldRadioBandsSet = config.getRadioBandsSet(oldRadioList);
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ public class Modeler implements Runnable {
|
|||||||
logger.debug("Removed some state entries from data model");
|
logger.debug("Removed some state entries from data model");
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
dataModel.latestDeviceStatus.entrySet()
|
dataModel.latestDeviceStatusRadios.entrySet()
|
||||||
.removeIf(e -> !isRRMEnabled(e.getKey()))
|
.removeIf(e -> !isRRMEnabled(e.getKey()))
|
||||||
) {
|
) {
|
||||||
logger.debug("Removed some status entries from data model");
|
logger.debug("Removed some status entries from data model");
|
||||||
|
|||||||
@@ -454,9 +454,10 @@ public class DatabaseManager {
|
|||||||
.map(o -> gson.fromJson(o, State.Interface.class))
|
.map(o -> gson.fromJson(o, State.Interface.class))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
.toArray(new State.Interface[0]);
|
.toArray(new State.Interface[0]);
|
||||||
state.radios = new JsonObject[radios.lastKey() + 1];
|
state.radios = new State.Radio[radios.lastKey() + 1];
|
||||||
for (Map.Entry<Integer, JsonObject> entry : radios.entrySet()) {
|
for (Map.Entry<Integer, JsonObject> entry : radios.entrySet()) {
|
||||||
state.radios[entry.getKey()] = entry.getValue();
|
State.Radio radio = new State.Radio();
|
||||||
|
state.radios[entry.getKey()] = radio;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public abstract class ChannelOptimizer {
|
|||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
||||||
this.model.latestState.keySet()
|
this.model.latestState.keySet()
|
||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
||||||
this.model.latestDeviceStatus.keySet()
|
this.model.latestDeviceStatusRadios.keySet()
|
||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
||||||
this.model.latestDeviceCapabilities.keySet()
|
this.model.latestDeviceCapabilities.keySet()
|
||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber));
|
||||||
@@ -234,8 +234,9 @@ public abstract class ChannelOptimizer {
|
|||||||
// the difference of 8 means it is consecutive
|
// the difference of 8 means it is consecutive
|
||||||
int channelDiff =
|
int channelDiff =
|
||||||
Math.abs(vhtOperObj.channel1 - vhtOperObj.channel2);
|
Math.abs(vhtOperObj.channel1 - vhtOperObj.channel2);
|
||||||
// the "8080" below does not mean 8080 MHz wide, it refers to 80+80 MHz channel
|
// TODO it will currently return just 80 for 80p80 - it should be dealt
|
||||||
return channelDiff == 8 ? 160 : 8080;
|
// with properly.
|
||||||
|
return channelDiff == 8 ? 160 : 80;
|
||||||
} else {
|
} else {
|
||||||
return MIN_CHANNEL_WIDTH;
|
return MIN_CHANNEL_WIDTH;
|
||||||
}
|
}
|
||||||
@@ -378,15 +379,26 @@ public abstract class ChannelOptimizer {
|
|||||||
radioIndex < state.radios.length;
|
radioIndex < state.radios.length;
|
||||||
radioIndex++
|
radioIndex++
|
||||||
) {
|
) {
|
||||||
int tempChannel = state.radios[radioIndex]
|
int tempChannel = state.radios[radioIndex].channel;
|
||||||
.get("channel")
|
|
||||||
.getAsInt();
|
|
||||||
if (UCentralUtils.isChannelInBand(tempChannel, band)) {
|
if (UCentralUtils.isChannelInBand(tempChannel, band)) {
|
||||||
currentChannel = tempChannel;
|
currentChannel = tempChannel;
|
||||||
currentChannelWidth = state.radios[radioIndex]
|
// treat as two separate 80MHz channel and only assign to one
|
||||||
.get("channel_width")
|
// TODO: support 80p80 properly
|
||||||
.getAsInt();
|
Integer parsedChannelWidth = UCentralUtils
|
||||||
break;
|
.parseChannelWidth(
|
||||||
|
state.radios[radioIndex].channel_width,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if (parsedChannelWidth != null) {
|
||||||
|
currentChannelWidth = parsedChannelWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(
|
||||||
|
"Invalid channel width {}",
|
||||||
|
state.radios[radioIndex].channel_width
|
||||||
|
);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new int[] { currentChannel, currentChannelWidth };
|
return new int[] { currentChannel, currentChannelWidth };
|
||||||
|
|||||||
@@ -331,11 +331,11 @@ public class LeastUsedChannelOptimizer extends ChannelOptimizer {
|
|||||||
public Map<String, Map<String, Integer>> computeChannelMap() {
|
public Map<String, Map<String, Integer>> computeChannelMap() {
|
||||||
Map<String, Map<String, Integer>> channelMap = new TreeMap<>();
|
Map<String, Map<String, Integer>> channelMap = new TreeMap<>();
|
||||||
Map<String, List<String>> bandsMap = UCentralUtils
|
Map<String, List<String>> bandsMap = UCentralUtils
|
||||||
.getBandsMap(model.latestDeviceStatus);
|
.getBandsMap(model.latestDeviceStatusRadios);
|
||||||
|
|
||||||
Map<String, Map<String, List<Integer>>> deviceAvailableChannels =
|
Map<String, Map<String, List<Integer>>> deviceAvailableChannels =
|
||||||
UCentralUtils.getDeviceAvailableChannels(
|
UCentralUtils.getDeviceAvailableChannels(
|
||||||
model.latestDeviceStatus,
|
model.latestDeviceStatusRadios,
|
||||||
model.latestDeviceCapabilities,
|
model.latestDeviceCapabilities,
|
||||||
AVAILABLE_CHANNELS_BAND
|
AVAILABLE_CHANNELS_BAND
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -119,11 +119,11 @@ public class RandomChannelInitializer extends ChannelOptimizer {
|
|||||||
public Map<String, Map<String, Integer>> computeChannelMap() {
|
public Map<String, Map<String, Integer>> computeChannelMap() {
|
||||||
Map<String, Map<String, Integer>> channelMap = new TreeMap<>();
|
Map<String, Map<String, Integer>> channelMap = new TreeMap<>();
|
||||||
Map<String, List<String>> bandsMap =
|
Map<String, List<String>> bandsMap =
|
||||||
UCentralUtils.getBandsMap(model.latestDeviceStatus);
|
UCentralUtils.getBandsMap(model.latestDeviceStatusRadios);
|
||||||
|
|
||||||
Map<String, Map<String, List<Integer>>> deviceAvailableChannels =
|
Map<String, Map<String, List<Integer>>> deviceAvailableChannels =
|
||||||
UCentralUtils.getDeviceAvailableChannels(
|
UCentralUtils.getDeviceAvailableChannels(
|
||||||
model.latestDeviceStatus,
|
model.latestDeviceStatusRadios,
|
||||||
model.latestDeviceCapabilities,
|
model.latestDeviceCapabilities,
|
||||||
AVAILABLE_CHANNELS_BAND
|
AVAILABLE_CHANNELS_BAND
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@@ -26,9 +25,6 @@ import com.facebook.openwifirrm.modules.Modeler.DataModel;
|
|||||||
import com.facebook.openwifirrm.ucentral.UCentralUtils;
|
import com.facebook.openwifirrm.ucentral.UCentralUtils;
|
||||||
import com.facebook.openwifirrm.ucentral.WifiScanEntry;
|
import com.facebook.openwifirrm.ucentral.WifiScanEntry;
|
||||||
import com.facebook.openwifirrm.ucentral.models.State;
|
import com.facebook.openwifirrm.ucentral.models.State;
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Measurement-based AP-AP TPC algorithm.
|
* Measurement-based AP-AP TPC algorithm.
|
||||||
@@ -178,32 +174,6 @@ public class MeasurementBasedApApTPC extends TPC {
|
|||||||
return managedBSSIDs;
|
return managedBSSIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current band radio tx power (the first one found) for an AP using
|
|
||||||
* the latest device status.
|
|
||||||
*
|
|
||||||
* @param latestDeviceStatus JsonArray containing radio config for the AP
|
|
||||||
* @param band band (e.g., "2G")
|
|
||||||
* @return an Optional containing the tx power if one exists, or else an
|
|
||||||
* empty Optional
|
|
||||||
*/
|
|
||||||
protected static Optional<Integer> getCurrentTxPower(
|
|
||||||
JsonArray latestDeviceStatus,
|
|
||||||
String band
|
|
||||||
) {
|
|
||||||
for (JsonElement e : latestDeviceStatus) {
|
|
||||||
if (!e.isJsonObject()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
JsonObject radioObject = e.getAsJsonObject();
|
|
||||||
String radioBand = radioObject.get("band").getAsString();
|
|
||||||
if (radioBand.equals(band) && radioObject.has("tx-power")) {
|
|
||||||
return Optional.of(radioObject.get("tx-power").getAsInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a map from BSSID to the received signal strength at neighboring APs (RSSI).
|
* Get a map from BSSID to the received signal strength at neighboring APs (RSSI).
|
||||||
* List of RSSIs are returned in sorted, ascending order.
|
* List of RSSIs are returned in sorted, ascending order.
|
||||||
@@ -340,7 +310,6 @@ public class MeasurementBasedApApTPC extends TPC {
|
|||||||
Map<String, List<Integer>> bssidToRssiValues =
|
Map<String, List<Integer>> bssidToRssiValues =
|
||||||
buildRssiMap(managedBSSIDs, model.latestWifiScans, band);
|
buildRssiMap(managedBSSIDs, model.latestWifiScans, band);
|
||||||
logger.debug("Starting TPC for the {} band", band);
|
logger.debug("Starting TPC for the {} band", band);
|
||||||
Map<String, JsonArray> allStatuses = model.latestDeviceStatus;
|
|
||||||
for (String serialNumber : serialNumbers) {
|
for (String serialNumber : serialNumbers) {
|
||||||
State state = model.latestState.get(serialNumber);
|
State state = model.latestState.get(serialNumber);
|
||||||
if (
|
if (
|
||||||
@@ -370,40 +339,68 @@ public class MeasurementBasedApApTPC extends TPC {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
JsonArray radioStatuses =
|
|
||||||
allStatuses.get(serialNumber).getAsJsonArray();
|
// An AP can have multiple interfaces, optimize for all of them
|
||||||
Optional<Integer> possibleCurrentTxPower = getCurrentTxPower(
|
for (State.Interface iface : state.interfaces) {
|
||||||
radioStatuses,
|
if (iface.ssids == null) {
|
||||||
band
|
continue;
|
||||||
);
|
}
|
||||||
if (possibleCurrentTxPower.isEmpty()) {
|
|
||||||
// this AP is not on the band of interest
|
for (State.Interface.SSID ssid : iface.ssids) {
|
||||||
continue;
|
Integer idx = UCentralUtils.parseReferenceIndex(
|
||||||
|
ssid.radio.get("$ref").getAsString()
|
||||||
|
);
|
||||||
|
if (idx == null) {
|
||||||
|
logger.error(
|
||||||
|
"Unable to get radio for {}, invalid radio ref {}",
|
||||||
|
serialNumber,
|
||||||
|
ssid.radio.get("$ref").getAsString()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
State.Radio radio = state.radios[idx];
|
||||||
|
|
||||||
|
// this specific SSID is not on the band of interest
|
||||||
|
if (
|
||||||
|
!UCentralUtils.isChannelInBand(radio.channel, band)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentTxPower = radio.tx_power;
|
||||||
|
String bssid = ssid.bssid;
|
||||||
|
List<Integer> rssiValues = bssidToRssiValues.get(bssid);
|
||||||
|
logger
|
||||||
|
.debug(
|
||||||
|
"Device <{}> : Interface <{}> : Channel <{}> : BSSID <{}>",
|
||||||
|
serialNumber,
|
||||||
|
iface.name,
|
||||||
|
channel,
|
||||||
|
bssid
|
||||||
|
);
|
||||||
|
for (int rssi : rssiValues) {
|
||||||
|
logger.debug(" Neighbor received RSSI: {}", rssi);
|
||||||
|
}
|
||||||
|
List<Integer> txPowerChoices = updateTxPowerChoices(
|
||||||
|
band,
|
||||||
|
serialNumber,
|
||||||
|
DEFAULT_TX_POWER_CHOICES
|
||||||
|
);
|
||||||
|
int newTxPower = computeTxPower(
|
||||||
|
serialNumber,
|
||||||
|
currentTxPower,
|
||||||
|
rssiValues,
|
||||||
|
coverageThreshold,
|
||||||
|
nthSmallestRssi,
|
||||||
|
txPowerChoices
|
||||||
|
);
|
||||||
|
logger.debug(" Old tx_power: {}", currentTxPower);
|
||||||
|
logger.debug(" New tx_power: {}", newTxPower);
|
||||||
|
txPowerMap
|
||||||
|
.computeIfAbsent(serialNumber, k -> new TreeMap<>())
|
||||||
|
.put(band, newTxPower);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int currentTxPower = possibleCurrentTxPower.get();
|
|
||||||
String bssid = state.interfaces[0].ssids[0].bssid;
|
|
||||||
List<Integer> rssiValues = bssidToRssiValues.get(bssid);
|
|
||||||
logger.debug("Device <{}> : BSSID <{}>", serialNumber, bssid);
|
|
||||||
for (int rssi : rssiValues) {
|
|
||||||
logger.debug(" Neighbor received RSSI: {}", rssi);
|
|
||||||
}
|
|
||||||
List<Integer> txPowerChoices = updateTxPowerChoices(
|
|
||||||
band,
|
|
||||||
serialNumber,
|
|
||||||
DEFAULT_TX_POWER_CHOICES
|
|
||||||
);
|
|
||||||
int newTxPower = computeTxPower(
|
|
||||||
serialNumber,
|
|
||||||
currentTxPower,
|
|
||||||
rssiValues,
|
|
||||||
coverageThreshold,
|
|
||||||
nthSmallestRssi,
|
|
||||||
txPowerChoices
|
|
||||||
);
|
|
||||||
logger.debug(" Old tx_power: {}", currentTxPower);
|
|
||||||
logger.debug(" New tx_power: {}", newTxPower);
|
|
||||||
txPowerMap.computeIfAbsent(serialNumber, k -> new TreeMap<>())
|
|
||||||
.put(band, newTxPower);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import com.facebook.openwifirrm.DeviceDataManager;
|
import com.facebook.openwifirrm.DeviceDataManager;
|
||||||
import com.facebook.openwifirrm.modules.Modeler.DataModel;
|
import com.facebook.openwifirrm.modules.Modeler.DataModel;
|
||||||
import com.facebook.openwifirrm.ucentral.models.State;
|
import com.facebook.openwifirrm.ucentral.models.State;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Measurement-based AP-client algorithm.
|
* Measurement-based AP-client algorithm.
|
||||||
@@ -42,6 +41,9 @@ public class MeasurementBasedApClientTPC extends TPC {
|
|||||||
/** Default tx power. */
|
/** Default tx power. */
|
||||||
public static final int DEFAULT_TX_POWER = 10;
|
public static final int DEFAULT_TX_POWER = 10;
|
||||||
|
|
||||||
|
/** Default channel width in HMz */
|
||||||
|
public static final int DEFAULT_CHANNEL_WIDTH = 20;
|
||||||
|
|
||||||
/** Mapping of MCS index to required SNR (dB) in 802.11ac. */
|
/** Mapping of MCS index to required SNR (dB) in 802.11ac. */
|
||||||
private static final List<Double> MCS_TO_SNR = Collections.unmodifiableList(
|
private static final List<Double> MCS_TO_SNR = Collections.unmodifiableList(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
@@ -154,19 +156,16 @@ public class MeasurementBasedApClientTPC extends TPC {
|
|||||||
private int computeTxPowerForRadio(
|
private int computeTxPowerForRadio(
|
||||||
String serialNumber,
|
String serialNumber,
|
||||||
State state,
|
State state,
|
||||||
JsonObject radio,
|
State.Radio radio,
|
||||||
List<Integer> txPowerChoices
|
List<Integer> txPowerChoices
|
||||||
) {
|
) {
|
||||||
// Find current tx power and bandwidth
|
// Find current tx power and bandwidth
|
||||||
int currentTxPower =
|
int currentTxPower = radio.tx_power;
|
||||||
radio.has("tx_power") && !radio.get("tx_power").isJsonNull()
|
// treat as one 160MHz channel vs two 80MHz channels
|
||||||
? radio.get("tx_power").getAsInt()
|
Integer channelWidthMHz =
|
||||||
: 0;
|
UCentralUtils.parseChannelWidth(radio.channel_width, false);
|
||||||
int channelWidth =
|
int channelWidth = (channelWidthMHz != null
|
||||||
1_000_000 /* convert MHz to Hz */ * (radio.has("channel_width") &&
|
? channelWidthMHz : DEFAULT_CHANNEL_WIDTH) * 1_000_000; // convert MHz to HZ
|
||||||
!radio.get("channel_width").isJsonNull()
|
|
||||||
? radio.get("channel_width").getAsInt()
|
|
||||||
: 20);
|
|
||||||
Collections.sort(txPowerChoices);
|
Collections.sort(txPowerChoices);
|
||||||
int minTxPower = txPowerChoices.get(0);
|
int minTxPower = txPowerChoices.get(0);
|
||||||
int maxTxPower = txPowerChoices.get(txPowerChoices.size() - 1);
|
int maxTxPower = txPowerChoices.get(txPowerChoices.size() - 1);
|
||||||
@@ -303,17 +302,10 @@ public class MeasurementBasedApClientTPC extends TPC {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Integer> radioMap = new TreeMap<>();
|
Map<String, Integer> radioMap = new TreeMap<>();
|
||||||
|
for (State.Radio radio : state.radios) {
|
||||||
for (JsonObject radio : state.radios) {
|
int currentChannel = radio.channel;
|
||||||
Integer currentChannel =
|
|
||||||
radio.has("channel") && !radio.get("channel").isJsonNull()
|
|
||||||
? radio.get("channel").getAsInt()
|
|
||||||
: null;
|
|
||||||
if (currentChannel == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String band = UCentralUtils.getBandFromChannel(currentChannel);
|
String band = UCentralUtils.getBandFromChannel(currentChannel);
|
||||||
if (band == null) {
|
if (band == null) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import com.facebook.openwifirrm.DeviceDataManager;
|
|||||||
import com.facebook.openwifirrm.modules.ConfigManager;
|
import com.facebook.openwifirrm.modules.ConfigManager;
|
||||||
import com.facebook.openwifirrm.modules.Modeler.DataModel;
|
import com.facebook.openwifirrm.modules.Modeler.DataModel;
|
||||||
import com.facebook.openwifirrm.ucentral.models.State;
|
import com.facebook.openwifirrm.ucentral.models.State;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -75,7 +74,7 @@ public abstract class TPC {
|
|||||||
this.model.latestState.keySet()
|
this.model.latestState.keySet()
|
||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber)
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber)
|
||||||
);
|
);
|
||||||
this.model.latestDeviceStatus.keySet()
|
this.model.latestDeviceStatusRadios.keySet()
|
||||||
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber)
|
.removeIf(serialNumber -> !deviceConfigs.containsKey(serialNumber)
|
||||||
);
|
);
|
||||||
this.model.latestDeviceCapabilities.keySet()
|
this.model.latestDeviceCapabilities.keySet()
|
||||||
@@ -203,12 +202,9 @@ public abstract class TPC {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JsonObject radio : state.radios) {
|
for (State.Radio radio : state.radios) {
|
||||||
Integer currentChannel =
|
Integer currentChannel = radio.channel;
|
||||||
radio.has("channel") && !radio.get("channel").isJsonNull()
|
if (currentChannel == 0) {
|
||||||
? radio.get("channel").getAsInt()
|
|
||||||
: null;
|
|
||||||
if (currentChannel == null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
apsPerChannel
|
apsPerChannel
|
||||||
|
|||||||
@@ -130,9 +130,24 @@ public class UCentralUtils {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare vs. existing value
|
// Compare vs. existing value.
|
||||||
int currentValue = radioConfig.get(fieldName).getAsInt();
|
// not all values are int so override those values
|
||||||
if (currentValue == newValue) {
|
Integer currentValue = null;
|
||||||
|
JsonElement fieldValue = radioConfig.get(fieldName);
|
||||||
|
if (
|
||||||
|
fieldValue.isJsonPrimitive() &&
|
||||||
|
fieldValue.getAsJsonPrimitive().isNumber()
|
||||||
|
) {
|
||||||
|
currentValue = fieldValue.getAsInt();
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
"Unable to get field '{}' as int, value was {}",
|
||||||
|
fieldName,
|
||||||
|
fieldValue.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue != null && currentValue == newValue) {
|
||||||
logger.info(
|
logger.info(
|
||||||
"Device {}: {} {} is already {}",
|
"Device {}: {} {} is already {}",
|
||||||
serialNumber,
|
serialNumber,
|
||||||
@@ -150,7 +165,7 @@ public class UCentralUtils {
|
|||||||
operationalBand,
|
operationalBand,
|
||||||
fieldName,
|
fieldName,
|
||||||
newValue,
|
newValue,
|
||||||
currentValue
|
currentValue != null ? currentValue : fieldValue.toString()
|
||||||
);
|
);
|
||||||
wasModified = true;
|
wasModified = true;
|
||||||
}
|
}
|
||||||
@@ -384,4 +399,52 @@ public class UCentralUtils {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to parse channel width, if it encounters an error it will return null.
|
||||||
|
* It can handle 80p80 in two ways. First it can just treat it as 160. Second,
|
||||||
|
* it can just apply to the first 80 channel and ignore the second. This is
|
||||||
|
* controlled by treatSeparate.
|
||||||
|
*
|
||||||
|
* @param channelWidthStr the channel width
|
||||||
|
* @param treatSeparate treats each band separately
|
||||||
|
* @return channel width in MHz
|
||||||
|
*/
|
||||||
|
public static Integer parseChannelWidth(
|
||||||
|
String channelWidthStr,
|
||||||
|
boolean treatSeparate
|
||||||
|
) {
|
||||||
|
// 80p80 is the only case where it can't be parsed into an integer
|
||||||
|
if (channelWidthStr.equals("80p80")) {
|
||||||
|
return treatSeparate ? 80 : 160;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(channelWidthStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to parse the index from the reference string in the JSON returned from
|
||||||
|
* other services. Note that this only returns the index, the caller is
|
||||||
|
* responsible for making sure that the correct field is passed in and the
|
||||||
|
* index is used in the correct fields. If there's an error parsing, it will
|
||||||
|
* return null.
|
||||||
|
*
|
||||||
|
* @param reference The reference string, keyed under "$ref"
|
||||||
|
* @return the index of the reference or null if an error occurred.
|
||||||
|
*/
|
||||||
|
public static Integer parseReferenceIndex(String reference) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(
|
||||||
|
reference,
|
||||||
|
reference.lastIndexOf("/") + 1,
|
||||||
|
reference.length(),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,8 +112,21 @@ public class State {
|
|||||||
|
|
||||||
public Unit unit;
|
public Unit unit;
|
||||||
|
|
||||||
|
public static class Radio {
|
||||||
|
public long active_ms;
|
||||||
|
public long busy_ms;
|
||||||
|
public int channel;
|
||||||
|
public String channel_width;
|
||||||
|
public long noise;
|
||||||
|
public String phy;
|
||||||
|
public long receive_ms;
|
||||||
|
public long transmit_ms;
|
||||||
|
public int tx_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Radio[] radios;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
public JsonObject[] radios;
|
|
||||||
@SerializedName("link-state") public JsonObject linkState;
|
@SerializedName("link-state") public JsonObject linkState;
|
||||||
public JsonObject gps;
|
public JsonObject gps;
|
||||||
public JsonObject poe;
|
public JsonObject poe;
|
||||||
|
|||||||
@@ -30,15 +30,23 @@ public class VHTOperationElement {
|
|||||||
* 160 MHz wide channel, this parameter is the channel number of the 80MHz
|
* 160 MHz wide channel, this parameter is the channel number of the 80MHz
|
||||||
* channel that contains the primary channel. For a 80+80 MHz wide channel, this
|
* channel that contains the primary channel. For a 80+80 MHz wide channel, this
|
||||||
* parameter is the channel number of the primary channel.
|
* parameter is the channel number of the primary channel.
|
||||||
|
* <p>
|
||||||
|
* This field is an unsigned byte in the specification (i.e., with values
|
||||||
|
* between 0 and 255). But because Java only supports signed bytes, a short
|
||||||
|
* data type is used to store the value.
|
||||||
*/
|
*/
|
||||||
public final byte channel1;
|
public final short channel1;
|
||||||
/**
|
/**
|
||||||
* This should be zero unless the channel is 160MHz or 80+80 MHz wide. If the
|
* This should be zero unless the channel is 160MHz or 80+80 MHz wide. If the
|
||||||
* channel is 160 MHz wide, this parameter is the channel number of the 160 MHz
|
* channel is 160 MHz wide, this parameter is the channel number of the 160 MHz
|
||||||
* wide channel. If the channel is 80+80 MHz wide, this parameter is the channel
|
* wide channel. If the channel is 80+80 MHz wide, this parameter is the channel
|
||||||
* index of the secondary 80 MHz wide channel.
|
* index of the secondary 80 MHz wide channel.
|
||||||
|
* <p>
|
||||||
|
* This field is an unsigned byte in the specification (i.e., with values
|
||||||
|
* between 0 and 255). But because Java only supports signed bytes, a short
|
||||||
|
* data type is used to store the value.
|
||||||
*/
|
*/
|
||||||
public final byte channel2;
|
public final short channel2;
|
||||||
/**
|
/**
|
||||||
* An 8-element array where each element is between 0 and 4 inclusive. MCS means
|
* An 8-element array where each element is between 0 and 4 inclusive. MCS means
|
||||||
* Modulation and Coding Scheme. NSS means Number of Spatial Streams. There can
|
* Modulation and Coding Scheme. NSS means Number of Spatial Streams. There can
|
||||||
@@ -60,8 +68,8 @@ public class VHTOperationElement {
|
|||||||
public VHTOperationElement(String vhtOper) {
|
public VHTOperationElement(String vhtOper) {
|
||||||
byte[] bytes = Base64.decodeBase64(vhtOper);
|
byte[] bytes = Base64.decodeBase64(vhtOper);
|
||||||
this.channelWidth = bytes[0];
|
this.channelWidth = bytes[0];
|
||||||
this.channel1 = bytes[1];
|
this.channel1 = (short) (bytes[1] & 0xff); // read as unsigned value
|
||||||
this.channel2 = bytes[2];
|
this.channel2 = (short) (bytes[2] & 0xff); // read as unsigned value
|
||||||
byte[] vhtMcsForNss = new byte[8];
|
byte[] vhtMcsForNss = new byte[8];
|
||||||
vhtMcsForNss[0] = (byte) (bytes[3] >>> 6);
|
vhtMcsForNss[0] = (byte) (bytes[3] >>> 6);
|
||||||
vhtMcsForNss[1] = (byte) ((bytes[3] & 0b00110000) >>> 4);
|
vhtMcsForNss[1] = (byte) ((bytes[3] & 0b00110000) >>> 4);
|
||||||
@@ -83,8 +91,8 @@ public class VHTOperationElement {
|
|||||||
*/
|
*/
|
||||||
public VHTOperationElement(
|
public VHTOperationElement(
|
||||||
byte channelWidth,
|
byte channelWidth,
|
||||||
byte channel1,
|
short channel1,
|
||||||
byte channel2,
|
short channel2,
|
||||||
byte[] vhtMcsForNss
|
byte[] vhtMcsForNss
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -397,23 +397,15 @@ public class TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Create an element of {@link State#radios}. */
|
/** Create an element of {@link State#radios}. */
|
||||||
private static JsonObject createStateRadio() {
|
private static State.Radio createStateRadio() {
|
||||||
// @formatter:off
|
State.Radio radio = new State.Radio();
|
||||||
return gson.fromJson(
|
radio.active_ms = 564328;
|
||||||
String.format(
|
radio.busy_ms = 36998;
|
||||||
" {\n" +
|
radio.noise = 4294967193L;
|
||||||
" \"active_ms\": 564328,\n" +
|
radio.phy = "platform/soc/c000000.wifi";
|
||||||
" \"busy_ms\": 36998,\n" +
|
radio.receive_ms = 28;
|
||||||
" \"noise\": 4294967193,\n" +
|
radio.transmit_ms = 4893;
|
||||||
" \"phy\": \"platform/soc/c000000.wifi\",\n" +
|
return radio;
|
||||||
" \"receive_ms\": 28,\n" +
|
|
||||||
" \"temperature\": 45,\n" +
|
|
||||||
" \"transmit_ms\": 4893\n" +
|
|
||||||
" }\n"
|
|
||||||
),
|
|
||||||
JsonObject.class
|
|
||||||
);
|
|
||||||
// @formatter:on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a {@code State.Unit}. */
|
/** Create a {@code State.Unit}. */
|
||||||
@@ -477,12 +469,12 @@ public class TestUtils {
|
|||||||
state.interfaces[index] = createUpStateInterface(index);
|
state.interfaces[index] = createUpStateInterface(index);
|
||||||
}
|
}
|
||||||
state.interfaces[numRadios] = createDownStateInterface(numRadios);
|
state.interfaces[numRadios] = createDownStateInterface(numRadios);
|
||||||
state.radios = new JsonObject[numRadios];
|
state.radios = new State.Radio[numRadios];
|
||||||
for (int i = 0; i < numRadios; i++) {
|
for (int i = 0; i < numRadios; i++) {
|
||||||
state.radios[i] = createStateRadio();
|
state.radios[i] = createStateRadio();
|
||||||
state.radios[i].addProperty("channel", channels[i]);
|
state.radios[i].channel = channels[i];
|
||||||
state.radios[i].addProperty("channel_width", channelWidths[i]);
|
state.radios[i].channel_width = Integer.toString(channelWidths[i]);
|
||||||
state.radios[i].addProperty("tx_power", txPowers[i]);
|
state.radios[i].tx_power = txPowers[i];
|
||||||
state.interfaces[i].ssids[0].bssid = bssids[i];
|
state.interfaces[i].ssids[0].bssid = bssids[i];
|
||||||
state.interfaces[i].ssids[0].associations =
|
state.interfaces[i].ssids[0].associations =
|
||||||
new State.Interface.SSID.Association[clientRssis[i].length];
|
new State.Interface.SSID.Association[clientRssis[i].length];
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (48)
|
// A -> No APs on current channel, so stay on it (48)
|
||||||
int aExpectedChannel = 48;
|
int aExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -73,7 +73,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int bExpectedChannel = channelsB.removeLast();
|
int bExpectedChannel = channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -94,7 +94,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int cExpectedChannel = channelsC.removeFirst();
|
int cExpectedChannel = channelsC.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -138,7 +138,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (1)
|
// A -> No APs on current channel, so stay on it (1)
|
||||||
int aExpectedChannel = 1;
|
int aExpectedChannel = 1;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -160,7 +160,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int bExpectedChannel = channelsB.removeLast();
|
int bExpectedChannel = channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 6)
|
TestUtils.createDeviceStatus(band, 6)
|
||||||
);
|
);
|
||||||
@@ -178,7 +178,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// C -> Assigned to only free prioritized channel (1)
|
// C -> Assigned to only free prioritized channel (1)
|
||||||
int cExpectedChannel = 1;
|
int cExpectedChannel = 1;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 6)
|
TestUtils.createDeviceStatus(band, 6)
|
||||||
);
|
);
|
||||||
@@ -231,7 +231,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A, B, C should just be assigned to the same userChannel
|
// A, B, C should just be assigned to the same userChannel
|
||||||
int aExpectedChannel = 48;
|
int aExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -252,7 +252,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsB.removeLast();
|
channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -272,7 +272,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.removeFirst();
|
channelsC.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -324,7 +324,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
// A -> No APs on current channel and the current channel is in allowedChannels,
|
// A -> No APs on current channel and the current channel is in allowedChannels,
|
||||||
// so stay on it (48)
|
// so stay on it (48)
|
||||||
int aExpectedChannel = 48;
|
int aExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -347,7 +347,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsB.removeLast();
|
channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -368,7 +368,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.removeFirst();
|
channelsC.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -414,7 +414,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (48)
|
// A -> No APs on current channel, so stay on it (48)
|
||||||
int aExpectedChannel = 157;
|
int aExpectedChannel = 157;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -438,7 +438,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsB.addAll(Arrays.asList(40, 48, 153, 161));
|
channelsB.addAll(Arrays.asList(40, 48, 153, 161));
|
||||||
channelsB.addAll(Arrays.asList(40, 48, 153, 161));
|
channelsB.addAll(Arrays.asList(40, 48, 153, 161));
|
||||||
int bExpectedChannel = channelsB.removeLast() - 4; // upper extension
|
int bExpectedChannel = channelsB.removeLast() - 4; // upper extension
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -459,7 +459,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int cExpectedChannel = channelsC.removeFirst();
|
int cExpectedChannel = channelsC.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -479,7 +479,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsD = new LinkedList<>();
|
LinkedList<Integer> channelsD = new LinkedList<>();
|
||||||
channelsD.addAll(Arrays.asList(36, 44, 149, 157));
|
channelsD.addAll(Arrays.asList(36, 44, 149, 157));
|
||||||
int dExpectedChannel = channelsD.removeLast();
|
int dExpectedChannel = channelsD.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceD,
|
deviceD,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -532,7 +532,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (36)
|
// A -> No APs on current channel, so stay on it (36)
|
||||||
int aExpectedChannel = 36;
|
int aExpectedChannel = 36;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -554,7 +554,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(Arrays.asList(40, 48, 149));
|
channelsB.addAll(Arrays.asList(40, 48, 149));
|
||||||
int bExpectedChannel = channelsB.removeLast();
|
int bExpectedChannel = channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 36)
|
TestUtils.createDeviceStatus(band, 36)
|
||||||
);
|
);
|
||||||
@@ -575,7 +575,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int cExpectedChannel = channelsC.removeFirst();
|
int cExpectedChannel = channelsC.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -597,7 +597,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsD.addAll(Arrays.asList(40, 48, 153, 161));
|
channelsD.addAll(Arrays.asList(40, 48, 153, 161));
|
||||||
channelsD.addAll(Arrays.asList(40, 48, 153, 161));
|
channelsD.addAll(Arrays.asList(40, 48, 153, 161));
|
||||||
int dExpectedChannel = channelsD.removeLast() - 12;
|
int dExpectedChannel = channelsD.removeLast() - 12;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceD,
|
deviceD,
|
||||||
TestUtils.createDeviceStatus(band, 36)
|
TestUtils.createDeviceStatus(band, 36)
|
||||||
);
|
);
|
||||||
@@ -622,7 +622,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
.put(UCentralConstants.BAND_5G, Arrays.asList(48, 165));
|
.put(UCentralConstants.BAND_5G, Arrays.asList(48, 165));
|
||||||
deviceDataManager.setDeviceApConfig(deviceE, apConfig);
|
deviceDataManager.setDeviceApConfig(deviceE, apConfig);
|
||||||
int eExpectedChannel = 36;
|
int eExpectedChannel = 36;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceE,
|
deviceE,
|
||||||
TestUtils.createDeviceStatus(band, eExpectedChannel)
|
TestUtils.createDeviceStatus(band, eExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -668,7 +668,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (48)
|
// A -> No APs on current channel, so stay on it (48)
|
||||||
int aExpectedChannel = 48;
|
int aExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -689,7 +689,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
// B -> Same setting as A, but the scan results are bandwidth aware
|
// B -> Same setting as A, but the scan results are bandwidth aware
|
||||||
// Assign to only free channel (165)
|
// Assign to only free channel (165)
|
||||||
int bExpectedChannel = 165;
|
int bExpectedChannel = 165;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 48)
|
TestUtils.createDeviceStatus(band, 48)
|
||||||
);
|
);
|
||||||
@@ -721,7 +721,7 @@ public class LeastUsedChannelOptimizerTest {
|
|||||||
channelsC1.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsC1.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
channelsC2.addAll(Arrays.asList(36, 157, 165));
|
channelsC2.addAll(Arrays.asList(36, 157, 165));
|
||||||
int cExpectedChannel = channelsC1.removeFirst();
|
int cExpectedChannel = channelsC1.removeFirst();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ public class RandomChannelInitializerTest {
|
|||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createState(11, channelWidth, deviceBBssid)
|
TestUtils.createState(11, channelWidth, deviceBBssid)
|
||||||
);
|
);
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, 7)
|
TestUtils.createDeviceStatus(band, 7)
|
||||||
);
|
);
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 8)
|
TestUtils.createDeviceStatus(band, 8)
|
||||||
);
|
);
|
||||||
@@ -99,11 +99,11 @@ public class RandomChannelInitializerTest {
|
|||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createState(11, channelWidth, deviceBBssid)
|
TestUtils.createState(11, channelWidth, deviceBBssid)
|
||||||
);
|
);
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, 7)
|
TestUtils.createDeviceStatus(band, 7)
|
||||||
);
|
);
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 8)
|
TestUtils.createDeviceStatus(band, 8)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (48)
|
// A -> No APs on current channel, so stay on it (48)
|
||||||
int aExpectedChannel = 48;
|
int aExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -76,7 +76,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int bExpectedChannel = channelsB.removeLast();
|
int bExpectedChannel = channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 40)
|
TestUtils.createDeviceStatus(band, 40)
|
||||||
);
|
);
|
||||||
@@ -110,7 +110,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
int cExpectedChannel = 48;
|
int cExpectedChannel = 48;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 149)
|
TestUtils.createDeviceStatus(band, 149)
|
||||||
);
|
);
|
||||||
@@ -156,7 +156,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
|
|
||||||
// A -> No APs on current channel, so stay on it (1)
|
// A -> No APs on current channel, so stay on it (1)
|
||||||
int aExpectedChannel = 1;
|
int aExpectedChannel = 1;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceA,
|
deviceA,
|
||||||
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
TestUtils.createDeviceStatus(band, aExpectedChannel)
|
||||||
);
|
);
|
||||||
@@ -178,7 +178,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
LinkedList<Integer> channelsB = new LinkedList<>();
|
LinkedList<Integer> channelsB = new LinkedList<>();
|
||||||
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
channelsB.addAll(ChannelOptimizer.AVAILABLE_CHANNELS_BAND.get(band));
|
||||||
int bExpectedChannel = channelsB.removeLast();
|
int bExpectedChannel = channelsB.removeLast();
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceB,
|
deviceB,
|
||||||
TestUtils.createDeviceStatus(band, 6)
|
TestUtils.createDeviceStatus(band, 6)
|
||||||
);
|
);
|
||||||
@@ -196,7 +196,7 @@ public class UnmanagedApAwareChannelOptimizerTest {
|
|||||||
|
|
||||||
// C -> Assigned to only free prioritized channel (1)
|
// C -> Assigned to only free prioritized channel (1)
|
||||||
int cExpectedChannel = 1;
|
int cExpectedChannel = 1;
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(band, 6)
|
TestUtils.createDeviceStatus(band, 6)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
|
|
||||||
DataModel dataModel = new DataModel();
|
DataModel dataModel = new DataModel();
|
||||||
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestDeviceStatusRadios.put(
|
||||||
device,
|
device,
|
||||||
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
||||||
);
|
);
|
||||||
@@ -195,7 +195,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
|
|
||||||
DataModel dataModel2 = new DataModel();
|
DataModel dataModel2 = new DataModel();
|
||||||
for (String device : Arrays.asList(deviceA, deviceB)) {
|
for (String device : Arrays.asList(deviceA, deviceB)) {
|
||||||
dataModel2.latestDeviceStatus.put(
|
dataModel2.latestDeviceStatusRadios.put(
|
||||||
device,
|
device,
|
||||||
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
||||||
);
|
);
|
||||||
@@ -213,7 +213,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
dataModel2.latestDeviceStatus
|
dataModel2.latestDeviceStatusRadios
|
||||||
.put(
|
.put(
|
||||||
deviceC,
|
deviceC,
|
||||||
TestUtils.createDeviceStatus(
|
TestUtils.createDeviceStatus(
|
||||||
@@ -304,7 +304,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
|
|
||||||
DataModel dataModel2 = new DataModel();
|
DataModel dataModel2 = new DataModel();
|
||||||
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
||||||
dataModel2.latestDeviceStatus.put(
|
dataModel2.latestDeviceStatusRadios.put(
|
||||||
device,
|
device,
|
||||||
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
||||||
);
|
);
|
||||||
@@ -363,7 +363,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
|
|
||||||
DataModel dataModel3 = new DataModel();
|
DataModel dataModel3 = new DataModel();
|
||||||
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
||||||
dataModel3.latestDeviceStatus.put(
|
dataModel3.latestDeviceStatusRadios.put(
|
||||||
device,
|
device,
|
||||||
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
||||||
);
|
);
|
||||||
@@ -412,7 +412,7 @@ public class LocationBasedOptimalTPCTest {
|
|||||||
|
|
||||||
DataModel dataModel4 = new DataModel();
|
DataModel dataModel4 = new DataModel();
|
||||||
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
for (String device : Arrays.asList(deviceA, deviceB, deviceC)) {
|
||||||
dataModel4.latestDeviceStatus.put(
|
dataModel4.latestDeviceStatusRadios.put(
|
||||||
device,
|
device,
|
||||||
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
TestUtils.createDeviceStatus(UCentralConstants.BANDS)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import com.facebook.openwifirrm.ucentral.UCentralConstants;
|
|||||||
import com.facebook.openwifirrm.ucentral.UCentralUtils;
|
import com.facebook.openwifirrm.ucentral.UCentralUtils;
|
||||||
import com.facebook.openwifirrm.ucentral.WifiScanEntry;
|
import com.facebook.openwifirrm.ucentral.WifiScanEntry;
|
||||||
import com.facebook.openwifirrm.ucentral.models.State;
|
import com.facebook.openwifirrm.ucentral.models.State;
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
|
|
||||||
@TestMethodOrder(OrderAnnotation.class)
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
public class MeasurementBasedApApTPCTest {
|
public class MeasurementBasedApApTPCTest {
|
||||||
@@ -122,17 +121,17 @@ public class MeasurementBasedApApTPCTest {
|
|||||||
model.latestState.put(DEVICE_B, stateB);
|
model.latestState.put(DEVICE_B, stateB);
|
||||||
model.latestState.put(DEVICE_C, stateC);
|
model.latestState.put(DEVICE_C, stateC);
|
||||||
|
|
||||||
model.latestDeviceStatus.put(
|
model.latestDeviceStatusRadios.put(
|
||||||
DEVICE_A,
|
DEVICE_A,
|
||||||
TestUtils
|
TestUtils
|
||||||
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
||||||
);
|
);
|
||||||
model.latestDeviceStatus.put(
|
model.latestDeviceStatusRadios.put(
|
||||||
DEVICE_B,
|
DEVICE_B,
|
||||||
TestUtils
|
TestUtils
|
||||||
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
||||||
);
|
);
|
||||||
model.latestDeviceStatus.put(
|
model.latestDeviceStatusRadios.put(
|
||||||
DEVICE_C,
|
DEVICE_C,
|
||||||
TestUtils
|
TestUtils
|
||||||
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
.createDeviceStatusDualBand(1, MAX_TX_POWER, 36, MAX_TX_POWER)
|
||||||
@@ -298,25 +297,6 @@ public class MeasurementBasedApApTPCTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(2)
|
@Order(2)
|
||||||
void testGetCurrentTxPower() throws Exception {
|
|
||||||
final int expectedTxPower = 29;
|
|
||||||
|
|
||||||
DataModel model = new DataModel();
|
|
||||||
model.latestDeviceStatus.put(
|
|
||||||
DEVICE_A,
|
|
||||||
TestUtils.createDeviceStatusDualBand(1, 5, 36, expectedTxPower)
|
|
||||||
);
|
|
||||||
|
|
||||||
JsonArray radioStatuses =
|
|
||||||
model.latestDeviceStatus.get(DEVICE_A).getAsJsonArray();
|
|
||||||
int txPower = MeasurementBasedApApTPC
|
|
||||||
.getCurrentTxPower(radioStatuses, UCentralConstants.BAND_5G)
|
|
||||||
.get();
|
|
||||||
assertEquals(expectedTxPower, txPower);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(3)
|
|
||||||
void testBuildRssiMap() throws Exception {
|
void testBuildRssiMap() throws Exception {
|
||||||
// This example includes three APs, and one AP that is unmanaged
|
// This example includes three APs, and one AP that is unmanaged
|
||||||
Set<String> bssidSet = Set.of(BSSID_A, BSSID_B, BSSID_C);
|
Set<String> bssidSet = Set.of(BSSID_A, BSSID_B, BSSID_C);
|
||||||
@@ -338,7 +318,7 @@ public class MeasurementBasedApApTPCTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(4)
|
@Order(3)
|
||||||
void testComputeTxPower() throws Exception {
|
void testComputeTxPower() throws Exception {
|
||||||
// Test examples here taken from algorithm design doc from @pohanhf
|
// Test examples here taken from algorithm design doc from @pohanhf
|
||||||
final String serialNumber = "testSerial";
|
final String serialNumber = "testSerial";
|
||||||
@@ -513,12 +493,13 @@ public class MeasurementBasedApApTPCTest {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
// make device C not operate in the 5G band instead of dual band
|
// make device C not operate in the 5G band instead of dual band
|
||||||
dataModel.latestDeviceStatus.put(
|
dataModel.latestState.put(
|
||||||
DEVICE_C,
|
DEVICE_C,
|
||||||
TestUtils.createDeviceStatus(
|
TestUtils.createState(
|
||||||
UCentralConstants.BAND_2G,
|
|
||||||
1,
|
1,
|
||||||
MAX_TX_POWER
|
DEFAULT_CHANNEL_WIDTH,
|
||||||
|
MAX_TX_POWER,
|
||||||
|
BSSID_C
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
DeviceDataManager deviceDataManager = createDeviceDataManager();
|
DeviceDataManager deviceDataManager = createDeviceDataManager();
|
||||||
|
|||||||
@@ -8,7 +8,12 @@
|
|||||||
|
|
||||||
package com.facebook.openwifirrm.ucentral;
|
package com.facebook.openwifirrm.ucentral;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -17,4 +22,60 @@ public class UCentralUtilsTest {
|
|||||||
void test_placeholder() throws Exception {
|
void test_placeholder() throws Exception {
|
||||||
assertEquals(3, 1 + 2);
|
assertEquals(3, 1 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test_setRadioConfigFieldChannel() throws Exception {
|
||||||
|
final String serialNumber = "aaaaaaaaaaaa";
|
||||||
|
final int expectedChannel = 1;
|
||||||
|
final Map<String, Integer> newValueList = Collections
|
||||||
|
.singletonMap(UCentralConstants.BAND_5G, expectedChannel);
|
||||||
|
|
||||||
|
// test case where channel value is a string and not an integer
|
||||||
|
UCentralApConfiguration config = new UCentralApConfiguration(
|
||||||
|
"{\"interfaces\": [], \"radios\": [{\"band\": \"5G\", \"channel\": \"auto\"}]}"
|
||||||
|
);
|
||||||
|
boolean modified = UCentralUtils
|
||||||
|
.setRadioConfigField(serialNumber, config, "channel", newValueList);
|
||||||
|
assertTrue(modified);
|
||||||
|
assertEquals(
|
||||||
|
config.getRadioConfig(0).get("channel").getAsInt(),
|
||||||
|
expectedChannel
|
||||||
|
);
|
||||||
|
|
||||||
|
// field doesn't exist
|
||||||
|
config = new UCentralApConfiguration(
|
||||||
|
"{\"interfaces\": [], \"radios\": [{\"band\": \"5G\"}]}"
|
||||||
|
);
|
||||||
|
modified = UCentralUtils
|
||||||
|
.setRadioConfigField(serialNumber, config, "channel", newValueList);
|
||||||
|
assertTrue(modified);
|
||||||
|
assertEquals(
|
||||||
|
config.getRadioConfig(0).get("channel").getAsInt(),
|
||||||
|
expectedChannel
|
||||||
|
);
|
||||||
|
|
||||||
|
// normal field, not modified
|
||||||
|
config = new UCentralApConfiguration(
|
||||||
|
"{\"interfaces\": [], \"radios\": [{\"band\": \"5G\", \"channel\": 1}]}"
|
||||||
|
);
|
||||||
|
modified = UCentralUtils
|
||||||
|
.setRadioConfigField(serialNumber, config, "channel", newValueList);
|
||||||
|
assertFalse(modified);
|
||||||
|
assertEquals(
|
||||||
|
config.getRadioConfig(0).get("channel").getAsInt(),
|
||||||
|
expectedChannel
|
||||||
|
);
|
||||||
|
|
||||||
|
// normal field, modified
|
||||||
|
config = new UCentralApConfiguration(
|
||||||
|
"{\"interfaces\": [], \"radios\": [{\"band\": \"5G\", \"channel\": 15}]}"
|
||||||
|
);
|
||||||
|
modified = UCentralUtils
|
||||||
|
.setRadioConfigField(serialNumber, config, "channel", newValueList);
|
||||||
|
assertTrue(modified);
|
||||||
|
assertEquals(
|
||||||
|
config.getRadioConfig(0).get("channel").getAsInt(),
|
||||||
|
expectedChannel
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ public class VHTOperationElementTest {
|
|||||||
String vhtOper = "ACQAAAA=";
|
String vhtOper = "ACQAAAA=";
|
||||||
VHTOperationElement vhtOperObj = new VHTOperationElement(vhtOper);
|
VHTOperationElement vhtOperObj = new VHTOperationElement(vhtOper);
|
||||||
byte expectedChannelWidthIndicator = 0; // 20 MHz channel width
|
byte expectedChannelWidthIndicator = 0; // 20 MHz channel width
|
||||||
byte expectedChannel1 = 36;
|
short expectedChannel1 = 36;
|
||||||
byte expectedChannel2 = 0;
|
short expectedChannel2 = 0;
|
||||||
byte[] expectedVhtMcsForNss = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
byte[] expectedVhtMcsForNss = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
VHTOperationElement expectedVhtOperObj = new VHTOperationElement(
|
VHTOperationElement expectedVhtOperObj = new VHTOperationElement(
|
||||||
expectedChannelWidthIndicator,
|
expectedChannelWidthIndicator,
|
||||||
@@ -57,5 +57,20 @@ public class VHTOperationElementTest {
|
|||||||
expectedVhtMcsForNss
|
expectedVhtMcsForNss
|
||||||
);
|
);
|
||||||
assertEquals(expectedVhtOperObj, vhtOperObj);
|
assertEquals(expectedVhtOperObj, vhtOperObj);
|
||||||
|
|
||||||
|
// test with channel number >= 128 (channel fields should be unsigned)
|
||||||
|
vhtOper = "AJUAAAA=";
|
||||||
|
vhtOperObj = new VHTOperationElement(vhtOper);
|
||||||
|
expectedChannelWidthIndicator = 0;
|
||||||
|
expectedChannel1 = 149;
|
||||||
|
expectedChannel2 = 0;
|
||||||
|
expectedVhtMcsForNss = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
expectedVhtOperObj = new VHTOperationElement(
|
||||||
|
expectedChannelWidthIndicator,
|
||||||
|
expectedChannel1,
|
||||||
|
expectedChannel2,
|
||||||
|
expectedVhtMcsForNss
|
||||||
|
);
|
||||||
|
assertEquals(expectedVhtOperObj, vhtOperObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user