a b/src/policies/DIF/Routing/SimpleRouting/SimpleLS/SimpleLS.cc
1
#include <SimpleLS/SimpleLS.h>
2
3
namespace SimpleLS {
4
5
Register_Class(SimpleLS);
6
7
using namespace std;
8
9
10
RoutingUpdate::RoutingUpdate(const Address &_addr, const unsigned short &_qos):IntRoutingUpdate(_addr){
11
    qos = _qos;
12
}
13
14
unsigned short RoutingUpdate::getQoS(){
15
    return qos;
16
}
17
18
void RoutingUpdate::addEntry(const std::string & id, linksU links){
19
    entries.insert(linksStEntry(id, links));
20
}
21
22
void RoutingUpdate::setEntries(linksSt _entries){
23
    RoutingUpdate::entries = _entries;
24
}
25
26
linksStIt RoutingUpdate::entriesBegin(){
27
    return entries.begin();
28
}
29
linksStIt RoutingUpdate::entriesEnd(){
30
    return entries.end();
31
}
32
33
34
//Flow inserted/removed
35
void SimpleLS::insertFlow(const Address &addr, const std::string &dst, const unsigned short &qos, const unsigned short &metric){
36
    neig[qos][addr] = metric;
37
    lastChanges[qos].insert(myAddr);
38
    secId++;
39
    linksU * myEntry = &(netState[qos][myAddr]);
40
    myEntry->sId = secId;
41
    myEntry->links[dst] = metric;
42
    scheduleUpdate();
43
}
44
void SimpleLS::removeFlow(const Address &addr, const std::string &dst, const unsigned short &qos){
45
    neig[qos].erase(addr);
46
    if(neig[qos].size() <= 0){
47
        neig.erase(qos);
48
    }
49
    lastChanges[qos].insert(myAddr);
50
    secId++;
51
    linksU * myEntry = &(netState[qos][myAddr]);
52
    myEntry->sId = secId;
53
    myEntry->links.erase(dst);
54
    scheduleUpdate();
55
}
56
57
58
void SimpleLS::scheduleUpdate(){
59
    Enter_Method_Silent();
60
    if(!scheduledUpdate){
61
        scheduledUpdate = true;
62
        scheduleAt(simTime()+1, new cMessage("Time2Update"));
63
    }
64
}
65
66
67
//Get Changes
68
entries2Next SimpleLS::getChanges(){
69
    entries2Next ret;
70
    for(linksStColIt qosIt = netState.begin(); qosIt != netState.end(); qosIt++){
71
        unsigned short qos = qosIt->first;
72
        TreeNode t = constructTree(qosIt->second);
73
        for(TreeNodeIt it = t.chl.begin(); it != t.chl.end(); it++){
74
            ret[qosPaddr(qos, (*it)->addr)] = (*it)->addr;
75
            addRecursive(ret, qos, (*it)->addr, *it);
76
        }
77
    }
78
79
    entries2Next t = ret;
80
81
    for(entries2NextIt tIt = table.begin(); tIt != table.end(); tIt++){
82
        if (ret[tIt->first]  == tIt->second){
83
            ret.erase(tIt->first);
84
        }
85
    }
86
    table = t;
87
88
    return ret;
89
}
90
91
entries2Next SimpleLS::getAll(){
92
    entries2Next ret;
93
94
    for(linksStColIt qosIt = netState.begin(); qosIt != netState.end(); qosIt++){
95
        unsigned short qos = qosIt->first;
96
        TreeNode t = constructTree(qosIt->second);
97
        for(TreeNodeIt it = t.chl.begin(); it != t.chl.end(); it++){
98
            ret[qosPaddr(qos, (*it)->addr)] = (*it)->addr;
99
            addRecursive(ret, qos, (*it)->addr, *it);
100
        }
101
    }
102
103
    table = ret;
104
    return table;
105
}
106
107
TreeNode SimpleLS::constructTree(linksSt &ls){
108
    TreeNode t(myAddr, 0);
109
    aMap added;
110
    added[myAddr] = 0;
111
112
    wMap waiting;
113
    aMap * links = &(ls[myAddr].links);
114
    for(linksIt it = links->begin(); it !=links->end(); it++){
115
        waiting[it->first] = psT(&t, it->second);
116
    }
117
118
119
    while(!waiting.empty()){
120
        unsigned short min = UINT16_MAX;
121
        addrList mins;
122
123
        for (wMapIt it = waiting.begin(); it != waiting.end(); it++){
124
            if(it->second.metric < min){
125
                min = it->second.metric;
126
                mins.clear();
127
            }
128
            if(it->second.metric == min){
129
                mins.push_back(it->first);
130
            }
131
        }
132
133
        while(!mins.empty()){
134
            string addr = mins.back();
135
            mins.pop_back();
136
137
            psT ps = waiting[addr];
138
            waiting.erase(addr);
139
140
            TreeNode * nt = new TreeNode(addr, ps.metric);
141
            ps.p->chl.insert(nt);
142
143
            added[addr] = ps.metric;
144
145
            links = &(ls[addr].links);
146
147
            for(linksIt it = links->begin(); it !=links->end(); it++){
148
                string daddr = it->first;
149
                if(added.find(daddr) == added.end()){
150
                    wMapIt eI = waiting.find(daddr);
151
                    if(eI == waiting.end()){
152
                        waiting[daddr] = psT(nt, ps.metric + it->second);
153
                    } else if(eI->second.metric > ps.metric + it->second){
154
                        eI->second.metric = ps.metric + it->second;
155
                        eI->second.p = nt;
156
                    }
157
                }
158
            }
159
        }
160
    }
161
162
    return t;
163
}
164
void SimpleLS::addRecursive(entries2Next &ret, const unsigned short &qos, const std::string &next, TreeNode * t){
165
    for(TreeNodeIt it = t->chl.begin(); it != t->chl.end(); it++){
166
        ret[qosPaddr(qos, (*it)->addr)] = next;
167
        addRecursive(ret, qos, next, *it);
168
    }
169
}
170
171
//Process a Routing Update, return true => inform FWDG of the update
172
bool SimpleLS::processUpdate(IntRoutingUpdate * update){
173
    RoutingUpdate * up = check_and_cast<RoutingUpdate*>(update);
174
175
    unsigned short qos = up->getQoS();
176
    linksSt * st = &(netState[qos]);
177
178
    for(linksStIt it = up->entriesBegin(); it != up->entriesEnd(); it++){
179
        string node = it->first;
180
        if((*st)[node].sId < it->second.sId){
181
            (*st)[node] = it->second;
182
            lastChanges[qos].insert(node);
183
        }
184
    }
185
    if(!lastChanges.empty()){
186
        scheduleUpdate();
187
        return true;
188
    }
189
    return false;
190
}
191
192
// Called after initialize
193
void SimpleLS::onPolicyInit(){
194
    myAddr = par("myAddr").stdstringValue();
195
    if(myAddr == "") {
196
        myAddr = myAddress.getIpcAddress().getName();
197
    }
198
199
    infMetric = 32;
200
    secId = 1;
201
}
202
203
204
void SimpleLS::handleMessage(cMessage *msg){
205
    if(msg->isSelfMessage()){
206
        //Iterate all Qos
207
        for(qosNeighMetricIt it = neig.begin(); it!= neig.end(); it++){
208
            //get Changes per QoS;
209
            linksSt _entries = getChangedEntries (it->first);
210
211
            //iterate all Qos->Neighbour
212
            for(neighMetricIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
213
                //New Update to QoS + Neighbour
214
                RoutingUpdate * update = new RoutingUpdate(it2->first, it->first);
215
216
                //Add entries
217
                update->setEntries(_entries);
218
219
                //And send
220
                sendUpdate(update);
221
            }
222
        }
223
224
        lastChanges.clear();
225
        scheduledUpdate = false;
226
    }
227
    delete msg;
228
}
229
230
linksSt SimpleLS::getChangedEntries (const unsigned short &qos){
231
    linksSt ret;
232
    addrSet * set = &lastChanges[qos];
233
    for(addrSetIt it = set->begin(); it != set->end(); it++){
234
        ret.insert(linksStEntry(*it, netState[qos][*it]));
235
    }
236
    return ret;
237
}
238
239
240
void SimpleLS::finish(){
241
    IntRouting::finish();
242
243
    EV << "I'm "<< myAddr<<endl;
244
245
    for(linksStColIt qosIt = netState.begin(); qosIt != netState.end(); qosIt++){
246
        EV << "  QoS " << qosIt->first<<endl;
247
        TreeNode t = constructTree(qosIt->second);
248
249
        for(TreeNodeIt it = t.chl.begin(); it != t.chl.end(); it++){
250
            printTreeNode(*it, (*it)->addr);
251
        }
252
253
    }
254
/*
255
    EV << "LS "<<endl;
256
    for(linksStColIt qosIt = netState.begin(); qosIt != netState.end(); qosIt++){
257
        EV << "  QoS " << qosIt->first<<endl;
258
        for(linksStIt lsIt = qosIt->second.begin(); lsIt != qosIt->second.end(); lsIt++){
259
            EV<<"    " << lsIt->first << "("<<lsIt->second.sId << ")"<< ":"<<endl;
260
            for(linksIt lIt = lsIt->second.links.begin(); lIt != lsIt->second.links.end(); lIt++){
261
                EV<<"      " << lIt->first << "("<<lIt->second << ")"<<endl;
262
            }
263
        }
264
    }
265
*/
266
}
267
268
void SimpleLS::printTreeNode(TreeNode *t, const std::string &next){
269
    EV<<"    " << t->addr << " -> "<<next << " ("<<t->metric<<") " << " c: "<< t->chl.size() << endl;
270
    for(TreeNodeIt it = t->chl.begin(); it != t->chl.end(); it++){
271
        printTreeNode(*it, next);
272
    }
273
}
274
275
}