/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.topology.views.wifi; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import de.tud.kom.p2psim.api.common.SimHost; 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.scenario.ConfigurationException; import de.tud.kom.p2psim.api.topology.views.TopologyView; import de.tud.kom.p2psim.api.topology.views.wifi.phy.ErrorRateModel; 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.api.topology.views.wifi.phy.WifiPhy.WifiPreamble; import de.tud.kom.p2psim.impl.linklayer.mac.wifi.Ieee80211AdHocMac; import de.tud.kom.p2psim.impl.topology.views.RangedLink; import de.tud.kom.p2psim.impl.topology.views.RangedTopologyView; import de.tud.kom.p2psim.impl.topology.views.wifi.phy.InterferenceHelper; 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.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; /** * Extends the RangedTopologyView for a second range, which contains all * neighbors, who can sense the signal.
* * In the first range, it is possible to communicate with the other station * (Link.isConnected() should be true).
* In the second range, it is only a signal on the medium, which cannot be read * from the other station, but the other station can be sense, that the medium * is busy. Rather, the second range can be called CS (Carrier Sense) Range. *

* Additionally this class is the interface to the {@link InterferenceHelper}. * This mean, that this class can add transfers and interferences to the * InterferenceHelper. On the other hand, this class can get the PER to a * packet. *

* This WifiTopology supported only one channel for all peers and one TxPower * for all peers.
* The extending for multiple channels, the structure of neighbors must be * changed and for every channel an own {@link InterferenceHelper}. For the * TxPower, to all MACs, must be stored the txPower and the resulting ranges. * * * TODO: Add Interface for Carrier Sensing * * @author Christoph Muenker * @version 1.0, 15.09.2012 */ public class WifiTopologyView extends RangedTopologyView { /** * Stores the radius of the carrier sense range, which is computed based on * the values for the two parameters maxTxPowerDbm and csDbm. */ private double csRange; /** * The SAT denotes the Signal Attention Threshold and represents the mean * minimal signal power, which should be used as noise for the calculation * of the SNR. In other words, a signal lower as this level can be ignored * and does not influence, for instance, the cs-range.
* The Signal Attention Threshold is not specified in ns-3 but comes from * OMNET++ and is specified in ChannelControl.ned and set to -110dBm. */ private double satDbm = -110; /** * Specifies the Signal Attention Threshold in Watt. */ private double satW = PropagationLossModel.dbmToW(satDbm); /** * rxSensitivityDbm denotes the receive sensitivity of a device and * specifies down to which value a Wi-Fi card can still read the signal from * the medium. In ns-3, this value is represented by the attribute * "EnergyDetectionThreshold" in the class yans-wifi-phy.cc and set to * -96dBm. */ private double rxSensitivityDbm = -96; /** * Specifies the receive sensitivity in Watt. */ private double rxSensitivityW = PropagationLossModel .dbmToW(rxSensitivityDbm); /** * csDbm denotes the carrier sense sensitivity of a device and specifies * down to which value a Wi-Fi card can still sense (but not read) a signal. * If signals above this level are received, the card knows that the medium * is busy. In ns-3, this value is represented by the attribute * "CcaMode1Threshold" in the class yans-wifi-phy.cc and set to -99dBm. */ private double csDbm = -99; /** * Specifies the carrier sense sensitivity in Watt. */ private double csW = PropagationLossModel.dbmToW(csDbm); /** * Stores the frequency of the utilized IEEE802.11 standard. */ private long frequency = 0; /** * Specifies the transmission power of a all Wi-Fi chips, which simulated in * a simulation. */ private double maxTxPowerDbm = 0; private Map> cachedCSNeighbors = new HashMap>(); private InterferenceHelper interferenceHelper; private Standard_802_11 standard_802_11; public WifiTopologyView(PhyType phy) { super(phy, 100.0); interferenceHelper = new InterferenceHelper(this); } @XMLConfigurableConstructor({ "phy" }) public WifiTopologyView(String phy) { this(PhyType.WIFI); setPhy(phy); } /** * Updates the carrier sense neighborhood and cache the neighborhood. * Additionally it executes the super method. * * @param source * @return */ @Override protected List updateNeighborhood(MacAddress source) { List csNeighbors = new ArrayList(); for (MacAddress neighbor : allMacAddresses) { if (!source.equals(neighbor)) { RangedLink link = getLinkBetween(source, neighbor); if (link.getNodeDistance() < csRange) { assert !neighbor.equals(source); csNeighbors.add(neighbor); } } } cachedCSNeighbors.put(source, csNeighbors); return super.updateNeighborhood(source); } /** * Gets all Neighbors which are in the carrier sense neighborhood of the * given {@link MacAddress}. * * @param source * The MacAddress * @return The unmodifable list of carrier sense neighborhood to the given * {@link MacAddress}. */ public List getCarrierSenseNeighbors(MacAddress source) { return Collections.unmodifiableList(getCachedCSNeighbors(source)); } private List getCachedCSNeighbors(MacAddress source) { // updates the cachedCSNeighbors, if it is outdated getNeighbors(source); return cachedCSNeighbors.get(source); } public InterferenceHelper getInterferenceHelper() { return interferenceHelper; } protected void setCSRange(double csRange) { this.csRange = csRange; } public PropagationLossModel getPropagationLossModel() { return interferenceHelper.getLossModel(); } public ErrorRateModel getErrorRateModel() { return interferenceHelper.getErrorModel(); } /** * Sets the new propagationLossModel in {@link InterferenceHelper}, * additionally it sets the frequency for the lossModel which is used. * Further, it executes a update of the ranges. * * @param lossModel * The new lossModel. */ public void setPropagationLossModel(PropagationLossModel lossModel) { lossModel.setFrequency(frequency); interferenceHelper.setLossModel(lossModel); updateRanges(); } /** * Sets the new ErrorRateModel in {@link InterferenceHelper}.Further, it * executes a update of the ranges. * * @param errorRateModel * The new errorRateModel. */ public void setErrorRateModel(ErrorRateModel errorRateModel) { interferenceHelper.setErrorModel(errorRateModel); updateRanges(); } /** * Add a new transfer to the {@link InterferenceHelper}. This mean, that * this will be added as Interference and it is possible to get to the given * message a Packet Error Rate (PER), to check for a drop. * * @param start * The start time in microseconds * @param end * The end time in microseconds * @param sourcePosition * The position of the source * @param txPowerDbm * The transmission power in dBm * @param id * The message which is the identifier for the calculation of the * PER * @param dataMode * The {@link WifiMode} for the data * @param preamble * The {@link WifiMode} of the preamble * @param host * The host which starts this transfer. * @param sourceAddress * The {@link MacAddress} of the source, which stats this * transfer */ public void addTransfer(long start, long end, Location sourcePosition, double txPowerDbm, Message id, WifiMode dataMode, WifiPreamble preamble, SimHost host, MacAddress sourceAddress) { interferenceHelper.addTransfer(start, end, sourcePosition, txPowerDbm, id, dataMode, preamble, host, sourceAddress); } /** * Add a new Interference to the {@link InterferenceHelper}. This should be * used, if you want to simulate a transfer, but you are not interested * about the Packet Error Rate of this message. * * @param start * The start time in microseconds * * @param end * The end time in microseconds * @param sourcePosition * The position of the source * @param txPowerDbm * The transmission power in dBm * @param dataMode * The {@link WifiMode} of this interference * @param sourceAddress * The sourceAddress of this interference (It will be used the * neighborhood of this peer, to inform about carrier sensing). */ public void addInterference(long start, long end, Location sourcePosition, double txPowerDbm, WifiMode dataMode, MacAddress sourceAddress) { interferenceHelper.addInterference(start, end, sourcePosition, txPowerDbm, dataMode, sourceAddress); } /** * Calculates the Packer Error Rate (PER) for the message at the given * Position. * * @param msg * The message which was added as interference (or rather as ID) * with * {@link WifiTopologyView#addInterference(long, long, Location, double, WifiMode, MacAddress)} * to the {@link InterferenceHelper}. * @param pos * The position for that the PER should be calculated for this * message. * @return The Packet Error Rate (PER) for the message at the given * Position. */ public double calculatePer(Message msg, Location pos) { return interferenceHelper.calculatePer(msg, pos); } /** * Gets all {@link MacAddress} which are known by this {@link TopologyView} * * @return An unmodifiable list of all known mac addresses */ public List getAllMacAddresses() { return Collections.unmodifiableList(allMacAddresses); } /** * Sets the frequency, which should be used. This will be multiple called * from the MAC-Layer, so we check for the condition, that all MACs have the * same frequency.
* Additionally the ranges will be updated * * @param frequency * The frequency, which will be used from the MAC-Layer. */ protected void setFrequency(long frequency) { if (this.frequency != 0 && this.frequency != frequency) { throw new ConfigurationException( "Using different Frequencies on the same Topology-View. This is not supported!"); } getPropagationLossModel().setFrequency(frequency); this.frequency = frequency; updateRanges(); } /** * Sets the transmission power in dBm, which should be used to calculate the * ranges. This will be multiple called from the MAC-Layer, so we check for * maximal transmission power and use the maximal transmission power for the * calculation of the ranges.
*
* Additionally the ranges will be updated * * @param txPowerDbm * the transmission power in dBm */ protected void setTxPowerDbm(double txPowerDbm) { // FIXME: Possible to store for every node, and for every node an own // range! this.maxTxPowerDbm = Math.max(maxTxPowerDbm, txPowerDbm); updateRanges(); } /** * Updates the ranges, which will be used to fill the caches of the * neighborhood. */ private void updateRanges() { double csRange = interferenceHelper.calculateMaximalRadius( maxTxPowerDbm, csDbm); double range = interferenceHelper.calculateMaximalRadius(maxTxPowerDbm, rxSensitivityDbm); double satRange = interferenceHelper.calculateMaximalRadius( maxTxPowerDbm, satDbm); System.out.println("satRange: " + satRange + " csRange: " + csRange + " range: " + range); Monitor.log(WifiTopologyView.class, Level.INFO, "WiFi underlay ranges: satRange: " + satRange + " csRange: " + csRange + " range: " + range); setRange(range); setCSRange(csRange); } /** * Sets the used standard of the MAC-Layer. This will be called multiple, * and we check for different standards. If we found different standards, we * throw an exception, because we only support a homogeneous network of the * same standard. * * @param standard * The standard which is used by the MAC-Layer. */ protected void setStandard_802_11(Standard_802_11 standard) { if (standard_802_11 != null && !standard_802_11.equals(standard)) { throw new ConfigurationException( "Using different IEEE 802.11 Standards on the same Topology-View. This is not supported!"); } this.standard_802_11 = standard; } @Override protected void addedMac(MacLayer mac) { super.addedMac(mac); Ieee80211AdHocMac wifiMac = (Ieee80211AdHocMac) mac; // sets the standard, txPower and the frequency, which is using of the // mac. // Additionally it will be checked for a homogeneous network of this // parameter. setStandard_802_11(wifiMac.getStandard_802_11()); setTxPowerDbm(wifiMac.getTxPowerDdm()); setFrequency(wifiMac.getFrequency()); } /** * Sets the Signal Attention Threshold in dBm for the * {@link InterferenceHelper}. * * @param satDbm * The Signal Attention Threshold in dBm. */ public void setSatDbm(double satDbm) { this.satDbm = satDbm; this.satW = PropagationLossModel.dbmToW(satDbm); this.interferenceHelper.setSatDbm(satDbm); } /** * Sets the Signal Attention Threshold in watt for the * {@link InterferenceHelper} * * @param satW * The Signal Attention Threshold in watt */ public void setSatW(double satW) { this.satW = satW; this.satDbm = PropagationLossModel.wToDbm(satW); this.interferenceHelper.setSatDbm(satDbm); } /** * Sets the carrier sense threshold. * * @param csDbm * the carrier sense threshold in dBm */ public void setCsDbm(double csDbm) { this.csDbm = csDbm; this.csW = PropagationLossModel.dbmToW(csDbm); } /** * Sets the carrier sense threshold. * * @param csW * the carrier sense threshold in watt */ public void setCsW(double csW) { this.csW = csW; this.csDbm = PropagationLossModel.wToDbm(csW); } /** * Sets the receive sensitivity threshold. * * @param rxSensitivityDbm * the receive sensitivity threshold in dBm */ public void setRxSensitivityDbm(double rxSensitivityDbm) { this.rxSensitivityDbm = rxSensitivityDbm; this.rxSensitivityW = PropagationLossModel.dbmToW(rxSensitivityDbm); } /** * Sets the receive sensitivity threshold. * * @param rxSensitivityW * the receive sensitivity threshold in watt */ public void setRxSensitivityW(double rxSensitivityW) { this.rxSensitivityW = rxSensitivityW; this.rxSensitivityDbm = PropagationLossModel.wToDbm(rxSensitivityW); } /** * Sets the transmit gain of the antenna in the {@link InterferenceHelper}. * * @param gain * The transmit gain */ public void setTxGain(double gain) { this.interferenceHelper.setTxGainDbm(gain); } /** * Sets the receive gain of the antenna in the {@link InterferenceHelper}. * * @param gain * The receive gain */ public void setRxGain(double gain) { this.interferenceHelper.setRxGainDbm(gain); } }