Commit 02dda393 authored by Nils Richerzhagen's avatar Nils Richerzhagen
Browse files

Merge branch 'master' into 'nr/master-debug'

Merge Master into nr/master-debug



See merge request !21
parents c9a213fb b1ae37ae
# PeerfactSim.KOM, Simonstrator-Version
# PeerfactSim.KOM, Simonstrator-Version, Open-Street-Map Integration
This is PeerfactSim.KOM in the Simonstrator-enabled version. It contains models for common network and physical layer types as well as movement and placement models. Combined with the analyzing and evaluation toolchain, it supports rapid prototyping and performance evaluations of new services, protocols, and overlays.
This branch of the PeerfactSim-project implements the functionality to load real world maps data out of several resources. All relevant modifications are in the `de.tud.kom.p2psim.impl.topology.movement.modularosm`-package. The `ModularMovementModel`-class is the main-class for this approach. This class loads all other classes as defined in the XML-configurable file in the simRunner-project.
## Installation
For the possible implementations of the AttractionGenerator (generates POIs), the map visualization and the transition strategy we have defined interfaces and implemented at least two implementations for each interface.
One configurable interface we copied from the `de.tud.kom.p2psim.impl.topology.movement.modular`-package. In the `de.tud.kom.p2psim.impl.topology.movement.local`-package are some classes, which calculate the routes of the moving nodes. Here you can use some simple algorithmic approaches or use one out of two possible implementations, which use real world street data to navigate the nodes through the sreets to their destination.
Just clone this repository, it already includes an Eclipse project. The project is built using Maven, so you need to install the M2E-extension in Eclipse when working with PeerfactSim.KOM. Furthermore, the project depends on the Simonstrator-API. Which version of the API to use is defined within the VERSION file contained in the root folder of this project.
## Usage
Usually, you do not need to touch a single line of code within this project. It is provided mostly for debugging purposes. In order to configure and run your simulations, please refer to the simonstrator-simRunner project and its documentation.
## Extending PeerfactSim.KOM
In some cases you might want to implement new movement models, network layer routing protocols, or any other kind of "below transport-layer"-functionality. In oder to do so, please create a new feature branch (name convention: [yourname]/[featurename]) and implement you feature there. Once you are finished, please create a merge request and assign it to one of the project maintainers (usually @br ) to get it approved. A description of the feature in the merge request is required, as well as corresponding simRunner configurations for sample simulation runs.
\ No newline at end of file
The code itself is (hopefully) self-explaining. All possible configurations can be made via the XML-config in the simRunner-project.
\ No newline at end of file
......@@ -400,7 +400,27 @@
<version>2.0.1</version>
</dependency> -->
<!-- OSM-Data for movement models -->
<dependency>
<groupId>com.graphhopper</groupId>
<artifactId>graphhopper</artifactId>
<version>0.5.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Json (used for OSM-Movement-Model) -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<!-- Simonstrator-Platform -->
<dependency>
<groupId>maki</groupId>
......
......@@ -21,7 +21,6 @@
package de.tud.kom.p2psim.api.linklayer.mac;
import de.tud.kom.p2psim.api.linklayer.LinkLayer;
import de.tud.kom.p2psim.impl.linklayer.DefaultLinkLayerMessage;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
......@@ -42,25 +41,8 @@ public enum PhyType {
/**
* Direct wireless connections between adjacent hosts or AP-based (decided
* by the MAC/TopologyView used)
*
* The provided values are based on the paper
* by the MAC/TopologyView used). Based on
* "WiFi in Ad Hoc Mode: A Meaurement Study" by Anastasi et al. (2004),
* which describes the behavior of a 802.11B WiFi interface. The following
* setup contains the values for the usage of this model with a Bitrate of
* 1Mbit/s:<br>
* <li>TODO For the drop-rate, the authors must be addressed to provide the
* underlying values <li>netto BW of 758000Bit/s (Based on mathematical
* calculations) <li>500us latency <li>2346 Byte (minus 2x6 Bytes for the
* sender and receiver address, which are automatically added by the
* {@link DefaultLinkLayerMessage}. <li>Broadcast
*/
WIFI80211B(NetInterfaceName.WIFI, -1, 758000 / 8,
500 * Time.MICROSECOND, 2334, true),
/**
* Direct wireless connections between adjacent hosts or AP-based (decided
* by the MAC/TopologyView used)
*
* Assuming the following defaults: 1% drop-rate of LinkLayer-Packets
* (LinkLayer might add retransmission behavior as in 802.11), 5MBit/s netto
......@@ -77,14 +59,15 @@ public enum PhyType {
ETHERNET(NetInterfaceName.ETHERNET, 0.001, 100000000 / 8,
1 * Time.MILLISECOND, 1500, false),
// /**
// * A centrally scheduled wireless connection connecting a host to at most
// * one base-station. No direct communication between hosts.
// *
// * Assuming the following defaults: zero link-layer packet loss due to
// * scheduling, 384kBit/s, 500us latency, 1,4 kByte MTU
// */
// UMTS(0, 384000 / 8, 500 * Simulator.MICROSECOND_UNIT, 1472, false),
/**
* A centrally scheduled wireless connection connecting a host to at most
* one base-station. No direct communication between hosts.
*
* Assuming the following defaults: zero link-layer packet loss due to
* scheduling, 384kBit/s, 500us latency, 1,4 kByte MTU
*/
UMTS(NetInterfaceName.MOBILE, 0, 384000 / 8,
500 * Simulator.MICROSECOND_UNIT, 1472, false),
/**
*
......
......@@ -19,40 +19,40 @@
*/
package de.tud.kom.p2psim.api.network;
import de.tud.kom.p2psim.api.common.Position;
package de.tud.kom.p2psim.api.network;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.routing.RoutingAlgorithm;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
/**
* The NetLayer provides a general interface to encapsulate various networking
* models. This way, it is possible to use network solutions with different
* abstraction levels and complexity. For instance, one can choose either
* between a lightweight simple implementation which offers an adequate model
* with minimum demands in resource requirements and a more complex
* implementation capable to model fairshare bandwidth allocation of TCP but
* having a lot of CPU consumption.
*
* @author Sebastian Kaune
* @author Konstantin Pussep
* @version 3.0, 11/29/2007
*
*/
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The NetLayer provides a general interface to encapsulate various networking
* models. This way, it is possible to use network solutions with different
* abstraction levels and complexity. For instance, one can choose either
* between a lightweight simple implementation which offers an adequate model
* with minimum demands in resource requirements and a more complex
* implementation capable to model fairshare bandwidth allocation of TCP but
* having a lot of CPU consumption.
*
* @author Sebastian Kaune
* @author Konstantin Pussep
* @version 3.0, 11/29/2007
*
*/
public interface NetLayer extends NetInterface {
/**
*
* @return
*/
public SimHost getHost();
public SimHost getHost();
/**
*
* Deliver a message with the given data to the destination using the given
......@@ -68,48 +68,48 @@ public interface NetLayer extends NetInterface {
* the remote receiver
* @param protocol
* the used network protocol
*/
public void send(Message msg, NetID receiver, NetProtocol protocol);
/**
* Returns whether the network layer has connectivity to the physical
* network.
*
* @return return true if the network layer has connectivity to the physical
* network
*/
public boolean isOnline();
/**
* Returns whether the network layer has connectivity to the physical
* network.
*
* @return return true if the network layer does not have connectivity to
* the physical network
*/
public boolean isOffline();
/**
* Returns the NetID of a NetLayer instance
*
* @return the NetID of a given NetLayer instance
*/
public NetID getNetID();
/**
* Establishes the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity.
*
*/
public void goOnline();
/**
* Releases the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity.
*
*/
*/
public void send(Message msg, NetID receiver, NetProtocol protocol);
/**
* Returns whether the network layer has connectivity to the physical
* network.
*
* @return return true if the network layer has connectivity to the physical
* network
*/
public boolean isOnline();
/**
* Returns whether the network layer has connectivity to the physical
* network.
*
* @return return true if the network layer does not have connectivity to
* the physical network
*/
public boolean isOffline();
/**
* Returns the NetID of a NetLayer instance
*
* @return the NetID of a given NetLayer instance
*/
public NetID getNetID();
/**
* Establishes the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity.
*
*/
public void goOnline();
/**
* Releases the connection to the physical network. Further to this, if
* installed, the correspondent ConnectivityListener will be informed about
* the changes in connectivity.
*
*/
public void goOffline();
/**
......@@ -122,8 +122,8 @@ public interface NetLayer extends NetInterface {
* which is described by two numbers--its latitude and its longitude.
*
* @return Position the appropriate position
*/
public Position getNetPosition();
*/
public Location getNetPosition();
/**
* Returns the maximum physical bandwidth that is available at the given
......@@ -131,8 +131,8 @@ public interface NetLayer extends NetInterface {
* and download connections are closed.
*
* @return
*/
public Bandwidth getMaxBandwidth();
*/
public Bandwidth getMaxBandwidth();
/**
* Returns the current available download bandwidth of the network layer as
......@@ -140,25 +140,25 @@ public interface NetLayer extends NetInterface {
* connections.
*
* @return the available download bandwidth
*/
public Bandwidth getCurrentBandwidth();
/**
* Adds the given NetMessageListener as a handler for incoming NetMsgEvents
* triggered by the NetLayer which implements the message passing from the
* NetLayer to a layer above.
*
* @param listener
* the listener for network events
*/
public void addNetMsgListener(NetMessageListener listener);
/**
* Removes the given NetMessageListener which handles incoming NetMsgEvents
*
* @param listener
* the listener for network events
*/
*/
public Bandwidth getCurrentBandwidth();
/**
* Adds the given NetMessageListener as a handler for incoming NetMsgEvents
* triggered by the NetLayer which implements the message passing from the
* NetLayer to a layer above.
*
* @param listener
* the listener for network events
*/
public void addNetMsgListener(NetMessageListener listener);
/**
* Removes the given NetMessageListener which handles incoming NetMsgEvents
*
* @param listener
* the listener for network events
*/
public void removeNetMsgListener(NetMessageListener listener);
}
}
......@@ -65,15 +65,4 @@ public interface HostBuilder extends Builder, GlobalComponent {
* de.tud.kom.p2psim.api.scenario.Configurator)
*/
public void parse(Element elem, Configurator config);
/**
* Return the group of hosts with the given ID. This must be the same id as
* specified in the configuration file. Single hosts with an own id will be
* returned by this method too (as a list with only one entry).
*
* @param groupId
* same group or host id as in the configuration file
* @return list of hosts (or single host packed in a list).
*/
public List<SimHost> getHosts(String groupId);
}
......@@ -26,6 +26,7 @@ import de.tud.kom.p2psim.api.topology.social.SocialView;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.api.topology.waypoints.WaypointModel;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
/**
* We provide a global Topology-Object (ie. this object is only created once in
......@@ -36,7 +37,7 @@ import de.tud.kom.p2psim.impl.topology.PositionVector;
* @author Bjoern Richerzhagen
* @version 1.0, 21.02.2012
*/
public interface Topology {
public interface Topology extends GlobalComponent {
/**
* This Position Vector contains the upper bounds for each dimension used in
......
......@@ -20,9 +20,7 @@
package de.tud.kom.p2psim.api.topology;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
......@@ -40,33 +38,10 @@ import de.tudarmstadt.maki.simonstrator.api.component.topology.UnderlayTopologyP
public interface TopologyComponent extends SimHostComponent, MovementSupported,
MovementListener, UnderlayTopologyProvider, LocationSensor {
/**
* Abstract QoS-Classes for the Accuracy of the position. Implementation
* depends on the {@link EnergyComponent}
*
* @author Bjoern Richerzhagen
* @version 1.0, 26.02.2012
*/
@Deprecated
public static enum PositionAccuracy {
HIGH, MEDIUM, LOW
}
/**
* This uses an {@link EnergyComponent} for position retrieving (ie a GPS).
* A call might trigger energy consumption and the result will in most cases
* not be 100% accurate. Use this in your application if you want to add
* another layer of realism.
*
* @param accuracy
* a QoS-Class for the accuracy
* @return An estimate of the current position
*/
@Deprecated
public Position getPosition(PositionAccuracy accuracy);
/**
* Returns the Topology-Object that provides access to {@link TopologyView}s
* Note: the {@link Topology} is also available as a GlobalComponent via the
* Binder-class.
*
* @return
*/
......
......@@ -109,10 +109,18 @@ public interface MovementSupported {
public double getMaxMovementSpeed();
/**
* Gets a movement speed between min and max movement speed. This will be
* randomly calculated!
* Gets the currently set movement speed for that node. Initialized with a
* random value between min and max. Use setMovementSpeed() to lateron
* change the value.
*
* @return A random movement speed between min and max movement speed.
* @return
*/
public double getMovementSpeed();
/**
* Allows to set the movement speed in meter per second. Should be between
* min and max speed, but this is not enforced.
*/
public void setMovementSpeed(double speed);
}
......@@ -24,7 +24,6 @@ import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.topology.views.TopologyView;
import de.tud.kom.p2psim.impl.topology.PositionVector;
......
......@@ -20,15 +20,17 @@
package de.tud.kom.p2psim.api.topology.views;
import de.tud.kom.p2psim.api.linklayer.mac.Link;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
/**
* Determines the probability of a packet drop on a link.
*
* @author Bjoern Richerzhagen
* @version 1.0, 24.07.2012
*/
public interface DropRateDeterminator {
public interface DropProbabilityDeterminator {
/**
* Called for each host that is added to the TopologyView
......@@ -38,7 +40,7 @@ public interface DropRateDeterminator {
public void onMacAdded(MacLayer mac, TopologyView viewParent);
/**
* Return the drop-rate between 0.0 and 1.0
* Return the drop-probability between 0.0 and 1.0
*
* @param view
* This object can be used to access advanced information such as
......@@ -46,9 +48,12 @@ public interface DropRateDeterminator {
* implementing a cache to speed up the calculations.
* @param source
* @param destination
* @param link
* in case a link object already exists (and should be updated),
* it is passed. Otherwise: null.
* @return
*/
public double getDropRate(TopologyView view, MacAddress source,
MacAddress destination);
public double getDropProbability(TopologyView view, MacAddress source,
MacAddress destination, Link link);
}
......@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.api.topology.views;
import de.tud.kom.p2psim.api.linklayer.mac.Link;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
......@@ -51,9 +52,12 @@ public interface LatencyDeterminator {
* implementing a cache to speed up the calculations.
* @param source
* @param destination
* @param link
* in case a link object already exists (and should be updated),
* it is passed. Otherwise: null.
* @return
*/
public long getLatency(TopologyView view, MacAddress source,
MacAddress destination);
MacAddress destination, Link link);
}
......@@ -23,13 +23,14 @@ package de.tud.kom.p2psim.api.topology.views;
import java.util.Collection;
import java.util.List;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.Link;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.topology.TopologyListener;
import de.tud.kom.p2psim.api.topology.movement.MovementListener;
import de.tudarmstadt.maki.simonstrator.api.component.GlobalComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Each MAC has a view on the global topology of hosts (ie. the
......@@ -42,7 +43,8 @@ import de.tud.kom.p2psim.api.topology.movement.MovementListener;
* @author Bjoern Richerzhagen
* @version 1.0, 21.02.2012
*/
public interface TopologyView extends TopologyListener, MovementListener {
public interface TopologyView
extends TopologyListener, MovementListener, GlobalComponent {
/**
* The {@link PhyType} this View represents
......@@ -119,7 +121,7 @@ public interface TopologyView extends TopologyListener, MovementListener {
* The {@link MacAddress} of the host
* @return The real Position of the Host.
*/
public Position getPosition(MacAddress address);
public Location getPosition(MacAddress address);
/**
* Gets the real distance between the two hosts.
......
......@@ -20,7 +20,7 @@
package de.tud.kom.p2psim.api.topology.views.wifi.phy;
import de.tud.kom.p2psim.api.common.Position;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* This interface is for the calculation of the propagation loss of an
......@@ -52,8 +52,8 @@ public abstract class PropagationLossModel {
* The second position
* @return The RX power in dBm
*/
public abstract double getRxPowerDbm(double txPowerDbm, Position a,
Position b);
public abstract double getRxPowerDbm(double txPowerDbm, Location a,
Location b);
/**
* Gets the RX Power in dBm for the distance.
......
......@@ -28,13 +28,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.MacAddress;
import de.tud.kom.p2psim.api.linklayer.mac.MacLayer;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.PropagationLossModel;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiMode;
import de.tud.kom.p2psim.api.topology.views.wifi.phy.WifiPhy.Standard_802_11;
import de.tud.kom.p2psim.impl.topology.views.wifi.phy.InterferenceHelper;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* This class is an interface for other implementation of Rate Managers. The
......@@ -598,8 +598,8 @@ public abstract class AbstractRateManager {
* antenna. <br>
* This is only a helper to calculate the SNR in the AdHocMac.
*/
public double calculateActuallySNR(Position startPosition,
Position targetPosition, WifiMode mode, double txPowerDbm) {
public double calculateActuallySNR(Location startPosition,
Location targetPosition, WifiMode mode, double txPowerDbm) {
InterferenceHelper helper = mac.getWifiTopologyView()
.getInterferenceHelper();
double noiseInterferenceW = helper
......
......@@ -28,7 +28,6 @@ import java.util.Random;
import de.tud.kom.p2psim.api.analyzer.LinklayerAnalyzer;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.LinkLayerMessage;
import de.tud.kom.p2psim.api.linklayer.mac.Link;
......@@ -47,6 +46,7 @@ import de.tud.kom.p2psim.impl.linklayer.DefaultLinkMessageEvent;
import de.tud.kom.p2psim.impl.linklayer.mac.AbstractMacLayer;
import de.tud.kom.p2psim.impl.linklayer.mac.wifi.AbstractRateManager.RateManagerTypes;
import de.tud.kom.p2psim.impl.linklayer.mac.wifi.DcfManager.WifiState;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.wifi.WifiTopologyView;
import de.tud.kom.p2psim.impl.util.LiveMonitoring;
import de.tud.kom.p2psim.impl.util.LiveMonitoring.ProgressValue;
......@@ -56,6 +56,7 @@ import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.operation.AbstractOperation;
/**
......@@ -671,14 +672,12 @@ public class Ieee80211AdHocMac extends AbstractMacLayer {
/**
* Gets a copy of the real position of this host.
*
* Clone <strong>ONLY</strong> here.
*
* @return The position of this host.
*/
private Position getPosition() {
/*
* FIXME this leads to serious performance degradations. Do we REALLY
* need a copy?
*/
return this.getHost().getTopologyComponent().getRealPosition(); // .clone();
private PositionVector getPosition() {
return this.getHost().getTopologyComponent().getRealPosition().clone();
}
/**
......@@ -919,9 +918,9 @@ public class Ieee80211AdHocMac extends AbstractMacLayer {
WifiMacEventInformation eInfo = (WifiMacEventInformation) eventInfo;
// startPosition is from receiver (because ack come from this!)
Position startPosition = ((Ieee80211AdHocMac) topoView
Location startPosition = ((Ieee80211AdHocMac) topoView
.getMac(eventInfo.getReceiver())).getPosition();
Position targetPosition = this.getPosition();
Location targetPosition = this.getPosition();
double ackSnr = rateManager.calculateActuallySNR(startPosition,
targetPosition, eInfo.getAckMode(), txPowerDbm);
rateManager.reportDataOk(eventInfo.getReceiver(), ackSnr,
......
......@@ -26,7 +26,6 @@ import java.util.List;
import de.tud.kom.p2psim.api.analyzer.ConnectivityAnalyzer;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.analyzer.NetlayerAnalyzer;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.NetMessage;
......@@ -42,6 +41,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Anal
import de.tudarmstadt.maki.simonstrator.api.component.network.Bandwidth;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
/**
......@@ -70,7 +70,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
private boolean online;
private Position position;
private Location position;
Bandwidth currentBandwidth;
......@@ -93,7 +93,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
* the NetPosition of the network layer
*/
public AbstractNetLayer(SimHost host, NetID netId, Bandwidth maxBandwidth,
Position position, NetMeasurementDB.Host hostMeta) {
Location position, NetMeasurementDB.Host hostMeta) {
this.myID = netId;
this.msgListeners = new LinkedList<NetMessageListener>();
this.connListeners = new LinkedList<ConnectivityListener>();
......@@ -378,7 +378,7 @@ public abstract class AbstractNetLayer implements SimNetworkComponent,
* @see de.tud.kom.p2psim.api.api.network.NetLayer#getNetPosition()
*/
@Override
public Position getNetPosition() {
public Location getNetPosition() {
return this.position;
}
......
package de.tud.kom.p2psim.impl.network.fairshareng;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.FlowBasedNetlayer;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
* The Class Node.
*/
public class FairshareNode extends AbstractNetLayer implements
FlowBasedNetlayer {
/** The subnet. */
private final FairshareSubnet subnet;
/** The host queues. */
private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues;
/** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */
private final static float FLOAT_DELTA = 1e-7f;
/** The hash code. */
private final int hashCode;
/**
* Instantiates a new node.
* @param netID
* @param geoLoc
*/
public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID,
BandwidthImpl maxBandwidth, Position position,
NetMeasurementDB.Host hostMeta) {
super(host, netID, maxBandwidth, position, hostMeta);
this.subnet = subnet;
this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>();
this.hashCode = this.getNetID().hashCode();
}
/**
* Adds rate to the current down rate.
*
* @param downRate
*
* the down rate
* @throws Exception
* the exception
*/
public void addCurrentDownRate(double downRate) throws Exception {
final double currentDownBW = this.getCurrentBandwidth().getDownBW();
double realDownRate = currentDownBW - downRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) {
realDownRate = Math.round(realDownRate);
}
this.getCurrentBandwidth().setDownBW(realDownRate);
}
/**
* Adds rate to the current up rate.
*
* @param upRate
* the up rate
* @throws Exception
* the exception
*/
public void addCurrentUpRate(double upRate) throws Exception {
final double currentUpBW = this.getCurrentBandwidth().getUpBW();
double realUpRate = currentUpBW - upRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) {
realUpRate = Math.round(realUpRate);
}
this.getCurrentBandwidth().setUpBW(realUpRate);
}
/**
* Resets the node by setting current rates to zero.
*/
public void reset() {
this.setCurrentBandwidth(this.getMaxBandwidth().clone());
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/
@Override
public void goOffline() {
super.goOffline();
this.subnet.disconnectHost(this);
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.api.network.NetLayer#send(de.tud.kom.p2psim.api.common.Message, de.tud.kom.p2psim.api.network.NetID, de.tud.kom.p2psim.api.network.NetProtocol)
*/
@Override
public void send(Message msg, NetID receiverId, NetProtocol protocol) {
if (isOnline()) {
assert (msg.getSize() >= 0);
assert (isSupported(((AbstractTransMessage) msg).getProtocol()));
final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID());
final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol();
if (tpMsg.equals(TransProtocol.UDP)) {
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
this.subnet.sendUDP(netMsg);
} else if (tpMsg.equals(TransProtocol.TCP)) {
final FairshareNode receiver = this.subnet.getNetLayer(receiverId);
LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver);
if (queuedMessages == null) {
queuedMessages = new LinkedList<NetMessage>();
this.hostQueues.put(receiver, queuedMessages);
}
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
if (queuedMessages.isEmpty()) {
try {
this.subnet.sendTCPMessage(netMsg);
} catch (final Exception e) {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Exception..: sendTCP failed. %s", e);
assert(false) : "sendTCP failed: " + e;
}
}
queuedMessages.add(netMsg);
} else {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Unsupported transport protocol " + tpMsg);
assert (false) : "Unsupported transport protocol " + tpMsg;
}
} else {
Monitor.log(FairshareNode.class, Level.WARN, "Host " + this
+ " is offline.");
}
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/
@Override
protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
}
/**
* Checks if message queue is empty.
*
* @param receiver the receiver
* @return true, if is message queue empty
*/
public boolean isMessageQueueEmpty(FairshareNode receiver) {
return this.hostQueues.get(receiver).isEmpty();
}
/**
* Peek message queue and return size of next expected arrival.
*
* @param receiver the receiver
* @return the double
*/
public double peekMessageQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).get(0).getSize();
}
/**
* Gets a read-only view on message queue.
*
* @param receiver the receiver
* @return the view on message queue
*/
public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) {
return Collections.unmodifiableList(this.hostQueues.get(receiver));
}
/**
* Removes the message from queue.
*
* @param receiver the receiver
* @return the net message
*/
public NetMessage removeMessageFromQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).remove(0);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getLocalInetAddress() + " (U:"
+ this.getCurrentBandwidth().getUpBW() + "/D:"
+ this.getCurrentBandwidth().getDownBW() + ")";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
/* Precomputed to save time. */
return this.hashCode;
}
}
package de.tud.kom.p2psim.impl.network.fairshareng;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.FlowBasedNetlayer;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.modular.db.NetMeasurementDB;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* The Class Node.
*/
public class FairshareNode extends AbstractNetLayer implements
FlowBasedNetlayer {
/** The subnet. */
private final FairshareSubnet subnet;
/** The host queues. */
private final Map<FairshareNode, LinkedList<NetMessage>> hostQueues;
/** The Constant FLOAT_DELTA to correct Floats 9.999 to 10. */
private final static float FLOAT_DELTA = 1e-7f;
/** The hash code. */
private final int hashCode;
/**
* Instantiates a new node.
* @param netID
* @param geoLoc
*/
public FairshareNode(SimHost host, FairshareSubnet subnet, NetID netID,
BandwidthImpl maxBandwidth, Location position,
NetMeasurementDB.Host hostMeta) {
super(host, netID, maxBandwidth, position, hostMeta);
this.subnet = subnet;
this.hostQueues = new LinkedHashMap<FairshareNode, LinkedList<NetMessage>>();
this.hashCode = this.getNetID().hashCode();
}
/**
* Adds rate to the current down rate.
*
* @param downRate
*
* the down rate
* @throws Exception
* the exception
*/
public void addCurrentDownRate(double downRate) throws Exception {
final double currentDownBW = this.getCurrentBandwidth().getDownBW();
double realDownRate = currentDownBW - downRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realDownRate) - realDownRate) < FLOAT_DELTA ) {
realDownRate = Math.round(realDownRate);
}
this.getCurrentBandwidth().setDownBW(realDownRate);
}
/**
* Adds rate to the current up rate.
*
* @param upRate
* the up rate
* @throws Exception
* the exception
*/
public void addCurrentUpRate(double upRate) throws Exception {
final double currentUpBW = this.getCurrentBandwidth().getUpBW();
double realUpRate = currentUpBW - upRate;
/* Fix float, in case we get 9.999 save 10. */
if( Math.abs(Math.round(realUpRate) - realUpRate) < FLOAT_DELTA ) {
realUpRate = Math.round(realUpRate);
}
this.getCurrentBandwidth().setUpBW(realUpRate);
}
/**
* Resets the node by setting current rates to zero.
*/
public void reset() {
this.setCurrentBandwidth(this.getMaxBandwidth().clone());
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/
@Override
public void goOffline() {
super.goOffline();
this.subnet.disconnectHost(this);
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.api.network.NetLayer#send(de.tud.kom.p2psim.api.common.Message, de.tud.kom.p2psim.api.network.NetID, de.tud.kom.p2psim.api.network.NetProtocol)
*/
@Override
public void send(Message msg, NetID receiverId, NetProtocol protocol) {
if (isOnline()) {
assert (msg.getSize() >= 0);
assert (isSupported(((AbstractTransMessage) msg).getProtocol()));
final NetMessage netMsg = new IPv4Message(msg, receiverId, this.getNetID());
final TransProtocol tpMsg = ((AbstractTransMessage) msg).getProtocol();
if (tpMsg.equals(TransProtocol.UDP)) {
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
this.subnet.sendUDP(netMsg);
} else if (tpMsg.equals(TransProtocol.TCP)) {
final FairshareNode receiver = this.subnet.getNetLayer(receiverId);
LinkedList<NetMessage> queuedMessages = this.hostQueues.get(receiver);
if (queuedMessages == null) {
queuedMessages = new LinkedList<NetMessage>();
this.hostQueues.put(receiver, queuedMessages);
}
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
if (queuedMessages.isEmpty()) {
try {
this.subnet.sendTCPMessage(netMsg);
} catch (final Exception e) {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Exception..: sendTCP failed. %s", e);
assert(false) : "sendTCP failed: " + e;
}
}
queuedMessages.add(netMsg);
} else {
/*
* Can't throw exception here as send(Message msg, NetID receiverId, NetProtocol protocol) is overwritten.
*/
Monitor.log(FairshareNode.class, Level.ERROR,
"Unsupported transport protocol " + tpMsg);
assert (false) : "Unsupported transport protocol " + tpMsg;
}
} else {
Monitor.log(FairshareNode.class, Level.WARN, "Host " + this
+ " is offline.");
}
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/
@Override
protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
}
/**
* Checks if message queue is empty.
*
* @param receiver the receiver
* @return true, if is message queue empty
*/
public boolean isMessageQueueEmpty(FairshareNode receiver) {
return this.hostQueues.get(receiver).isEmpty();
}
/**
* Peek message queue and return size of next expected arrival.
*
* @param receiver the receiver
* @return the double
*/
public double peekMessageQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).get(0).getSize();
}
/**
* Gets a read-only view on message queue.
*
* @param receiver the receiver
* @return the view on message queue
*/
public List<NetMessage> getViewOnMessageQueue(FairshareNode receiver) {
return Collections.unmodifiableList(this.hostQueues.get(receiver));
}
/**
* Removes the message from queue.
*
* @param receiver the receiver
* @return the net message
*/
public NetMessage removeMessageFromQueue(FairshareNode receiver) {
return this.hostQueues.get(receiver).remove(0);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return (obj instanceof FairshareNode) ? ((FairshareNode) obj).getNetID().hashCode() == this.getNetID().hashCode() : super.equals(obj);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getLocalInetAddress() + " (U:"
+ this.getCurrentBandwidth().getUpBW() + "/D:"
+ this.getCurrentBandwidth().getDownBW() + ")";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
/* Precomputed to save time. */
return this.hashCode;
}
}
......@@ -19,12 +19,10 @@
*/
package de.tud.kom.p2psim.impl.network.gnp;
package de.tud.kom.p2psim.impl.network.gnp;
import java.util.Random;
import umontreal.iro.lecuyer.probdist.LognormalDist;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.NetLatencyModel;
import de.tud.kom.p2psim.api.network.NetLayer;
......@@ -35,133 +33,135 @@ import de.tud.kom.p2psim.impl.network.gnp.topology.CountryLookup;
import de.tud.kom.p2psim.impl.network.gnp.topology.PingErLookup;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import umontreal.iro.lecuyer.probdist.LognormalDist;
public class GnpLatencyModel implements NetLatencyModel {
private Random rnd = Randoms.getRandom(GnpLatencyModel.class);
private Random rnd = Randoms.getRandom(GnpLatencyModel.class);
public static final int MSS = PhyType.ETHERNET.getDefaultMTU()
- NetProtocol.IPv4.getHeaderSize()
- TransProtocol.TCP.getHeaderSize();
private static PingErLookup pingErLookup;
private static CountryLookup countryLookup;
private boolean usePingErInsteadOfGnp = false;
private boolean useAnalyticalFunctionInsteadOfGnp = false;
private boolean usePingErJitter = false;
private boolean usePingErPacketLoss = false;
public void init(PingErLookup pingErLookup, CountryLookup countryLookup) {
GnpLatencyModel.pingErLookup = pingErLookup;
GnpLatencyModel.countryLookup = countryLookup;
}
private double getMinimumRTT(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double minRtt = 0.0;
if (usePingErInsteadOfGnp) {
minRtt = pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
} else if (useAnalyticalFunctionInsteadOfGnp) {
double distance = GeoLocationOracle.getGeographicalDistance(sender.getNetID(), receiver.getNetID());
minRtt = 62 + (0.02 * distance);
} else {
Position senderPos = sender.getNetPosition();
Position receiverPos = receiver.getNetPosition();
minRtt = senderPos.getDistance(receiverPos);
}
return minRtt;
}
private double getPacketLossProbability(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double twoWayLossRate = 0.0;
double oneWayLossRate = 0.0;
if (usePingErPacketLoss) {
twoWayLossRate = pingErLookup.getPacktLossRate(ccSender, ccReceiver, countryLookup);
twoWayLossRate /= 100;
oneWayLossRate = 1 - Math.sqrt(1 - twoWayLossRate);
}
return oneWayLossRate;
}
private double getNextJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double randomJitter = 0.0;
if (usePingErJitter) {
LognormalDist distri = pingErLookup.getJitterDistribution(ccSender, ccReceiver, countryLookup);
randomJitter = distri.inverseF(rnd.nextDouble());
}
return randomJitter;
}
private double getAverageJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double jitter = 0.0;
if (usePingErJitter) {
jitter = pingErLookup.getAverageRtt(ccSender, ccReceiver, countryLookup) - pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
}
return jitter;
}
public double getUDPerrorProbability(GnpNetLayer sender, GnpNetLayer receiver, IPv4Message msg) {
if (msg.getPayload().getSize() > 65507)
throw new IllegalArgumentException("Message-Size ist too big for a UDP-Datagramm (max 65507 byte)");
double lp = getPacketLossProbability(sender, receiver);
double errorProb = 1 - Math.pow(1 - lp, msg.getNoOfFragments());
return errorProb;
}
public double getTcpThroughput(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver);
double averageJitter = getAverageJitter(sender, receiver);
double packetLossRate = getPacketLossProbability(sender, receiver);
double mathisBW = ((MSS * 1000) / (minRtt + averageJitter)) * Math.sqrt(1.5 / packetLossRate);
return mathisBW;
}
public long getTransmissionDelay(double bytes, double bandwidth) {
double messageTime = bytes / bandwidth;
long delay = Math.round((messageTime * Time.SECOND));
return delay;
}
public long getPropagationDelay(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver);
double randomJitter = getNextJitter(sender, receiver);
double receiveTime = (minRtt + randomJitter) / 2.0;
long latency = Math.round(receiveTime * Time.MILLISECOND);
return latency;
}
public long getLatency(NetLayer sender, NetLayer receiver) {
return getPropagationDelay((GnpNetLayer) sender, (GnpNetLayer) receiver);
}
public void setUsePingErRttData(boolean pingErRtt) {
usePingErInsteadOfGnp = pingErRtt;
}
public void setUseAnalyticalRtt(boolean analyticalRtt) {
useAnalyticalFunctionInsteadOfGnp = analyticalRtt;
}
public void setUsePingErJitter(boolean pingErRtt) {
usePingErJitter = pingErRtt;
}
public void setUsePingErPacketLoss(boolean pingErPacketLoss) {
usePingErPacketLoss = pingErPacketLoss;
}
- TransProtocol.TCP.getHeaderSize();
private static PingErLookup pingErLookup;
private static CountryLookup countryLookup;
private boolean usePingErInsteadOfGnp = false;
private boolean useAnalyticalFunctionInsteadOfGnp = false;
private boolean usePingErJitter = false;
private boolean usePingErPacketLoss = false;
public void init(PingErLookup pingErLookup, CountryLookup countryLookup) {
GnpLatencyModel.pingErLookup = pingErLookup;
GnpLatencyModel.countryLookup = countryLookup;
}
private double getMinimumRTT(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double minRtt = 0.0;
if (usePingErInsteadOfGnp) {
minRtt = pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
} else if (useAnalyticalFunctionInsteadOfGnp) {
double distance = GeoLocationOracle.getGeographicalDistance(sender.getNetID(), receiver.getNetID());
minRtt = 62 + (0.02 * distance);
} else {
Location senderPos = sender.getNetPosition();
Location receiverPos = receiver.getNetPosition();
minRtt = senderPos.distanceTo(receiverPos);
}
return minRtt;
}
private double getPacketLossProbability(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double twoWayLossRate = 0.0;
double oneWayLossRate = 0.0;
if (usePingErPacketLoss) {
twoWayLossRate = pingErLookup.getPacktLossRate(ccSender, ccReceiver, countryLookup);
twoWayLossRate /= 100;
oneWayLossRate = 1 - Math.sqrt(1 - twoWayLossRate);
}
return oneWayLossRate;
}
private double getNextJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double randomJitter = 0.0;
if (usePingErJitter) {
LognormalDist distri = pingErLookup.getJitterDistribution(ccSender, ccReceiver, countryLookup);
randomJitter = distri.inverseF(rnd.nextDouble());
}
return randomJitter;
}
private double getAverageJitter(GnpNetLayer sender, GnpNetLayer receiver) {
String ccSender = sender.getCountryCode();
String ccReceiver = receiver.getCountryCode();
double jitter = 0.0;
if (usePingErJitter) {
jitter = pingErLookup.getAverageRtt(ccSender, ccReceiver, countryLookup) - pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
}
return jitter;
}
public double getUDPerrorProbability(GnpNetLayer sender, GnpNetLayer receiver, IPv4Message msg) {
if (msg.getPayload().getSize() > 65507)
throw new IllegalArgumentException("Message-Size ist too big for a UDP-Datagramm (max 65507 byte)");
double lp = getPacketLossProbability(sender, receiver);
double errorProb = 1 - Math.pow(1 - lp, msg.getNoOfFragments());
return errorProb;
}
public double getTcpThroughput(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver);
double averageJitter = getAverageJitter(sender, receiver);
double packetLossRate = getPacketLossProbability(sender, receiver);
double mathisBW = ((MSS * 1000) / (minRtt + averageJitter)) * Math.sqrt(1.5 / packetLossRate);
return mathisBW;
}
public long getTransmissionDelay(double bytes, double bandwidth) {
double messageTime = bytes / bandwidth;
long delay = Math.round((messageTime * Time.SECOND));
return delay;
}
public long getPropagationDelay(GnpNetLayer sender, GnpNetLayer receiver) {
double minRtt = getMinimumRTT(sender, receiver);
double randomJitter = getNextJitter(sender, receiver);
double receiveTime = (minRtt + randomJitter) / 2.0;
long latency = Math.round(receiveTime * Time.MILLISECOND);
return latency;
}
public long getLatency(NetLayer sender, NetLayer receiver) {
return getPropagationDelay((GnpNetLayer) sender, (GnpNetLayer) receiver);
}
public void setUsePingErRttData(boolean pingErRtt) {
usePingErInsteadOfGnp = pingErRtt;
}
public void setUseAnalyticalRtt(boolean analyticalRtt) {
useAnalyticalFunctionInsteadOfGnp = analyticalRtt;
}
public void setUsePingErJitter(boolean pingErRtt) {
usePingErJitter = pingErRtt;
}
public void setUsePingErPacketLoss(boolean pingErPacketLoss) {
usePingErPacketLoss = pingErPacketLoss;
}
}
\ No newline at end of file
......@@ -19,59 +19,53 @@
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
package de.tud.kom.p2psim.impl.network.gnp.topology;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.impl.topology.PositionVector;
/**
* Implementation of NetPosition for Position and distance measurnment on the
* earth.
*
* @author Gerald Klunker
* @version 0.1, 05.02.2008
*
*/
public class GeographicPosition extends PositionVector {
private double latitude;
private double longitude;
/**
*
* @param longitude
* @param latitude
*/
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* Implementation of NetPosition for Position and distance measurnment on the
* earth.
*
* @author Gerald Klunker
* @version 0.1, 05.02.2008
*
*/
public class GeographicPosition extends PositionVector {
private double latitude;
private double longitude;
/**
*
* @param longitude
* @param latitude
*/
public GeographicPosition(double longitude, double latitude) {
super(new double[] { longitude, latitude });
this.longitude = longitude;
this.latitude = latitude;
}
/**
* @return geographical distance in km
*/
public double getDistance(Position point) {
double pi = 3.14159265;
double radConverter = pi / 180;
double lat1 = latitude * radConverter;
double lat2 = ((GeographicPosition) point).getLatitude() * radConverter;
double delta_lat = lat2 - lat1;
double delta_lon = (((GeographicPosition) point).getLongitude() - longitude)
* radConverter;
double temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return 2 * 6378.2 * Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
super(new double[] { longitude, latitude });
this.longitude = longitude;
this.latitude = latitude;
}
@Override
public double getAngle(Position target) {
throw new AssertionError(
"getAngle is not defined for this Position-Type");
/**
* @return geographical distance in km
*/
public double distanceTo(Location point) {
double pi = 3.14159265;
double radConverter = pi / 180;
double lat1 = latitude * radConverter;
double lat2 = ((GeographicPosition) point).getLatitude() * radConverter;
double delta_lat = lat2 - lat1;
double delta_lon = (((GeographicPosition) point).getLongitude() - longitude)
* radConverter;
double temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return 2 * 6378.2 * Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
}
@Override
......@@ -81,22 +75,22 @@ public class GeographicPosition extends PositionVector {
public GeographicPosition clone() {
return new GeographicPosition(longitude, latitude);
}
/**
*
* @return latitude of position
*/
public double getLatitude() {
return latitude;
}
/**
*
* @return longitude of position
*/
public double getLongitude() {
return longitude;
}
}
}
/**
*
* @return latitude of position
*/
public double getLatitude() {
return latitude;
}
/**
*
* @return longitude of position
*/
public double getLongitude() {
return longitude;
}
}
......@@ -19,296 +19,283 @@
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
package de.tud.kom.p2psim.impl.network.gnp.topology;
import java.util.ArrayList;
import de.tud.kom.p2psim.api.common.Position;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
/**
* This class implements a NetPosition for a GNP-Based calculation of round trip
* times. Therefore it includes methods for error estimation and methods for
* positioning by a downhill simplex algorithm in the GnpSpace class
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
public class GnpPosition implements Position, Comparable<GnpPosition> {
private static final long serialVersionUID = -1103996725403557900L;
private double[] gnpCoordinates;
private GnpSpace gnpRef;
private Host hostRef;
private double error = -1.0;
/**
*
* @param gnpCoordinates
* coordinate array for new position
*/
public GnpPosition(double[] gnpCoordinates) {
super();
this.gnpCoordinates = gnpCoordinates;
}
/**
* Object will be initialized with a random position. Position must be
* random according to the downhill simplex
*
* @param noOfDimensions
* number of dimensions
* @param hostRef
* related Host object
* @param gnpRef
* related GnpSpace object
*/
public GnpPosition(int noOfDimensions, Host hostRef, GnpSpace gnpRef) {
super();
gnpCoordinates = new double[noOfDimensions];
this.hostRef = hostRef;
this.gnpRef = gnpRef;
for (int c = 0; c < gnpCoordinates.length; c++)
/**
* This class implements a NetPosition for a GNP-Based calculation of round trip
* times. Therefore it includes methods for error estimation and methods for
* positioning by a downhill simplex algorithm in the GnpSpace class
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
public class GnpPosition implements Location, Comparable<GnpPosition> {
private static final long serialVersionUID = -1103996725403557900L;
private double[] gnpCoordinates;
private GnpSpace gnpRef;
private Host hostRef;
private double error = -1.0;
/**
*
* @param gnpCoordinates
* coordinate array for new position
*/
public GnpPosition(double[] gnpCoordinates) {
super();
this.gnpCoordinates = gnpCoordinates;
}
/**
* Object will be initialized with a random position. Position must be
* random according to the downhill simplex
*
* @param noOfDimensions
* number of dimensions
* @param hostRef
* related Host object
* @param gnpRef
* related GnpSpace object
*/
public GnpPosition(int noOfDimensions, Host hostRef, GnpSpace gnpRef) {
super();
gnpCoordinates = new double[noOfDimensions];
this.hostRef = hostRef;
this.gnpRef = gnpRef;
for (int c = 0; c < gnpCoordinates.length; c++)
gnpCoordinates[c] = Randoms.getRandom(GnpPosition.class)
.nextDouble();
}
/**
*
* @param dimension
* @param maxDiversity
*/
public void diversify(double[][] dimension, double maxDiversity) {
for (int c = 0; c < this.gnpCoordinates.length; c++) {
double rand = (2 * maxDiversity * Math.random()) - maxDiversity;
gnpCoordinates[c] = gnpCoordinates[c] + (rand * dimension[c][2]);
}
error = -1.0;
}
/**
* reposition
*
* @param pos
* position in the coordinate array
* @param value
* new value at position pos
*/
public void setGnpCoordinates(int pos, double value) {
gnpCoordinates[pos] = value;
error = -1.0;
}
/**
*
* @return the related GnpSpace object
*/
private GnpSpace getGnpRef() {
return gnpRef;
}
/**
*
* @return the related Host object
*/
public Host getHostRef() {
return hostRef;
}
/**
*
* @return number of dimensions
*/
public int getNoOfDimensions() {
return gnpCoordinates.length;
}
/**
*
* @param pos
* position in the coordinate array
* @return value at position pos
*/
public double getGnpCoordinates(int pos) {
return gnpCoordinates[pos];
}
/**
* Calculates the sum of all errors according to the downhill simplex
* operator.
*
* @return error
*/
public double getDownhillSimplexError() {
if (error < 0.0) {
error = 0.0;
for (int c = 0; c < getGnpRef().getNumberOfMonitors(); c++) {
error += getDownhillSimplexError(getGnpRef()
.getMonitorPosition(c));
}
}
return error;
}
/**
* Calculates the error to a monitor according to the downhill simplex
* operator
*
* @param monitor
* @return error
*/
public double getDownhillSimplexError(GnpPosition monitor) {
double calculatedDistance = this.getDistance(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return 0.0;
double error = Math.pow((calculatedDistance - measuredDistance)
/ calculatedDistance, 2);
return error;
}
/**
* Calculates an error, that indicates the deviation of the measured vs. the
* calculated rtt.
*
* @param monitor
* @return error value
*/
public double getDirectionalRelativError(GnpPosition monitor) {
double calculatedDistance = this.getDistance(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return Double.NaN;
double error = (calculatedDistance - measuredDistance)
/ Math.min(calculatedDistance, measuredDistance);
return error;
}
/**
* Method must be overwrite to sort different GnpPositions in order of their
* quality.
*
* Is needed for the positioning with the downhill simplex
*
*/
public int compareTo(GnpPosition arg0) {
double val1 = this.getDownhillSimplexError();
double val2 = arg0.getDownhillSimplexError();
if (val1 < val2)
return -1;
if (val1 > val2)
return 1;
else
return 0;
}
/**
*
* @return Comma-separated list of coordinates
*/
public String getCoordinateString() {
if (gnpCoordinates.length == 0) {
return "";
} else {
String result = String.valueOf(gnpCoordinates[0]);
for (int c = 1; c < gnpCoordinates.length; c++)
result = result + "," + gnpCoordinates[c];
return result;
}
}
/**
*
* @param monitor
* @return measured rtt to monitor, nan if no rtt was measured
*/
public double getMeasuredRtt(GnpPosition monitor) {
return this.getHostRef().getRtt(monitor.getHostRef());
}
/**
* @return euclidean distance
*/
public double getDistance(Position point) {
GnpPosition coord = (GnpPosition) point;
double distance = 0.0;
for (int c = 0; c < gnpCoordinates.length; c++)
distance += Math.pow(
gnpCoordinates[c] - coord.getGnpCoordinates(c), 2);
return Math.sqrt(distance);
.nextDouble();
}
@Override
public double getAngle(Position target) {
throw new AssertionError(
"getAngle is not defined for this Position-Type");
/**
*
* @param dimension
* @param maxDiversity
*/
public void diversify(double[][] dimension, double maxDiversity) {
for (int c = 0; c < this.gnpCoordinates.length; c++) {
double rand = (2 * maxDiversity * Math.random()) - maxDiversity;
gnpCoordinates[c] = gnpCoordinates[c] + (rand * dimension[c][2]);
}
error = -1.0;
}
@Override
public Position getTarget(double distance, double angle) {
throw new AssertionError(
"getTarget is not defined for this Position-Type");
}
/**
* reposition
*
* @param pos
* position in the coordinate array
* @param value
* new value at position pos
*/
public void setGnpCoordinates(int pos, double value) {
gnpCoordinates[pos] = value;
error = -1.0;
}
/**
*
* @return the related GnpSpace object
*/
private GnpSpace getGnpRef() {
return gnpRef;
}
/**
*
* @return the related Host object
*/
public Host getHostRef() {
return hostRef;
}
/**
*
* @return number of dimensions
*/
public int getNoOfDimensions() {
return gnpCoordinates.length;
}
/**
*
* @param pos
* position in the coordinate array
* @return value at position pos
*/
public double getGnpCoordinates(int pos) {
return gnpCoordinates[pos];
}
/**
* Calculates the sum of all errors according to the downhill simplex
* operator.
*
* @return error
*/
public double getDownhillSimplexError() {
if (error < 0.0) {
error = 0.0;
for (int c = 0; c < getGnpRef().getNumberOfMonitors(); c++) {
error += getDownhillSimplexError(getGnpRef()
.getMonitorPosition(c));
}
}
return error;
}
/**
* Calculates the error to a monitor according to the downhill simplex
* operator
*
* @param monitor
* @return error
*/
public double getDownhillSimplexError(GnpPosition monitor) {
double calculatedDistance = this.distanceTo(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return 0.0;
double error = Math.pow((calculatedDistance - measuredDistance)
/ calculatedDistance, 2);
return error;
}
/**
* Calculates an error, that indicates the deviation of the measured vs. the
* calculated rtt.
*
* @param monitor
* @return error value
*/
public double getDirectionalRelativError(GnpPosition monitor) {
double calculatedDistance = this.distanceTo(monitor);
double measuredDistance = this.getMeasuredRtt(monitor);
if (Double.compare(measuredDistance, Double.NaN) == 0)
return Double.NaN;
double error = (calculatedDistance - measuredDistance)
/ Math.min(calculatedDistance, measuredDistance);
return error;
}
/**
* Method must be overwrite to sort different GnpPositions in order of their
* quality.
*
* Is needed for the positioning with the downhill simplex
*
*/
public int compareTo(GnpPosition arg0) {
double val1 = this.getDownhillSimplexError();
double val2 = arg0.getDownhillSimplexError();
if (val1 < val2)
return -1;
if (val1 > val2)
return 1;
else
return 0;
}
/**
*
* @return Comma-separated list of coordinates
*/
public String getCoordinateString() {
if (gnpCoordinates.length == 0) {
return "";
} else {
String result = String.valueOf(gnpCoordinates[0]);
for (int c = 1; c < gnpCoordinates.length; c++)
result = result + "," + gnpCoordinates[c];
return result;
}
}
/**
*
* @param monitor
* @return measured rtt to monitor, nan if no rtt was measured
*/
public double getMeasuredRtt(GnpPosition monitor) {
return this.getHostRef().getRtt(monitor.getHostRef());
}
/**
* @return euclidean distance
*/
public double getDistance(Location point) {
GnpPosition coord = (GnpPosition) point;
double distance = 0.0;
for (int c = 0; c < gnpCoordinates.length; c++)
distance += Math.pow(
gnpCoordinates[c] - coord.getGnpCoordinates(c), 2);
return Math.sqrt(distance);
}
@Override
public int getTransmissionSize() {
return 16; // 2 * double
}
/**
* Static method generates a new GnpPosition according to the downhill
* simplex operator
*
* @param solution
* @param moveToSolution
* @param moveFactor
* @return new position
*/
public static GnpPosition getMovedSolution(GnpPosition solution,
GnpPosition moveToSolution, double moveFactor) {
GnpPosition returnValue = new GnpPosition(solution.getNoOfDimensions(),
solution.getHostRef(), solution.getGnpRef());
for (int c = 0; c < solution.getNoOfDimensions(); c++) {
double newCoord = (moveToSolution.getGnpCoordinates(c) - solution
.getGnpCoordinates(c))
* moveFactor + solution.getGnpCoordinates(c);
returnValue.setGnpCoordinates(c, newCoord);
}
return returnValue;
}
/**
* Static method generates a new GnpPosition according to the downhill
* simplex operator
*
* @param solution
* @param moveToSolution
* @param moveFactor
* @return new position
*/
public static GnpPosition getCenterSolution(ArrayList<GnpPosition> solutions) {
GnpPosition returnValue = new GnpPosition(solutions.get(0)
.getNoOfDimensions(), solutions.get(0).getHostRef(), solutions
.get(0).getGnpRef());
for (int d = 0; d < solutions.size(); d++) {
for (int c = 0; c < solutions.get(0).getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue
.getGnpCoordinates(c)
+ solutions.get(d).getGnpCoordinates(c));
}
}
for (int c = 0; c < returnValue.getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue.getGnpCoordinates(c)
/ solutions.size());
}
return returnValue;
/**
* Static method generates a new GnpPosition according to the downhill
* simplex operator
*
* @param solution
* @param moveToSolution
* @param moveFactor
* @return new position
*/
public static GnpPosition getMovedSolution(GnpPosition solution,
GnpPosition moveToSolution, double moveFactor) {
GnpPosition returnValue = new GnpPosition(solution.getNoOfDimensions(),
solution.getHostRef(), solution.getGnpRef());
for (int c = 0; c < solution.getNoOfDimensions(); c++) {
double newCoord = (moveToSolution.getGnpCoordinates(c) - solution
.getGnpCoordinates(c))
* moveFactor + solution.getGnpCoordinates(c);
returnValue.setGnpCoordinates(c, newCoord);
}
return returnValue;
}
/**
* Static method generates a new GnpPosition according to the downhill
* simplex operator
*
* @param solution
* @param moveToSolution
* @param moveFactor
* @return new position
*/
public static GnpPosition getCenterSolution(ArrayList<GnpPosition> solutions) {
GnpPosition returnValue = new GnpPosition(solutions.get(0)
.getNoOfDimensions(), solutions.get(0).getHostRef(), solutions
.get(0).getGnpRef());
for (int d = 0; d < solutions.size(); d++) {
for (int c = 0; c < solutions.get(0).getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue
.getGnpCoordinates(c)
+ solutions.get(d).getGnpCoordinates(c));
}
}
for (int c = 0; c < returnValue.getNoOfDimensions(); c++) {
returnValue.setGnpCoordinates(c, returnValue.getGnpCoordinates(c)
/ solutions.size());
}
return returnValue;
}
public GnpPosition clone() {
......@@ -323,7 +310,7 @@ public class GnpPosition implements Position, Comparable<GnpPosition> {
@Override
public double distanceTo(Location dest) {
return getDistance((Position) dest);
return getDistance(dest);
}
@Override
......@@ -344,5 +331,5 @@ public class GnpPosition implements Position, Comparable<GnpPosition> {
@Override
public void set(Location l) {
throw new UnsupportedOperationException();
}
}
}
}
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