📄 rfid_reader_mac.cpp
字号:
#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 + -