rfid_tag_mac.cpp

00001 
00002 #include "rfid_tag_mac.hpp"
00003 #include "rfid_tag_app.hpp"
00004 #include "rfid_reader_mac.hpp"
00005 #include "rand_num_generator.hpp"
00006 #include "simulator.hpp"
00007 #include "log_stream_manager.hpp"
00008 
00009 const double RfidTagMac::m_TAG_GENERIC_IFS = 15e-6;
00010 const double RfidTagMac::m_TAG_REPLY_IFS = 20e-6;
00011 
00012 RfidTagMac::RfidTagMac(NodePtr node, RfidTagAppPtr tagApp)
00013    : SlottedMac(node), m_tagApp(tagApp)
00014 {
00015    setSlotTime(SimTime(m_DEFAULT_SLOT_TIME));
00016 }
00017 
00018 RfidTagMac::~RfidTagMac()
00019 {
00020 
00021 }
00022 
00023 void RfidTagMac::simulationEndHandler()
00024 {
00025 
00026 }
00027 
00028 void RfidTagMac::beginSlotEvent()
00029 {
00030    if(m_currentSlotNumber == m_txSlotNumber) {
00031       if(m_packetToTransmit.get() != 0) {
00032 
00033          // Set the IFS delay based on the packet type.
00034          double ifsDelay = m_TAG_GENERIC_IFS;
00035          if(isPacketType(m_packetToTransmit, RfidTagMacData::Types_Reply))
00036             ifsDelay = m_TAG_REPLY_IFS;
00037 
00038          startSendTimer(CommunicationLayer::Directions_Lower, 
00039             m_packetToTransmit, ifsDelay);
00040          m_packetToTransmit.reset();
00041       }
00042    } else if(m_numberOfSlots == 0 || 
00043          m_currentSlotNumber >= (m_numberOfSlots - 1)) {
00044       // If the current slot is m_numberOfSlots - 1, then
00045       // we've reached the last slot and we didn't transmit
00046       // in it, so we can stop.
00047       assert(m_packetToTransmit.get() == 0);
00048       stopContentionCycle();
00049       unblockUpperQueues();
00050    }
00051 
00052    m_currentSlotNumber++;
00053    assert(m_slotTimer.get() != 0);
00054    m_slotTimer->reschedule(getSlotTime());
00055 }
00056 
00057 void RfidTagMac::handleChannelBusy(PacketPtr packet)
00058 {
00059    if(isPacketType(packet, RfidTagMacData::Types_Reply))
00060       stopContentionCycle();
00061    unblockUpperQueues();
00062 }
00063 
00064 void RfidTagMac::handlePacketSent(PacketPtr packet)
00065 {
00066    if(isPacketType(packet, RfidTagMacData::Types_Generic)) {
00067       stopContentionCycle();
00068       unblockUpperQueues();
00069    }
00070 }
00071 
00072 bool RfidTagMac::isPacketType(PacketPtr packet, 
00073    RfidTagMacData::Types type) const
00074 {
00075    bool isType = false;
00076    RfidTagMacDataPtr macData =
00077       boost::dynamic_pointer_cast<RfidTagMacData>
00078       (packet->getData(Packet::DataTypes_Link));
00079    if(macData.get() != 0 && macData->getType() == type) {
00080       isType = true;
00081    }
00082    return isType;
00083 }
00084 
00085 PacketPtr RfidTagMac::createReplyPacket(NodeId receiverId) const
00086 {
00087    RfidTagMacDataPtr macData = RfidTagMacData::create();
00088    macData->setType(RfidTagMacData::Types_Reply);
00089    macData->setSenderId(getNode()->getNodeId());
00090    macData->setReceiverId(receiverId);
00091    PacketPtr packet = Packet::create();
00092    packet->addData(Packet::DataTypes_Link, *macData);
00093    return packet;
00094 }
00095 
00096 bool RfidTagMac::handleRequestPacket(RfidReaderMacDataPtr macData, 
00097    t_uint sendingLayerIdx)
00098 {
00099    if(!inContentionCycle()) {
00100       // Reset the current cycle
00101       m_currentSlotNumber = 0;
00102       // Get the number of slots from the read packet
00103       m_numberOfSlots = macData->getNumberOfSlots();
00104       // We must have at least: (1) a contention slot,
00105       // (2) a slot for the SELECT to be sent by the ready,
00106       // (3) a slot for the tag to reply with an app packet,
00107       // (4) a slot for the reader to reply with an ACK.
00108       assert(m_numberOfSlots >= 4);
00109       // Choose a slot uniformly at random.
00110       if(m_numberOfSlots > 0) {
00111          RandNumGeneratorPtr rand = 
00112             Simulator::instance()->getRandNumGenerator();
00113          m_txSlotNumber = rand->uniformInt(0, m_numberOfSlots - 4);
00114          assert(m_packetToTransmit.get() == 0);
00115          if(m_tagApp->getReplyToReads()) {
00116             // Only create a reply packet if the tag state
00117             // allows it to reply.
00118             m_packetToTransmit = 
00119                createReplyPacket(macData->getSenderId());
00120             if(m_DEBUG) {
00121                ostringstream debugStream;
00122                debugStream << __PRETTY_FUNCTION__ <<
00123                " nodeId=" << getNode()->getNodeId() <<
00124                ", txSlotNumber=" << m_txSlotNumber <<
00125                ", currentSlot=" << m_currentSlotNumber;
00126                LogStreamManager::instance()->logDebugItem(
00127                   debugStream.str());
00128             } // end if DEBUG
00129          } // end if tag can reply
00130       } // end if number of slots > 0
00131    } // end in contention cycle
00132    return true;
00133 }
00134 
00135 bool RfidTagMac::packetIsForMe(RfidReaderMacDataPtr macData) const
00136 {
00137    return (macData->getReceiverId() == getNode()->getNodeId() ||
00138       macData->getReceiverId() == NodeId::broadcastDestination());
00139 }
00140 
00141 bool RfidTagMac::handleRecvdMacPacket(PacketPtr packet,
00142    t_uint sendingLayerIdx)
00143 {
00144    RfidReaderMacDataPtr macData =
00145       boost::dynamic_pointer_cast<RfidReaderMacData>
00146       (packet->getData(Packet::DataTypes_Link));
00147 
00148    bool wasSuccessful = true;
00149 
00150    // For now, we'll only handle reader packets.
00151    if(macData.get() != 0) {
00152       switch(macData->getType()) {
00153       case RfidReaderMacData::Types_Request:
00154          assert(macData->getReceiverId() == 
00155             NodeId::broadcastDestination());
00156          wasSuccessful = handleRequestPacket(macData, sendingLayerIdx);
00157          break;
00158       case RfidReaderMacData::Types_Select:
00159          if(macData->getReceiverId() == getNode()->getNodeId()) {
00160             // If we were selected for a slot, send the packet
00161             // to the upper layer.
00162             wasSuccessful = sendToLinkLayer(
00163                CommunicationLayer::Directions_Upper, packet);
00164          } else {
00165             // Otherwise, stop the contention cycle
00166             stopContentionCycle();
00167             m_packetToTransmit.reset();
00168             unblockUpperQueues();
00169          }
00170          break;
00171       case RfidReaderMacData::Types_Generic:
00172          if(packetIsForMe(macData)) {
00173             // Just pass the packet to upper layers.
00174             wasSuccessful = sendToLinkLayer(
00175                CommunicationLayer::Directions_Upper, packet);
00176          }
00177          break;
00178       case RfidReaderMacData::Types_Ack:
00179          // We'll set the reply bit here.
00180          // If the ACK is received, then we stop replying
00181          // until a reset packet is received.
00182          if(packetIsForMe(macData))
00183             m_tagApp->setReplyToReads(false);
00184          break;
00185       default:
00186          wasSuccessful = false;
00187          assert(false);
00188       } // end switch
00189    } // end packet is not null
00190    
00191    return wasSuccessful;
00192 }
00193 
00194 
00195 void RfidTagMac::addGenericHeader(PacketPtr packet,
00196    NodeId receiverId) const
00197 {
00198    RfidTagMacDataPtr macData = RfidTagMacData::create();
00199    macData->setType(RfidTagMacData::Types_Generic);
00200    macData->setSenderId(getNode()->getNodeId());
00201    macData->setReceiverId(receiverId);
00202    packet->addData(Packet::DataTypes_Link, *macData);
00203 }
00204 
00205 bool RfidTagMac::handleRecvdUpperLayerPacket(PacketPtr packet,
00206    t_uint sendingLayerIdx)
00207 {
00208    RfidTagAppDataPtr appData =
00209       boost::dynamic_pointer_cast<RfidTagAppData>
00210       (packet->getData(Packet::DataTypes_Application));
00211 
00212    bool wasSuccessful = false;
00213 
00214    // For now, we only handle application packets.
00215    if(appData.get() != 0) {
00216       // We'll only handle one packet at a time.
00217       blockUpperQueues();
00218       assert(m_packetToTransmit.get() == 0);
00219       // This should be an ID packet and it should be
00220       // sent immediately since the node has already
00221       // won its contention period.
00222       // The underlying assumptions are:
00223       // 1. That this packet
00224       // reaches the MAC fast enough that it is sent in
00225       // the next slot after the select packet was received.
00226       // 2. That this is the packet generated in response
00227       // to the select packet.
00228       m_packetToTransmit = packet;
00229       addGenericHeader(packet, packet->getDestination());
00230       // The current slot number is incremented at the end
00231       // of the beginSlot function.  So, this will cause
00232       // the packet to be transmitted in the next slot.
00233       m_txSlotNumber = m_currentSlotNumber;
00234       if(m_DEBUG) {
00235          ostringstream debugStream;
00236          debugStream << __PRETTY_FUNCTION__ <<
00237          " txSlot=" << m_txSlotNumber <<
00238          ", currentSlot=" << m_currentSlotNumber <<
00239          ", numberOfSlots=" << m_numberOfSlots;
00240          LogStreamManager::instance()->logDebugItem(
00241             debugStream.str());
00242       }
00243 
00244       assert(m_slotTimer.get() != 0 && 
00245          m_slotTimer->isRunning() && inContentionCycle());
00246    }
00247    return wasSuccessful;
00248 }
00249 
00251 // RfidTagMacData Class
00253 
00254 RfidTagMacData::RfidTagMacData()
00255    : m_type(RfidTagMacData::Types_Generic)
00256 {
00257    fill(m_senderId, &m_senderId[m_senderIdBytes], 0);
00258    fill(m_receiverId, &m_receiverId[m_receiverIdBytes], 0);
00259 }
00260 
00261 RfidTagMacData::RfidTagMacData(const RfidTagMacData& rhs)
00262    : PacketData(rhs), m_type(rhs.m_type)
00263 {
00264    copy(rhs.m_senderId, &rhs.m_senderId[m_senderIdBytes], m_senderId);
00265    copy(rhs.m_receiverId, &rhs.m_receiverId[m_receiverIdBytes], 
00266       m_receiverId);
00267 }
00268 
00269 PacketDataPtr RfidTagMacData::clone() const
00270 {
00271     PacketDataPtr p(new RfidTagMacData(*this));
00272     return p;
00273 }
00274 
00275 void RfidTagMacData::setSenderId(const NodeId& nodeId)
00276 {
00277    nodeId.writeToByteArray(m_senderId, m_senderIdBytes);
00278 }
00279 
00280 NodeId RfidTagMacData::getSenderId() const
00281 {
00282    NodeId nodeId(m_senderId, m_senderIdBytes);
00283    return nodeId;
00284 }
00285 
00286 void RfidTagMacData::setReceiverId(const NodeId& nodeId)
00287 {
00288    nodeId.writeToByteArray(m_receiverId, m_receiverIdBytes);
00289 }
00290 
00291 NodeId RfidTagMacData::getReceiverId() const
00292 {
00293    NodeId nodeId(m_receiverId, m_receiverIdBytes);
00294    return nodeId;
00295 }
00296 
00297 

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