RINASim  October 2016
Documentation of framework for OMNeT++
SimpleDV.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 <SimpleDV/SimpleDV.h>
24 
25 namespace SimpleDV {
26 
28 
29 using namespace std;
30 
31 
32 RoutingUpdate::RoutingUpdate(const Address &_addr, const std::string &_src, const std::string&_qos):IntRoutingUpdate(_addr){
33  src = _src;
34  qos = _qos;
35 }
36 
37 std::string RoutingUpdate::getSrc(){
38  return src;
39 }
40 std::string RoutingUpdate::getQoS(){
41  return qos;
42 }
43 
45  entries.push_back(entry);
46 }
47 
49  return entries.begin();
50 }
52  return entries.end();
53 }
54 
55 
56 void SimpleDV::scheduleUpdate(){
57  Enter_Method_Silent();
58  if(!scheduledUpdate){
59  scheduledUpdate = true;
60  scheduleAt(simTime()+1, new cMessage("Time2Update"));
61  }
62 }
63 
64 //Flow inserted/removed
65 void SimpleDV::insertFlow(const Address &addr, const std::string &dst, const std::string& qos, const unsigned short &metric){
66  EV << "Insert Flow info" << endl;
67  neig[qos][addr] = metric;
68 
69  rtEntry * oldEntry = &table[qos][dst];
70 
71  bool entryChangedDst = false;
72 
73  if(oldEntry->addr == dst){
74  if(oldEntry->metric != metric){
75  oldEntry->metric = metric;
76  }
77  } else if(oldEntry->metric >= metric){
78  oldEntry->addr = dst;
79  oldEntry->metric = metric;
80  entryChangedDst = true;
81  }
82 
83  entType et;
84  if(oldEntry->metric >= infMetric){
85  et.metric = infMetric;
86  table[qos].erase(dst);
87  } else if(entryChangedDst){
88  et.metric = infMetric;
89  et.nh.insert(dst);
90  }
91  changes[qosPaddr(qos, dst)] = et;
92  scheduleUpdate();
93 }
94 void SimpleDV::removeFlow(const Address &addr, const std::string &dst, const std::string& qos){
95  neig[qos].erase(addr);
96  if(neig[qos].size() <= 0){
97  neig.erase(qos);
98  }
99 
100  tTable * qosTable = &table[qos];
101 
102 
103  for(tTableIt it = qosTable->begin(); it != qosTable->end();){
104  rtEntry * oldEntry = &it->second;
105  tTableIt actIt = it;
106  it++;
107 
108  if(oldEntry->addr == dst){
109  entType et;
110  et.metric = infMetric;
111  changes[qosPaddr(qos, oldEntry->addr)] = et;
112  qosTable->erase(actIt);
113  }
114  }
115  scheduleUpdate();
116 }
117 
118 //Get Changes
119 entries2Next SimpleDV::getChanges(){
120  entries2Next ret = changes;
121  changes.clear();
122  return ret;
123 }
124 
125 entries2Next SimpleDV::getAll(){
126  entries2Next ret;
127 
128 
129  for(rtTableIt it = table.begin(); it != table.end(); it++){
130  for(tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
131  entType et;
132  if(it2->second.metric < infMetric) {
133  et.metric = it2->second.metric;
134  et.nh.insert(it2->second.addr);
135  } else {
136  et.metric = infMetric;
137  }
138  ret[qosPaddr(it->first, it2->first)] = et;
139  }
140  }
141  map<unsigned short, map<string, rtEntry> > table;
142 
143  return ret;
144 }
145 
146 //Process a Routing Update, return true => inform FWDG of the update
147 bool SimpleDV::processUpdate(IntRoutingUpdate * update){
148  RoutingUpdate * up = check_and_cast<RoutingUpdate*>(update);
149 
150  std::string src = up->getSrc();
151  if(src == myAddr){
152  return false;
153  }
154 
155  bool chan = false;
156 
157  std::string qos = up->getQoS();
158 
159  for(entriesIt it = up->entriesBegin(); it!= up->entriesEnd(); it++){
160  if(it->addr == myAddr) { continue; }
161 
162  rtEntry * newEntry = &(*it);
163  rtEntry * oldEntry = &table[qos][newEntry->addr];
164 
165  bool entryChangedDst = false;
166 
167  if(oldEntry->addr == src){
168  if(oldEntry->metric != newEntry->metric){
169  oldEntry->metric = newEntry->metric;
170  chan = true;
171  }
172  } else if(oldEntry->metric > newEntry->metric){
173  oldEntry->addr = src;
174  oldEntry->metric = newEntry->metric;
175  entryChangedDst = true;
176  chan = true;
177  }
178 
179  entType et;
180 
181  if(oldEntry->metric >= infMetric){
182  et.metric = infMetric;
183  changes[qosPaddr(qos, newEntry->addr)] = et;
184  table[qos].erase(newEntry->addr);
185  chan = true;
186  } else if(entryChangedDst){
187  et.metric = oldEntry->metric;
188  et.nh.insert(src);
189  changes[qosPaddr(qos, newEntry->addr)] = et;
190  chan = true;
191  }
192  }
193 
194  if(chan) {
195  scheduleUpdate();
196  }
197 
198  return ! changes.empty();
199 }
200 
201 // Called after initialize
202 void SimpleDV::onPolicyInit(){
203  myAddr = par("myAddr").stdstringValue();
204  if(myAddr == "") {
205  myAddr = myAddress.getIpcAddress().getName();
206  }
207 
208  infMetric = par("infMetric").longValue();
209 
210  scheduledUpdate = false;
211  scheduleUpdate();
212 }
213 
214 
215 void SimpleDV::handleMessage(cMessage *msg){
216  if(msg->isSelfMessage()){
217  //Iterate all Qos
218  for(qosNeighMetricIt it = neig.begin(); it!= neig.end(); it++){
219  //getTable per QoS
220  tTable * qosTable = &table[it->first];
221 
222  //iterate all Qos->Neighbour
223  for(neighMetricIt it2 = it->second.begin(); it2 != it->second.end(); it2++){
224  //New Update to QoS + Neighbour
225  RoutingUpdate * update = new RoutingUpdate(it2->first, myAddr, it->first);
226 
227  //Populate the update
228  for(tTableIt it3 = qosTable->begin(); it3 != qosTable->end();it3++){
229  update->addEntry(rtEntry(it3->first, it3->second.metric+ it2->second));
230  }
231 
232  //Add our entry
233  update->addEntry(rtEntry(myAddr, it2->second));
234 
235  //And send
236  sendUpdate(update);
237  }
238  }
239 
240  scheduledUpdate = false;
241  }
242  delete msg;
243 }
244 
245 
246 void SimpleDV::finish(){
248 
249  if(par("printAtEnd").boolValue() ){
250  EV << "I'm " << myAddr<<endl;
251 
252  for (rtTableIt it = table.begin(); it != table.end(); it++)
253  {
254  EV << " QoS " << it->first << endl;
255  for (tTableIt it2 = it->second.begin(); it2 != it->second.end(); it2++)
256  {
257  EV << " " << it2->first << " via " << it2->second.addr << " ("
258  << it2->second.metric << ")" << endl;
259  }
260  }
261  }
262 }
263 
264 }
std::vector< rtEntry >::iterator entriesIt
Definition: SimpleDV.h:44
Definition: SimpleDV.h:30
qosNeighMetric::iterator qosNeighMetricIt
Definition: SimpleDV.h:49
std::set< std::string > nh
entriesIt entriesEnd()
Definition: SimpleDV.cc:51
std::map< std::string, rtEntry > tTable
Definition: SimpleDV.h:51
rtTable::iterator rtTableIt
Definition: SimpleDV.h:54
std::map< qosPaddr, std::string > entries2Next
virtual void finish()
Definition: IntRouting.cc:25
RoutingUpdate(const Address &_addr, const std::string &_src, const std::string &_qos)
Definition: SimpleDV.cc:32
std::string getSrc()
Definition: SimpleDV.cc:37
unsigned short metric
Definition: SimpleDV.h:32
std::string getQoS()
Definition: SimpleDV.cc:40
tTable::iterator tTableIt
Definition: SimpleDV.h:53
neighMetric::iterator neighMetricIt
Definition: SimpleDV.h:48
unsigned short metric
std::pair< std::string, std::string > qosPaddr
entriesIt entriesBegin()
Definition: SimpleDV.cc:48
std::string addr
Definition: SimpleDV.h:31
Register_Class(SimpleDV)
Address class holds IPC Process identification.
Definition: Address.h:42
void addEntry(rtEntry)
Definition: SimpleDV.cc:44