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 SimulatorLink::sendData(PacketPtr data) { // Create a copy, or we get the really wierd situation where updating the number of // hops on one router will change all copies of the packet, even those in transit! PacketPtr ptr = std::make_shared<Packet>(data->getData(), data->getDataLength()); sendQueue.push(ptr); return true; }
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::handleRecvdUpperLayerPacket(PacketPtr packet, t_uint sendingLayerIdx) { RfidReaderAppDataPtr appData = boost::dynamic_pointer_cast<RfidReaderAppData> (packet->getData(Packet::DataTypes_Application)); bool wasSuccessful = false; if(m_DEBUG) { ostringstream debugStream; debugStream << __PRETTY_FUNCTION__; LogStreamManager::instance()->logDebugItem( debugStream.str()); } // For now, we only handle application packets. if(appData.get() != 0) { switch(appData->getType()) { case RfidReaderAppData::Types_Read: // We'll only handle one packet at a time blockUpperQueues(); assert(m_currentAppReadPacket.get() == 0); m_currentAppReadPacket = packet; m_doEntireReadCycle = appData->getDoEntireReadCycle(); // Start cycle timer assert(m_cycleTimer.get() != 0); m_cycleTimer->start(m_nextCycleTime); if(isEnoughTimeForContentionCycle()) { startNextContentionCycle(); } wasSuccessful = true; break; case RfidReaderAppData::Types_Reset: // We'll only handle one packet at a time blockUpperQueues(); assert(m_packetToTransmit == 0); addGenericHeader(packet, NodeId::broadcastDestination()); m_packetToTransmit = packet; m_txSlotNumber = m_currentSlotNumber; wasSuccessful = true; break; default: wasSuccessful = false; } assert(m_slotTimer.get() != 0 && m_slotTimer->isRunning()); } return wasSuccessful; }
bool RfidReaderMac::handleRecvdMacPacket(PacketPtr packet, t_uint sendingLayerIdx) { RfidTagMacDataPtr macData = boost::dynamic_pointer_cast<RfidTagMacData> (packet->getData(Packet::DataTypes_Link)); bool wasSuccessful = true; // For now, we'll only handle MAC packets from tags. if(macData.get() != 0) { if(packetIsForMe(macData)) { switch(macData->getType()) { case RfidTagMacData::Types_Reply: // If we ended the cycle early due to too many // consecutive missed reads, then the timer will // be stopped and we shouldn't handle anymore // REPLY packets. if(m_cycleTimer->isRunning()) { // It could be the case that this reply is received // in a contention cycle after the a SELECT packet // was lost. In response to the SELECT packet being // lost in slot i, the reader will reset in // slot i+2 and send a REQUEST in slot i+3. // If this reply is received in slot i+2, we should // ignore it since m_packetToTransmit already // has a REQUEST packet pending. if(m_packetToTransmit.get() == 0) { assert(m_currentAppReadPacket.get() != 0); // Send SELECT message header on the original // app packet. addSelectHeader(m_currentAppReadPacket, macData->getSenderId()); m_packetToTransmit = m_currentAppReadPacket; m_txSlotNumber = m_currentSlotNumber; assert(m_slotTimer.get() != 0 && m_slotTimer->isRunning()); } } break; case RfidTagMacData::Types_Generic: // Subtract three from the winning slot number for: // 1. The current slot number was incremented // at the beginning of the slot. // 2. The REPLY was sent two slots prior // to this packet being received (the SELECT // packet was sent one slot prior). m_winningSlotNumbers.push_back( make_pair(macData->getSenderId(), (m_currentSlotNumber - 3))); // Just pass the packet to upper layers. wasSuccessful = sendToLinkLayer( CommunicationLayer::Directions_Upper, packet); m_packetToTransmit = createAckPacket(macData->getSenderId()); m_txSlotNumber = m_currentSlotNumber; assert(m_slotTimer.get() != 0 && m_slotTimer->isRunning()); break; default: wasSuccessful = false; } } } return wasSuccessful; }