Switch to side-by-side view

--- a
+++ b/src/policies/DIF/Routing/DomainRouting/DV/DV.cc
@@ -0,0 +1,204 @@
+/*
+ * DV.cc
+ *
+ *  Created on: Mar 23, 2015
+ *      Author: gaixas1
+ */
+
+#include "DomainRouting/DV/DV.h"
+#include "DomainRouting/Routing.h"
+
+namespace DMRnmsDV {
+
+using namespace DMRnms;
+using namespace std;
+
+DVUpdate::DVUpdate(const Address &_addr, const string &_domain)
+    :RoutingUpdate(_addr, _domain){}
+
+void DVUpdate::addEntry(rtEntry _e) {
+    entries.push_back(_e);
+}
+
+entriesIt DVUpdate::entriesBegin() {
+    return entries.begin();
+}
+
+entriesIt DVUpdate::entriesEnd() {
+    return entries.end();
+}
+
+
+DV::DV(Routing * parent, const Address &_nAddr, const string &_domain, const string &_addr)
+    :rModule(parent, _nAddr,_domain, _addr) {
+    infMetric = 32;
+    scheduledUpdate = false;
+    myAddrSet.insert(_addr);
+}
+
+bool DV::processUpdate(RoutingUpdate * update){
+    // Cast update to known type
+    DVUpdate * up = dynamic_cast<DVUpdate*>(update);
+    if(up == NULL) { return false; }
+
+    // Check I'm not the src
+    Address src = up->getSource();
+    if(src == myNAddress){ return false; }
+
+
+    for(entriesIt newE = up->entriesBegin(); newE!= up->entriesEnd(); newE++){
+        // Not consider entries to myself or my aliasses
+        if(myAddrSet.find(newE->addr) != myAddrSet.end()){ continue; }
+
+        tEntry * oldE = &table[newE->addr];
+        bool entryChanged = false;
+
+        if(oldE->addr == src){
+            if(oldE->metric == newE->metric){
+                oldE->metric = newE->metric;
+            }
+        } else if(oldE->metric >= newE->metric){
+            oldE->addr = src;
+            oldE->metric = newE->metric;
+            entryChanged = true;
+        }
+
+        if(oldE->metric >= infMetric){
+            changes[newE->addr] = Address();
+            table.erase(newE->addr);
+        } else if(entryChanged){
+            changes[newE->addr] = src;
+            changedEntries.insert(newE->addr);
+        }
+    }
+
+    if(! changes.empty()) {
+        scheduleUpdate();
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void DV::addFlow(const Address &_nAddr, const std::string &_addr, const unsigned short &_metric){
+    nei[_nAddr] = _metric;
+
+    tEntry * oldE = &table[_addr];
+    bool entryChangedDst = false, entryChanged = false;
+    if(oldE->addr == _nAddr){
+        if(oldE->metric != _metric){
+            oldE->metric = _metric;
+            entryChanged = true;
+        }
+    } else if (oldE->metric >= _metric) {
+        oldE->addr = _nAddr;
+        oldE->metric = _metric;
+        entryChanged = true;
+        entryChangedDst = true;
+    }
+
+    if(oldE->metric >= infMetric){
+        changes[_addr] = Address();
+        table.erase(_addr);
+    } else {
+        if(entryChanged){
+            changedEntries.insert(_addr);
+        }
+        if(entryChangedDst){
+            changes[_addr] = _nAddr;
+        }
+    }
+
+    scheduleUpdate();
+}
+
+void DV::removeFlow(const Address &_nAddr, const std::string &_addr){
+    nei.erase(_nAddr);
+
+    for(tTableIt it = table.begin(); it != table.end();){
+        tEntry * oldE = &it->second;
+        tTableIt actIt = it++;
+
+        if(oldE->addr == _nAddr){
+            table.erase(actIt);
+            changedEntries.insert(_addr);
+            changes[_addr] = Address();
+        }
+    }
+
+    scheduleUpdate();
+}
+
+void DV::addAddr(const std::string &_addr){
+    myAddrSet.insert(_addr);
+}
+
+void DV::removeAddr(const std::string &_addr){
+    myAddrSet.erase(_addr);
+}
+
+void DV::setInfMetric(const unsigned short &inf){
+    infMetric = inf;
+}
+
+dmNxt DV::getChanges(){
+    dmNxt ret(domain, changes);
+    changes.clear();
+    return ret;
+}
+
+dmNxt DV::getAll() {
+    dmNxt ret(domain);
+
+    for(tTableIt it = table.begin(); it != table.end(); it++){
+        if(it->second.metric < infMetric){
+            ret.entries[it->first] = it->second.addr;
+        } else {
+            ret.entries[it->first] = Address();
+        }
+    }
+
+    changes.clear();
+    return ret;
+}
+
+void DV::handleMessage(cMessage *msg){
+    if(msg->isSelfMessage()){
+
+        //iterate all Neighbour
+        for(neighMetricIt itN = nei.begin(); itN != nei.end(); itN++){
+            //New Update to Neighbour
+            DVUpdate * update = new DVUpdate(itN->first, domain);
+
+            //Populate the update
+            for(sSetIt cIt = changedEntries.begin(); cIt != changedEntries.end(); cIt++){
+                tEntry * rt = &table[*cIt];
+                update->addEntry(
+                        rtEntry(*cIt, rt->metric + itN->second)
+                        );
+            }
+
+            //Add our entries
+            update->addEntry(rtEntry(myAddr, itN->second));
+            for(sSetIt mIt = myAddrSet.begin(); mIt != myAddrSet.end(); mIt++){
+                update->addEntry(rtEntry(*mIt, itN->second));
+            }
+
+            parent->chSendUpdate(update);
+        }
+
+        changedEntries.clear();
+        scheduledUpdate = false;
+    }
+    delete msg;
+}
+
+
+void DV::scheduleUpdate(){
+    if(!scheduledUpdate){
+        scheduledUpdate = true;
+        scheduleAt(1, new cMessage("Time2Update"));
+    }
+}
+
+} /* namespace DomainRouting */