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