Commit b1ae37ae authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

5G-Topology

- added support for access points
- defined host groups have access to those APs
- if in range of an AP, the AP is used instead of the Cellular
connection
- implements the handoverSensor for application/overlay usage

Removed deprecated topology container
parent 6823059b
......@@ -35,6 +35,8 @@ import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView.CellLink;
import de.tud.kom.p2psim.impl.topology.views.fiveg.FiveGTopologyDatabase;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.handover.HandoverSensor;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
import edu.emory.mathcs.backport.java.util.Arrays;
......@@ -74,12 +76,20 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
private Set<MacAddress> mobileClients = new LinkedHashSet<>();
/**
* A subset of mobileClients -> contains all clients that may use access
* points.
*/
private Set<MacAddress> mobileClientsUsingAccessPoints = new LinkedHashSet<>();
private List<MacAddress> mobileClientsList = new LinkedList<>();
private List<MacAddress> cloudsAndCloudletsList = new LinkedList<>();
private FiveGTopologyDatabase database = null;
private FiveGTopologyDatabase databaseAccessPoints = null;
/**
* Configuration setting: all group IDs of nodes that act as cloudlets
* (e.g., act as basestations with a lower delay, whatever that means w.r.t.
......@@ -95,6 +105,14 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
*/
private Set<String> groupIDsCloud = new LinkedHashSet<>();
/**
* Configuration setting: all group IDs that act as clients but have access
* to access points.
*/
private Set<String> groupIDsAccessPointUsage = new LinkedHashSet<>();
private List<HandoverSensor5G> handoverSensors = new LinkedList<>();
/**
*
* @param phy
......@@ -138,6 +156,15 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
} else {
mobileClients.add(mac.getMacAddress());
mobileClientsList.add(mac.getMacAddress());
if (groupIDsAccessPointUsage.contains(groupId)) {
assert databaseAccessPoints != null : "An AP Database is needed if AP-Functionality is desired.";
mobileClientsUsingAccessPoints.add(mac.getMacAddress());
HandoverSensor5G hs = new HandoverSensor5G(mac.getHost(),
mac.getMacAddress());
mac.getHost().registerComponent(hs);
handoverSensors.add(hs);
}
}
}
......@@ -148,10 +175,53 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
return;
}
PositionVector pos = getCachedPosition(link.getMobileClient());
int segId = database.getSegmentID(pos.getX(), pos.getY());
if (segId != link.getSegmentId()) {
// update link data
link.setLinkData(database.getEntryFor(segId, link.isCloudlet()));
int apSegId = -1;
if (link.supportsAccessPoints()) {
/*
* Check, if an AP-segment is available
*/
apSegId = databaseAccessPoints.getSegmentID(pos.getX(), pos.getY());
if (link.getSegmentId() != segId
|| link.getApSegmentId() != apSegId) {
// Update
link.setLinkData(database.getEntryFor(segId, link.isCloudlet()),
databaseAccessPoints.getEntryFor(apSegId,
link.isCloudlet()));
}
} else if (link.getSegmentId() != segId) {
link.setLinkData(database.getEntryFor(segId, link.isCloudlet()),
null);
}
if (link.getSegmentId() != segId || (link.supportsAccessPoints()
&& link.getApSegmentId() != apSegId)) {
// Update
link.setLinkData(database.getEntryFor(segId, link.isCloudlet()),
database.getEntryFor(apSegId, link.isCloudlet()));
}
}
@Override
public void afterComponentsMoved() {
super.afterComponentsMoved();
/*
* Check, if a node moved into a new segment. If so, we need to update
* the HandoverSensor to trigger the listeners. We only need to check
* nodes that are included in the list of ap-enabled nodes (i.e., they
* already have a HandoverSensor-instance).
*/
for (HandoverSensor5G sensor : handoverSensors) {
PositionVector pos = getCachedPosition(sensor.macAddr);
int segId = databaseAccessPoints.getSegmentID(pos.getX(),
pos.getY());
if (segId != sensor.apSegmentId) {
sensor.apSegmentId = segId;
// Connected to AP, if segment is provided in the DB
sensor.setConnectedToAccessPoint(
databaseAccessPoints.getEntryFor(segId, false) != null);
}
}
}
......@@ -167,7 +237,8 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
MacAddress mobileClient = sourceIsClient ? source : destination;
CellLink link = new CellLink(source, destination, true,
getPhyType().getDefaultMTU(), mobileClient,
cloudlets.contains(mobileClient));
cloudlets.contains(mobileClient),
mobileClientsUsingAccessPoints.contains(mobileClient));
updateOutdatedLink(link);
return link;
}
......@@ -210,6 +281,17 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
Arrays.asList(cloudletGroups));
}
/**
* GroupIDs that act as clients and have access to access points.
*
* @param cloudletGroups
*/
@SuppressWarnings("unchecked")
public void setAccessPointGroups(String[] accessPointGroups) {
this.groupIDsAccessPointUsage = new LinkedHashSet<>(
Arrays.asList(accessPointGroups));
}
/**
* Set the measurement database providing link quality data for clients
* based on their position.
......@@ -221,6 +303,16 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
this.database = database;
}
/**
* Another layer of a database, this time for access points.
*
* @param accessPoints
*/
public void setAccessPoints(FiveGTopologyDatabase accessPoints) {
assert this.databaseAccessPoints == null;
this.databaseAccessPoints = accessPoints;
}
/**
* A custom link object supporting dynamic updates of the properties without
* relying on a movement model notification - the client's position is used
......@@ -238,8 +330,12 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
private FiveGTopologyDatabase.Entry linkData;
private FiveGTopologyDatabase.Entry apLinkData;
private final boolean isUpload;
private final boolean supportsAccessPoints;
private final boolean isCloudlet;
private final boolean isInvalidLink;
......@@ -256,11 +352,12 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
this.isUpload = false;
this.isCloudlet = false;
this.isInvalidLink = true;
this.supportsAccessPoints = false;
}
public CellLink(MacAddress source, MacAddress destination,
boolean isConnected, int mtu, MacAddress mobileClient,
boolean isCloudlet) {
boolean isCloudlet, boolean supportsAccessPoints) {
super(source, destination, isConnected, -1, -1, -1, mtu);
this.mobileClient = mobileClient;
this.isCloudlet = isCloudlet;
......@@ -271,18 +368,32 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
isUpload = false;
}
this.isInvalidLink = false;
this.supportsAccessPoints = supportsAccessPoints;
}
public boolean isInvalidLink() {
return isInvalidLink;
}
public boolean supportsAccessPoints() {
return supportsAccessPoints;
}
public int getSegmentId() {
return linkData == null ? -1 : linkData.getSegmentID();
}
public void setLinkData(FiveGTopologyDatabase.Entry linkData) {
public int getApSegmentId() {
assert supportsAccessPoints;
return apLinkData == null ? -1 : apLinkData.getSegmentID();
}
public void setLinkData(FiveGTopologyDatabase.Entry linkData,
FiveGTopologyDatabase.Entry apLinkData) {
this.linkData = linkData;
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
this.apLinkData = apLinkData;
}
public MacAddress getMobileClient() {
......@@ -295,17 +406,92 @@ public class FiveGTopologyView extends AbstractTopologyView<CellLink> {
@Override
public long getBandwidth(boolean isBroadcast) {
return linkData.getBandwidth(isUpload);
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
return apLinkData != null ? apLinkData.getBandwidth(isUpload)
: linkData.getBandwidth(isUpload);
}
@Override
public double getDropProbability() {
return linkData.getDropProbability(isUpload);
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
return apLinkData != null ? apLinkData.getDropProbability(isUpload)
: linkData.getDropProbability(isUpload);
}
@Override
public long getLatency() {
return linkData.getLatency(isUpload);
assert (apLinkData != null && supportsAccessPoints)
|| apLinkData == null;
return apLinkData != null ? apLinkData.getLatency(isUpload)
: linkData.getLatency(isUpload);
}
}
/**
* Implementation of a {@link HandoverSensor} within the 5G topo-view.
*
* @author Bjoern Richerzhagen
* @version 1.0, Nov 20, 2015
*/
public class HandoverSensor5G implements HandoverSensor {
private List<HandoverListener> listeners = new LinkedList<>();
private boolean isConnectedToAccessPoint;
public int apSegmentId = -1;
public final MacAddress macAddr;
private Host host;
public HandoverSensor5G(Host host, MacAddress macAddr) {
this.host = host;
this.macAddr = macAddr;
}
@Override
public boolean isConnectedToAccessPoint() {
return isConnectedToAccessPoint;
}
public void setConnectedToAccessPoint(
boolean isConnectedToAccessPoint) {
if (this.isConnectedToAccessPoint != isConnectedToAccessPoint) {
this.isConnectedToAccessPoint = isConnectedToAccessPoint;
for (HandoverListener listener : listeners) {
listener.onHandover(isConnectedToAccessPoint);
}
}
}
@Override
public void addHandoverListener(HandoverListener listener) {
listeners.add(listener);
}
@Override
public boolean removeHandoverListener(
HandoverListener listenerToRemove) {
return listeners.remove(listenerToRemove);
}
@Override
public void initialize() {
// not needed
}
@Override
public void shutdown() {
// not needed
}
@Override
public Host getHost() {
return host;
}
}
......
......@@ -45,6 +45,8 @@ public abstract class AbstractGridBasedTopologyDatabase
private final Map<Integer, FiveGTopologyDatabase.Entry> cloudletEntries;
public static int _visId = 1;
/**
* Grid-based {@link CellularTopologyDatabase} with a grid length (squares)
* of gridSize in meters.
......@@ -64,7 +66,7 @@ public abstract class AbstractGridBasedTopologyDatabase
@Override
public void eventOccurred(Object content, int type) {
VisualizationInjector.injectComponent("5G-Properties", -1,
VisualizationInjector.injectComponent("5G " + _visId++, -1,
new FiveGVisualization(
AbstractGridBasedTopologyDatabase.this),
true, true);
......@@ -139,6 +141,19 @@ public abstract class AbstractGridBasedTopologyDatabase
private final long latencyUp, latencyDown, bandwidthUp, bandwidthDown;
/**
* Segment offering both, cell and access point with different
* characteristics.
*
* @param segment
* @param dropUp
* @param dropDown
* @param latencyUp
* @param latencyDown
* @param bandwidthUp
* @param bandwidthDown
*/
public StaticEntry(int segment, double dropUp, double dropDown,
long latencyUp, long latencyDown, long bandwidthUp,
long bandwidthDown) {
......
......@@ -18,31 +18,34 @@
*
*/
package de.tud.kom.p2psim.impl.topology;
package de.tud.kom.p2psim.impl.topology.views.fiveg;
/**
* The created Topology should be added to this static class! So it is possible
* to access the Topology from overall!
*
* FIXME Rename this to resolve conflict with API - check, if this is really the
* way to go
*
* @author Christoph Muenker
* @version 1.0, 25.06.2013
*/
public class Topology {
private static de.tud.kom.p2psim.api.topology.Topology topo;
import de.tudarmstadt.maki.simonstrator.api.Time;
public static de.tud.kom.p2psim.api.topology.Topology getTopology() {
return topo;
}
public class AccessPointSegmentDatabase
extends AbstractGridBasedTopologyDatabase {
public static void setTopology(
de.tud.kom.p2psim.api.topology.Topology topology) {
topo = topology;
public AccessPointSegmentDatabase() {
super(50, true);
}
public static PositionVector getWorldDimension() {
return topo.getWorldDimensions().clone();
@Override
protected Entry createEntryFor(int segmentID, boolean isCloudlet) {
if (segmentID == 105) {
/*
* FIXME just testing
*/
return new StaticEntry(segmentID, 0, 0, 10 * Time.MILLISECOND,
10 * Time.MILLISECOND, 1000000, 1000000);
}
if (segmentID == 240) {
/*
* FIXME just testing
*/
return new StaticEntry(segmentID, 0, 0, 38 * Time.MILLISECOND,
38 * Time.MILLISECOND, 1000000, 1000000);
}
return null;
}
}
......@@ -52,7 +52,9 @@ public interface FiveGTopologyDatabase {
* outperform the link to a cloud.
*
* @param segmentID
* @return
* @return the entry. ONLY for access point databases, this might also
* return null, if the given segment is not offering access point
* connectivity.
*/
public FiveGTopologyDatabase.Entry getEntryFor(int segmentID,
boolean isCloudlet);
......
......@@ -51,7 +51,6 @@ public class FiveGVisualization extends JComponent {
private final AbstractGridBasedTopologyDatabase database;
public FiveGVisualization(AbstractGridBasedTopologyDatabase database) {
setBounds(0, 0, VisualizationInjector.getWorldX(),
VisualizationInjector.getWorldY());
......@@ -109,6 +108,9 @@ public class FiveGVisualization extends JComponent {
// TODO add checkbox for cloudlets?
Entry entry = database.getEntryFor(database.getSegmentID(x, y),
false);
if (entry == null) {
continue;
}
if (entry.getLatency(isUpload) > maxLatency) {
maxLatency = entry.getLatency(isUpload);
}
......@@ -117,7 +119,7 @@ public class FiveGVisualization extends JComponent {
}
}
}
for (int x = 0; x < VisualizationInjector.getWorldX(); x += stepSize) {
for (int y = 0; y < VisualizationInjector
.getWorldY(); y += stepSize) {
......@@ -125,6 +127,9 @@ public class FiveGVisualization extends JComponent {
// TODO add checkbox for cloudlets?
Entry entry = database.getEntryFor(database.getSegmentID(x, y),
false);
if (entry == null) {
continue;
}
// TODO add checkbox for upload/download toggle?
......@@ -150,7 +155,7 @@ public class FiveGVisualization extends JComponent {
x + 10, y + 25);
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment