00001
00002 #include "physical_layer.hpp"
00003 #include "node.hpp"
00004 #include "packet.hpp"
00005
00006
00007
00008
00009
00010 const double PhysicalLayer::m_DEFAULT_TX_POWER = 1.0;
00011 const double PhysicalLayer::m_DEFAULT_MAX_TX_POWER = 1.0;
00012
00013
00014
00015
00016 const double PhysicalLayer::m_DEFAULT_RX_THRESHOLD = 100e-6;
00017
00018
00019 const double PhysicalLayer::m_DEFAULT_CS_THRESHOLD = 5e-6;
00020
00021 const double PhysicalLayer::m_DEFAULT_CAPTURE_THRESHOLD = 10;
00022
00023
00024 const double PhysicalLayer::m_DEFAULT_MINIMUM_SIGNAL_STRENGTH = 7.94e-12;
00025
00026
00027 const double PhysicalLayer::m_DEFAULT_DATA_RATE = 128e3;
00028
00029 const double PhysicalLayer::m_DEFAULT_BANDWIDTH = 960e6;
00030
00031
00032 const double PhysicalLayer::m_RADIO_TEMPERATURE = 290;
00033 const double PhysicalLayer::m_RADIO_NOISE_FACTOR = 10;
00034 const double PhysicalLayer::m_BOLTZMANNS_CONSTANT = 1.3806503e-23;
00035
00036 const t_uint PhysicalLayer::m_PHYSICAL_QUEUE_LENGTH = 1;
00037
00038 PhysicalLayer::PhysicalLayer(NodePtr node)
00039 : CommunicationLayer(node),
00040 m_currentTxPower(m_DEFAULT_TX_POWER),
00041 m_maxTxPower(m_DEFAULT_MAX_TX_POWER),
00042 m_rxThreshold(m_DEFAULT_RX_THRESHOLD),
00043 m_csThreshold(m_DEFAULT_CS_THRESHOLD),
00044 m_captureThreshold(m_DEFAULT_CAPTURE_THRESHOLD),
00045 m_minimumSignalStrength(m_DEFAULT_MINIMUM_SIGNAL_STRENGTH),
00046 m_dataRate(m_DEFAULT_DATA_RATE),
00047 m_bandwidth(m_DEFAULT_BANDWIDTH),
00048 m_pendingRecvSignalError(false),
00049 m_signalSendingDelay(0.0)
00050 {
00051 assert(m_dataRate > 0.0);
00052 assert(m_bandwidth > 0.0);
00053 assert(m_currentTxPower > 0.0);
00054 assert(m_maxTxPower >= m_currentTxPower);
00055 setMaxQueueLength(m_PHYSICAL_QUEUE_LENGTH);
00056 DummyEventPtr dummyEvent = DummyEvent::create();
00057 m_transmittingTimer = Timer::create(getNode(), dummyEvent);
00058 }
00059
00060 PhysicalLayer::~PhysicalLayer()
00061 {
00062
00063 }
00064
00065 bool PhysicalLayer::recvPendingSignal(WirelessCommSignalPtr signal,
00066 double recvdSignalStrength)
00067 {
00068
00069
00070 bool wasSuccessful = true;
00071 PacketPtr packet = signal->getPacketPtr();
00072 packet->setHasError(m_pendingRecvSignalError);
00073 LogStreamManager::instance()->logPktRecvItem(getNodeId(),
00074 getLayerType(), *packet);
00075 if(!packet->getHasError()) {
00076 recvdErrorFreeSignal(signal, recvdSignalStrength);
00077 wasSuccessful = sendToLayer(
00078 CommunicationLayer::Directions_Upper, packet);
00079 }
00080
00081 return wasSuccessful;
00082 }
00083
00084 void PhysicalLayer::recvdErrorFreeSignal(WirelessCommSignalPtr signal,
00085 double recvdSignalStrength)
00086 {
00087
00088 }
00089
00090 bool PhysicalLayer::recvFromLayer(
00091 CommunicationLayer::Directions direction,
00092 PacketPtr packet, t_uint sendingLayerIdx)
00093 {
00094
00095
00096
00097 assert(direction == CommunicationLayer::Directions_Upper);
00098 assert(getNode().get() != 0);
00099 Location myLocation = getNode()->getLocation();
00100 packet->setDataRate(getDataRate());
00101
00102 double signalTxPower = m_currentTxPower;
00103 if(packet->getDoMaxTxPower()) {
00104 signalTxPower = m_maxTxPower;
00105 } else if(packet->getTxPower() > 0.0) {
00106 signalTxPower = packet->getTxPower();
00107 }
00108
00109 if(m_DEBUG_TRANSMIT_POWER) {
00110 ostringstream debugStream;
00111 debugStream << __PRETTY_FUNCTION__ << ": txPower: " <<
00112 signalTxPower;
00113 LogStreamManager::instance()->logDebugItem(debugStream.str());
00114 }
00115
00116 WirelessCommSignalPtr signal =
00117 WirelessCommSignal::create(myLocation,
00118 powerToDecibels(signalTxPower),
00119 getWavelength(), getGain(), packet);
00120 return sendSignal(signal);
00121 }
00122
00123 bool PhysicalLayer::isTransmitting() const
00124 {
00125 assert(m_transmittingTimer.get() != 0);
00126 return m_transmittingTimer->isRunning();
00127 }
00128
00129 bool PhysicalLayer::sendSignal(WirelessCommSignalPtr signal)
00130 {
00131 return scheduleSignal(signal);
00132 }
00133
00134 bool PhysicalLayer::scheduleSignal(WirelessCommSignalPtr signal)
00135 {
00136 EventPtr recvEvent(new SignalRecvEvent(m_wirelessChannelManagerPtr,
00137 thisPhysicalLayer(), signal));
00138 assert(getNode().get() != 0);
00139 bool wasScheduled = getNode()->scheduleEvent(recvEvent,
00140 getSignalSendingDelay());
00141 return wasScheduled;
00142 }
00143
00144 void PhysicalLayer::addSignal(WirelessCommSignalPtr signal,
00145 double signalStrength)
00146 {
00147 if(signalStrength > getMinimumSignalStrength()) {
00148 assert(signal.get() != 0);
00149 SignalStrengthMap::const_iterator mapIterator =
00150 m_signalStrengths.find(signal);
00151
00152 bool wasFound = (mapIterator != m_signalStrengths.end());
00153 if(wasFound) {
00154
00155
00156 m_signalStrengths.erase(signal);
00157 }
00158
00159 m_signalStrengths.insert(make_pair(signal, signalStrength));
00160 }
00161 }
00162
00163 void PhysicalLayer::removeSignal(WirelessCommSignalPtr signal)
00164 {
00165 assert(signal.get() != 0);
00166 m_signalStrengths.erase(signal);
00167
00168
00169 }
00170
00171 double PhysicalLayer::getPendingSignalSinr()
00172 {
00173
00174
00175
00176
00177
00178
00179 double sinr = 0.0;
00180 if(m_pendingRecvSignal.get() != 0) {
00181 double pendingSignalStrength = getPendingSignalStrength();
00182 double interferenceFloor =
00183 (getCulmulativeSignalStrength() - pendingSignalStrength) +
00184 getNoiseFloor();
00185 sinr = pendingSignalStrength / interferenceFloor;
00186 }
00187 return sinr;
00188 }
00189
00190 bool PhysicalLayer::pendingSignalIsWeak()
00191 {
00192
00193
00194
00195 bool isWeak = (getPendingSignalStrength() <= getRxThreshold());
00196 if(m_pendingRecvSignal.get() != 0) {
00197 isWeak |= (getPendingSignalSinr() <= getCaptureThreshold());
00198 }
00199 return isWeak;
00200 }
00201
00202 bool PhysicalLayer::captureSignal(double signalStrength) const
00203 {
00204 bool isSufficientlyStrong = (signalStrength > getRxThreshold());
00205
00206 if(isSufficientlyStrong) {
00207 double interferenceFloor = getCulmulativeSignalStrength() +
00208 getNoiseFloor();
00209 double sinr = signalStrength / interferenceFloor;
00216 isSufficientlyStrong &= (sinr > getCaptureThreshold());
00217 if(m_DEBUG_SIGNAL_CAPTURE) {
00218 ostringstream debugStream;
00219 debugStream << __PRETTY_FUNCTION__ <<
00220 ": NodeId: " << getNodeId() <<
00221 " SINR: " << sinr <<
00222 " SS: " << signalStrength <<
00223 " RxThreshold: " << getRxThreshold() <<
00224 " CsThreshold: " << getCsThreshold() <<
00225 " captureThresh: " << getCaptureThreshold() <<
00226 " INTR: " << interferenceFloor <<
00227 " culmulative: " << getCulmulativeSignalStrength() <<
00228 " noise: " << getNoiseFloor();
00229 LogStreamManager::instance()->logDebugItem(debugStream.str());
00230 }
00231 }
00232 return isSufficientlyStrong;
00233 }
00234
00235 double PhysicalLayer::getCulmulativeSignalStrength() const
00236 {
00237 double culmulativeStrength = 0;
00238 SignalStrengthMap::const_iterator mapIterator;
00239 for(mapIterator = m_signalStrengths.begin();
00240 mapIterator != m_signalStrengths.end(); ++mapIterator) {
00241 culmulativeStrength += mapIterator->second;
00242 }
00243 return culmulativeStrength;
00244 }
00245
00246 void PhysicalLayer::setPendingSignal(WirelessCommSignalPtr signal)
00247 {
00248 assert(signal.get() != 0);
00249 m_pendingRecvSignal = signal;
00250 }
00251
00252 ConstWirelessCommSignalPtr PhysicalLayer::getPendingSignal() const
00253 {
00254 return m_pendingRecvSignal;
00255 }
00256
00257 double PhysicalLayer::getPendingSignalStrength()
00258 {
00259 double signalStrength = 0.0;
00260 if(m_pendingRecvSignal.get() != 0) {
00261 SignalStrengthMap::iterator mapIterator =
00262 m_signalStrengths.find(m_pendingRecvSignal);
00263
00264 bool wasFound = (mapIterator != m_signalStrengths.end());
00265 assert(wasFound);
00266 signalStrength = mapIterator->second;
00267 }
00268
00269 return signalStrength;
00270 }
00271
00272 void PhysicalLayer::resetPendingSignal()
00273 {
00274 m_pendingRecvSignalError = false;
00275 m_pendingRecvSignal.reset();
00276 }
00277
00278 void PhysicalLayer::resetRecvSignals()
00279 {
00280 resetPendingSignal();
00281 m_signalStrengths.empty();
00282 }
00283
00284 bool PhysicalLayer::channelCarrierSensedBusy() const
00285 {
00286 bool isBusy = (getCulmulativeSignalStrength() > getCsThreshold());
00287 return isBusy;
00288 }
00289
00290 Location PhysicalLayer::getLocation() const
00291 {
00292 return getNode()->getLocation();
00293 }
00294