RINASim  October 2016
Documentation of framework for OMNeT++
PLQoSAwareMEntries.cc
Go to the documentation of this file.
1 //
2 // This program is free software: you can redistribute it and/or modify
3 // it under the terms of the GNU Lesser General Public License as published by
4 // the Free Software Foundation, either version 3 of the License, or
5 // (at your option) any later version.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public License
13 // along with this program. If not, see http://www.gnu.org/licenses/.
14 //
15 
17 #include "APN.h"
18 
19 
20 
21 namespace PLQoSAwareMEntries {
22 
24 
25 using namespace std;
26 using namespace common_GraphCL;
27 
28 // A new flow has been inserted/or removed
29 void PLQoSAwareMEntries::insertedFlow(const Address &addr, const QoSCube &qos, RMTPort * port){
30 
31  string dst = addr.getIpcAddress().getName();
32  string qosId = qos.getQosId();
33  portQoS[port] = qosId;
34  neighbours[qosId][dst].insert(port);
35  int lat = dstLat[dst];
36 
37  fwd->setPortDelay(port, dstDLat[dst]);
38 
39  if(lat <= 0) {
40  lat = maxLat;
41  dstLat[dst] = maxLat;
42  }
43 
44  if(neighbours[qosId][dst].size() == 1){
45  if(urgentQoS.find(qosId) != urgentQoS.end()) {
46  rt->insertFlow(addr, dst, qosId, lat);
47  } else {
48  rt->insertFlow(addr, dst, qosId, 1);
49  }
50  routingUpdated();
51  }
52 
53  qosId = "*";
54  neighbours[qosId][dst].insert(port);
55  if(neighbours[qosId][dst].size() == 1){
56  if(urgentQoS.find(qosId) != urgentQoS.end()) {
57  rt->insertFlow(addr, dst, qosId, lat);
58  } else {
59  rt->insertFlow(addr, dst, qosId, 1);
60  }
61  routingUpdated();
62  }
63 }
64 void PLQoSAwareMEntries::removedFlow(const Address &addr, const QoSCube& qos, RMTPort * port){
65  std::string dst = addr.getIpcAddress().getName();
66  string qosId = portQoS[port];
67  neighbours[qosId][dst].erase(port);
68  if(neighbours[qosId][dst].size() <= 0){
69  rt->removeFlow(addr, dst, qosId);
70  neighbours[qosId].erase(dst);
71  if(neighbours[qosId].size()<=0) {
72  neighbours.erase(qosId);
73  }
74  routingUpdated();
75  }
76 
77  qosId = "*";
78  neighbours[qosId][dst].erase(port);
79  if(neighbours[qosId][dst].size() <= 0){
80  rt->removeFlow(addr, dst, qosId);
81  neighbours[qosId].erase(dst);
82  if(neighbours[qosId].size()<=0) {
83  neighbours.erase(qosId);
84  }
85  routingUpdated();
86  }
87 
88  portQoS.erase(port);
89 }
90 
91 //Routing has processes a routing update
93  map<string, map<string, nhLMetric<mType> > > changes = rt->getChanges();
94 
95  for(const auto & qosEntries : changes){
96  string qosId = qosEntries.first;
97  for(const auto & entry : qosEntries.second){
98  std::vector< RMTPort * > ps;
99  for(string nextHop : entry.second.nh){
100  RMTPort * p = NULL;
101  if(nextHop != "") {
102  auto n = neighbours[qosId].find(nextHop);
103  if(n != neighbours[qosId].end()){
104  if(!n->second.empty()) {
105  p = *(n->second.begin());
106  }
107  }
108  }
109  if(p != NULL) {
110  ps.push_back(p);
111  }
112  }
113  fwd->addReplace(entry.first, qosId, ps);
114  if(ps.empty()) {
115  for(auto qId : qIds) {
116  qId->setDistance(entry.first, qosId, INT_MAX);
117  }
118  } else {
119  for(auto qId : qIds) {
120  qId->setDistance(entry.first, qosId, entry.second.metric);
121  }
122  }
123  }
124  }
125 }
126 
127 // Called after initialize
129  //Set Forwarding policy
130  fwd = check_and_cast<IntIQoSMForwarding *>
131  (getModuleByPath("^.^.relayAndMux.pduForwardingPolicy"));
132  rt = check_and_cast<IntTSimpleRouting<mType> *>
133  (getModuleByPath("^.^.routingPolicy"));
134 
135  difA = check_and_cast<DA *>(getModuleByPath("^.^.^.difAllocator.da"));
136 
137  mType infMetric = par("infinite");
138  rt->setInfinite(infMetric);
139 
140  maxLat = par("maxLat").longValue();
141 
142  string myAddr = getModuleByPath("^.^")->par("ipcAddress").stringValue();
143 
144 
145  cXMLElement* Xml = NULL;
146  if (par("data").xmlValue() != NULL && par("data").xmlValue()->hasChildren()){
147  Xml = par("data").xmlValue();
148  } else { return; }
149 
150 
151  cXMLElementList QoSs = Xml->getChildrenByTagName("Qos");
152  for(auto qos : QoSs){
153  if (!qos->getAttribute("id")) { error("Error. ID is missing!"); }
154  std::string id = qos->getAttribute("id");
155  if (id=="") { error("Error. ID cannot be empty!"); }
156 
157  if (!qos->getAttribute("urgent")) { continue; }
158  urgentQoS.insert(id);
159  }
160 
161  double latMultip = par("latMultip").doubleValue();
162 
163  cXMLElementList Links = Xml->getChildrenByTagName("Link");
164  for(auto link : Links){
165  if (!link->getAttribute("src")) { error("Error. Addr is missing!"); }
166  std::string src = link->getAttribute("src");
167  if (src=="") { error("Error. Addr cannot be empty!"); }
168 
169  if (!link->getAttribute("dst")) { error("Error. Addr is missing!"); }
170  std::string dst = link->getAttribute("dst");
171  if (dst=="") { error("Error. Addr cannot be empty!"); }
172 
173 
174  if (!link->getAttribute("l")) { error("Error. Latency is missing!"); }
175  double l = atof(link->getAttribute("l"));
176  if (l < 0.0) { error("Error. Latency cannot be < 0"); }
177  int lat = l*latMultip;
178  if (lat > maxLat) { lat = maxLat; }
179 
180  if(src == myAddr) { dstLat[dst] = lat; dstDLat[dst] = l/1000.0; }
181  else if(dst == myAddr) { dstLat[src] = lat; dstDLat[src] = l/1000.0; }
182  }
183 }
184 
186  qIds.insert(qId);
187 }
189  qIds.erase(qId);
190 }
191 
192 }
const APN & getIpcAddress() const
Getter of IPC Process address which should be unambiguous within DIF.
Definition: Address.cc:83
void unregisterQidsGen(IDPerNQoSxPLen *qId)
virtual void removedFlow(const Address &addr, const QoSCube &qos, RMTPort *port)
Definition: DA.h:43
virtual void insertedFlow(const Address &addr, const QoSCube &qos, RMTPort *port)
Register_Class(PLQoSAwareMEntries)
Class representing QoSCube with all its properties that is primarily used by FA, RMT and RA Specifica...
Definition: QoSCube.h:57
std::string getQosId() const
Gets QoSCube identifier.
Definition: QoSCube.cc:364
unsigned short mType
const std::string & getName() const
Gets APN string name representation.
Definition: APN.cc:40
Address class holds IPC Process identification.
Definition: Address.h:42