RINASim  October 2016
Documentation of framework for OMNeT++
LS.cc
Go to the documentation of this file.
1 // The MIT License (MIT)
2 //
3 // Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 
23 /*
24  * LS.cc
25  *
26  * Created on: Mar 23, 2015
27  * Author: gaixas1
28  */
29 
30 #include "DomainRouting/LS/LS.h"
31 #include "DomainRouting/Routing.h"
32 
33 namespace DMRnmsLS {
34 
35 using namespace DMRnms;
36 using namespace std;
37 
38 
39 
40 LSUpdate::LSUpdate(const Address &_addr, const string &_domain)
41  :RoutingUpdate(_addr, _domain){}
42 
43 
44 void LSUpdate::addEntry(const std::string & _addr, linksU _neig) {
45  entries[_addr] = _neig;
46 }
47 void LSUpdate::setEntries(linksSt _entries) {
48  entries = _entries;
49 }
50 
52  return entries.begin();
53 }
54 
56  return entries.end();
57 }
58 
59 
60 LS::LS(Routing * parent, const Address &_nAddr, const string &_domain, const string &_addr)
61  :rModule(parent, _nAddr, _domain, _addr) {
62  scheduledUpdate = false;
63  secId = 1;
64 }
65 
67  // Cast update to known type
68  LSUpdate * up = dynamic_cast<LSUpdate*>(update);
69  if(up == NULL) { return false; }
70 
71  for(linksStIt it = up->entriesBegin(); it != up->entriesEnd(); it++){
72  string node = it->first;
73  if(netState[node].sId < it->second.sId){
74  netState[node] = it->second;
75  changed.insert(node);
76  }
77  }
78 
79  if(! changed.empty()) {
81  return true;
82  } else {
83  return false;
84  }
85 }
86 
87 void LS::addFlow(const Address &_nAddr, const std::string &_addr, const unsigned short &_metric){
88  nei[_nAddr] = _metric;
89  neigTable[_addr] = _nAddr;
90 
91  changed.insert(myAddr);
92  secId++;
93 
94  linksU * myEntry = &(netState[myAddr]);
95  myEntry->sId = secId;
96  myEntry->links[_addr] = _metric;
97 
99 }
100 
101 void LS::removeFlow(const Address &_nAddr, const std::string &_addr){
102  nei.erase(_nAddr);
103  neigTable.erase(_addr);
104 
105  changed.insert(myAddr);
106  secId++;
107 
108  linksU * myEntry = &(netState[myAddr]);
109  myEntry->sId = secId;
110  myEntry->links.erase(_addr);
111 
112  scheduleUpdate();
113 }
114 
115 void LS::addAddr(const std::string &_addr){
116  myAddrSet.insert(_addr);
117 
118  secId++;
119 
120  linksU * myEntry = &(netState[myAddr]);
121  myEntry->sId = secId;
122  myEntry->links[_addr] = 0;
123 
124  scheduleUpdate();
125 }
126 
127 void LS::removeAddr(const std::string &_addr){
128  myAddrSet.erase(_addr);
129 
130  secId++;
131 
132  linksU * myEntry = &(netState[myAddr]);
133  myEntry->sId = secId;
134  myEntry->links.erase(_addr);
135 
136  scheduleUpdate();
137 }
138 
139 void LS::setInfMetric(const unsigned short &inf){}
140 
142  dmNxt ret(domain);
143 
144  TreeNode t = constructTree();
145  for(TreeNodeIt it = t.chl.begin(); it != t.chl.end(); it++){
146  ret.entries[(*it)->addr] = neigTable[(*it)->addr];
147  addRecursive(ret.entries, neigTable[(*it)->addr], *it);
148  }
149 
150  s2A tmp = ret.entries;
151 
152  for(s2AIt tIt = currentTable.begin(); tIt != currentTable.end(); tIt++){
153  if(ret.entries[tIt->first] == tIt->second){
154  ret.entries.erase(tIt->first);
155  }
156  }
157 
158  currentTable = tmp;
159 
160  return ret;
161 }
162 
164  dmNxt ret(domain);
165 
166  TreeNode t = constructTree();
167  for(TreeNodeIt it = t.chl.begin(); it != t.chl.end(); it++){
168  ret.entries[(*it)->addr] = neigTable[(*it)->addr];
169  addRecursive(ret.entries, neigTable[(*it)->addr], *it);
170  }
171 
172  currentTable = ret.entries;
173  return ret;
174 }
175 
176 void LS::handleMessage(cMessage *msg){
177  if(msg->isSelfMessage()){
178  //get Changes
179  linksSt _entries = getChangedEntries ();
180 
181  //iterate all Neighbour
182  for(neighMetricIt itN = nei.begin(); itN != nei.end(); itN++){
183  //New Update to Neighbour
184  LSUpdate * update = new LSUpdate(itN->first, domain);
185 
186  //Populate the update
187  update->setEntries(_entries);
188 
189  parent->chSendUpdate(update);
190  }
191 
192  changed.clear();
193  scheduledUpdate = false;
194  }
195  delete msg;
196 }
197 
198 
200  if(!scheduledUpdate){
201  scheduledUpdate = true;
202  scheduleAt(1, new cMessage("Time2Update"));
203  }
204 }
205 
206 
207 
209  linksSt ret;
210  for(sSetIt it = changed.begin(); it != changed.end(); it++){
211  ret[*it] = netState[*it];
212  }
213  return ret;
214 }
215 
216 
218  TreeNode t(myAddr, 0);
219  s2m added;
220  added[myAddr] = 0;
221 
222  wMap waiting;
223  s2m * links = &(netState[myAddr].links);
224  for(s2mIt it = links->begin(); it !=links->end(); it++){
225  waiting[it->first] = psT(&t, it->second);
226  }
227 
228 
229  while(!waiting.empty()){
230  unsigned short min = UINT16_MAX;
231  sList mins;
232 
233  for (wMapIt it = waiting.begin(); it != waiting.end(); it++){
234  if(it->second.metric < min){
235  min = it->second.metric;
236  mins.clear();
237  }
238  if(it->second.metric == min){
239  mins.push_back(it->first);
240  }
241  }
242 
243  while(!mins.empty()){
244  string addr = mins.back();
245  mins.pop_back();
246 
247  psT ps = waiting[addr];
248  waiting.erase(addr);
249 
250  TreeNode * nt = new TreeNode(addr, ps.metric);
251  ps.p->chl.insert(nt);
252 
253  added[addr] = ps.metric;
254 
255  links = &(netState[addr].links);
256 
257  for(s2mIt it = links->begin(); it !=links->end(); it++){
258  string daddr = it->first;
259  if(added.find(daddr) == added.end()){
260  wMapIt eI = waiting.find(daddr);
261  if(eI == waiting.end()){
262  waiting[daddr] = psT(nt, ps.metric + it->second);
263  } else if(eI->second.metric > ps.metric + it->second){
264  eI->second.metric = ps.metric + it->second;
265  eI->second.p = nt;
266  }
267  }
268  }
269  }
270  }
271 
272  return t;
273 }
274 
275 void LS::addRecursive(s2A &ret, const Address &next, TreeNode * t) {
276  for(TreeNodeIt it = t->chl.begin(); it != t->chl.end(); it++){
277  ret[(*it)->addr] = next;
278  addRecursive(ret, next, *it);
279  }
280 }
281 
282 
283 
284 } /* namespace DomainRouting */
void scheduleUpdate()
Definition: LS.cc:199
void addFlow(const Address &_nAddr, const std::string &_addr, const unsigned short &_metric)
Definition: LS.cc:87
s2A::iterator s2AIt
Definition: rModule.h:54
s2A currentTable
Definition: LS.h:155
linksSt::iterator linksStIt
Definition: LS.h:55
LS(Routing *parent, const Address &_nAddr, const std::string &_domain, const std::string &_addr)
Definition: LS.cc:60
linksSt netState
Definition: LS.h:149
void setInfMetric(const unsigned short &inf)
Definition: LS.cc:139
wMap::iterator wMapIt
Definition: LS.h:100
dmNxt getAll()
Definition: LS.cc:163
s2A entries
Definition: rModule.h:46
neighMetric nei
Definition: LS.h:145
void chSendUpdate(RoutingUpdate *update)
Definition: Routing.cc:111
void removeFlow(const Address &_nAddr, const std::string &_addr)
Definition: LS.cc:101
void addAddr(const std::string &_addr)
Definition: LS.cc:115
linksStIt entriesBegin()
Definition: LS.cc:51
Routing * parent
Definition: rModule.h:87
std::string myAddr
Definition: rModule.h:90
void addEntry(const std::string &_addr, linksU _neig)
Definition: LS.cc:44
TreeNode * p
Definition: LS.h:89
bool scheduledUpdate
Definition: LS.h:159
Definition: LS.cc:33
sSet changed
Definition: LS.h:152
bool processUpdate(RoutingUpdate *update)
Definition: LS.cc:66
void setEntries(linksSt _entries)
Definition: LS.cc:47
linksSt entries
Definition: LS.h:117
sSet::iterator sSetIt
Definition: LS.h:61
s2m::iterator s2mIt
Definition: LS.h:43
sSet myAddrSet
Definition: LS.h:143
TreeNode constructTree()
Definition: LS.cc:217
std::map< std::string, psT > wMap
Definition: LS.h:99
void handleMessage(cMessage *msg)
Definition: LS.cc:176
std::set< TreeNode * > chl
Definition: LS.h:70
void scheduleAt(const double &time, cMessage *)
Definition: rModule.cc:42
linksSt getChangedEntries()
Definition: LS.cc:208
dmNxt getChanges()
Definition: LS.cc:141
s2A neigTable
Definition: LS.h:148
unsigned short metric
Definition: LS.h:90
linksStIt entriesEnd()
Definition: LS.cc:55
std::set< TreeNode * >::iterator TreeNodeIt
Definition: LS.h:86
std::map< std::string, Address > s2A
Definition: rModule.h:43
std::map< std::string, linksU > linksSt
Definition: LS.h:54
void addRecursive(s2A &ret, const Address &next, TreeNode *t)
Definition: LS.cc:275
std::map< std::string, unsigned short > s2m
Definition: LS.h:42
std::vector< std::string > sList
Definition: LS.h:63
std::string domain
Definition: rModule.h:89
neighMetric::iterator neighMetricIt
Definition: LS.h:58
unsigned int secId
Definition: LS.h:150
Address class holds IPC Process identification.
Definition: Address.h:42
void removeAddr(const std::string &_addr)
Definition: LS.cc:127
LSUpdate(const Address &_addr, const std::string &_domain)
Definition: LS.cc:40