--- a
+++ b/src/DAF/IRM/IRM.cc
@@ -0,0 +1,211 @@
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see http://www.gnu.org/licenses/.
+//
+
+
+#include "IRM.h"
+
+Define_Module(IRM);
+
+IRM::IRM() {
+}
+
+IRM::~IRM() {
+}
+
+void IRM::initPointers() {
+ ConTable = ModuleAccess<ConnectionTable>(MOD_CONNTABLE).get();
+ DifAllocator = ModuleAccess<DA>(MOD_DA).get();
+}
+
+void IRM::initialize() {
+ initPointers();
+ initSignalsAndListeners();
+}
+
+void IRM::handleMessage(cMessage* msg) {
+ if (!msg->isSelfMessage()) {
+ //Find output gate based on input
+ cGate* g = ConTable->findOutputGate(msg->getArrivalGate());
+ //Send out if gate exist
+ if (g)
+ send(msg, g);
+ else {
+ EV << "Received message but destination gate is not in the ConnectionTable!" << endl;
+ }
+ }
+ //Process self-message
+ else {
+
+ }
+
+}
+
+void IRM::initSignalsAndListeners() {
+ cModule* catcher = this->getParentModule()->getParentModule();
+
+ //Signals that this module emits
+ sigIRMAllocReq = registerSignal(SIG_IRM_AllocateRequest);
+ sigIRMDeallocReq = registerSignal(SIG_IRM_DeallocateRequest);
+ sigIRMAllocResPosi = registerSignal(SIG_IRM_AllocateResponsePositive);
+ sigIRMAllocResNega = registerSignal(SIG_IRM_AllocateResponseNegative);
+
+ //Signals that this module is processing
+ // AllocationResponseNegative from FA
+ lisAllocResNegaFa = new LisIRMAllocResNegaFa(this);
+ catcher->subscribe(SIG_FA_AllocateResponseNegative, this->lisAllocResNegaFa);
+ // AllocationResponseNegative from FAI
+ lisAllocResNegaFai = new LisIRMAllocResNegaFai(this);
+ catcher->subscribe(SIG_FAI_AllocateResponseNegative, this->lisAllocResNegaFai);
+ // AllocationRequest from FAI
+ this->lisAllocReqFai = new LisIRMAllocReqFai(this);
+ catcher->subscribe(SIG_FAI_AllocateRequest, this->lisAllocReqFai);
+ // Allocate Request from App
+ this->lisAllocReq = new LisIRMAllocReq(this);
+ catcher->subscribe(SIG_AE_AllocateRequest, this->lisAllocReq);
+ // Deallocate Request from App
+ this->lisDeallocReq = new LisIRMDeallocReq(this);
+ catcher->subscribe(SIG_AE_DeallocateRequest, this->lisDeallocReq);
+}
+
+bool IRM::createBindings(Flow* flow) {
+ EV << "Attempts to create bindings and bind registration of gates"<< endl;
+ //Retrieve IPC process with allocated flow and prepared bindings
+
+ cModule* Ipc = ConTable->findEntryByFlow(flow)->getIpc();
+ cModule* Ap = this->getParentModule();
+
+ //Create connections
+
+ // Retrieve IPC gates
+ std::ostringstream nam1;
+ nam1 << GATE_NORTHIO << flow->getSrcPortId();
+ cGate* g1i = Ipc->gateHalf(nam1.str().c_str(), cGate::INPUT);
+ cGate* g1o = Ipc->gateHalf(nam1.str().c_str(), cGate::OUTPUT);
+
+ // Add AP gates
+ std::ostringstream nam2;
+ nam2 << GATE_SOUTHIO << flow->getSrcPortId();
+ Ap->addGate(nam2.str().c_str(), cGate::INOUT, false);
+ cGate* g2i = Ap->gateHalf(nam2.str().c_str(), cGate::INPUT);
+ cGate* g2o = Ap->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
+
+ // Add IRM gates
+ this->addGate(nam2.str().c_str(), cGate::INOUT, false);
+ cGate* g3i = this->gateHalf(nam2.str().c_str(), cGate::INPUT);
+ cGate* g3o = this->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
+
+ //TODO: Status check
+
+ // Connect gates together
+ g1o->connectTo(g2o);
+ g2o->connectTo(g3i);
+
+ g3o->connectTo(g2i);
+ g2i->connectTo(g1i);
+
+ //Set south-half of the routing in ConnectionTable
+ bool status = ConTable->setSouthGates(flow, g3i, g3o);
+
+ return status;
+}
+
+void IRM::receiveAllocationRequest(cObject* obj) {
+ Enter_Method("receiveAllocateRequest()");
+ EV << this->getFullPath() << " received Allocation Request" << endl;
+
+ Flow* flow = dynamic_cast<Flow*>(obj);
+
+ //Ask DA which IPC to use to reach dst App
+ DirectoryEntry* de = DifAllocator->resolveApn(flow->getDstApni().getApn());
+
+ if (de == NULL) {
+ EV << "DA does not know target application" << endl;
+ return;
+ }
+
+ //TODO: Vesely - Now using first available APN to DIFMember mapping
+ Address addr = de->getSupportedDifs().front();
+
+ //TODO: Vesely - New IPC must be enrolled or DIF created
+ if (!DifAllocator->isDifLocal(addr.getDifName())) {
+ EV << "Local CS does not have any IPC in DIF " << addr.getDifName() << endl;
+ return;
+ }
+
+ //Retrieve DIF's local IPC member
+ cModule* targetIpc = DifAllocator->getDifMember(addr.getDifName());
+
+ //Store info into ConnectionTable
+ ConTable->setFa(flow, DifAllocator->findFaInsideIpc(targetIpc));
+
+
+ //Command target FA to allocate flow
+ bool status = ConTable->getFa(flow)->receiveAllocateRequest(flow);
+
+ //If AllocationRequest ended by creating connections
+ if (status)
+ status = createBindings(flow);
+ //Allocation either failed OR app not found
+ else
+ EV << "Flow not allocated!\n" << flow << endl;
+
+ //TODO: Vesely - Change ConnectionTable status
+}
+
+void IRM::receiveDeallocationRequest(cObject* obj) {
+ Enter_Method("receiveDeallocateRequest()");
+ EV << this->getFullPath() << " received DeallocationRequest" << endl;
+ Flow* fl = dynamic_cast<Flow*>(obj);
+ signalizeDeallocateRequest(fl);
+}
+
+void IRM::receiveAllocationResponseNegativeAppNotFound(cObject* obj) {
+ EV << this->getFullPath() << " received Negative Allocation Response App not found" << endl;
+}
+
+void IRM::receiveAllocationResponseNegative(cObject* obj) {
+ //Flow* fl = dynamic_cast<Flow*>(obj);
+ EV << this->getFullPath() << " received Negative Allocation Response" << endl;
+}
+
+void IRM::receiveAllocationRequestFromFAI(cObject* obj) {
+ //EV << this->getFullPath() << " received AllocationRequest from FAI" << endl;
+ Flow* fl = dynamic_cast<Flow*>(obj);
+ //TODO: Vesely - Simulate AllocationResponses
+ if (true) {
+ this->signalizeAllocateResponsePositive(fl);
+ }
+ else {
+ this->signalizeAllocateResponseNegative(fl);
+ }
+}
+
+void IRM::signalizeAllocateRequest(Flow* flow) {
+ //EV << "!!!!VYemitovano" << endl;
+ //EV << "Emits AllocReq Flow = " << flow->getSrcApni() << "_" << flow->getDstApni() << endl;
+ emit(sigIRMAllocReq, flow);
+}
+
+void IRM::signalizeDeallocateRequest(Flow* flow) {
+ emit(sigIRMDeallocReq, flow);
+}
+
+void IRM::signalizeAllocateResponsePositive(Flow* flow) {
+ emit(sigIRMAllocResPosi, flow);
+}
+
+void IRM::signalizeAllocateResponseNegative(Flow* flow) {
+ emit(sigIRMAllocResNega, flow);
+}