RINASim  October 2016
Documentation of framework for OMNeT++
IRM.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 #include "IRM.h"
25 
26 const int VAL_UNDEF_HANDLE = -1;
27 const char* SIG_STAT_IRM_UP = "IRM_PassUp";
28 const char* SIG_STAT_IRM_DOWN = "IRM_PassDown";
29 
31 
33  statPassUp = 0;
34  statPassDown = 0;
35  statDiscarded = 0;
36 }
37 
39  ConTable = NULL;
40  DifAllocator = NULL;
41  statPassUp = 0;
42  statPassDown = 0;
43  statDiscarded = 0;
44 }
45 
47  ConTable = getRINAModule<ConnectionTable*>(this, 1, {MOD_CONNTABLE});
48  if (!ConTable)
49  error("ConTab is NULL!");
50  DifAllocator = getRINAModule<DA*>(this, 2, {MOD_DIFALLOC, MOD_DA});
51 }
52 
54  initPointers();
56 }
57 
58 void IRM::handleMessage(cMessage* msg) {
59  if (!msg->isSelfMessage()) {
60  //Find output gate based on input
61  bool isGoingUp = false;
62  cGate* g = ConTable->findOutputGate(msg->getArrivalGate(), isGoingUp);
63  //Send out if gate exist
64  cPacket* packet = dynamic_cast<cPacket*>(msg);
65  cPacket* outPacket;
66  if (g) {
67  if (isGoingUp) {
68  statPassUp++;
69  emit(sigStatIRMPassUp, true);
70  outPacket = packet->decapsulate();
71  delete packet;
72  }
73  else
74  {
75  statPassDown++;
76  emit(sigStatIRMPassDown, true);
77  SDUData* sduData = new SDUData();
78  sduData->encapsulate(packet);
79  outPacket = sduData;
80  }
81 
82 
83  send(outPacket, g);
84 
85  }
86  else {
87  EV << "Received message but destination gate is not in the ConnectionTable!" << endl;
88  statDiscarded++;
89  delete msg;
90  }
91 
93  }
94  //Process self-message
95  else {
96 
97  }
98 
99 }
100 
102  cModule* catcher = this->getModuleByPath("^.^");
103 
104  //Signals that this module emits
105  /*
106  sigIRMAllocReq = registerSignal(SIG_IRM_AllocateRequest);
107  sigIRMDeallocReq = registerSignal(SIG_IRM_DeallocateRequest);
108  */
109  sigStatIRMPassUp = registerSignal(SIG_STAT_IRM_UP);
110  sigStatIRMPassDown = registerSignal(SIG_STAT_IRM_DOWN);
111 
112  // Allocate Request from App
113  this->lisAllocReq = new LisIRMAllocReq(this);
114  catcher->subscribe(SIG_AE_AllocateRequest, this->lisAllocReq);
115  // Deallocate Request from App
116  this->lisDeallocReq = new LisIRMDeallocReq(this);
117  catcher->subscribe(SIG_AE_DeallocateRequest, this->lisDeallocReq);
118 }
119 
121  Enter_Method("createBindings()");
122  EV << "Attempts to create bindings and bind registration of gates"<< endl;
123  //Retrieve IPC process with allocated flow and prepared bindings
124 
126  //if (!cte) {
127  // EV << "======================" << endl << flow->info() << endl;
128  // return false;
129  //}
130  cModule* Ipc = cte->getIpc();
131  cModule* IrmMod = this->getParentModule();
132 
133  //Decide portId
134  int portId = flow->getSrcPortId();
135  /*
136  if ( DifAllocator->isAppLocal(flow->getDstApni().getApn()) )
137  portId = flow->getDstPortId();
138  else if ( DifAllocator->isAppLocal(flow->getSrcApni().getApn()) )
139  portId
140  else
141  throw("Binding to inconsistant PortId occured!");
142  */
143 
144  // Retrieve IPC gates
145  std::ostringstream nam1;
146  nam1 << GATE_NORTHIO_ << portId;
147  cGate* g1i = Ipc->gateHalf(nam1.str().c_str(), cGate::INPUT);
148  cGate* g1o = Ipc->gateHalf(nam1.str().c_str(), cGate::OUTPUT);
149 
150  // Add AP gates
151  std::ostringstream nam2;
152  nam2 << GATE_SOUTHIO_ << portId;
153  if (!IrmMod->hasGate(nam2.str().c_str()))
154  IrmMod->addGate(nam2.str().c_str(), cGate::INOUT, false);
155  cGate* g2i = IrmMod->gateHalf(nam2.str().c_str(), cGate::INPUT);
156  cGate* g2o = IrmMod->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
157 
158  // Add IRM gates
159  if (!this->hasGate(nam2.str().c_str()))
160  this->addGate(nam2.str().c_str(), cGate::INOUT, false);
161  cGate* g3i = this->gateHalf(nam2.str().c_str(), cGate::INPUT);
162  cGate* g3o = this->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
163 
164  //TODO: Status check
165 
166  // Connect gates together
167  if (!g1o->getNextGate())
168  g1o->connectTo(g2i);
169  if (!g2i->getNextGate())
170  g2i->connectTo(g3i);
171 
172  if (!g3o->getNextGate())
173  g3o->connectTo(g2o);
174  if (!g2o->getNextGate())
175  g2o->connectTo(g1i);
176 
177 
178  //Set south-half of the routing in ConnectionTable
179  bool status = ConTable->setSouthGates(flow, g3i, g3o);
180 
181  return status;
182 }
183 
185  Enter_Method("receiveAllocateRequest()");
186  EV << this->getFullPath() << " received Allocation Request" << endl;
187 
188  //Command target FA to allocate flow
189  FABase* fab = ConTable->getFa(flow);
190  bool status = false;
191 
192  if (fab) {
193  //signalizeAllocateRequest(fl);
194  status = fab->receiveAllocateRequest(flow);
195  //If AllocationRequest NOT ended by creating connections
196  if (!status)
197  EV << "Flow not allocated!\n" << flow << endl;
198  }
199  else
200  EV << "FA could not be found in ConnectionTable!" << endl;
201 
202  return status;
203 }
204 
206  Enter_Method("receiveDeallocateRequest()");
207  EV << this->getFullPath() << " received DeallocationRequest" << endl;
208 
209  auto cte = ConTable->findEntryByFlow(flow);
210  bool status = false;
211 
212  if (cte) {
213  //TODO: Vesely - Change CONNECT_PENDING to establish ASAP when AE Enrollment
214  // implementation is finished
215  if (cte->getConStatus() == ConnectionTableEntry::CON_CONNECTPENDING
216  && cte->getSouthGateOut() && cte->getSouthGateIn() ) {
217  status = cte->getFlowAlloc()->receiveDeallocateRequest(flow);
218  }
219  else {
220  EV << "Connection not in proper state or south gates are missing!" << endl;
221  }
222  }
223  else {
224  EV << "There is no valid entry in Connection Table!" << endl;
225  }
226  return status;
227 }
228 /*
229 void IRM::signalizeAllocateRequest(Flow* flow) {
230  //EV << "!!!!VYemitovano" << endl;
231  //EV << "Emits AllocReq Flow = " << flow->getSrcApni() << "_" << flow->getDstApni() << endl;
232  emit(sigIRMAllocReq, flow);
233 }
234 */
235 void IRM::newFlow(Flow* flow) {
236  Enter_Method("newFlow()");
237 
238  //Create a new record in ConnectionTable
239  ConTable->insertNew(flow);
240 
241  //Ask DA which IPC to use to reach dst App
243  if (ad == NULL) {
244  EV << "DifAllocator returned NULL for resolving " << flow->getDstApni().getApn() << endl;
245  return;
246  }
247  Address addr = *ad;
248 
249  //TODO: Vesely - New IPC must be enrolled or DIF created
250  if (!DifAllocator->isDifLocal(addr.getDifName())) {
251  EV << "Local CS does not have any IPC in DIF " << addr.getDifName() << endl;
252  return;
253  }
254 
255  //Retrieve DIF's local IPC member
256  cModule* targetIpc = DifAllocator->getDifMember(addr.getDifName());
257 
258  //Store info into ConnectionTable
259  ConTable->setFa(flow, DifAllocator->findFaInsideIpc(targetIpc));
260 }
261 
263  std::ostringstream os;
264  os << "up: " << statPassUp << endl << "down: " << statPassDown << endl << "discard: " << statDiscarded;
265  setPolicyDisplayString(this, os.str().c_str());
266 }
267 /*
268 void IRM::signalizeDeallocateRequest(Flow* flow) {
269  emit(sigIRMDeallocReq, flow);
270 }
271 */
273  return ConTable;
274 }
275 
277  Enter_Method("allocationResponsePositive()");
278  bool status = createBindings(flow);
279 
280  status ?
282  :
284  return status;
285 }
286 
288  Enter_Method("deleteBindings()");
289  EV << "Attempts to delete bindings"<< endl;
290  //Retrieve IPC process with allocated flow and prepared bindings
291 
293  cModule* Ipc = cte->getIpc();
294  cModule* IrmMod = this->getParentModule();
295 
296  //Decide portId
297  int portId = flow->getSrcPortId();
298 
299  // Retrieve IPC gates
300  std::ostringstream nam1;
301  nam1 << GATE_NORTHIO_ << portId;
302  cGate* g1i = Ipc->gateHalf(nam1.str().c_str(), cGate::INPUT);
303  cGate* g1o = Ipc->gateHalf(nam1.str().c_str(), cGate::OUTPUT);
304 
305  // Add AP gates
306  std::ostringstream nam2;
307  nam2 << GATE_SOUTHIO_ << portId;
308  cGate* g2i = IrmMod->gateHalf(nam2.str().c_str(), cGate::INPUT);
309  cGate* g2o = IrmMod->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
310 
311  // Add IRM gates
312  cGate* g3i = this->gateHalf(nam2.str().c_str(), cGate::INPUT);
313  cGate* g3o = this->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
314 
315  // Connect gates together
316  g1o->disconnect();
317  g2i->disconnect();
318  g3i->disconnect();
319 
320  g3o->disconnect();
321  g2o->disconnect();
322  g1i->disconnect();
323 
324  return !g1o->isConnected() && !g1i->isConnected()
325  && !g2o->isConnected() && !g2i->isConnected()
326  && !g3o->isConnected() && !g3i->isConnected();
327 }
328 
330  ConTable->setStatus(flow, status);
331 }
332 
333 int IRM::getIrmGateHandle(Flow* flow) const {
335  if (cte && cte->getNorthGateIn()) {
336  //EV << "!!!!!!!!!!!!!!" << cte->getNorthGateIn()->getFullName() << endl;
337  return cte->getNorthGateIn()->getIndex();
338  }
339  return VAL_UNDEF_HANDLE;
340 }
341 
342 void IRM::setNorthGates(Flow* flow, cGate* nIn, cGate* nOut) {
343  ConTable->setNorthGates(flow, nIn, nOut);
344 }
345 
346 int IRM::getApGateHandle(Flow* flow) const {
348  if (cte && cte->getNorthGateIn()) {
349  std::string desc = cte->getNorthGateIn()->getPreviousGate()->getPreviousGate()->getFullName();
350  //EV << "!!!!!!!!!!!!!!" << desc << endl;
351  return cte->getNorthGateIn()->getPreviousGate()->getPreviousGate()->getIndex();
352  }
353  return VAL_UNDEF_HANDLE;
354 }
const DAP & getDifName() const
Getter of common DIF name.
Definition: Address.cc:73
FABase * getFlowAlloc() const
bool setStatus(Flow *flow, ConnectionTableEntry::ConnectionStatus status)
Class representing flow object with attributes from specs.
Definition: Flow.h:45
bool deleteBindings(Flow *flow)
Definition: IRM.cc:287
LisIRMDeallocReq * lisDeallocReq
Definition: IRM.h:86
void initSignalsAndListeners()
Definition: IRM.cc:101
int statPassDown
Definition: IRM.h:67
const char * MOD_DIFALLOC
Definition: ExternConsts.cc:34
cGate * findOutputGate(cGate *input, bool &isGoingUp)
ConnectionStatus
const char * SIG_STAT_IRM_DOWN
Definition: IRM.cc:28
virtual bool receiveAllocateRequest(Flow *flow)=0
bool setNorthGates(Flow *flow, cGate *nIn, cGate *nOut)
Definition: IRM.h:41
simsignal_t sigStatIRMPassDown
Definition: IRM.h:82
const char * SIG_AE_DeallocateRequest
Definition: RINASignals.cc:35
virtual ~IRM()
Definition: IRM.cc:38
const char * GATE_NORTHIO_
cModule * getIpc() const
bool isDifLocal(const DAP &difName)
Definition: DA.cc:134
void changeStatus(Flow *flow, ConnectionTableEntry::ConnectionStatus status)
Definition: IRM.cc:329
virtual void initialize()
Definition: IRM.cc:53
IRM()
Definition: IRM.cc:32
FABase * getFa(Flow *flow)
bool receiveAllocationRequestFromAe(Flow *flow)
Definition: IRM.cc:184
ConnectionTable * getConTable() const
Definition: IRM.cc:272
const APN & getApn() const
Getter of APN.
Definition: APNamingInfo.h:142
simsignal_t sigStatIRMPassUp
Definition: IRM.h:81
const char * GATE_SOUTHIO_
const char * SIG_AE_AllocateRequest
Definition: RINASignals.cc:34
FABase * findFaInsideIpc(cModule *ipc)
Definition: DA.cc:183
bool setFa(Flow *flow, FABase *fa)
void initPointers()
Definition: IRM.cc:46
bool receiveDeallocationRequestFromAe(Flow *flow)
Definition: IRM.cc:205
int statPassUp
Definition: IRM.h:66
DA * DifAllocator
Definition: IRM.h:71
void newFlow(Flow *flow)
Definition: IRM.cc:235
void insertNew(Flow *flow)
ConnectionTableEntry * findEntryByFlow(Flow *flow)
const char * MOD_CONNTABLE
Definition: ExternConsts.cc:32
Define_Module(IRM)
int getApGateHandle(Flow *flow) const
Definition: IRM.cc:346
int getSrcPortId() const
Gets source PortId.
Definition: Flow.cc:142
int statDiscarded
Definition: IRM.h:68
const char * SIG_STAT_IRM_UP
Definition: IRM.cc:27
cGate * getNorthGateIn() const
void setPolicyDisplayString(cModule *mod, const char *str)
Definition: Utils.cc:69
virtual bool receiveDeallocateRequest(Flow *flow)=0
LisIRMAllocReq * lisAllocReq
Definition: IRM.h:85
virtual void handleMessage(cMessage *msg)
Definition: IRM.cc:58
void setNorthGates(Flow *flow, cGate *nIn, cGate *nOut)
Definition: IRM.cc:342
const char * MOD_DA
Definition: ExternConsts.cc:33
Definition: FABase.h:33
void updateDisplayString()
Definition: IRM.cc:262
bool setSouthGates(Flow *flow, cGate *sIn, cGate *sOut)
bool createBindings(Flow *flow)
Definition: IRM.cc:120
cModule * getDifMember(const DAP &difName)
Definition: DA.cc:158
bool receiveAllocationResponsePositiveFromIpc(Flow *flow)
Definition: IRM.cc:276
ConnectionTable * ConTable
Definition: IRM.h:70
Address class holds IPC Process identification.
Definition: Address.h:42
const APNamingInfo & getDstApni() const
Gets read-only destination APNamingInfo.
Definition: Flow.cc:102
const int VAL_UNDEF_HANDLE
Definition: IRM.cc:26
const Address * resolveApnToBestAddress(const APN &apn)
Definition: DA.cc:31
int getIrmGateHandle(Flow *flow) const
Definition: IRM.cc:333