Switch to side-by-side view

--- a/src/DIF/RMT/RMTPort.cc
+++ b/src/DIF/RMT/RMTPort.cc
@@ -24,30 +24,37 @@
 
 void RMTPort::initialize()
 {
-    ready = false; // port should get activated by RA
+    outputReady = false; // port should get activated by RA
+    inputReady = false; // port should get activated by RA
     blockedOutput = false;
     blockedInput = false;
 
+    inputReadRate = 0;
+    postReadDelay = 0.0;
+
     waitingOnInput = 0;
     waitingOnOutput = 0;
 
     southInputGate = gateHalf(GATE_SOUTHIO, cGate::INPUT);
     southOutputGate = gateHalf(GATE_SOUTHIO, cGate::OUTPUT);
-    postServeDelay = par("postServeDelay").doubleValue() / 1000;
 
     queueIdGen = check_and_cast<QueueIDGenBase*>
             (getModuleByPath("^.^.^.resourceAllocator.queueIdGenerator"));
 
     sigStatRMTPortUp = registerSignal(SIG_STAT_RMTPORT_UP);
     sigStatRMTPortDown = registerSignal(SIG_STAT_RMTPORT_DOWN);
-    sigRMTPortReady = registerSignal(SIG_RMT_PortReadyToServe);
-
-    WATCH(ready);
+    sigRMTPortReadyToWrite = registerSignal(SIG_RMT_PortReadyToServe);
+    sigRMTPortReadyForRead = registerSignal(SIG_RMT_PortReadyForRead);
+
+    WATCH(outputReady);
+    WATCH(inputReady);
+
+    WATCH(waitingOnOutput);
     WATCH(waitingOnInput);
-    WATCH(waitingOnOutput);
+    WATCH(inputReadRate);
+
+    WATCH(blockedOutput);
     WATCH(blockedInput);
-    WATCH(blockedOutput);
-    WATCH(postServeDelay);
     WATCH_PTR(flow);
 }
 
@@ -64,13 +71,17 @@
         if (!opp_strcmp(msg->getFullName(), "portTransmitEnd"))
         { // a PDU transmit procedure has just been finished
             emit(sigStatRMTPortDown, true);
-            setReadyDelayed();
+            scheduleNextWrite();
         }
         else if (!opp_strcmp(msg->getFullName(), "readyToServe"))
         {
-            setReady();
-            emit(sigRMTPortReady, this);
-        }
+            setOutputReady();
+        }
+        else if (!opp_strcmp(msg->getFullName(), "readyForRead"))
+        {
+            setInputReady();
+        }
+
         delete msg;
     }
     else if (msg->getArrivalGate() == southInputGate) // incoming message
@@ -106,6 +117,7 @@
         cPacket* packet = NULL;
         if ((packet = dynamic_cast<cPacket*>(msg)) != NULL)
         {
+            setOutputBusy();
             // start the transmission
             send(packet, southOutputGate);
 
@@ -119,15 +131,15 @@
                 }
                 else
                 {
-                    setReadyDelayed();
+                    scheduleNextWrite();
                     emit(sigStatRMTPortDown, true);
                 }
             }
             else
             { // there isn't any delay or rate control in place
-                setReadyDelayed();
+                scheduleNextWrite();
                 emit(sigStatRMTPortDown, true);
-                emit(sigRMTPortReady, this);
+                emit(sigRMTPortReadyToWrite, this);
             }
         }
         else
@@ -234,37 +246,91 @@
     return NULL;
 }
 
-bool RMTPort::isReady()
-{
-    return ready;
-}
-
-void RMTPort::setReady()
+bool RMTPort::isOutputReady()
+{
+    return outputReady;
+}
+
+void RMTPort::setOutputReady()
 {
     if (blockedOutput == false)
     {
-        ready = true;
-        emit(sigRMTPortReady, this);
+        outputReady = true;
+        emit(sigRMTPortReadyToWrite, this);
         redrawGUI();
     }
 }
 
-void RMTPort::setReadyDelayed()
-{
-    scheduleAt(simTime() + postServeDelay, new cMessage("readyToServe"));
-}
-
-void RMTPort::setBusy()
-{
-    ready = false;
+void RMTPort::setOutputBusy()
+{
+    outputReady = false;
     redrawGUI();
 }
 
+bool RMTPort::isInputReady()
+{
+    return inputReady;
+}
+
+void RMTPort::setInputReady()
+{
+    if (blockedInput == false)
+    {
+        inputReady = true;
+        emit(sigRMTPortReadyForRead, this);
+        redrawGUI();
+    }
+}
+
+void RMTPort::setInputBusy()
+{
+    inputReady = false;
+    redrawGUI();
+}
+
+void RMTPort::scheduleNextWrite()
+{
+    scheduleAt(simTime(), new cMessage("readyToServe"));
+}
+
+void RMTPort::scheduleNextRead()
+{
+    Enter_Method_Silent("scheduleNextRead()");
+    setInputBusy();
+    scheduleAt(simTime() + postReadDelay, new cMessage("readyForRead"));
+}
+
+unsigned long RMTPort::getWaiting(RMTQueueType direction)
+{
+    return (direction == RMTQueue::INPUT ? waitingOnInput : waitingOnOutput);
+}
+
+void RMTPort::addWaiting(RMTQueueType direction)
+{
+    direction == RMTQueue::INPUT ? waitingOnInput++ : waitingOnOutput++;
+}
+
+void RMTPort::substractWaiting(RMTQueueType direction)
+{
+    direction == RMTQueue::INPUT ? waitingOnInput-- : waitingOnOutput--;
+}
+
+long RMTPort::getInputRate()
+{
+    return inputReadRate;
+}
+
+void RMTPort::setInputRate(long pdusPerSecond)
+{
+    inputReadRate = pdusPerSecond;
+    postReadDelay = 60.0 / pdusPerSecond;
+}
+
 void RMTPort::redrawGUI(bool redrawParent)
 {
     if (ev.isGUI())
     {
-        getDisplayString().setTagArg("i2", 0, (isReady() ? "status/green" : "status/noentry"));
+        getDisplayString().setTagArg("i2", 0, (isOutputReady() ? "status/green" : "status/noentry"));
 
         if (redrawParent)
         {
@@ -301,7 +367,7 @@
     {
         if (flow != NULL)
         {
-            // shitty temporary hack to strip the layer name off
+            // shitty temporary (yeah, right) hack to strip the layer name off
             const std::string& dstAppFull = flow->getDstApni().getApn().getName();
             dstAppAddr = dstAppFull.substr(0, dstAppFull.find("_"));
         }
@@ -317,9 +383,9 @@
 {
     EV << getFullPath() << ": blocking the port output." << endl;
     blockedOutput = true;
-    if (ready)
-    {
-        setBusy();
+    if (outputReady)
+    {
+        setOutputBusy();
     }
     redrawGUI(true);
 }
@@ -328,7 +394,7 @@
 {
     EV << getFullPath() << ": unblocking the port output." << endl;
     blockedOutput = false;
-    setReady();
+    setOutputReady();
     redrawGUI(true);
 }
 
@@ -343,5 +409,6 @@
 {
     EV << getFullPath() << ": unblocking the port input." << endl;
     blockedInput = false;
+    setInputReady();
     redrawGUI(true);
 }