⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfid_reader_mac.cpp

📁 RFID reader 语 tag 模拟器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 #include "rfid_reader_mac.hpp" #include "packet.hpp" #include "rfid_tag_mac.hpp" #include "rfid_reader_app.hpp" #include "log_stream_manager.hpp" const double RfidReaderMac::m_READER_IFS = 10e-6; const t_uint RfidReaderMac::m_DEFAULT_NUMBER_OF_SLOTS = 10; const double RfidReaderMac::m_DEFAULT_CYCLE_TIME = 5.25; const t_uint RfidReaderMac::m_MISSED_READ_THRESHOLD = 3; const string RfidReaderMac::m_MISSED_READ_TOTAL_STRING = "missedReadTotal"; const string RfidReaderMac::m_MISSED_READ_SLOT_AVG_STRING = "missedReadSlotAvg"; const string RfidReaderMac::m_WINNING_SLOT_AVG_STRING = "winningSlotAvg"; RfidReaderMac::RfidReaderMac(NodePtr node, RfidReaderAppPtr readerApp)    : SlottedMac(node),    m_doResetSlot(false), m_resetSlotNumber(0),    m_doEntireReadCycle(false), m_missedReadCount(0),    m_nextCycleNumberOfSlots(m_DEFAULT_NUMBER_OF_SLOTS),    m_nextCycleTime(m_DEFAULT_CYCLE_TIME), m_readerApp(readerApp) {    setSlotTime(SimTime(m_DEFAULT_SLOT_TIME)); } RfidReaderMac::~RfidReaderMac() { } void RfidReaderMac::simulationEndHandler() {    t_uint missedReadSlotSum = 0;    for(t_uint i = 0; i < m_missedReads.size(); ++i) {       missedReadSlotSum += m_missedReads[i];    }    double missedReadSlotAvg = 0.0;    if(m_missedReads.size() > 0)       missedReadSlotAvg = static_cast<double>(missedReadSlotSum) /          m_missedReads.size();    ostringstream missedReadTotalStream;    missedReadTotalStream << m_missedReads.size();    LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),       m_MISSED_READ_TOTAL_STRING, missedReadTotalStream.str());    ostringstream missedReadSlotAvgStream;    missedReadSlotAvgStream << missedReadSlotAvg;    LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),       m_MISSED_READ_SLOT_AVG_STRING, missedReadSlotAvgStream.str());    t_uint winningSlotSum = 0;    for(t_uint i = 0; i < m_winningSlotNumbers.size(); ++i) {       winningSlotSum += m_winningSlotNumbers[i].second;    }    double winningSlotAvg = 0.0;    if(m_winningSlotNumbers.size() > 0)       winningSlotAvg = static_cast<double>(winningSlotSum) /          m_winningSlotNumbers.size();    ostringstream winningSlotAvgStream;    winningSlotAvgStream << winningSlotAvg;    LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),       m_WINNING_SLOT_AVG_STRING, winningSlotAvgStream.str()); } bool RfidReaderMac::isEnoughTimeForContentionCycle() const {    // We need one extra slot be cycle to send the REQUEST    // packet.    double nextContentionCycleTime =    (m_nextCycleNumberOfSlots + 1) * m_DEFAULT_SLOT_TIME;    if(m_DEBUG_CONTENTION_CYCLE_TIME) {       SimTime timeRemaining = m_cycleTimer->timeRemaining();       if(timeRemaining > 0.0) {          ostringstream debugStream;          debugStream << __PRETTY_FUNCTION__ <<          " nextCycleTime=" << nextContentionCycleTime <<          ", readCycleRemaining=" << timeRemaining;          LogStreamManager::instance()->logDebugItem(             debugStream.str());       }    }    return (SimTime(nextContentionCycleTime) <          m_cycleTimer->timeRemaining()); } void RfidReaderMac::beginSlotEvent() {    // Check for a transmission slot before checking for the end    // slot.  This lets us transmit on the next slot after calling    // stopContentionCycle() without triggering the actions    // for the end slot.    if(m_currentSlotNumber == m_txSlotNumber) {       if(m_packetToTransmit.get() != 0) {          if(m_DEBUG) {             ostringstream debugStream;             debugStream << __PRETTY_FUNCTION__ <<             " is enough time, txSlot=" << m_txSlotNumber <<             ", currentSlot=" << m_currentSlotNumber;             LogStreamManager::instance()->logDebugItem(                debugStream.str());          }          startSendTimer(CommunicationLayer::Directions_Lower,             m_packetToTransmit, m_READER_IFS);          m_packetToTransmit.reset();       }    } else if(m_numberOfSlots == 0 ||          m_currentSlotNumber >= m_numberOfSlots ||          (m_doResetSlot && m_currentSlotNumber == m_resetSlotNumber)) {       // Send another request if there is sufficient time in       // the current cycle.  Note that this occurs when       // no tags were read in a contention cycle.  There is a one       // slot delay between the last slot of the previous contention       // cycle and when the next REQUEST packet gets sent.  This       // is needed to avoid stopping the contention cycle when       // a tag is transmitting data in the last slot of the       // contention cycle.       assert(m_packetToTransmit.get() == 0);       ostringstream debugStream;       debugStream << __PRETTY_FUNCTION__ <<          " currentSlot: " << m_currentSlotNumber << " resetSlot: " <<          m_resetSlotNumber << " numSlots: " << m_numberOfSlots <<          " missedReadCount: " << m_missedReadCount <<          boolalpha << " doReset: " << m_doResetSlot <<          " isEnoughCycleTime: " << isEnoughTimeForContentionCycle();       LogStreamManager::instance()->logDebugItem(          debugStream.str());       // We were unable to successfully read a packet       // in the given interval.  We only do this if we       // are currently in a read interval (i.e., the timer       // is running).       if(!m_doEntireReadCycle && m_cycleTimer->isRunning()) {          m_missedReads.push_back(m_currentSlotNumber);          m_missedReadCount++;       } else          m_missedReadCount = 0;       m_doResetSlot = false;       //cout << "stopCycle1" << endl;       stopContentionCycle();       if(!m_doEntireReadCycle &&             m_missedReadCount == m_MISSED_READ_THRESHOLD) {          // The timer should be running since, otherwise,          // the missedReadCount was reset to zero above.          assert(m_cycleTimer->isRunning());          // If we have missed too many consecutive reads, then          // we will force the current read cycle to stop.          m_cycleTimer->stop();          endRequestCycleEvent();       } else {          if(isEnoughTimeForContentionCycle()) {             m_packetToTransmit = createRequestPacket();             // Have to set this for the next slot number since             // currentSlotNumber is incremented at the end of this             // function.             m_txSlotNumber = m_currentSlotNumber + 1;          } else if(!m_cycleTimer->isRunning()) {             assert(!getQueueIsBlocked());          }       }    }    m_currentSlotNumber++;    assert(m_slotTimer.get() != 0);    m_slotTimer->reschedule(getSlotTime()); } void RfidReaderMac::endRequestCycleEvent() {    assert(!inContentionCycle());    m_currentAppReadPacket.reset();    unblockUpperQueues();    m_readerApp->signalReadEnd(); } void RfidReaderMac::handleChannelBusy(PacketPtr packet) {    // For now, we will just silently drop the packet    // rather than implement a retransmission scheme.    if(!isPacketType(packet, RfidReaderMacData::Types_Request) &&          !isPacketType(packet, RfidReaderMacData::Types_Select)) {       unblockUpperQueues();    } } void RfidReaderMac::handlePacketSent(PacketPtr packet) {    if(isPacketType(packet, RfidReaderMacData::Types_Request)) {       // Start a cycle       m_currentSlotNumber = 0;       RfidReaderMacDataPtr macData =          boost::dynamic_pointer_cast<RfidReaderMacData>          (packet->getData(Packet::DataTypes_Link));       assert(macData.get() != 0);       m_numberOfSlots = macData->getNumberOfSlots();    } else if(isPacketType(packet, RfidReaderMacData::Types_Select)) {       m_doResetSlot = true;       // m_currentSlotNumber is already set to slot i+1, so       // the resetSlotNumber should be slot i+2.  Thus, we       // add one to currentSlotNumber.       m_resetSlotNumber = m_currentSlotNumber + 1;       /*       cout << "slot: " << m_currentSlotNumber << " resetSlot: " <<          m_resetSlotNumber << endl;       */    } else if(isPacketType(packet, RfidReaderMacData::Types_Ack)) {       if(isEnoughTimeForContentionCycle()) {          startNextContentionCycle();       }    } else {       unblockUpperQueues();    } } bool RfidReaderMac::isPacketType(PacketPtr packet,    RfidReaderMacData::Types type) const {    bool isType = false;    RfidReaderMacDataPtr macData =       boost::dynamic_pointer_cast<RfidReaderMacData>       (packet->getData(Packet::DataTypes_Link));    if(macData.get() != 0 && macData->getType() == type) {       isType = true;    }    return isType; } bool RfidReaderMac::packetIsForMe(RfidTagMacDataPtr macData) const {    return (macData->getReceiverId() == getNode()->getNodeId() ||       macData->getReceiverId() == NodeId::broadcastDestination()); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -