RINASim  October 2016
Documentation of framework for OMNeT++
HierarchicalTable.cc
Go to the documentation of this file.
2 
3 
5 
6 #include "Utils.h"
7 #include <sstream>
8 
9 namespace HierarchicalTable {
10 
11 using namespace std;
12 
13 
15 
16 void HierarchicalTable::addDomain(const string & domId, const string & qos, const string & prefix) {
17  table[domId];
18  if(prefix == "") {
19  domains[prefix][qos] = domData(domId, 0);
20  } else {
21  vector<string> parsed = split(prefix, '.');
22  domains[prefix][qos] = domData(domId, parsed.size());
23  }
24 }
25 
26 void HierarchicalTable::addDomain(const string & domId, const string & prefix) {
27  addDomain(domId, anyQoS, prefix);
28 }
29 
30 void HierarchicalTable::removeDomain(string domId) {
31  string prefix, qos;
32  for(const auto & addrP : domains) {
33  for(const auto & qosP : addrP.second) {
34  if(qosP.second.domId == domId) {
35  prefix = addrP.first;
36  qos = qosP.first;
37  }
38  }
39  }
40  domains[prefix].erase(qos);
41  table.erase(domId);
42 }
43 
44 
45 // Lookup function, return a list of RMTPorts to forward a PDU/Address+qos.
46 vector<RMTPort * > HierarchicalTable::lookup(const PDU * pdu){
47  return lookup(pdu->getDstAddr(), pdu->getConnId().getQoSId());
48 }
49 vector<RMTPort * > HierarchicalTable::lookup(const Address &dst, const std::string& qos){
50 
51  vector<RMTPort* > ret;
52  string domId;
53  string dstAddr = dst.getIpcAddress().getName();
54  if(dstAddr == "") { return ret; };
55  vector<RMTPort* >* found = NULL;
56  vector<string> parsed = split(dstAddr, '.');
57 
58  for(auto & addrP : domains) {
59  if(!isPrefix(addrP.first, dstAddr)){ continue; }
60  found = NULL;
61  bool foundAtQoS = false;
62  bool foundAtAddr = false;
63 
64  if(addrP.second.find(qos) != addrP.second.end()) {
65  domData dd = addrP.second[qos];
66  string val = parsed[dd.prefLen];
67  if(table[dd.domId].find(val) != table[dd.domId].end()){
68  found = &table[dd.domId][val];
69  foundAtQoS = true;
70  foundAtAddr = true;
71  } else if(table[dd.domId].find("*") != table[dd.domId].end()) {
72  found = &table[dd.domId]["*"];
73  foundAtQoS = true;
74  }
75  }
76  if(!foundAtAddr && addrP.second.find(anyQoS) != addrP.second.end()) {
77  domData dd = addrP.second[anyQoS];
78 
79  string val = parsed[dd.prefLen];
80  if(table[dd.domId].find(val) != table[dd.domId].end()){
81  found = &table[dd.domId][val];
82  } else if(!foundAtQoS && table[dd.domId].find("*") != table[dd.domId].end()) {
83  found = &table[dd.domId]["*"];
84  }
85  }
86  }
87 
88  if(found != NULL && !found->empty()) {
89  ret.push_back((*found)[intuniform(0, found->size()-1)]);
90  } else if(direct.find(dst) != direct.end()) {
91  ret.push_back(direct[dst]);
92  }
93 
94  return ret;
95 }
96 
97 // Returns a representation of the Forwarding Knowledge
98 string HierarchicalTable::toString(){
99  std::ostringstream os;
100 
101  os << this->getName()<<endl;
102  for(const auto & addrP : domains) {
103  for(const auto & qosP : addrP.second) {
104  os << " Domain " << qosP.second.domId << " (\""<<addrP.first<<"\" , QoS "<< qosP.first<<")" << endl;
105  for(const auto &entry : table[qosP.second.domId]) {
106  os << "\t" <<entry.first << " -> ";
107  for(RMTPort * p : entry.second){
108  os << p->getFullPath() << " ";
109  }
110  os << endl;
111  }
112  }
113  }
114 
115  return os.str();
116 }
117 
118 //Insert/Remove an entry
119 void HierarchicalTable::addReplace(const string &domId, const string &addr, vector<RMTPort *> ports){
120  if(ports.empty()){
121  table[domId].erase(addr);
122  } else {
123  table[domId][addr] = ports;
124  }
125 }
126 
127 // Called after initialize
128 void HierarchicalTable::onPolicyInit(){
129  // IPCProcess module.
130  cModule * ipcModule = getModuleByPath("^.^");
131 
132  myAddr = Address(
133  ipcModule->par("ipcAddress").stringValue(),
134  ipcModule->par("difName").stringValue());
135 }
136 
137 void HierarchicalTable::setAddr(const Address & addr) {
138  myAddr = addr;
139 }
140 
141 void HierarchicalTable::setTmp(const Address & dst, RMTPort *p) {
142  direct[dst] = p;
143 }
144 
145 void HierarchicalTable::removeTmp(const Address & dst, RMTPort *p) {
146  if(direct[dst]== NULL || direct[dst]==p) {
147  direct.erase(dst);
148  }
149 }
150 
151 void HierarchicalTable::finish(){
152  if(par("printAtEnd").boolValue()){
153  EV << "-----------------" << endl;
154  EV << "Forwarding table::" << endl;
155  EV << toString() <<endl;
156  EV << "-----------------" << endl;
157  for(auto tmp : direct){
158  EV << "\t" << tmp.first << " -> " << tmp.second->getFullPath() << endl;
159  }
160  }
161 }
162 
163 }
std::string getQoSId() const
Getter of selected QoS-cube identifier.
Definition: ConnectionId.cc:44
const APN & getIpcAddress() const
Getter of IPC Process address which should be unambiguous within DIF.
Definition: Address.cc:83
bool isPrefix(std::string prefix, std::string s)
Definition: Utils.cc:62
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition: Utils.cc:33
virtual ConnectionId & getConnId()
Definition: PDU_m.cc:336
Definition: PDU.h:42
Register_Class(HierarchicalTable::HierarchicalTable)
virtual Address & getDstAddr()
Definition: PDU_m.cc:306
const std::string & getName() const
Gets APN string name representation.
Definition: APN.cc:40
Address class holds IPC Process identification.
Definition: Address.h:42