physical_layer.cpp

00001 
00002 #include "physical_layer.hpp"
00003 #include "node.hpp"
00004 #include "packet.hpp"
00005 
00006 // These values are from a variety of sources, most
00007 // notably Alien and EPCglobal.
00008 
00009 // Alien ALR-9800: 30 dBm RF Power == 1 Watt
00010 const double PhysicalLayer::m_DEFAULT_TX_POWER = 1.0;
00011 const double PhysicalLayer::m_DEFAULT_MAX_TX_POWER = 1.0;
00012 // This is based on published reports that the received
00013 // power should be 100 to 400 microwatts for commercial tags.
00014 // www.enigmatic-consulting.com/Communications_articles/
00015 // RFID/Link_budgets.html
00016 const double PhysicalLayer::m_DEFAULT_RX_THRESHOLD = 100e-6;
00017 // In ns-2 the default ratio between CS and RX is about a
00018 // factor of 23.
00019 const double PhysicalLayer::m_DEFAULT_CS_THRESHOLD = 5e-6;
00020 // This is from ns-2
00021 const double PhysicalLayer::m_DEFAULT_CAPTURE_THRESHOLD = 10;
00022 // This is -111 dBm, which is the thermal noise floor for
00023 // GPS signals and the default for Qualnet
00024 const double PhysicalLayer::m_DEFAULT_MINIMUM_SIGNAL_STRENGTH = 7.94e-12;
00025 // EPCglobal: 26.7 to 128 kbps for reader
00026 // 40 to 640 kbps or 5 to 320 kbps for tag depending on modulation
00027 const double PhysicalLayer::m_DEFAULT_DATA_RATE = 128e3;
00028 // EPCglobal: 860 to 960 MHz
00029 const double PhysicalLayer::m_DEFAULT_BANDWIDTH = 960e6;
00030 
00031 // Temperature is in Kelvins
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    // By default, just pass the signals packet on to the
00069    // default upper layer if it's not in error.
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    // The physical layer should not have a lower communication
00095    // layer from which to receive.  Its lower layer is a channel
00096    // which is not a CommunicationLayer subclass.
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          // We replace the existing signal strength with a new
00155          // signal strength.
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    //int numErased = m_signalStrengths.erase(signal);
00168    //bool wasRemoved = (numErased > 0);
00169 }
00170 
00171 double PhysicalLayer::getPendingSignalSinr()
00172 {
00173    // This is similar to the captureSignal function except
00174    // that the signal strength in consideration, that of the
00175    // pending signal, is already included in the culmulative
00176    // signal strength.  So, we need to subtract that signal
00177    // strength out of the culmulative signal strength and
00178    // use it for the numerator.  
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    // Note that this function returns
00193    // true if the signal is too weak, whereas captureSignal
00194    // returns true if the signal is sufficiently strong.
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 

Generated on Tue Dec 12 17:04:38 2006 for rfidsim by  doxygen 1.4.7