RINASim  October 2016
Documentation of framework for OMNeT++
DTP.cc
Go to the documentation of this file.
1 // The MIT License (MIT)
2 //
3 // Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 
23 #include "DTP.h"
24 
25 const char * SIG_STAT_DTP_RTT = "DTP_RTT";
26 const char * SIG_STAT_DTP_CLOSED_WIN_Q = "DTP_CLOSED_WIN_Q";
27 const char * DTP_SEQ_NUM_RCVD = "DTP_SEQ_NUM_RCVD";
28 const char * DTP_SEQ_NUM_SENT = "DTP_SEQ_NUM_SENT";
29 
31 
33 {
34  deletePdu = 0;
35 
36  rcvrInactivityTimer = nullptr;
37  senderInactivityTimer = nullptr;
38 
39 
40  rcvrInactivityPolicy = nullptr;
41  senderInactivityPolicy = nullptr;
42  initialSeqNumPolicy = nullptr;
43  rttEstimatorPolicy = nullptr;
44 
45  state = nullptr;
46 
47  pduDroppingEnabled = false;
48 
49  sduSeqNum = 0;
50  //intentionally left out callInitialize
51 
52 }
54 {
55 
57 // delete state;
58  if (state->isDtcpPresent())
59  {
60 
61  }
62 
63 }
64 
65 cModule* DTP::createPolicyModule(const char* prefix, const char* name)
66 {
67  if (std::string(par(name).stringValue()).empty())
68  {
69  return nullptr;
70  }
71  else
72  {
73  std::stringstream moduleName;
74  moduleName << prefix << par(name).stringValue();
75  cModuleType* policyType = cModuleType::get(moduleName.str().c_str());
76  return policyType->createScheduleInit(name, getParentModule());
77  }
78 }
79 
81 {
82  Enter_Method
83  ("RTTEstimatorPolicy");
85 
86  emit(sigStatDTPRTT, state->getRtt());
87 
88 }
89 
91 {
93 }
94 
96 {
97  handleQueueInfo(queueInfo);
98 }
99 
101 {
102 }
103 
105 {
106  //Signals that this module is emmiting
107  sigEFCPStahpSending = registerSignal(SIG_EFCP_StopSending);
108  sigEFCPStartSending = registerSignal(SIG_EFCP_StartSending);
109  sigStatDTPRTT = registerSignal(SIG_STAT_DTP_RTT);
111 // sigStatDTPRxCount = registerSignal(SIG_STAT_DTP_RX_SENT);
112  sigStatDTPRecvSeqNum = registerSignal(DTP_SEQ_NUM_RCVD);
113  sigStatDTPSentSeqNum = registerSignal(DTP_SEQ_NUM_SENT);
114 }
115 
116 void DTP::initialize(int step)
117 {
118 
119  if (step == 0)
120  {
121 
122  initGates();
123  initialSeqNumPolicy = getRINAModule<InitialSeqNumPolicyBase*>(this, 1, {INITIAL_SEQ_NUM_POLICY_NAME});
124  rcvrInactivityPolicy = getRINAModule<RcvrInactivityPolicyBase*>(this, 1, {RCVR_INACTIVITY_POLICY_NAME});
125  senderInactivityPolicy = getRINAModule<SenderInactivityPolicyBase*>(this, 1, {SENDER_INACTIVITY_POLICY_NAME});
126  rttEstimatorPolicy = getRINAModule<RTTEstimatorPolicyBase*>(this, 1, {RTT_ESTIMATOR_POLICY_NAME});
127 
130 
131 
132  rendezvousEnabled = getModuleByPath(".^.^.efcp")->par("rendezvousEnabled").boolValue();
133 
134  }
135  else if (step == 1)
136  {
137 
139 
140 // if(state->isDtcpPresent()){
141 
142 // }else{
143 // senderInactivityTimer = nullptr;
144 // rcvrInactivityTimer = nullptr;
145 // }
146 
147 // par(RCVR_INACTIVITY_POLICY_NAME).setStringValue(getModuleByPath((std::string(".^.^.") + std::string(MOD_EFCP)).c_str())->par(RCVR_INACTIVITY_POLICY_NAME).stringValue());
148 // par(SENDER_INACTIVITY_POLICY_NAME).setStringValue(getModuleByPath((std::string(".^.^.") + std::string(MOD_EFCP)).c_str())->par(SENDER_INACTIVITY_POLICY_NAME).stringValue());
149 // par(INITIAL_SEQ_NUM_POLICY_NAME).setStringValue(getModuleByPath((std::string(".^.^.") + std::string(MOD_EFCP)).c_str())->par(INITIAL_SEQ_NUM_POLICY_NAME).stringValue());
150 // par(RTT_ESTIMATOR_POLICY_NAME).setStringValue(getModuleByPath((std::string(".^.^.") + std::string(MOD_EFCP)).c_str())->par(RTT_ESTIMATOR_POLICY_NAME).stringValue());
151 
152 // rcvrInactivityPolicy = (RcvrInactivityPolicyBase*) createPolicyModule(RCVR_INACTIVITY_POLICY_PREFIX,
153 // RCVR_INACTIVITY_POLICY_NAME);
154 // senderInactivityPolicy = (SenderInactivityPolicyBase*) createPolicyModule(SENDER_INACTIVITY_POLICY_PREFIX,
155 // SENDER_INACTIVITY_POLICY_NAME);
156 // initialSeqNumPolicy = (InitialSeqNumPolicyBase*) createPolicyModule(INITIAL_SEQ_NUM_POLICY_PREFIX,
157 // INITIAL_SEQ_NUM_POLICY_NAME);
158 // rttEstimatorPolicy = (RTTEstimatorPolicyBase*) createPolicyModule(RTT_ESTIMATOR_POLICY_PREFIX,
159 // RTT_ESTIMATOR_POLICY_NAME);
160 
161 // runInitialSeqNumPolicy();
162 
163 
164  bool interrupter = false;
165  interrupter = getModuleByPath(".^.^.")->par("interrupter").boolValue();
166  if(interrupter){
167 
170  scheduleAt(120, startR);
171 
174  scheduleAt(140, stopR);
175 
176  }
177 
178  //set initial value for RTO based on RTT from .ned
180 
181  }
182 
183 }
184 
186 {
187  northI = this->gateHalf(GATE_DTP_NORTHIO, cGate::INPUT);
188  northO = this->gateHalf(GATE_DTP_NORTHIO, cGate::OUTPUT);
189  southI = this->gateHalf(GATE_DTP_SOUTHIO, cGate::INPUT);
190  southO = this->gateHalf(GATE_DTP_SOUTHIO, cGate::OUTPUT);
191 }
196 const QoSCube* DTP::getQoSCube() const
197 {
198  return state->getQoSCube();
199 }
200 
205 void DTP::setQoSCube(const QoSCube* qosCube)
206 {
207  //TODO A2 Make copy; ... Why?
208  state->setQoSCube(qosCube);
209 }
210 
216 void DTP::setPduDroppingEnabled(bool pduDroppingEnabled)
217 {
218  this->pduDroppingEnabled = pduDroppingEnabled;
219 }
220 
226 {
227  cancelAndDelete(senderInactivityTimer);
228  senderInactivityTimer = nullptr;
229  cancelAndDelete(rcvrInactivityTimer);
230  rcvrInactivityTimer = nullptr;
231 
232  for(auto it = aTimerQ.begin(); it != aTimerQ.end(); )
233  {
234  cancelAndDelete((*it));
235  it = aTimerQ.erase(it);
236  }
237 
238 }
239 
244 {
245  if (!getEnvir()->isGUI())
246  {
247  return;
248  }
249 
250  if (state->isDtcpPresent())
251  {
252  dtcp->redrawGUI();
253  }
254 
255  cDisplayString& disp = getDisplayString();
256  disp.setTagArg("t", 1, "r");
257  std::ostringstream desc;
258  desc << "nextSeqNum: " << state->getNextSeqNumToSendWithoutIncrement() << "\n";
259 
260  desc << "rLWE: " << state->getRcvLeftWinEdge() << "\n";
261 
262  desc << "maxSeqNumRcvd: " << state->getMaxSeqNumRcvd() << "\n";
263 
264  std::vector<DataTransferPDU*>::iterator it;
265  std::vector<DataTransferPDU*>* pduQ;
266 
267  pduQ = state->getReassemblyPDUQ();
268  if (pduQ->empty())
269  {
270  desc << "reassemblyQ: empty" << "\n";
271  }
272  else
273  {
274  desc << "reassemblyQ: ";
275  std::vector<DataTransferPDU*>::iterator it;
276  for (it = pduQ->begin(); it != pduQ->end(); ++it)
277  {
278  desc << (*it)->getSeqNum() << " | ";
279  }
280  desc << "\n";
281  }
282 
283  desc << "droppedPDU: " << state->getDropDup() << "\n";
284  desc << "rtt: " << state->getRtt() << "\n";
285 
286  disp.setTagArg("t", 0, desc.str().c_str());
287 
288 }
289 
294 void DTP::setConnId(const ConnectionId& connId)
295 {
296  this->connId = connId;
297 }
298 
300 {
301 // timer->setCounter(timer->getCounter() + 1);
302  //TODO A2 increment counter to indicate retransmission of RendezvousPDU
304 
305 }
306 
308 {
310 
311  if(state->isDtcpPresent()){
314  }
315  }
316 
317 }
318 
320 {
321  sendAckFlowPDU();
323 }
324 
326 {
327  switch(interrupter->getAction()){
330  break;
331  }
334  changeInBuffers();
335 
336 
337  }
338  }
339 
340  delete interrupter;
341 }
342 
343 void DTP::handleMessage(cMessage *msg)
344 {
345  if (msg->isSelfMessage())
346  {
347  /* Timers */
348  DTPTimers* timer = static_cast<DTPTimers*>(msg);
349  switch (timer->getType())
350  {
351  case (DTP_RCVR_INACTIVITY_TIMER): {
352  handleDTPRcvrInactivityTimer(static_cast<RcvrInactivityTimer*>(timer));
353  break;
354  }
355 
357  handleDTPSenderInactivityTimer(static_cast<SenderInactivityTimer*>(timer));
358  break;
359  }
360 
361  case (DTP_A_TIMER): {
362  handleDTPATimer(static_cast<ATimer*>(timer));
363 // delete msg;
364  break;
365  }
366 
367  case (DTP_INTERRUPTER_TIMER): {
368  handleInterrupterTimer(static_cast<TheInterrupterTimer*>(msg));
369  break;
370 
371  }
372 
373  }
374  }
375  else
376  {
377 
378  /* Either PDUs from RMT or UserDataField from Delimiting */
379  if (msg->arrivedOn(northI->getId()))
380  {
381 
382  handleMsgFromUp(static_cast<UserDataField*>(msg));
383 
384  }
385  else if (msg->arrivedOn(southI->getId()))
386  {
387  handleMsgFromRMT((PDU*) msg);
388  }
389  }
390 
391  if (state->isDtcpPresent())
392  {
394 // emit(sigStatDTPRxCount, dtcp->dtcpState->getRxSent());
395  }
396 
397  redrawGUI();
398 }
399 
405 {
406  pdu->setConnId(this->flow->getConId());
407  pdu->setSrcAddr(this->flow->getSrcAddr());
408  pdu->setDstAddr(this->flow->getDstAddr());
409  pdu->setSrcApn(this->flow->getDstApni().getApn());
410  pdu->setDstApn(this->flow->getSrcApni().getApn());
411 }
412 
413 
418 void DTP::generateDTPDU(UserDataField* userDataField)
419 {
420  DataTransferPDU* dataPDU = new DataTransferPDU();
421  setPDUHeader(dataPDU);
422  dataPDU->setSeqNum(state->getNextSeqNumToSend());
423  /* Set DRF flag in PDU */
424  if (setDRFInPDU(false))
425  {
426  dataPDU->setFlags(dataPDU->getFlags() | DRF_FLAG);
427  }
428  dataPDU->encapsulate(userDataField);
429  state->pushBackToGeneratedPDUQ(dataPDU);
430 }
431 
438 {
439  cancelEvent(senderInactivityTimer);
440 
441 // delimit(sduData);
442  userDataFieldQOut.push_back(userDataField);
443 
444  generatePDUsnew();
445 
446 // generateDTPDU(userDataField);
447 
449 
451 }
452 
459 {
461 }
462 
469 {
470  Enter_Method_Silent();
471  PDUQ_t* pduQ = state->getReassemblyPDUQ();
472 
473  for (auto it = pduQ->begin();
474  it != pduQ->end() && (*it)->getSeqNum() <= state->getRcvLeftWinEdge();)
475  {/* DO NOT FORGET TO PUT '++it' in all cases where we DO NOT erase PDUs from queue */
476  send((*it)->decapsulate(), northO);
477  delete (*it);
478  it = pduQ->erase(it);
479  }
480 
481 }
482 
489 {
490  if (pdu->getSeqNum() <= dtcp->getLastCtrlSeqNumRcv())/* Duplicate ControlPDU */
491  {
492  if ((pdu->getType() & PDU_ACK_BIT) == PDU_ACK_BIT)
493  {
494  dtcp->incDupAcks();
495  }
496  if ((pdu->getType() & PDU_FC_BIT) == PDU_FC_BIT)
497  {
498  dtcp->incDupFC();
499  }
500  delete pdu;
501  return false;
502  }
503  else if (pdu->getSeqNum() > dtcp->getLastCtrlSeqNumRcv() + 1)/* Out of order */
504  {
505  /* LostControlPDU Policy */
507  }
508  else
509  {
511  }
512 
513  return true;
514 }
515 
520 {
521  Enter_Method_Silent
522  ();
523 
524  FlowControlOnlyPDU* fcOnlyPdu = new FlowControlOnlyPDU();
525 
526  setPDUHeader(fcOnlyPdu);
527 
528  fcOnlyPdu->setSeqNum(dtcp->getNextSndCtrlSeqNum());
529 
530  fillFlowControlPDU(fcOnlyPdu);
531 
532  sendToRMT(fcOnlyPdu);
533 }
534 
541 {
542 
543  flowControlPdu->setRcvRightWinEdge(dtcp->getRcvRightWinEdge());
544 
545  flowControlPdu->setRcvRate(dtcp->getRcvrRate());
546 
547  flowControlPdu->setTimeUnit(dtcp->getSendingTimeUnit());
548 
549  flowControlPdu->setSndLeftWinEdge(dtcp->getSndLeftWinEdge());
550 
551  flowControlPdu->setSndRightWinEdge(dtcp->getSndRtWinEdge());
552 
553  flowControlPdu->setSndRate(dtcp->getSendingRate());
554 
556 }
557 
565 void DTP::sendAckFlowPDU(unsigned int seqNum, bool seqNumValid)
566 {
567  Enter_Method_Silent();
568 
569  if(!state->isDtcpPresent()){
570  return;
571  }
572 
573  if (!seqNumValid)
574  {
575  seqNum = state->getRcvLeftWinEdge();
576  }
577 
578 
580  {
581  // Send Ack/Flow Control PDU with LWE and RWE
582  AckFlowPDU* ackFlowPdu = new AckFlowPDU();
583  setPDUHeader(ackFlowPdu);
584  ackFlowPdu->setSeqNum(dtcp->getNextSndCtrlSeqNum());
585 
586  ackFlowPdu->setAckNackSeqNum(seqNum);
587 
588  fillFlowControlPDU(ackFlowPdu);
589  sendToRMT(ackFlowPdu);
590  }
591  else if (dtcp->dtcpState->isFCPresent())
592  {
593  sendFCOnlyPDU();
594  }
595  else if (dtcp->dtcpState->isRxPresent())
596  {
597  sendAckOnlyPDU(seqNum);
598  }
599 
600 }
601 
603 {
604 
605  if (!commonRcvControl(pdu))
606  {
607  //The Control PDU has been deleted because of duplicate
608  return;
609  }
610 
611  if (pdu->getType() == CONTROL_ACK_PDU)
612  {
614  if(dtcp->getDTCPState()->isSndRendez()){
615  ControlAckPDU* controlAckPDU = static_cast<ControlAckPDU*>(pdu);
616  if(dtcp->getDTCPState()->getRendezvousTimer()->getSeqNum() == controlAckPDU->getLastCtrlSeqNumRcv()){
617  cancelAndDelete(dtcp->getDTCPState()->getRendezvousTimer());
618  dtcp->getDTCPState()->setRendezvousTimer(nullptr);
619  }
620 
621 
622  }
623 
624  }
625  else if (pdu->getType() == RENDEZVOUS_PDU)
626  {
627  RendezvousPDU* rendezPDU = (RendezvousPDU*) pdu;
629 // if(rendezPDU->getLastCtrlSeqNumRcv() == dtcp->dtcpState->getLastControlSeqNumSent()){
630  /* The sender sent this RendezvousPDU based on up-to-date information
631  * so this C-PDU can be assumed valid.
632  */
633  dtcp->dtcpState->setRcvRendez(true);
635 // }
636  }
637  else
638  {
639 
640  if (pdu->getType() & PDU_SEL_BIT)
641  {
642  /*
643  SELECT_ACK_PDU = 0xC9;
644  SELECT_NACK_PDU = 0xCA;
645  SELECT_ACK_FLOW_PDU = 0xCD;
646  SELECT_NACK_FLOW_PDU = 0xCE;
647  */
648 
649  //RTT estimator
651 
652  if (pdu->getType() & PDU_NACK_BIT)
653  {
654  SelectiveNackPDU* selNackPdu = (SelectiveNackPDU*) pdu;
655 
656  for (unsigned int i = 0; i < selNackPdu->getNackListLen(); i++)
657  {
658  unsigned int startSeqNum = selNackPdu->getNackList(i * 2);
659  unsigned int endSeqNum = selNackPdu->getNackList((i * 2) + 1);
660 
661  dtcp->nackPDU(startSeqNum, endSeqNum);
662 
663  }
664  }
665  else if (pdu->getType() & PDU_ACK_BIT)
666  {
667 
668  //TODO B1 Shoudn't this be a policy?
669  SelectiveAckPDU* selAckPdu = (SelectiveAckPDU*) pdu;
670  unsigned int tempSLWE = 0;
671  for (unsigned int i = 0; i < selAckPdu->getNackListLen(); i++)
672  {
673  unsigned int startSeqNum = selAckPdu->getNackList(i * 2);
674  unsigned int endSeqNum = selAckPdu->getNackList((i * 2) + 1);
675 
676  tempSLWE = std::max(endSeqNum, tempSLWE);
677 
678  dtcp->ackPDU(startSeqNum, endSeqNum);
679 
680  // min = dtcp->getSmallestSeqNumFromRxQOrNextSeqNumToSend - 1
681  //state->setSenderLeftWinEdge(std::min(min, state->getSndLeftWinEdge);
682 
683  // state->setSenderLeftWinEdge(tempSLWE);
684  //TODO B2 O'really? Shouldn't it always be nextSeqNum -1?
685  dtcp->updateSenderLWE(tempSLWE + 1);
686 
687  }
688  }
689 
690  }
691  else
692 
693  if (pdu->getType() & (PDU_ACK_BIT | PDU_NACK_BIT))
694  {
695 
696  //Retrieve the Time of this Ack - RTT estimator policy
698 
699  if (pdu->getType() & PDU_NACK_BIT)
700  {
701 
702  NackOnlyPDU *nackPdu = (NackOnlyPDU*) pdu;
703 
704  dtcp->nackPDU(nackPdu->getAckNackSeqNum());
705 
706  }
707  else if (pdu->getType() & PDU_ACK_BIT)
708  {
709 
710  AckOnlyPDU *ackPdu = (AckOnlyPDU*) pdu;
711  EV << getFullPath() << ": PDU number: " << ackPdu->getAckNackSeqNum() << " Acked" << endl;
712 
714 
715  }
716  /* End of Ack/Nack */
717 
718  }
719 
720  if ((pdu->getType() & PDU_FC_BIT))
721  {
722  FlowControlOnlyPDU *flowPdu = (FlowControlOnlyPDU*) pdu;
723 
724  //Update RightWindowEdge and SendingRate.
726  dtcp->setSendingRate(flowPdu->getRcvRate());
727 
728  if (dtcp->getDTCPState()->getClosedWinQueLen() > 0)
729  {
730  /* Note: The ClosedWindow flag could get set back to true immediately in trySendGenPDUs */
731  dtcp->getDTCPState()->setClosedWindow(false);
733 
734  if (dtcp->dtcpState->isWinBased())
735  {
736  if (!dtcp->isClosedWinQClosed())
737  {
739  }
740 
741  }
742  }
743 
745  }
746 
747  }
748  delete pdu;
749 }
750 
758 {
759 
760  state->setCurrentPdu(msg);
761 
762  if (dynamic_cast<DataTransferPDU*>(msg))
763  {
764  DataTransferPDU* pdu = (DataTransferPDU*) msg;
765 
767 
768  }
769  else if (dynamic_cast<ControlPDU*>(msg))
770  {
771  ControlPDU* pdu = (ControlPDU*) msg;
772  EV << getFullPath() << ": Control PDU number: " << pdu->getSeqNum() << " received" << endl;
773 
774  //Putting it before ControlAckPDU might be an issue
775 
777  }
778  else
779  {
780 
781  throw cRuntimeError("Unexptected PDU Type");
782  }
783 
784  state->setCurrentPdu(nullptr);
785 }
786 
787 
788 
790 {
791 
792  return aTimerQ.empty();
793 }
794 
795 
800 void DTP::cancelATimer(unsigned int seqNum)
801 {
802  Enter_Method_Silent();
803  for (auto it = aTimerQ.begin(); it != aTimerQ.end() && (*it)->getSeqNum() <= seqNum;)
804  {
805  cancelAndDelete((*it));
806  it = aTimerQ.erase(it);
807  }
808 
809 
810 }
811 
812 void DTP::startATimer(unsigned int seqNum)
813 {
814 
815  if(!(state->getQoSCube()->getATime() > 0.0))
816  {
817  return;
818  }
819  //TODO A1 Make a vector in DTPState of all active ATimers.
820  Enter_Method_Silent();
821  ATimer* aTimer = new ATimer();
822  aTimer->setSeqNum(seqNum);
823  schedule(aTimer);
824 
825 
826 
827  auto it = aTimerQ.begin();
828  for(; it != aTimerQ.end(); ++it)
829  {
830  if((*it)->getSeqNum() > seqNum)
831  {
832  break;
833  }
834  }
835  aTimerQ.insert(it, aTimer);
836 
837 
838 }
839 
840 bool DTP::isDuplicate(unsigned int seqNum)
841 {
842  /* Not a true duplicate. (Might be a duplicate among the gaps) */
843  bool dup = false;
844  PDUQ_t::iterator it;
845  PDUQ_t* pduQ = state->getReassemblyPDUQ();
846  for (it = pduQ->begin(); it != pduQ->end(); ++it)
847  {
848  if ((*it)->getSeqNum() == seqNum)
849  {
850  dup = true;
851  break;
852  }
853  }
854  return dup;
855 }
856 
858 {
859  return state->getQoSCube()->getATime();
860 }
861 
863 {
864 
865  EV << getFullPath() << ": PDU number: " << pdu->getSeqNum() << " received" << endl;
866 
867  emit(sigStatDTPRecvSeqNum, pdu->getSeqNum());
868 
869  cancelEvent(rcvrInactivityTimer);
870  /*
871  * What to do when you want to discard the incomming PDU?
872  * How to handle both cases - you want to keep it for further processing/ you want to drop it.
873  */
874  if (state->isDtcpPresent())
875  {
876  if (dtcp->dtcpState->isWinBased())
877  {
878  if (pdu->getSeqNum() > dtcp->getRcvRightWinEdge())
879  {
882  if (state->getCurrentPdu() == nullptr)
883  {
884  return;
885  }
886  }
887  }
888  else if (dtcp->dtcpState->isRateBased())
889  {
890  if (dtcp->getPdusRcvdInTimeUnit() + 1 > dtcp->getRcvrRate())
891  {
894  if (state->getCurrentPdu() == nullptr)
895  {
896  return;
897  }
898  }
899  }
900 
901  if (dtcp->dtcpState->isFCPresent())
902  {
903  // dtcp->resetWindowTimer();
904 
905  /* Run ECN policy */
907 
908  }
909  }
910 
911  // if PDU.DRF == true
912  if (pdu->getFlags() & DRF_FLAG)
913  {
914  bubble("Received PDU with DRF set");
915  /* Case 1) DRF is set - either first PDU or new run */
916 
917  delimitFromRMT();
918 
919  //Flush the PDUReassemblyQueue
921 
924 
925  //Put PDU on ReassemblyQ
926  addPDUToReassemblyQ(pdu);
927 
928  /* I guess i did not think this through (will be removed) */
929 // if (getATime() > 0)
930 // {
931 // startATimer(pdu->getSeqNum());
932 // }
933 // else
934 // {
935 // svUpdate(pdu->getSeqNum());
936 // }
937 
938  if (state->isDtcpPresent())
939  {
940  svUpdate(pdu->getSeqNum());
941 
942  }
943  else
944  {
946  //TODO A2: No A-Timer?
947  }
948  delimitFromRMT();
949 
951 
952  }
953  else
954  {
955 
956  /* Not the start of a run */
957  if (pdu->getSeqNum() <= state->getRcvLeftWinEdge() || pdu->getSeqNum() == state->getMaxSeqNumRcvd())
958  {
959  bubble("Dropping duplicate PDU");
960  EV << getFullPath() << ":Duplicated PDU number: " << pdu->getSeqNum() << " received - DROPPING!" << endl;
961  /* Case 2) A Real Duplicate */
962  //Discard PDU and increment counter of dropped duplicates PDU
963  delete pdu;
964 
965  state->incDropDup();
966 
967  sendAckFlowPDU();
968 
969  return;
970  }
971  if (state->getRcvLeftWinEdge() < pdu->getSeqNum() && pdu->getSeqNum() < state->getMaxSeqNumRcvd())
972  {
973  /* Not a true duplicate. (Might be a duplicate among the gaps) */
974  if (isDuplicate(pdu->getSeqNum()))
975  {
976  /* Case 3) Duplicate Among gaps */
977  EV << getFullPath() << ":Duplicated PDU number: " << pdu->getSeqNum() << " received - DROPPING!" << endl;
978  //Discard PDU and increment counter of dropped duplicates PDU
979  delete pdu;
980  //increment counter of dropped duplicates PDU
981  state->incDropDup();
982 
983  //send an Ack/Flow Control PDU with current window values
984  sendAckFlowPDU();
985  return;
986  }
987  else
988  {
989  /* Case 3) This goes in a gap */
990  /* Put at least the User-Data of the PDU with its Sequence Number on PDUReassemblyQueue in Sequence Number order */
991  addPDUToReassemblyQ(pdu);
992 
993 // svUpdate(state->getMaxSeqNumRcvd()); /* Update left edge, etc */
994 
995  if (state->isDtcpPresent())
996  {
997  svUpdate(state->getMaxSeqNumRcvd()); /* Update left edge, etc */
998  }
999  else
1000  {
1002  /* No A-Timer necessary, already running */
1003  }
1004 
1005  delimitFromRMT();
1007  return;
1008  }
1009  }
1010  /* Case 4) This is in order */
1011  if (pdu->getSeqNum() == state->getMaxSeqNumRcvd() + 1)
1012 // if (pdu->getSeqNum() == state->getRcvLeftWinEdge())
1013  {
1015  addPDUToReassemblyQ(pdu);
1016 
1017 // if (getATime() > 0)
1018 // {
1019 // startATimer(pdu->getSeqNum());
1020 // }
1021 // else
1022 // {
1023 // svUpdate(state->getMaxSeqNumRcvd());
1024 // }
1025 
1026  if (state->isDtcpPresent())
1027  {
1028  svUpdate(state->getMaxSeqNumRcvd()); /* Update Left Edge, etc. */
1029  }
1030  else
1031  {
1033  //start A-Timer (for this PDU)
1034  startATimer(pdu->getSeqNum());
1035  }
1036 
1037  delimitFromRMT();/* Create as many whole SDUs as possible */
1038 
1040 
1041  }
1042  else
1043  {
1044  /* Case 5) it is out of order */
1045  if (pdu->getSeqNum() > state->getMaxSeqNumRcvd() + 1)
1046  {
1047  state->setMaxSeqNumRcvd(pdu->getSeqNum());
1048  addPDUToReassemblyQ(pdu);
1049 
1050 // if (getATime() > 0)
1051 // {
1052 // startATimer(state->getMaxSeqNumRcvd());
1053 // }
1054 // else
1055 // {
1056 // svUpdate(state->getMaxSeqNumRcvd());
1057 // }
1058 
1059  if (state->isDtcpPresent())
1060  {
1061  svUpdate(state->getMaxSeqNumRcvd()); /* Update Left Edge, etc. */
1062  }
1063  else
1064  {
1066  }
1067 
1068  delimitFromRMT();
1070 
1071  }
1072 // /* Backstop timer */
1073 // schedule(rcvrInactivityTimer);
1074  }
1075 
1076  //TODO C1 DIF.integrity
1077  /* If we are encrypting, we can't let PDU sequence numbers roll over */
1078 
1079  //If DIF.Integrity and PDU.SeqNum > SequenceNumberRollOverThreshhold Then
1081  //RequestFAICreateNewConnection( PDU.FlowID )
1082  //Fi
1083  }
1084 
1085 }
1086 
1088 {
1089 
1091 
1092 }
1093 
1095 {
1097 
1098 }
1099 
1101 {
1102  Enter_Method_Silent();
1103  cancelEvent(senderInactivityTimer);
1105 }
1106 
1108 {
1109 
1110  state->setTmpAtimer(timer);
1111 
1112  if (state->isDtcpPresent())
1113  {
1114  // runSendingAckPolicy(timer);
1115  dtcp->runSendingAckPolicy(state, timer);
1116  }
1117  else
1118  {
1119 
1120  //Update RcvLeftWindowEdge
1121  PDUQ_t* pduQ = state->getReassemblyPDUQ();
1122 
1123  // Advance RLWE as much as possible
1124  for (auto it = pduQ->begin(); it != pduQ->end() && (*it)->getSeqNum() <= timer->getSeqNum(); ++it)
1125  {
1126  if((state->getRcvLeftWinEdge() + 1) + state->getQoSCube()->getMaxAllowGap() >= (*it)->getSeqNum())
1127  {
1128  state->setRcvLeftWinEdge((*it)->getSeqNum());
1129  }
1130  else
1131  {
1132  break;
1133  }
1134  }
1135  //Discard any PDUs that are bigger than RLWE but smaller than A-Timer seqNum
1136  for (auto it = pduQ->begin(); it != pduQ->end() && (*it)->getSeqNum() <= timer->getSeqNum();)
1137  {
1138  if((*it)->getSeqNum() > state->getRcvLeftWinEdge())
1139  {
1140  delete (*it);
1141  it = pduQ->erase(it);
1142  }
1143 
1144  }
1145 
1146  if (state->getRcvLeftWinEdge() > timer->getSeqNum())
1147  {
1148  bubble("RcvLeftWindowEdge SHOULD not be bigger than seqNum in A-Timer, right?");
1149  // throw cRuntimeError("RcvLeftWindowEdge SHOULD not be bigger than seqNum in A-Timer, right?");
1150  }
1151 
1152 
1153  state->setRcvLeftWinEdge(timer->getSeqNum());
1154 
1155  cancelATimer(timer->getSeqNum());
1156 
1157 
1158  //Invoke delimiting
1159  delimitFromRMT();
1160 
1161 
1162  //reset SenderInactivity timer
1163  // resetSenderInactivTimer();
1164 
1165 
1166  }
1167 
1168  state->setTmpAtimer(nullptr);
1169 }
1170 
1171 unsigned int DTP::delimit(SDUData* sduData)
1172 {
1173 
1174 
1175  //TODO A1 update return statement
1176 return 1;
1177 
1178 // //TODO B2 Does PDU header counts to MaxFlowPDUSize? edit: yes, it does!
1179 // if (sdu->getSize() > state->getMaxFlowPduSize())
1180 // {
1181 // unsigned int size = state->getMaxFlowPduSize();
1182 // //SDU is bigger than Max Allowed PDU
1183 // //S/DUFrag *frag = new SDUFrag
1184 //
1185 // SDU* tmp;
1186 // unsigned int i;
1187 // for (i = 0; i * size < sdu->getSize(); i++)
1188 // {
1189 // tmp = sdu->genFragment(size, i, i * size);
1190 // dataQ.push_back(tmp);
1191 //
1192 // }
1193 // return i;
1194 // }
1195 // else
1196 // {
1197 // dataQ.push_back(sdu);
1198 // return 1;
1199 // }
1200 
1201 }
1202 
1203 unsigned int DTP::delimitFromRMT(PDU *pdu, unsigned int len)
1204 {
1205  unsigned int counter = 0;
1206 
1207 // if()
1208 
1209  return counter;
1210 }
1211 
1212 bool DTP::setDRFInPDU(bool override)
1213 {
1214  if (state->isSetDrfFlag() || override)
1215  {
1216  state->setSetDrfFlag(false);
1217  return true;
1218  }
1219  else
1220  {
1221  return false;
1222  }
1223 }
1224 
1226 {
1227  DataTransferPDU* baseDataPDU = new DataTransferPDU();
1228  setPDUHeader(baseDataPDU);
1229 
1230 // //invoke SDU protection so we don't have to bother with it afterwards; EDIT: sduQ is not used anymore!!!
1231 // for (std::vector<SDU*>::iterator it = dataQ.begin(); it != dataQ.end(); ++it)
1232 // {
1233 // sduProtection(*it);
1234 // }
1235 
1236  while (!userDataFieldQOut.empty())
1237  {
1238  DataTransferPDU* genPDU = baseDataPDU->dup();
1239  genPDU->setSeqNum(state->getNextSeqNumToSend());
1240 
1241  /* Set DRF flag in PDU */
1242  if (setDRFInPDU(false))
1243  {
1244  genPDU->setFlags(genPDU->getFlags() | DRF_FLAG);
1245  }
1246 
1247  genPDU->encapsulate(userDataFieldQOut.front());
1248  userDataFieldQOut.erase(userDataFieldQOut.begin());
1249 
1250  state->pushBackToGeneratedPDUQ(genPDU);
1251  }
1252 
1253  //HOTFIX
1254  if(!state->isDtcpPresent()){
1255  state->setSetDrfFlag(true);
1256  }
1257 
1258  delete baseDataPDU;
1259 }
1260 
1262 {
1263  /* Fill in Rendezvous PDU */
1264  fillControlAckPDU(rendezPDU);
1265  if(dtcp->dtcpState->isRxPresent()){
1266  rendezPDU->setRendezSeqNum(dtcp->dtcpState->getSndLeftWinEdge() + 1);
1267  }else{
1269  }
1270 }
1271 
1273 {
1274  /* Send Rendezvous PDU */
1275  RendezvousPDU* rendezPDU = new RendezvousPDU();
1276  setPDUHeader(rendezPDU);
1277  /* Fill in Rendezvous PDU */
1278  fillRendezvousPDU(rendezPDU);
1279  sendToRMT(rendezPDU);
1280  //TODO A! restart SenderInactivity Timer
1281 }
1282 
1284 {
1285  Enter_Method_Silent();
1286 
1287  //TODO A1 Remove after sucessfull testing
1288  if(!rendezvousEnabled){
1289  return;
1290  }
1291 
1292  /* Rendezvous condition */
1293  if (!dtcp->getDTCPState()->isSndRendez())
1294  {
1295 // if (((state->isDtcpPresent() && dtcp->getDTCPState()->isRxPresent() && dtcp->getDTCPState()->getRxQLen() == 0) || (!dtcp->getDTCPState()->isRxPresent())) && (dtcp->getDTCPState()->getClosedWinQueLen() != 0))
1296  if ((state->isDtcpPresent() && (!dtcp->getDTCPState()->isRxPresent() || dtcp->getDTCPState()->getRxQLen() == 0)) && (dtcp->getDTCPState()->getClosedWinQueLen() != 0))
1297  {//condition is satisfied if all DT-PDUs are Acked or Retransmission is not present; AND there is DT-PDU on closedWindowQ (we have something to send)
1298 
1299 
1301  {
1302  /* Send Rendezvous PDU */
1304  dtcp->getDTCPState()->setSndRendez(true);
1305 
1307 
1308  }
1309  }
1310  }else{
1311  /* Sender is in rendez_at_sender state */
1313  dtcp->getDTCPState()->setSndRendez(false);
1314  cancelAndDelete(dtcp->getDTCPState()->getRendezvousTimer());
1315  dtcp->getDTCPState()->setRendezvousTimer(nullptr);
1316  }
1317  }
1318 }
1319 
1323 void DTP::trySendGenPDUs(std::vector<DataTransferPDU*>* pduQ)
1324 {
1325 
1326  if (state->isDtcpPresent())
1327  {
1328  //postablePDUs = empty;
1329 
1330  //if flowControl present
1332  {
1333  std::vector<DataTransferPDU*>::iterator it;
1334  for (it = pduQ->begin(); it != pduQ->end(); it = pduQ->begin())
1335  {
1336  if (dtcp->dtcpState->isWinBased())
1337  {
1338  if (((*it)->getSeqNum() <= dtcp->getSndRtWinEdge()) && !dtcp->getDTCPState()->isClosedWindow())
1339  {
1340  /* The Window is Open. */
1341  dtcp->runTxControlPolicy(state, pduQ);
1342  /* Watchout because the current 'it' could be freed */
1343  }
1344  else
1345  {
1346  /* The Window is Closed */
1347  dtcp->getDTCPState()->setClosedWindow(true);
1348 
1349  if (pduQ == dtcp->getDTCPState()->getClosedWindowQ())
1350  {
1351  /* It indicates that trySendGenPDUs method has been called for closedWindowQ
1352  * So no point of trying to put the DT-PDU on closedWindowQ (again).
1353  */
1354  break;
1355  }
1356 
1358  {
1359  /* Put PDU on the closedWindowQueue */
1361  /* I know it is nasty to access it directly */
1362  state->getGeneratedPDUQ()->erase(it);
1363 
1364  }
1365  else
1366  {
1367  state->setCurrentPdu(*it);
1368  state->getGeneratedPDUQ()->erase(it);
1369 
1371 
1372  }
1373 
1374  /* Rendezvous condition */
1376  }
1377  } // end of Window based
1378 
1379  if (dtcp->dtcpState->isRateBased())
1380  {
1382  {
1384  }
1385  else
1386  {
1387  /* Exceeding Sending Rate */
1388 
1390  }
1391  } // end of RateBased
1392 
1394  {
1396  }
1397 
1398  } //end of for
1399 
1400  }
1401  else
1402  {
1403  /* FlowControl is not present */
1404  std::vector<DataTransferPDU*>::iterator it;
1405  PDUQ_t* pduQ = state->getGeneratedPDUQ();
1406  for (it = pduQ->begin(); it != pduQ->end();)
1407  {
1408  state->pushBackToPostablePDUQ((*it));
1409  it = pduQ->erase(it);
1410  }
1411  }
1412 
1413  /* Iterate over postablePDUs and give them to the RMT */
1414  if (dtcp->dtcpState->isRxPresent())
1415  {
1416  std::vector<DataTransferPDU*>::iterator it;
1417  PDUQ_t* pduQ = state->getPostablePDUQ();
1418  for (it = pduQ->begin(); it != pduQ->end();)
1419  {
1420  /* Put a copy of each PDU in the RetransmissionQueue */
1421  dtcp->pushBackToRxQ((*it)->dup());
1422 
1423  sendToRMT((*it));
1424 
1425  it = pduQ->erase(it);
1426  }
1427 
1428  }
1429  else
1430  {
1431  /*No Retransmission Control is present, but FlowControl */
1432  /* Post all postablePDUs to RMT */
1433  std::vector<DataTransferPDU*>::iterator it;
1434  PDUQ_t* pduQ = state->getPostablePDUQ();
1435  for (it = pduQ->begin(); it != pduQ->end();)
1436  {
1437 
1438  sendToRMT((*it));
1439  it = pduQ->erase(it);
1440  }
1441 
1442  }
1443 
1444  }
1445  else
1446  {
1447  /* DTCP is not present */
1448  /* Post all generatedPDUs to RMT */
1449  std::vector<DataTransferPDU*>::iterator it;
1450  PDUQ_t* pduQ = state->getGeneratedPDUQ();
1451  for (it = pduQ->begin(); it != pduQ->end();)
1452  {
1453  sendToRMT((*it));
1454  it = pduQ->erase(it);
1455  }
1456  }
1457 }
1458 
1465 {
1466  //TODO C1
1467 
1468 }
1469 
1471 {
1472  Enter_Method("InitialSeqNumPolicy");
1473 
1474 // if(initialSeqNumPolicy->run(state, dtcp->getDTCPState())){
1475 // initialSeqNumPolicy->defaultAction(state, dtcp->getDTCPState());
1476 // }
1477 
1478  if (state->isDtcpPresent())
1479  {
1481  }
1482  else
1483  {
1484  initialSeqNumPolicy->call(state, nullptr);
1485  }
1486 
1487  return false;
1488 }
1489 
1490 void DTP::sendAckOnlyPDU(unsigned int seqNum)
1491 {
1492 
1493  //send an Ack/FlowControlPDU
1494  AckOnlyPDU* ackPDU = new AckOnlyPDU();
1495  setPDUHeader(ackPDU);
1496  ackPDU->setSeqNum(dtcp->getNextSndCtrlSeqNum());
1497  ackPDU->setAckNackSeqNum(seqNum);
1498  EV << getFullPath() << ": Sending Ack for PDU number: " << seqNum << endl;
1499  // send(ackPDU, southO);
1500  sendToRMT(ackPDU);
1501 }
1502 
1504 {
1505  ctrlAckPdu->setSeqNum(dtcp->getNextSndCtrlSeqNum());
1507  ctrlAckPdu->setRcvLeftWinEdge(dtcp->getSndLeftWinEdge());
1508  ctrlAckPdu->setRcvRightWinEdge(dtcp->getSndRtWinEdge());
1509  ctrlAckPdu->setSndLeftWinEdge(state->getRcvLeftWinEdge());
1510  ctrlAckPdu->setSndRightWinEdge(dtcp->getRcvRightWinEdge());
1511  ctrlAckPdu->setRcvRate(dtcp->getRcvrRate());
1512 }
1513 
1515 {
1516  Enter_Method_Silent();
1517 
1518  ControlAckPDU* ctrlAckPdu = new ControlAckPDU();
1519  setPDUHeader(ctrlAckPdu);
1520  fillControlAckPDU(ctrlAckPdu);
1521 
1522  sendToRMT(ctrlAckPdu);
1523 }
1524 
1526 {
1527  Enter_Method_Silent
1528  ();
1529 
1530  //Send Transfer PDU With Zero length
1531  DataTransferPDU* dataPdu = new DataTransferPDU();
1532  setPDUHeader(dataPdu);
1533  unsigned int seqNum = state->getNextSeqNumToSend();
1534  dataPdu->setSeqNum(seqNum);
1535 
1536  if (setDRFInPDU(false))
1537  {
1538  dataPdu->setFlags(dataPdu->getFlags() | DRF_FLAG);
1539  }
1540  Data* data = new Data();
1542 
1543  PDUData* pduData = new PDUData();
1544  pduData->encapsulate(data);
1545 
1546 
1547  UserDataField* userData = new UserDataField();
1548  userData->encapsulate(pduData);
1549  userData->setCompleteSDU(true);
1550 
1551  dataPdu->encapsulate(userData);
1552 
1553  if (dtcp->dtcpState->isRxPresent())
1554  {
1555 // RxExpiryTimer* rxExpTimer = new RxExpiryTimer("RxExpiryTimer");
1556 // rxExpTimer->setPdu(dataPdu->dup());
1557 // rxQ.push_back(rxExpTimer);
1558 // schedule(rxExpTimer);
1559  dtcp->pushBackToRxQ(dataPdu->dup());
1560  }
1561 
1562  sendToRMT(dataPdu);
1563 }
1564 
1566 {
1567  //FIX A2 - activate when CDAP Splitter is ready
1568  return;
1569  // Notify User Flow that we were unable to maintain the QoS for this connection
1570  //CDAPMessage* uMaintainMsg = new CDAP_M_Unable_Maintain;
1571  //SDU* sdu = new SDU();
1572  //sdu->addUserData(uMaintainMsg);
1573  //send(sdu, northO);
1574 }
1575 
1582 {
1583  if (state->isBlockingPort())
1584  {
1585  emit(sigEFCPStartSending, flow);
1586  state->setBlockingPort(false);
1587  }
1588 }
1589 
1595 {
1596 
1597  // Notify User Flow to Stop sending due to closed window and full closedWindowQ.
1598 
1599  if (!state->isBlockingPort())
1600  {
1601  emit(sigEFCPStahpSending, flow);
1602  state->setBlockingPort(true);
1603  }
1604 
1605 }
1606 
1608 {
1609  //FIX A2 - activate when CDAP Splitter is ready
1610  return;
1611  // Notify User Flow there has been no activity for awhile.
1612  //CDAPMessage* inactivMsg = new CDAP_M_Inactiv();
1613  //SDU* sdu = new SDU();
1614  //sdu->addUserData(inactivMsg);
1615  //send(sdu, northO);
1616 
1617 }
1618 
1620 {
1621  Enter_Method
1622  ("RcvrInactivityPolicy");
1623  if (state->isDtcpPresent())
1624  {
1626  }
1627  else
1628  {
1629  rcvrInactivityPolicy->call(state, nullptr);
1630  }
1631 }
1632 
1634 {
1635  Enter_Method
1636  ("SenderInactivityPolicy");
1637 
1638  if (state->isDtcpPresent())
1639  {
1641  }
1642  else
1643  {
1644  senderInactivityPolicy->call(state, nullptr);
1645  }
1646 
1647 }
1648 
1650 {
1651  Enter_Method_Silent("SendToRMT");
1652  take(pdu);
1653  if (pdu->getType() == DATA_TRANSFER_PDU)
1654  {
1655  emit(sigStatDTPSentSeqNum, pdu->getSeqNum());
1656  //TODO B1 What to do in case of retransmission?
1658  EV << getFullPath() << ": PDU number: " << pdu->getSeqNum() << " sent in time: " << simTime() << endl;
1659  }
1660  else
1661  {
1662  //This should be controlPDU so do not have to increment LastSeqNumSent
1664  EV << getFullPath() << ": Control PDU number: " << pdu->getSeqNum() << " sent in time: " << simTime() << endl;
1665  }
1666 
1667  send(pdu, southO);
1668 }
1669 
1671 {
1672  //TODO A2 Epsilon
1673  // RTT + A + epsilon
1674 
1675  return state->getRtt() + getQoSCube()->getATime() / 1000;
1676 }
1677 
1678 unsigned int DTP::getAllowableGap()
1679 {
1680 
1682  return 4;
1683 }
1684 
1685 //TODO B! When to call it?
1687 {
1688  if (dtcp->dtcpState->isRateBased())
1689  {
1691  }
1692 }
1693 
1694 void DTP::svUpdate(unsigned int seqNum)
1695 {
1696 
1697 
1698  if(dtcp->dtcpState->isRcvRendez()){
1700  dtcp->dtcpState->setRcvRendez(false);
1701  }
1702  //update RcvLeftWindoEdge
1703  state->updateRcvLWE(seqNum);
1704 
1705  if (dtcp->dtcpState->isFCPresent())
1706  {
1707  if (dtcp->dtcpState->isWinBased())
1708  {
1710  }
1711  }
1712 
1713  if (dtcp->dtcpState->isRxPresent())
1714  {
1716  }
1717 
1719  {
1720 
1722  }
1723 
1724 }
1725 
1727 {
1729 }
1730 
1732 {
1733  dtcp->clearRxQ();
1734 }
1735 
1736 void DTP::schedule(DTPTimers *timer, double time)
1737 {
1738  //TODO A1 Can't have MPL = 0
1739  double MPL = (state->getMPL() > 0) ? state->getMPL() : 0;
1740 
1741 // (state->isDtcpPresent() && dtcp->dtcpState->isRxPresent() )? dtcp->getDataReXmitMax() : 0;
1742  unsigned int rxCount = (state->isDtcpPresent() && dtcp->dtcpState->isRxPresent()) ? dtcp->getDataReXmitMax() : 0;
1743  double R = (state->getRtt() > 0 && rxCount > 0) ? state->getRtt() * rxCount : 0;
1744  double A = (state->getQoSCube()->getATime() > 0) ? state->getQoSCube()->getATime() / 1000 : 0;
1745 
1746  switch (timer->getType())
1747  {
1748 
1750  //3(MPL+R+A)
1751  scheduleAt(simTime() + 3 * (MPL + R + A), timer);
1752  break;
1754  //2(MPL+R+A)
1755  scheduleAt(simTime() + 2 * (MPL + R + A), timer);
1756  break;
1757  case (DTP_A_TIMER):
1758 
1759  scheduleAt(simTime() + A, timer);
1760  break;
1761 // case (DTP_DELIMITING_TIMER):
1762 // if(!timer->isScheduled()){
1763 // scheduleAt(simTime() + state->getDelimitDelay(), timer);
1764 // }
1765 // break;
1766  }
1767 }
1768 
1769 void DTP::setFlow(const Flow* flow)
1770 {
1771  this->flow = flow;
1772 }
1773 
1774 void DTP::setDTCP(DTCP* dtcp)
1775 {
1776  this->dtcp = dtcp;
1777  if (dtcp != nullptr)
1778  {
1779  dtcp->setDTP(this);
1780  }
1781 }
1782 
1784 {
1785  this->state = state;
1786 }
1787 
1789 {
1790  handleQueueInfo(queueInfo);
1791 }
bool runSenderAckPolicy(DTPState *dtpState)
Definition: DTCP.cc:216
void runRTTEstimatorPolicy()
Definition: DTP.cc:80
bool runInitialSeqNumPolicy()
Definition: DTP.cc:1470
void rcvrBufferStateChange()
Definition: DTP.cc:1686
void generateDTPDU(UserDataField *userDataField)
Definition: DTP.cc:418
void sendReliableControlPDU()
Definition: DTP.cc:319
Class representing flow object with attributes from specs.
Definition: Flow.h:45
virtual void handleMessage(cMessage *msg)
Definition: DTP.cc:343
virtual void setAction(int action)
bool isRcvRendez() const
Definition: DTCPState.cc:561
virtual void setRcvRate(unsigned int rcvRate)
void trySendGenPDUs(std::vector< DataTransferPDU * > *pduQ)
Definition: DTP.cc:1323
void fillRendezvousPDU(RendezvousPDU *rendezPDU)
Definition: DTP.cc:1261
const APNamingInfo & getSrcApni() const
Gets read-only source APNamingInfo.
Definition: Flow.cc:134
cGate * northO
Definition: DTP.h:107
void setPduDroppingEnabled(bool pduDroppingEnabled)
Definition: DTP.cc:216
void handleQueueInfo(QueueInfo *queueInfo)
Definition: DTP.cc:100
void setRcvLeftWinEdge(unsigned int rcvLeftWinEdge)
Definition: DTPState.cc:262
virtual unsigned int getSeqNum() const
DTPState * state
Definition: DTP.h:72
void resetSenderInactivTimer()
Definition: DTP.cc:1100
void sendFCOnlyPDU()
Definition: DTP.cc:519
void handleDTPRcvrInactivityTimer(RcvrInactivityTimer *timer)
Definition: DTP.cc:1087
Definition: Data.h:36
void setSndRendez(bool sndRendez)
Definition: DTCPState.cc:576
virtual void setRcvRightWinEdge(unsigned int rcvRightWinEdge)
simsignal_t sigStatDTPRecvSeqNum
Definition: DTP.h:293
RcvrInactivityPolicyBase * rcvrInactivityPolicy
Definition: DTP.h:79
void setPDUHeader(PDU *pdu)
Definition: DTP.cc:404
RTTEstimatorPolicyBase * rttEstimatorPolicy
Definition: DTP.h:82
unsigned int getLastSeqNumSent() const
Definition: DTPState.cc:319
void ackPDU(unsigned int startSeqNum, unsigned int endSeqNum=0)
Definition: DTCP.cc:341
void updateSenderLWE(unsigned int seqNum)
Definition: DTCP.cc:706
void redrawGUI()
Definition: DTCP.cc:618
void handleDTPATimer(ATimer *timer)
Definition: DTP.cc:1107
PDUQ_t * getPostablePDUQ()
Definition: DTPState.cc:419
void notifyStartSending()
Definition: DTP.cc:1581
void generatePDUsnew()
Definition: DTP.cc:1225
void setDTP(DTP *dtp)
Definition: DTCP.cc:146
virtual void setSndRightWinEdge(unsigned int sndRightWinEdge)
virtual unsigned int getSeqNum() const
double getRxTime()
Definition: DTP.cc:1670
double getMPL() const
Definition: DTPState.cc:33
void handleMsgFromRMT(PDU *msg)
Definition: DTP.cc:757
void svUpdate(unsigned int seqNum)
Definition: DTP.cc:1694
simsignal_t sigStatDTPSentSeqNum
Definition: DTP.h:292
void fillControlAckPDU(ControlAckPDU *ctrlAckPdu)
Definition: DTP.cc:1503
bool isClosedWinQClosed()
Definition: DTCP.cc:701
virtual void setSeqNum(unsigned int seqNum)
void pushBackToGeneratedPDUQ(DataTransferPDU *pdu)
Definition: DTPState.cc:414
void runRcvrInactivityTimerPolicy()
Definition: DTP.cc:1619
unsigned int getMaxSeqNumRcvd() const
Definition: DTPState.cc:194
unsigned int getNextSeqNumToSend()
Definition: DTPState.cc:215
DTCPState * dtcpState
Definition: DTCP.h:68
virtual unsigned int getLastCtrlSeqNumRcv() const
bool isWinBased() const
Definition: DTCPState.cc:533
void addPDUToReassemblyQ(DataTransferPDU *pdu)
Definition: DTP.cc:458
virtual void setDstApn(const APN &dstApn)
Definition: PDU_m.cc:331
void startReliableCPDUTimer()
Definition: DTCP.cc:472
virtual void setTimeUnit(unsigned long timeUnit)
void handleRendezvousTimer(DTCPRendezvousTimer *timer)
Definition: DTP.cc:299
void fillFlowControlPDU(FlowControlPDU *flowControlPdu)
Definition: DTP.cc:540
unsigned int getSendingRate() const
Definition: DTCP.cc:59
Connection identifier as defined in specifications.
Definition: ConnectionId.h:42
virtual bool call(DTPState *dtpState, DTCPState *dtcpState)
Definition: EFCPPolicy.cc:44
void rendezvousCondition()
Definition: DTP.cc:1283
virtual void setSrcAddr(const Address &srcAddr)
Definition: PDU_m.cc:301
SenderInactivityTimer * senderInactivityTimer
Definition: DTP.h:94
unsigned int getPdusSentInTimeUnit() const
Definition: DTCP.cc:598
bool runRateReductionPolicy(DTPState *dtpState)
Definition: DTCP.cc:273
void notifyAboutInactivity()
Definition: DTP.cc:1607
#define INITIAL_SEQ_NUM_POLICY_NAME
Definition: EFCP.cc:86
void handleInterrupterTimer(TheInterrupterTimer *msg)
Definition: DTP.cc:325
virtual void setDstAddr(const Address &dstAddr)
Definition: PDU_m.cc:311
void setRcvCredit(unsigned int rcvCredit)
Definition: DTCPState.cc:163
unsigned int getRendezSeqNum() const
Definition: DTCPState.cc:591
void schedule(DTPTimers *timer, double time=0.0)
Definition: DTP.cc:1736
void setRcvRightWinEdgeSent(unsigned int rcvrRightWinEdgeSent)
Definition: DTCPState.cc:129
Definition: DTCP.h:63
void sendToRMT(PDU *pdu)
Definition: DTP.cc:1649
bool runRcvrAckPolicy(DTPState *dtpState)
Definition: DTCP.cc:175
void setSendingRate(unsigned int sendingRate)
Definition: DTCP.cc:64
unsigned int getSndRightWinEdge() const
Definition: DTCPState.cc:142
void sduProtection(SDU *sdu)
Definition: DTP.cc:1464
bool runTxControlPolicy(DTPState *dtpState, PDUQ_t *pduQ)
Definition: DTCP.cc:249
const APN & getApn() const
Getter of APN.
Definition: APNamingInfo.h:142
double getATime() const
Gets A-Timer parameter.
Definition: QoSCube.cc:384
bool runECNPolicy(DTPState *dtpState)
Definition: DTCP.cc:151
bool isBlockingPort() const
Definition: DTPState.cc:43
void startATimer(unsigned int seqNum)
Definition: DTP.cc:812
void initGates()
Definition: DTP.cc:185
bool isSendingRateFullfilled() const
Definition: DTCP.cc:588
bool isDuplicate(unsigned int seqNum)
Definition: DTP.cc:840
void notifyStopSending()
Definition: DTP.cc:1594
bool runRcvrControlAckPolicy(DTPState *dtpState)
Definition: DTCP.cc:208
void redrawGUI()
Definition: DTP.cc:243
Define_Module(DTP)
bool isSetDrfFlag() const
Definition: DTPState.cc:298
void sendRendezvousPDU()
Definition: DTP.cc:1272
void handleDTPSenderInactivityTimer(SenderInactivityTimer *timer)
Definition: DTP.cc:1094
void updateRcvRtWinEdge(DTPState *dtpState)
Definition: DTCP.cc:456
unsigned int sduSeqNum
Definition: DTP.h:66
void sendEmptyDTPDU()
Definition: DTP.cc:1525
const QoSCube * getQoSCube() const
Definition: DTP.cc:196
PDUQ_t * getGeneratedPDUQ()
Definition: DTPState.cc:409
unsigned int getClosedWinQueLen() const
Definition: DTCPState.cc:337
ConnectionId connId
Definition: DTP.h:113
Definition: PDU.h:42
virtual void setAckNackSeqNum(unsigned int ackNackSeqNum)
bool isDtcpPresent() const
Definition: DTPState.cc:162
virtual void setFlags(int flags)
Definition: PDU_m.cc:361
void clearReassemblyPDUQ()
Definition: DTPState.cc:140
void setQoSCube(const QoSCube *&qoSCube)
Definition: DTPState.cc:448
const Address & getSrcAddr() const
Gets source Address, which is the address of communication start-point.
Definition: Flow.cc:158
InitialSeqNumPolicyBase * initialSeqNumPolicy
Definition: DTP.h:81
unsigned int delimit(SDUData *sduData)
Definition: DTP.cc:1171
unsigned long getSendingTimeUnit()
Definition: DTCP.cc:583
void addPDUToReassemblyQ(DataTransferPDU *pdu)
Definition: DTPState.cc:364
cGate * northI
Definition: DTP.h:106
bool isClosedWindow() const
Definition: DTCPState.cc:328
void runSenderInactivityTimerPolicy()
Definition: DTP.cc:1633
DTCP * dtcp
Definition: DTP.h:73
void incDupAcks()
Definition: DTCP.cc:680
unsigned int getMaxClosedWinQueLen() const
Definition: DTCPState.cc:341
virtual unsigned int getRcvRate() const
unsigned int getSndRtWinEdge()
Definition: DTCP.cc:558
bool commonRcvControl(ControlPDU *pdu)
Definition: DTP.cc:488
unsigned int getRcvLeftWinEdge() const
Definition: DTPState.cc:258
const QoSCube * getQoSCube() const
Definition: DTPState.cc:433
bool runRcvrFCPolicy(DTPState *dtpState)
Definition: DTCP.cc:168
virtual void setDataType(int dataType)
Definition: Data_m.cc:221
bool runReceivingFCPolicy(DTPState *dtpState)
Definition: DTCP.cc:182
void updateRcvLWE(unsigned int seqNum)
Definition: DTPState.cc:453
virtual void setRcvLeftWinEdge(unsigned int rcvLeftWinEdge)
virtual void initialize(int step)
Definition: DTP.cc:116
const char * DTP_SEQ_NUM_SENT
Definition: DTP.cc:28
void sendControlAckPDU()
Definition: DTP.cc:1514
void incMaxSeqNumRcvd()
Definition: DTPState.cc:203
bool isRateBased() const
Definition: DTCPState.cc:517
virtual unsigned int getSeqNum() const
Definition: PDU_m.cc:376
#define SENDER_INACTIVITY_POLICY_NAME
Definition: EFCP.cc:83
std::vector< DataTransferPDU * > PDUQ_t
void handleControlPDUFromRMT(ControlPDU *pdu)
Definition: DTP.cc:602
bool isRxPresent() const
Definition: DTCPState.cc:525
void stopReliableCPDUTimer()
Definition: DTCP.cc:467
void setTmpAtimer(ATimer *tmpAtimer)
Definition: DTPState.cc:483
void handleQueueInfoFromSocket(QueueInfo *queueInfo)
Definition: DTP.cc:95
virtual void setSeqNum(unsigned int seqNum)
Definition: PDU_m.cc:381
simsignal_t sigStatDTPRTT
Definition: DTP.h:289
unsigned int getPdusRcvdInTimeUnit() const
Definition: DTCP.cc:603
void setSetDrfFlag(bool setDrfFlag)
Definition: DTPState.cc:314
unsigned int getRcvRightWinEdge() const
Definition: DTCPState.cc:178
cModule * createPolicyModule(const char *prefix, const char *name)
Definition: DTP.cc:65
void pushBackToPostablePDUQ(DataTransferPDU *pdu)
Definition: DTPState.cc:424
simsignal_t sigStatDTPClosedWinQ
Definition: DTP.h:290
virtual void setSrcApn(const APN &srcApn)
Definition: PDU_m.cc:321
const char * SIG_EFCP_StopSending
Definition: RINASignals.cc:142
RcvrInactivityTimer * rcvrInactivityTimer
Definition: DTP.h:95
virtual int getType() const
Definition: PDU_m.cc:346
unsigned int getSndLeftWinEdge() const
Definition: DTCP.cc:87
virtual unsigned int getNackList(unsigned int k) const
bool runLostControlPDUPolicy(DTPState *dtpState)
Definition: DTCP.cc:200
const PDU * getCurrentPdu() const
Definition: DTPState.cc:339
void setRendezSeqNum(unsigned int rendezSeqNum)
Definition: DTCPState.cc:596
bool runSendingAckPolicy(DTPState *dtpState, ATimer *timer)
Definition: DTCP.cc:192
unsigned int getRcvrRate() const
Definition: DTCP.cc:69
bool isSndRendez() const
Definition: DTCPState.cc:571
virtual void setRcvRate(unsigned int rcvRate)
int deletePdu
Definition: DTP.h:68
void incDupFC()
Definition: DTCP.cc:691
void sendAckFlowPDU(unsigned int seqNum=0, bool seqNumValid=false)
Definition: DTP.cc:565
unsigned int getSndLeftWinEdge() const
Definition: DTCPState.cc:134
virtual unsigned int getRendezSeqNum() const
double getRtt() const
Definition: DTPState.cc:303
unsigned int getRcvRightWinEdge()
Definition: DTCP.cc:573
virtual unsigned int getNackListLen() const
cGate * southI
Definition: DTP.h:110
#define DRF_FLAG
Definition: PDU.h:36
std::vector< DataTransferPDU * > * getReassemblyPDUQ()
Definition: DTPState.cc:351
SenderInactivityPolicyBase * senderInactivityPolicy
Definition: DTP.h:80
void delimitFromRMT()
Definition: DTP.cc:468
bool runReconcileFCPolicy(DTPState *dtpState)
Definition: DTCP.cc:265
Class representing QoSCube with all its properties that is primarily used by FA, RMT and RA Specifica...
Definition: QoSCube.h:57
const ConnectionId & getConId() const
Gets read-only Flow's ConnectionId.
Definition: Flow.cc:86
virtual DataTransferPDU * dup() const
virtual ~DTP()
Definition: DTP.cc:53
void handleMsgFromUp(UserDataField *userDataField)
Definition: DTP.cc:437
virtual void setCompleteSDU(bool completeSDU)
simsignal_t sigEFCPStartSending
Definition: DTP.h:286
unsigned int getDataReXmitMax() const
Definition: DTCP.cc:406
virtual void setLastCtrlSeqNumRcv(unsigned int lastCtrlSeqNumRcv)
Definition: SDU.h:47
unsigned int getDropDup() const
Definition: DTPState.cc:428
void setDTCP(DTCP *dtcp)
Definition: DTP.cc:1774
bool runNoRateSlowDownPolicy(DTPState *dtpState)
Definition: DTCP.cc:257
DTCPState * getDTCPState() const
Definition: DTCP.cc:54
const char * GATE_DTP_NORTHIO
void setSndRtWinEdge(unsigned int sndRtWinEdge)
Definition: DTCP.cc:552
virtual void setRcvRightWinEdge(unsigned int rcvRightWinEdge)
double getATime()
Definition: DTP.cc:857
virtual void setSndRate(unsigned int sndRate)
void incDropDup()
Definition: DTPState.h:130
bool isFCPresent()
Definition: DTCPState.h:217
std::vector< DataTransferPDU * > * getClosedWindowQ()
Definition: DTCPState.cc:312
virtual void setSndRightWinEdge(unsigned int sndRightWinEdge)
DTP()
Definition: DTP.cc:32
virtual void setSndLeftWinEdge(unsigned int sndLeftWinEdge)
void nackPDU(unsigned int startSeqNum, unsigned int endSeqNum=0)
Definition: DTCP.cc:292
void setRendezvousTimer(DTCPRendezvousTimer *rendezvousTimer)
Definition: DTCPState.cc:586
const char * GATE_DTP_SOUTHIO
#define RTT_ESTIMATOR_POLICY_NAME
Definition: EFCP.cc:89
virtual int getFlags() const
Definition: PDU_m.cc:356
void sendAckOnlyPDU(unsigned int seqNum)
Definition: DTP.cc:1490
void setLastSeqNumSent(unsigned int lastSeqNumSent)
Definition: DTPState.cc:324
void startRendezvousTimer()
Definition: DTCP.cc:107
const char * SIG_EFCP_StartSending
Definition: RINASignals.cc:143
unsigned int getRxQLen()
Definition: DTCPState.cc:512
bool pduDroppingEnabled
Definition: DTP.h:69
unsigned int getNextSndCtrlSeqNum()
Definition: DTCP.cc:537
void setClosedWindow(bool closedWindow)
Definition: DTCPState.cc:333
virtual void encapsulate(Data *data)
Definition: PDUData.cc:59
void handleQueueInfoFromRMT(QueueInfo *queueInfo)
Definition: DTP.cc:1788
void initSignalsAndListeners()
Definition: DTP.cc:104
virtual unsigned int getAckNackSeqNum() const
void clearRxQ()
Definition: DTCP.cc:401
std::vector< UserDataField * > userDataFieldQOut
Definition: DTP.h:87
const Address & getDstAddr() const
Gets source Address, which is the address of communication end-point.
Definition: Flow.cc:150
virtual int getAction() const
#define RCVR_INACTIVITY_POLICY_NAME
Definition: EFCP.cc:80
void runCongestionNotificationPolicy()
Definition: DTP.cc:90
void setFlow(const Flow *flow)
Definition: DTP.cc:1769
unsigned int getAllowableGap()
Definition: DTP.cc:1678
void cancelATimer(unsigned int seqNum)
Definition: DTP.cc:800
void setQoSCube(const QoSCube *qosCube)
Definition: DTP.cc:205
bool isATimerQEmpty()
Definition: DTP.cc:789
cGate * southO
Definition: DTP.h:111
bool runNoOverridePeakPolicy(DTPState *dtpState)
Definition: DTCP.cc:240
void setLastControlSeqNumSent(unsigned int lastControlSeqNumSent)
Definition: DTCPState.cc:556
bool setDRFInPDU(bool override)
Definition: DTP.cc:1212
const char * DTP_SEQ_NUM_RCVD
Definition: DTP.cc:27
void setLastCtrlSeqnumRcvd(unsigned int ctrlSeqNum)
Definition: DTCP.cc:547
void pushBackToRxQ(DataTransferPDU *pdu)
Definition: DTCP.cc:390
void setConnId(const ConnectionId &connId)
Definition: DTP.cc:294
virtual unsigned int getRcvRightWinEdge() const
DTCPRendezvousTimer * getRendezvousTimer()
Definition: DTCPState.cc:581
void flushAllQueuesAndPrepareToDie()
Definition: DTP.cc:225
const char * SIG_STAT_DTP_RTT
Definition: DTP.cc:25
unsigned int getLastCtrlSeqNumRcv()
Definition: DTCP.cc:542
void handleDataTransferPDUFromRMT(DataTransferPDU *pdu)
Definition: DTP.cc:862
virtual void setRendezSeqNum(unsigned int rendezSeqNum)
virtual void setConnId(const ConnectionId &connId)
Definition: PDU_m.cc:341
void setRcvRendez(bool rcvRendez)
Definition: DTCPState.cc:566
simsignal_t sigEFCPStahpSending
Definition: DTP.h:285
virtual void setSndLeftWinEdge(unsigned int sndLeftWinEdge)
bool runSndFCOverrunPolicy(DTPState *dtpState)
Definition: DTCP.cc:225
void setCurrentPdu(PDU *currentPdu)
Definition: DTPState.cc:344
const APNamingInfo & getDstApni() const
Gets read-only destination APNamingInfo.
Definition: Flow.cc:102
void setState(DTPState *state)
Definition: DTP.cc:1783
std::vector< ATimer * > aTimerQ
Definition: DTP.h:89
void setBlockingPort(bool blockingPort)
Definition: DTPState.cc:48
const char * SIG_STAT_DTP_CLOSED_WIN_Q
Definition: DTP.cc:26
bool runRcvFCOverrunPolicy(DTPState *dtpState)
Definition: DTCP.cc:233
void clearRxQ()
Definition: DTP.cc:1731
Definition: DTP.h:60
void notifyAboutUnableMaintain()
Definition: DTP.cc:1565
void pushBackToClosedWinQ(DataTransferPDU *pdu)
Definition: DTCPState.cc:305
bool runECNSlowDownPolicy(DTPState *dtpState)
Definition: DTCP.cc:282
void flushReassemblyPDUQ()
Definition: DTP.cc:1726
bool rendezvousEnabled
Definition: DTP.h:70
const Flow * flow
Definition: DTP.h:74
int getMaxAllowGap() const
Gets Maximum Allowable Gap in SDUs parameter.
Definition: QoSCube.cc:316
virtual int getType() const
Definition: DTPTimers_m.cc:221
void changeInBuffers()
Definition: DTP.cc:307
void setMaxSeqNumRcvd(unsigned int maxSeqNumRcvd)
Definition: DTPState.cc:198
unsigned int getNextSeqNumToSendWithoutIncrement()
Definition: DTPState.cc:220