--- a
+++ b/src/DIF/RMT/policies/monitor/RED.cc
@@ -0,0 +1,83 @@
+/*
+ * RED.cpp
+ *
+ * Created on: 17. 11. 2014
+ * Author: cloq
+ */
+
+#include <RED.h>
+
+Define_Module(RED);
+
+void RED::postQueueCreation(RMTQueue* queue)
+{
+ // TODO: fix variable initialization, these are just for demo purposes
+ qAvgLengths[queue] = 0.0;
+ qWeights[queue] = 0.5;
+ qProbabilities[queue] = 0.4;
+ qCounters[queue] = -1;
+}
+
+void RED::preQueueRemoval(RMTQueue* queue)
+{
+ qAvgLengths.erase(queue);
+ qWeights.erase(queue);
+ qProbabilities.erase(queue);
+ qCounters.erase(queue);
+}
+
+
+void RED::run(RMTQueue* queue)
+{
+ maxQPolicy = ModuleAccess<RMTMaxQBase>("maxQueuePolicy").get();
+
+ int length = queue->getLength();
+ int minThresh = queue->getThreshLength();
+ int maxThresh = queue->getMaxLength();
+
+ double avr = qAvgLengths[queue];
+ double wq = qWeights[queue];
+ double maxP = qProbabilities[queue];
+ int count = qCounters[queue];
+
+ simtime_t qTime = queue->getQTime();
+ const char* qname = queue->getFullName();
+
+ if (length > 0)
+ {
+ avr = (1 - wq) * avr + wq * length;
+ }
+ else
+ {
+ const double m = SIMTIME_DBL(simTime() - qTime);
+ avr = pow(1 - wq, m) * avr;
+ }
+
+ qAvgLengths[queue] = avr;
+
+ if (length > maxThresh)
+ {
+ EV << "RED: Queue " << qname << " is full! Dropping the incoming message." << endl;
+ maxQPolicy->run(queue);
+ qCounters[queue] = 0;
+ }
+ else if (minThresh <= avr && avr < maxThresh)
+ {
+ qCounters[queue] += 1;
+ const double pb = maxP * (avr - minThresh) / (maxThresh - minThresh);
+ const double pa = pb / (1 - count * pb);
+ const double rand = dblrand();
+
+ if (rand < pa)
+ {
+ EV << "RED: rand < pa (" << rand << " < " << pa << ")! Executing MaxQPolicy." << endl;
+ maxQPolicy->run(queue);
+ qCounters[queue] = 0;
+ }
+ }
+ else
+ {
+ qCounters[queue] = -1;
+ }
+}
+