package org.lucci.madhoc.network;
import org.lucci.madhoc.network.net.NetworkInterface;
import org.lucci.madhoc.network.net.NetworkingTechnology;
public class Connection
{
private NetworkInterface d1;
private NetworkInterface d2;
private int usedBandwith = 0;
private double creationDate = -1;
private double suppressionDate = -1;
private double environmentPerturbation = 0;
public Connection(NetworkInterface d1, NetworkInterface d2)
{
if (!d1.getNetworkingTechnology().isCompliantWith(d2.getNetworkingTechnology()))
throw new IllegalArgumentException("network interfaces do not use the same technology, then hence cannot establish a connection to each other");
this.d1 = d1;
this.d2 = d2;
}
public NetworkInterface getNetworkInterface1()
{
return d1;
}
public NetworkInterface getNetworkInterface2()
{
return d2;
}
public int hashCode()
{
return getIdentifier().hashCode();
}
public String getIdentifier()
{
int ni1 = getNetworkInterface1().hashCode();
int ni2 = getNetworkInterface2().hashCode();
return Math.min(ni1, ni2) + ":" + Math.max(ni1, ni2) + ":" + getNetworkType().getName();
}
public boolean equals(Object o)
{
return o instanceof Connection && o.hashCode() == hashCode();
}
public NetworkInterface getSibbling(NetworkInterface d)
{
if ( d == d1 )
{
return d2;
}
else if ( d == d2 )
{
return d1;
}
else
{
throw new IllegalArgumentException("station not associated to this connection");
}
}
public double getDistance()
{
return getNetworkInterface1().getNetworkingUnit().getStation().getLocation().getDistanceTo(getNetworkInterface2().getNetworkingUnit().getStation().getLocation());
}
public double getGreatestDistancePossible()
{
return Math.min(getNetworkInterface1().getCoverageRadius(), getNetworkInterface2().getCoverageRadius());
}
public double getQuality()
{
double distance = getDistance();
double maxDistance = getGreatestDistancePossible();
double quality = (maxDistance - distance) / maxDistance;
quality *= 1 - getEnvironmentPerturbation();
return quality;
}
public int getUsedBandwith()
{
return this.usedBandwith;
}
public void loadBandwith(int i)
{
if ( i < 0 )
throw new IllegalArgumentException("load cannot be negative");
if (i > getAvailableBandwith())
throw new IllegalArgumentException("load too high: " + i + " > " + getAvailableBandwith());
usedBandwith += i;
}
public int getMaximumBandwidth()
{
double resolution = getNetworkInterface1().getNetworkingUnit().getStation().getNetwork().getSimulation().getResolution();
return (int) (Math.min(getNetworkInterface1().getNetworkingTechnology().getMaximumBandwith(), getNetworkInterface2().getNetworkingTechnology().getMaximumBandwith()) * getQuality() * resolution);
}
public int getAvailableBandwith()
{
return getMaximumBandwidth() - getUsedBandwith();
}
public NetworkingTechnology getNetworkType()
{
if (getNetworkInterface1().getNetworkingTechnology() == getNetworkInterface2().getNetworkingTechnology())
{
return getNetworkInterface1().getNetworkingTechnology();
}
else
{
throw new IllegalStateException();
}
}
public void remove()
{
getNetworkInterface1().getConnections().remove(this);
getNetworkInterface2().getConnections().remove(this);
setSuppressionDate(getNetworkInterface1().getNetworkingUnit().getStation().getNetwork().getSimulation().getSimulatedTime());
}
public void resetIterationScopedValues()
{
usedBandwith = 0;
}
public double getEnvironmentPerturbation()
{
return environmentPerturbation;
}
public void setEnvironmentPerturbation(double p)
{
if (p < 0)
throw new IllegalArgumentException();
if (p > 1)
throw new IllegalArgumentException();
this.environmentPerturbation = p;
}
public double getCreationDate()
{
return creationDate;
}
public void setCreationDate(double creationDate)
{
if (this.creationDate != -1)
throw new IllegalStateException("connection creation already timestamped");
this.creationDate = creationDate;
}
public double getSuppressionDate()
{
return suppressionDate;
}
public void setSuppressionDate(double suppressionDate)
{
if (this.suppressionDate != -1)
throw new IllegalStateException("connection suppression already timestamped");
this.suppressionDate = suppressionDate;
}
public double getCollisionProbability()
{
double numberOfConcurentConnections = getNetworkInterface1().getConnections().size() + getNetworkInterface2().getConnections().size() - 1;
return numberOfConcurentConnections / 100;
}
}