00001
00002 #include "rfid_reader_mac.hpp"
00003 #include "packet.hpp"
00004 #include "rfid_tag_mac.hpp"
00005 #include "rfid_reader_app.hpp"
00006 #include "log_stream_manager.hpp"
00007
00008 const double RfidReaderMac::m_READER_IFS = 10e-6;
00009 const t_uint RfidReaderMac::m_DEFAULT_NUMBER_OF_SLOTS = 10;
00010 const double RfidReaderMac::m_DEFAULT_CYCLE_TIME = 5.25;
00011 const t_uint RfidReaderMac::m_MISSED_READ_THRESHOLD = 3;
00012
00013 const string RfidReaderMac::m_MISSED_READ_TOTAL_STRING = "missedReadTotal";
00014 const string RfidReaderMac::m_MISSED_READ_SLOT_AVG_STRING = "missedReadSlotAvg";
00015 const string RfidReaderMac::m_WINNING_SLOT_AVG_STRING = "winningSlotAvg";
00016
00017 RfidReaderMac::RfidReaderMac(NodePtr node, RfidReaderAppPtr readerApp)
00018 : SlottedMac(node),
00019 m_doResetSlot(false), m_resetSlotNumber(0),
00020 m_doEntireReadCycle(false), m_missedReadCount(0),
00021 m_nextCycleNumberOfSlots(m_DEFAULT_NUMBER_OF_SLOTS),
00022 m_nextCycleTime(m_DEFAULT_CYCLE_TIME), m_readerApp(readerApp)
00023 {
00024 setSlotTime(SimTime(m_DEFAULT_SLOT_TIME));
00025 }
00026
00027 RfidReaderMac::~RfidReaderMac()
00028 {
00029
00030 }
00031
00032 void RfidReaderMac::simulationEndHandler()
00033 {
00034 t_uint missedReadSlotSum = 0;
00035 for(t_uint i = 0; i < m_missedReads.size(); ++i) {
00036 missedReadSlotSum += m_missedReads[i];
00037 }
00038 double missedReadSlotAvg = 0.0;
00039 if(m_missedReads.size() > 0)
00040 missedReadSlotAvg = static_cast<double>(missedReadSlotSum) /
00041 m_missedReads.size();
00042
00043 ostringstream missedReadTotalStream;
00044 missedReadTotalStream << m_missedReads.size();
00045 LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),
00046 m_MISSED_READ_TOTAL_STRING, missedReadTotalStream.str());
00047
00048 ostringstream missedReadSlotAvgStream;
00049 missedReadSlotAvgStream << missedReadSlotAvg;
00050 LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),
00051 m_MISSED_READ_SLOT_AVG_STRING, missedReadSlotAvgStream.str());
00052
00053 t_uint winningSlotSum = 0;
00054 for(t_uint i = 0; i < m_winningSlotNumbers.size(); ++i) {
00055 winningSlotSum += m_winningSlotNumbers[i].second;
00056 }
00057 double winningSlotAvg = 0.0;
00058 if(m_winningSlotNumbers.size() > 0)
00059 winningSlotAvg = static_cast<double>(winningSlotSum) /
00060 m_winningSlotNumbers.size();
00061
00062 ostringstream winningSlotAvgStream;
00063 winningSlotAvgStream << winningSlotAvg;
00064 LogStreamManager::instance()->logStatsItem(getNode()->getNodeId(),
00065 m_WINNING_SLOT_AVG_STRING, winningSlotAvgStream.str());
00066
00067 }
00068
00069 bool RfidReaderMac::isEnoughTimeForContentionCycle() const
00070 {
00071
00072
00073 double nextContentionCycleTime =
00074 (m_nextCycleNumberOfSlots + 1) * m_DEFAULT_SLOT_TIME;
00075
00076 if(m_DEBUG_CONTENTION_CYCLE_TIME) {
00077 SimTime timeRemaining = m_cycleTimer->timeRemaining();
00078 if(timeRemaining > 0.0) {
00079 ostringstream debugStream;
00080 debugStream << __PRETTY_FUNCTION__ <<
00081 " nextCycleTime=" << nextContentionCycleTime <<
00082 ", readCycleRemaining=" << timeRemaining;
00083 LogStreamManager::instance()->logDebugItem(
00084 debugStream.str());
00085 }
00086 }
00087
00088 return (SimTime(nextContentionCycleTime) <
00089 m_cycleTimer->timeRemaining());
00090 }
00091
00092 void RfidReaderMac::beginSlotEvent()
00093 {
00094
00095
00096
00097
00098
00099 if(m_currentSlotNumber == m_txSlotNumber) {
00100 if(m_packetToTransmit.get() != 0) {
00101 if(m_DEBUG) {
00102 ostringstream debugStream;
00103 debugStream << __PRETTY_FUNCTION__ <<
00104 " is enough time, txSlot=" << m_txSlotNumber <<
00105 ", currentSlot=" << m_currentSlotNumber;
00106 LogStreamManager::instance()->logDebugItem(
00107 debugStream.str());
00108 }
00109
00110 startSendTimer(CommunicationLayer::Directions_Lower,
00111 m_packetToTransmit, m_READER_IFS);
00112 m_packetToTransmit.reset();
00113 }
00114 } else if(m_numberOfSlots == 0 ||
00115 m_currentSlotNumber >= m_numberOfSlots ||
00116 (m_doResetSlot && m_currentSlotNumber == m_resetSlotNumber)) {
00117
00118
00119
00120
00121
00122
00123
00124
00125 assert(m_packetToTransmit.get() == 0);
00126
00127 ostringstream debugStream;
00128 debugStream << __PRETTY_FUNCTION__ <<
00129 " currentSlot: " << m_currentSlotNumber << " resetSlot: " <<
00130 m_resetSlotNumber << " numSlots: " << m_numberOfSlots <<
00131 " missedReadCount: " << m_missedReadCount <<
00132 boolalpha << " doReset: " << m_doResetSlot <<
00133 " isEnoughCycleTime: " << isEnoughTimeForContentionCycle();
00134 LogStreamManager::instance()->logDebugItem(
00135 debugStream.str());
00136
00137
00138
00139
00140
00141 if(!m_doEntireReadCycle && m_cycleTimer->isRunning()) {
00142 m_missedReads.push_back(m_currentSlotNumber);
00143 m_missedReadCount++;
00144 } else
00145 m_missedReadCount = 0;
00146
00147 m_doResetSlot = false;
00148
00149 stopContentionCycle();
00150
00151 if(!m_doEntireReadCycle &&
00152 m_missedReadCount == m_MISSED_READ_THRESHOLD) {
00153
00154
00155 assert(m_cycleTimer->isRunning());
00156
00157
00158 m_cycleTimer->stop();
00159 endRequestCycleEvent();
00160 } else {
00161 if(isEnoughTimeForContentionCycle()) {
00162 m_packetToTransmit = createRequestPacket();
00163
00164
00165
00166 m_txSlotNumber = m_currentSlotNumber + 1;
00167 } else if(!m_cycleTimer->isRunning()) {
00168 assert(!getQueueIsBlocked());
00169 }
00170 }
00171 }
00172
00173 m_currentSlotNumber++;
00174 assert(m_slotTimer.get() != 0);
00175 m_slotTimer->reschedule(getSlotTime());
00176 }
00177
00178 void RfidReaderMac::endRequestCycleEvent()
00179 {
00180 assert(!inContentionCycle());
00181 m_currentAppReadPacket.reset();
00182 unblockUpperQueues();
00183 m_readerApp->signalReadEnd();
00184 }
00185
00186 void RfidReaderMac::handleChannelBusy(PacketPtr packet)
00187 {
00188
00189
00190 if(!isPacketType(packet, RfidReaderMacData::Types_Request) &&
00191 !isPacketType(packet, RfidReaderMacData::Types_Select)) {
00192 unblockUpperQueues();
00193 }
00194 }
00195
00196 void RfidReaderMac::handlePacketSent(PacketPtr packet)
00197 {
00198 if(isPacketType(packet, RfidReaderMacData::Types_Request)) {
00199
00200 m_currentSlotNumber = 0;
00201 RfidReaderMacDataPtr macData =
00202 boost::dynamic_pointer_cast<RfidReaderMacData>
00203 (packet->getData(Packet::DataTypes_Link));
00204 assert(macData.get() != 0);
00205 m_numberOfSlots = macData->getNumberOfSlots();
00206 } else if(isPacketType(packet, RfidReaderMacData::Types_Select)) {
00207 m_doResetSlot = true;
00208
00209
00210
00211 m_resetSlotNumber = m_currentSlotNumber + 1;
00212
00213
00214
00215
00216 } else if(isPacketType(packet, RfidReaderMacData::Types_Ack)) {
00217 if(isEnoughTimeForContentionCycle()) {
00218 startNextContentionCycle();
00219 }
00220 } else {
00221 unblockUpperQueues();
00222 }
00223 }
00224
00225 bool RfidReaderMac::isPacketType(PacketPtr packet,
00226 RfidReaderMacData::Types type) const
00227 {
00228 bool isType = false;
00229 RfidReaderMacDataPtr macData =
00230 boost::dynamic_pointer_cast<RfidReaderMacData>
00231 (packet->getData(Packet::DataTypes_Link));
00232 if(macData.get() != 0 && macData->getType() == type) {
00233 isType = true;
00234 }
00235 return isType;
00236 }
00237
00238 bool RfidReaderMac::packetIsForMe(RfidTagMacDataPtr macData) const
00239 {
00240 return (macData->getReceiverId() == getNode()->getNodeId() ||
00241 macData->getReceiverId() == NodeId::broadcastDestination());
00242 }
00243
00244 void RfidReaderMac::startNextContentionCycle()
00245 {
00246
00247 if(m_packetToTransmit.get() != 0) {
00248 ostringstream debugStream;
00249 debugStream << __PRETTY_FUNCTION__ << *m_packetToTransmit <<
00250 " curSlot: " << m_currentSlotNumber << ", numSlots: " <<
00251 m_numberOfSlots;
00252 LogStreamManager::instance()->logDebugItem(
00253 debugStream.str());
00254 }
00255 assert(m_packetToTransmit.get() == 0);
00256 m_packetToTransmit = createRequestPacket();
00257 m_missedReadCount = 0;
00258 m_doResetSlot = false;
00259
00260 stopContentionCycle();
00261 m_txSlotNumber = m_currentSlotNumber;
00262 }
00263
00264 bool RfidReaderMac::handleRecvdMacPacket(PacketPtr packet,
00265 t_uint sendingLayerIdx)
00266 {
00267 RfidTagMacDataPtr macData =
00268 boost::dynamic_pointer_cast<RfidTagMacData>
00269 (packet->getData(Packet::DataTypes_Link));
00270
00271 bool wasSuccessful = true;
00272
00273
00274 if(macData.get() != 0) {
00275 if(packetIsForMe(macData)) {
00276 switch(macData->getType()) {
00277 case RfidTagMacData::Types_Reply:
00278
00279
00280
00281
00282 if(m_cycleTimer->isRunning()) {
00283
00284
00285
00286
00287
00288
00289
00290
00291 if(m_packetToTransmit.get() == 0) {
00292 assert(m_currentAppReadPacket.get() != 0);
00293
00294
00295 addSelectHeader(m_currentAppReadPacket,
00296 macData->getSenderId());
00297 m_packetToTransmit = m_currentAppReadPacket;
00298 m_txSlotNumber = m_currentSlotNumber;
00299 assert(m_slotTimer.get() != 0 &&
00300 m_slotTimer->isRunning());
00301 }
00302 }
00303 break;
00304 case RfidTagMacData::Types_Generic:
00305
00306
00307
00308
00309
00310
00311 m_winningSlotNumbers.push_back(
00312 make_pair(macData->getSenderId(),
00313 (m_currentSlotNumber - 3)));
00314
00315 wasSuccessful = sendToLinkLayer(
00316 CommunicationLayer::Directions_Upper, packet);
00317 m_packetToTransmit = createAckPacket(macData->getSenderId());
00318 m_txSlotNumber = m_currentSlotNumber;
00319 assert(m_slotTimer.get() != 0 &&
00320 m_slotTimer->isRunning());
00321 break;
00322 default:
00323 wasSuccessful = false;
00324 }
00325 }
00326 }
00327
00328 return wasSuccessful;
00329 }
00330
00331 PacketPtr RfidReaderMac::createRequestPacket() const
00332 {
00333 RfidReaderMacDataPtr macData = RfidReaderMacData::create();
00334 macData->setType(RfidReaderMacData::Types_Request);
00335 macData->setSenderId(getNode()->getNodeId());
00336 macData->setReceiverId(NodeId::broadcastDestination());
00337
00338
00339
00340
00341 assert(m_nextCycleNumberOfSlots >= 4);
00342 macData->setNumberOfSlots(m_nextCycleNumberOfSlots);
00343 PacketPtr packet = Packet::create();
00344 assert(m_currentAppReadPacket.get() != 0);
00345 packet->setTxPower(m_currentAppReadPacket->getTxPower());
00346 packet->addData(Packet::DataTypes_Link, *macData);
00347 return packet;
00348 }
00349
00350 PacketPtr RfidReaderMac::createAckPacket(NodeId destination) const
00351 {
00352 RfidReaderMacDataPtr macData = RfidReaderMacData::create();
00353 macData->setType(RfidReaderMacData::Types_Ack);
00354 macData->setSenderId(getNode()->getNodeId());
00355 macData->setReceiverId(destination);
00356
00357 PacketPtr packet = Packet::create();
00358 packet->setDoMaxTxPower(true);
00359 packet->addData(Packet::DataTypes_Link, *macData);
00360 return packet;
00361 }
00362
00363 void RfidReaderMac::addGenericHeader(PacketPtr packet,
00364 NodeId receiverId) const
00365 {
00366 RfidReaderMacDataPtr macData = RfidReaderMacData::create();
00367 macData->setType(RfidReaderMacData::Types_Generic);
00368 macData->setSenderId(getNode()->getNodeId());
00369 macData->setReceiverId(receiverId);
00370 packet->addData(Packet::DataTypes_Link, *macData);
00371 }
00372
00373 void RfidReaderMac::addSelectHeader(PacketPtr packet,
00374 NodeId receiverId) const
00375 {
00376 RfidReaderMacDataPtr macData = RfidReaderMacData::create();
00377 macData->setType(RfidReaderMacData::Types_Select);
00378 macData->setSenderId(getNode()->getNodeId());
00379 macData->setReceiverId(receiverId);
00380 packet->setDoMaxTxPower(true);
00381 packet->addData(Packet::DataTypes_Link, *macData);
00382 }
00383
00384 bool RfidReaderMac::handleRecvdUpperLayerPacket(PacketPtr packet,
00385 t_uint sendingLayerIdx)
00386 {
00387 RfidReaderAppDataPtr appData =
00388 boost::dynamic_pointer_cast<RfidReaderAppData>
00389 (packet->getData(Packet::DataTypes_Application));
00390
00391 bool wasSuccessful = false;
00392
00393 if(m_DEBUG) {
00394 ostringstream debugStream;
00395 debugStream << __PRETTY_FUNCTION__;
00396 LogStreamManager::instance()->logDebugItem(
00397 debugStream.str());
00398 }
00399
00400
00401 if(appData.get() != 0) {
00402 switch(appData->getType()) {
00403 case RfidReaderAppData::Types_Read:
00404
00405 blockUpperQueues();
00406
00407 assert(m_currentAppReadPacket.get() == 0);
00408 m_currentAppReadPacket = packet;
00409 m_doEntireReadCycle = appData->getDoEntireReadCycle();
00410
00411 assert(m_cycleTimer.get() != 0);
00412 m_cycleTimer->start(m_nextCycleTime);
00413 if(isEnoughTimeForContentionCycle()) {
00414 startNextContentionCycle();
00415 }
00416 wasSuccessful = true;
00417 break;
00418 case RfidReaderAppData::Types_Reset:
00419
00420 blockUpperQueues();
00421
00422 assert(m_packetToTransmit == 0);
00423 addGenericHeader(packet, NodeId::broadcastDestination());
00424 m_packetToTransmit = packet;
00425 m_txSlotNumber = m_currentSlotNumber;
00426 wasSuccessful = true;
00427 break;
00428 default:
00429 wasSuccessful = false;
00430 }
00431 assert(m_slotTimer.get() != 0 && m_slotTimer->isRunning());
00432 }
00433
00434 return wasSuccessful;
00435 }
00436
00438
00440
00441 RfidReaderMacData::RfidReaderMacData()
00442 : m_numberOfSlots(0), m_type(RfidReaderMacData::Types_Generic)
00443 {
00444 fill(m_senderId, &m_senderId[m_senderIdBytes], 0);
00445 fill(m_receiverId, &m_receiverId[m_receiverIdBytes], 0);
00446 }
00447
00448 RfidReaderMacData::RfidReaderMacData(const RfidReaderMacData& rhs)
00449 : PacketData(rhs), m_numberOfSlots(rhs.m_numberOfSlots),
00450 m_type(rhs.m_type)
00451 {
00452 copy(rhs.m_senderId, &rhs.m_senderId[m_senderIdBytes], m_senderId);
00453 copy(rhs.m_receiverId, &rhs.m_receiverId[m_receiverIdBytes],
00454 m_receiverId);
00455 }
00456
00457 PacketDataPtr RfidReaderMacData::clone() const
00458 {
00459 PacketDataPtr p(new RfidReaderMacData(*this));
00460 return p;
00461 }
00462
00463 void RfidReaderMacData::setSenderId(const NodeId& nodeId)
00464 {
00465 nodeId.writeToByteArray(m_senderId, m_senderIdBytes);
00466 }
00467
00468 NodeId RfidReaderMacData::getSenderId() const
00469 {
00470 NodeId nodeId(m_senderId, m_senderIdBytes);
00471 return nodeId;
00472 }
00473
00474 void RfidReaderMacData::setReceiverId(const NodeId& nodeId)
00475 {
00476 nodeId.writeToByteArray(m_receiverId, m_receiverIdBytes);
00477 }
00478
00479 NodeId RfidReaderMacData::getReceiverId() const
00480 {
00481 NodeId nodeId(m_receiverId, m_receiverIdBytes);
00482 return nodeId;
00483 }
00484
00485