Switch to side-by-side view

--- a
+++ b/src/policies/DIF/Routing/SimpleRouting/SimpleDV/SimpleDV.cc
@@ -0,0 +1,205 @@
+#include <SimpleDV/SimpleDV.h>
+
+namespace SimpleDV {
+
+Register_Class(SimpleDV);
+
+using namespace std;
+
+
+RoutingUpdate::RoutingUpdate(const Address &_addr, const std::string &_src, const unsigned short &_qos):IntRoutingUpdate(_addr){
+    src = _src;
+    qos = _qos;
+}
+
+std::string RoutingUpdate::getSrc(){
+    return src;
+}
+unsigned short RoutingUpdate::getQoS(){
+    return qos;
+}
+
+void RoutingUpdate::addEntry(rtEntry entry){
+    entries.push_back(entry);
+}
+
+entriesIt RoutingUpdate::entriesBegin(){
+    return entries.begin();
+}
+entriesIt RoutingUpdate::entriesEnd(){
+    return entries.end();
+}
+
+
+//Flow inserted/removed
+void SimpleDV::insertFlow(const Address &addr, const std::string &dst, const unsigned short &qos, const unsigned short &metric){
+
+    neig[qos][addr] = metric;
+
+    rtEntry * oldEntry = &table[qos][dst];
+
+    bool entryChangedDst = false;
+
+    if(oldEntry->addr == dst){
+        if(oldEntry->metric != metric){
+            oldEntry->metric = metric;
+        }
+    } else if(oldEntry->metric >= metric){
+        oldEntry->addr = dst;
+        oldEntry->metric = metric;
+        entryChangedDst = true;
+    }
+
+    if(oldEntry->metric >= infMetric){
+        changes.insert(entries2NextItem(qosPaddr(qos, dst),""));
+        table[qos].erase(dst);
+    } else if(entryChangedDst){
+        changes.insert(entries2NextItem(qosPaddr(qos, dst),dst));
+    }
+}
+void SimpleDV::removeFlow(const Address &addr, const std::string &dst, const unsigned short &qos){
+    neig[qos].erase(addr);
+    if(neig[qos].size() <= 0){
+        neig.erase(qos);
+    }
+
+    tTable * qosTable = &table[qos];
+
+    for(tTableIt it = qosTable->begin(); it != qosTable->end();){
+        rtEntry * oldEntry = &it->second;
+        tTableIt actIt = it;
+        it++;
+
+        if(oldEntry->addr == dst){
+            changes.insert(entries2NextItem(qosPaddr(qos, oldEntry->addr),""));
+            qosTable->erase(actIt);
+        }
+    }
+}
+
+//Get Changes
+entries2Next SimpleDV::getChanges(){
+    entries2Next ret = changes;
+    changes.clear();
+    return ret;
+}
+
+entries2Next SimpleDV::getAll(){
+    entries2Next ret;
+
+    for(rtTableIt it = table.begin(); it != table.end(); it++){
+        for(tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
+            if(it2->second.metric < infMetric) {
+                ret[qosPaddr(it->first, it2->first)] = it2->second.addr;
+            } else {
+                ret[qosPaddr(it->first, it2->first)] = "";
+            }
+        }
+    }
+    map<unsigned short, map<string, rtEntry> > table;
+
+    return ret;
+}
+
+//Process a Routing Update, return true => inform FWDG of the update
+bool SimpleDV::processUpdate(IntRoutingUpdate * update){
+    RoutingUpdate * up = check_and_cast<RoutingUpdate*>(update);
+
+    std::string src = up->getSrc();
+    if(src == myAddr){
+        return false;
+    }
+
+    unsigned short qos = up->getQoS();
+
+    for(entriesIt it = up->entriesBegin(); it!= up->entriesEnd(); it++){
+        if(it->addr == myAddr) {
+            continue;
+        }
+
+        rtEntry * newEntry = &(*it);
+        rtEntry * oldEntry = &table[qos][newEntry->addr];
+
+        bool entryChangedDst = false;
+
+        if(oldEntry->addr == newEntry->addr){
+            if(oldEntry->metric == newEntry->metric){
+                oldEntry->metric = newEntry->metric;
+            }
+        } else if(oldEntry->metric >= newEntry->metric){
+            oldEntry->addr = src;
+            oldEntry->metric = newEntry->metric;
+            entryChangedDst = true;
+        }
+
+        if(oldEntry->metric >= infMetric){
+            changes.insert(entries2NextItem(qosPaddr(qos, newEntry->addr),""));
+            table[qos].erase(newEntry->addr);
+        } else if(entryChangedDst){
+            changes.insert(entries2NextItem(qosPaddr(qos, newEntry->addr),src));
+        }
+    }
+    return ! changes.empty();
+}
+
+// Called after initialize
+void SimpleDV::onPolicyInit(){
+    myAddr = par("myAddr").stdstringValue();
+    if(myAddr == "") {
+        myAddr = myAddress.getIpcAddress().getName();
+    }
+
+    infMetric = 32;
+
+    scheduleAt(simTime()+30, new cMessage("Time2Update"));
+}
+
+
+void SimpleDV::handleMessage(cMessage *msg){
+    if(msg->isSelfMessage()){
+        //Iterate all Qos
+        for(qosNeighMetricIt it = neig.begin(); it!= neig.end(); it++){
+            //getTable per QoS
+            tTable * qosTable = &table[it->first];
+
+            //iterate all Qos->Neighbour
+            for(neighMetricIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
+                //New Update to QoS + Neighbour
+                RoutingUpdate * update = new RoutingUpdate(it2->first, myAddr, it->first);
+
+                //Populate the update
+                for(tTableIt it3 = qosTable->begin(); it3 != qosTable->end();it3++){
+                    update->addEntry(rtEntry(it3->first, it3->second.metric+ it2->second));
+                }
+
+                //Add our entry
+                update->addEntry(rtEntry(myAddr, it2->second));
+
+                //And send
+                sendUpdate(update);
+            }
+        }
+
+        scheduleAt(simTime()+30, msg);
+    }
+}
+
+
+void SimpleDV::finish(){
+    IntRouting::finish();
+
+    EV << "I'm " << myAddr<<endl;
+
+    for (rtTableIt it = table.begin(); it != table.end(); it++)
+    {
+        EV << "  QoS " << it->first << endl;
+        for (tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++)
+        {
+            EV << "    " << it2->first << " via " << it2->second.addr << " ("
+                    << it2->second.metric << " hops)" << endl;
+        }
+    }
+
+}
+
+}