a b/src/policies/DIF/Routing/SimpleRouting/SimpleDV/SimpleDV.cc
1
#include <SimpleDV/SimpleDV.h>
2
3
namespace SimpleDV {
4
5
Register_Class(SimpleDV);
6
7
using namespace std;
8
9
10
RoutingUpdate::RoutingUpdate(const Address &_addr, const std::string &_src, const unsigned short &_qos):IntRoutingUpdate(_addr){
11
    src = _src;
12
    qos = _qos;
13
}
14
15
std::string RoutingUpdate::getSrc(){
16
    return src;
17
}
18
unsigned short RoutingUpdate::getQoS(){
19
    return qos;
20
}
21
22
void RoutingUpdate::addEntry(rtEntry entry){
23
    entries.push_back(entry);
24
}
25
26
entriesIt RoutingUpdate::entriesBegin(){
27
    return entries.begin();
28
}
29
entriesIt RoutingUpdate::entriesEnd(){
30
    return entries.end();
31
}
32
33
34
//Flow inserted/removed
35
void SimpleDV::insertFlow(const Address &addr, const std::string &dst, const unsigned short &qos, const unsigned short &metric){
36
37
    neig[qos][addr] = metric;
38
39
    rtEntry * oldEntry = &table[qos][dst];
40
41
    bool entryChangedDst = false;
42
43
    if(oldEntry->addr == dst){
44
        if(oldEntry->metric != metric){
45
            oldEntry->metric = metric;
46
        }
47
    } else if(oldEntry->metric >= metric){
48
        oldEntry->addr = dst;
49
        oldEntry->metric = metric;
50
        entryChangedDst = true;
51
    }
52
53
    if(oldEntry->metric >= infMetric){
54
        changes.insert(entries2NextItem(qosPaddr(qos, dst),""));
55
        table[qos].erase(dst);
56
    } else if(entryChangedDst){
57
        changes.insert(entries2NextItem(qosPaddr(qos, dst),dst));
58
    }
59
}
60
void SimpleDV::removeFlow(const Address &addr, const std::string &dst, const unsigned short &qos){
61
    neig[qos].erase(addr);
62
    if(neig[qos].size() <= 0){
63
        neig.erase(qos);
64
    }
65
66
    tTable * qosTable = &table[qos];
67
68
    for(tTableIt it = qosTable->begin(); it != qosTable->end();){
69
        rtEntry * oldEntry = &it->second;
70
        tTableIt actIt = it;
71
        it++;
72
73
        if(oldEntry->addr == dst){
74
            changes.insert(entries2NextItem(qosPaddr(qos, oldEntry->addr),""));
75
            qosTable->erase(actIt);
76
        }
77
    }
78
}
79
80
//Get Changes
81
entries2Next SimpleDV::getChanges(){
82
    entries2Next ret = changes;
83
    changes.clear();
84
    return ret;
85
}
86
87
entries2Next SimpleDV::getAll(){
88
    entries2Next ret;
89
90
    for(rtTableIt it = table.begin(); it != table.end(); it++){
91
        for(tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
92
            if(it2->second.metric < infMetric) {
93
                ret[qosPaddr(it->first, it2->first)] = it2->second.addr;
94
            } else {
95
                ret[qosPaddr(it->first, it2->first)] = "";
96
            }
97
        }
98
    }
99
    map<unsigned short, map<string, rtEntry> > table;
100
101
    return ret;
102
}
103
104
//Process a Routing Update, return true => inform FWDG of the update
105
bool SimpleDV::processUpdate(IntRoutingUpdate * update){
106
    RoutingUpdate * up = check_and_cast<RoutingUpdate*>(update);
107
108
    std::string src = up->getSrc();
109
    if(src == myAddr){
110
        return false;
111
    }
112
113
    unsigned short qos = up->getQoS();
114
115
    for(entriesIt it = up->entriesBegin(); it!= up->entriesEnd(); it++){
116
        if(it->addr == myAddr) {
117
            continue;
118
        }
119
120
        rtEntry * newEntry = &(*it);
121
        rtEntry * oldEntry = &table[qos][newEntry->addr];
122
123
        bool entryChangedDst = false;
124
125
        if(oldEntry->addr == newEntry->addr){
126
            if(oldEntry->metric == newEntry->metric){
127
                oldEntry->metric = newEntry->metric;
128
            }
129
        } else if(oldEntry->metric >= newEntry->metric){
130
            oldEntry->addr = src;
131
            oldEntry->metric = newEntry->metric;
132
            entryChangedDst = true;
133
        }
134
135
        if(oldEntry->metric >= infMetric){
136
            changes.insert(entries2NextItem(qosPaddr(qos, newEntry->addr),""));
137
            table[qos].erase(newEntry->addr);
138
        } else if(entryChangedDst){
139
            changes.insert(entries2NextItem(qosPaddr(qos, newEntry->addr),src));
140
        }
141
    }
142
    return ! changes.empty();
143
}
144
145
// Called after initialize
146
void SimpleDV::onPolicyInit(){
147
    myAddr = par("myAddr").stdstringValue();
148
    if(myAddr == "") {
149
        myAddr = myAddress.getIpcAddress().getName();
150
    }
151
152
    infMetric = 32;
153
154
    scheduleAt(simTime()+30, new cMessage("Time2Update"));
155
}
156
157
158
void SimpleDV::handleMessage(cMessage *msg){
159
    if(msg->isSelfMessage()){
160
        //Iterate all Qos
161
        for(qosNeighMetricIt it = neig.begin(); it!= neig.end(); it++){
162
            //getTable per QoS
163
            tTable * qosTable = &table[it->first];
164
165
            //iterate all Qos->Neighbour
166
            for(neighMetricIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
167
                //New Update to QoS + Neighbour
168
                RoutingUpdate * update = new RoutingUpdate(it2->first, myAddr, it->first);
169
170
                //Populate the update
171
                for(tTableIt it3 = qosTable->begin(); it3 != qosTable->end();it3++){
172
                    update->addEntry(rtEntry(it3->first, it3->second.metric+ it2->second));
173
                }
174
175
                //Add our entry
176
                update->addEntry(rtEntry(myAddr, it2->second));
177
178
                //And send
179
                sendUpdate(update);
180
            }
181
        }
182
183
        scheduleAt(simTime()+30, msg);
184
    }
185
}
186
187
188
void SimpleDV::finish(){
189
    IntRouting::finish();
190
191
    EV << "I'm " << myAddr<<endl;
192
193
    for (rtTableIt it = table.begin(); it != table.end(); it++)
194
    {
195
        EV << "  QoS " << it->first << endl;
196
        for (tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++)
197
        {
198
            EV << "    " << it2->first << " via " << it2->second.addr << " ("
199
                    << it2->second.metric << " hops)" << endl;
200
        }
201
    }
202
203
}
204
205
}