Switch to side-by-side view

--- a/src/DIF/FA/FAI.cc
+++ b/src/DIF/FA/FAI.cc
@@ -1,19 +1,24 @@
+// The MIT License (MIT)
 //
-// Copyright Š 2014 PRISTINE Consortium (http://ict-pristine.eu)
+// Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
 //
-// 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.
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
 //
-// 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.
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
 //
-// 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/.
-//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
 
 #include "FAI.h"
 
@@ -24,7 +29,7 @@
 
 FAI::FAI() : FAIBase() {
     FaModule = NULL;
-    creReqTimer = NULL;
+    //creReqTimer = NULL;
 }
 
 FAI::~FAI() {
@@ -35,8 +40,8 @@
     localCEPId      = VAL_UNDEF_CEPID;
     remotePortId    = VAL_UNDEF_PORTID;
     remoteCEPId     = VAL_UNDEF_CEPID;
-    if (creReqTimer)
-        cancelAndDelete(creReqTimer);
+    //if (creReqTimer)
+    //    cancelAndDelete(creReqTimer);
 }
 
 void FAI::initialize() {
@@ -45,7 +50,7 @@
     remotePortId = par(PAR_REMOTEPORTID);
     remoteCEPId  = par(PAR_REMOTECEPID);
 
-    creReqTimeout = par(PAR_CREREQTIMEOUT).doubleValue();
+    //creReqTimeout = par(PAR_CREREQTIMEOUT).doubleValue();
 
     AllocRetryPolicy = check_and_cast<AllocateRetryBase*>(getParentModule()->getSubmodule(MOD_ALLOCRETRYPOLICY));
 
@@ -59,16 +64,16 @@
     //Initialize pointers! It cannot be done during model creation :(
     this->FaModule = fa;
     this->FlowObject = fl;
-    this->efcp = efcp;
+    this->EfcpModule = efcp;
 }
 
 bool FAI::receiveAllocateRequest() {
     Enter_Method("receiveAllocateRequest()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::ALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::ALLOC_PEND) {
         EV << "Cannot allocate flow which is not in pending state" << endl;
         return false;
     }
@@ -77,7 +82,7 @@
     bool status = this->FaModule->invokeNewFlowRequestPolicy(this->FlowObject);
     if (!status){
         EV << "invokeNewFlowPolicy() failed"  << endl;
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         this->signalizeAllocateResponseNegative();
         return false;
     }
@@ -85,7 +90,7 @@
     status = this->createEFCPI();
     if (!status) {
         EV << "createEFCP() failed" << endl;
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         this->signalizeAllocateResponseNegative();
         return false;
     }
@@ -93,7 +98,7 @@
     status = this->createBindings();
     if (!status) {
         EV << "createBindings() failed" << endl;
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         this->signalizeAllocateResponseNegative();
         return false;
     }
@@ -117,9 +122,9 @@
     Enter_Method("receiveAllocateResponsePositive()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::ALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::ALLOC_PEND) {
         EV << "Cannot continue allocation of flow which is not in pending state" << endl;
         return false;
     }
@@ -129,7 +134,7 @@
     bool status = this->createEFCPI();
     if (!status) {
         EV << "createEFCP() failed" << endl;
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         //Schedule negative M_Create_R(Flow)
         this->signalizeCreateFlowResponseNegative();
         return false;
@@ -139,7 +144,7 @@
     status = this->createBindings();
     if (!status) {
         EV << "createBindings() failed" << endl;
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         //Schedule M_Create_R(Flow-)
         this->signalizeCreateFlowResponseNegative();
         return false;
@@ -149,7 +154,7 @@
     RABase* raModule = (RABase*) getModuleByPath("^.^.resourceAllocator.ra");
     status = isDegenerateDataTransfer() ? true : raModule->bindNFlowToNM1Flow(FlowObject);
 
-    ft->changeAllocStatus(FlowObject, FAITableEntry::TRANSFER);
+    ft->changeAllocStatus(FlowObject, NFlowTableEntry::TRANSFER);
     //Signalizes M_Create_R(flow)
     if (status) {
         this->signalizeCreateFlowResponsePositive();
@@ -159,15 +164,16 @@
 }
 
 void FAI::receiveAllocateResponseNegative() {
+    Enter_Method("receiveAllocateResponseNegative()");
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::ALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::ALLOC_PEND) {
         EV << "Cannot continue allocation of flow which is not in pending state" << endl;
         return;
     }
 
-    ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+    ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
 
     //IF it is not DDT then retry M_CREATE
     //if (!isDegenerateDataTransfer())
@@ -178,9 +184,9 @@
     Enter_Method("receiveCreateRequest()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::ALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::ALLOC_PEND) {
         EV << "Cannot allocate flow which is not in pending state" << endl;
         return false;
     }
@@ -190,7 +196,7 @@
     if (!status){
         EV << "invokeNewFlowPolicy() failed"  << endl;
         //Schedule negative M_Create_R(Flow)
-        ft->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        ft->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         this->signalizeCreateFlowResponseNegative();
         return false;
     }
@@ -198,7 +204,7 @@
     //Create IPC north gates
     createNorthGates();
 
-    //Pass AllocationRequest to AP or RMT
+    //Pass AllocationRequest to AP or RIBd
     this->signalizeAllocationRequestFromFai();
 
     //Everything went fine
@@ -209,9 +215,9 @@
     Enter_Method("receiveDeallocateRequest()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::DEALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::DEALLOC_PEND) {
         EV << "Cannot deallocate flow which is not in deallocate pending state" << endl;
         return false;
     }
@@ -229,14 +235,14 @@
     Enter_Method("receiveDeleteRequest()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::TRANSFER) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::TRANSFER) {
         EV << "Cannot deallocate flow which is not in transfer state" << endl;
         return;
     }
 
-    ft->changeAllocStatus(FlowObject, FAITableEntry::DEALLOC_PEND);
+    ft->changeAllocStatus(FlowObject, NFlowTableEntry::DEALLOC_PEND);
 
     //Get deallocation invokeId from Request
     FlowObject->setDeallocInvokeId(flow->getDeallocInvokeId());
@@ -250,7 +256,7 @@
     //Signalizes M_Delete_R(Flow)
     this->signalizeDeleteFlowResponse();
 
-    ft->changeAllocStatus(FlowObject, FAITableEntry::DEALLOCATED);
+    ft->changeAllocStatus(FlowObject, NFlowTableEntry::DEALLOCATED);
     fte->setTimeDeleted(simTime());
 }
 
@@ -267,7 +273,7 @@
     //...otherwise signalize to AE or RIBd failure
     else  {
         EV << "invokeAllocateRetryPolicy() failed"  << endl;
-        FaModule->getFaiTable()->changeAllocStatus(FlowObject, FAITableEntry::ALLOC_NEGA);
+        FaModule->getNFlowTable()->changeAllocStatus(FlowObject, NFlowTableEntry::ALLOC_NEGA);
         this->signalizeAllocateResponseNegative();
     }
 
@@ -279,7 +285,7 @@
     //TODO: Vesely - D-Base-2011-015.pdf, p.9
     //              Create bindings. WTF? Bindings should be already created!''
 
-    cancelEvent(creReqTimer);
+    //cancelEvent(creReqTimer);
 
     //Change dstCep-Id and dstPortId according to new information
     FlowObject->getConnectionId().setDstCepId(flow->getConId().getDstCepId());
@@ -290,10 +296,15 @@
     par(PAR_REMOTECEPID) = remoteCEPId;
 
     //Change status
-    FaModule->getFaiTable()->changeAllocStatus(FlowObject, FAITableEntry::TRANSFER);
-
-    //Pass Allocate Response to AE or RIBd
-    this->signalizeAllocateResponsePositive();
+    FaModule->getNFlowTable()->changeAllocStatus(FlowObject, NFlowTableEntry::TRANSFER);
+
+    //if (FlowObject->isManagementFlowLocalToIPCP()) {
+    //    signalizeAllocateRequestToOtherFais( FlowObject );
+    //}
+    //else {
+        //Pass Allocate Response to AE or RIBd
+        this->signalizeAllocateResponsePositive();
+    //}
 
     //FIXME: Vesely - always true
     return true;
@@ -303,9 +314,9 @@
     Enter_Method("receiveDeleteResponse()");
 
     //Check for proper FSM state
-    FAITable* ft = FaModule->getFaiTable();
-    FAITableEntry* fte = ft->findEntryByFlow(FlowObject);
-    if (fte->getAllocateStatus() != FAITableEntry::DEALLOC_PEND) {
+    NFlowTable* ft = FaModule->getNFlowTable();
+    NFlowTableEntry* fte = ft->findEntryByFlow(FlowObject);
+    if (fte->getAllocateStatus() != NFlowTableEntry::DEALLOC_PEND) {
         EV << "Cannot deallocate flow which is not in deallocatre pending state" << endl;
         return;
     }
@@ -313,11 +324,12 @@
     //Notify application
     signalizeDeallocateRequestFromFai();
 
-    ft->changeAllocStatus(FlowObject, FAITableEntry::DEALLOCATED);
+    ft->changeAllocStatus(FlowObject, NFlowTableEntry::DEALLOCATED);
     fte->setTimeDeleted(simTime());
 }
 
 void FAI::handleMessage(cMessage *msg) {
+    /*
     //CreateRequest was not delivered in time
     if ( !strcmp(msg->getName(), TIM_CREREQ) ) {
         //Increment and resend
@@ -325,6 +337,7 @@
         if (!status)
             EV << "CreateRequest retries reached its maximum!" << endl;
     }
+    */
 }
 
 std::string FAI::info() const {
@@ -343,24 +356,14 @@
 bool FAI::createEFCPI() {
     EV << this->getFullPath() << " attempts to create EFCP instance" << endl;
     //Create EFCPI for local bindings
-    EFCPInstance* efcpi = efcp->createEFCPI(FlowObject, localCEPId, localPortId);
+    EFCPInstance* efcpi = EfcpModule->createEFCPI(FlowObject, localCEPId, localPortId);
     return efcpi ? true : false;
 }
 
 bool FAI::createBindings() {
     EV << this->getFullPath() << " attempts to bind EFCP and RMT" << endl;
 
-    std::ostringstream nameIpcDown;
-    nameIpcDown << GATE_NORTHIO_ << localPortId;
     cModule* IPCModule = FaModule->getParentModule()->getParentModule();
-
-    //IF called as consequence of AllocateRequest then createNorthGate
-    //ELSE (called as consequence of CreateRequestFlow) skip
-    if (!IPCModule->hasGate(nameIpcDown.str().c_str()))
-        createNorthGates();
-
-    cGate* gateIpcDownIn = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::INPUT);
-    cGate* gateIpcDownOut = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::OUTPUT);
 
     std::ostringstream nameEfcpNorth;
     nameEfcpNorth << GATE_APPIO_ << localPortId;
@@ -368,9 +371,44 @@
     cGate* gateEfcpUpIn = efcpModule->gateHalf(nameEfcpNorth.str().c_str(), cGate::INPUT);
     cGate* gateEfcpUpOut = efcpModule->gateHalf(nameEfcpNorth.str().c_str(), cGate::OUTPUT);
 
-    //IPCModule.northIo <--> Efcp.fai
-    gateEfcpUpOut->connectTo(gateIpcDownOut);
-    gateIpcDownIn->connectTo(gateEfcpUpIn);
+    //Management Flow should be connected with RIBd
+    if (FlowObject->isManagementFlowLocalToIPCP()) {
+        std::ostringstream ribdName;
+        ribdName << GATE_EFCPIO_ << localPortId;
+        cModule* ribdModule = IPCModule->getModuleByPath(".ribDaemon");
+        cModule* ribdSplitterModule = IPCModule->getModuleByPath(".ribDaemon.ribdSplitter");
+
+        if (!ribdModule->hasGate(ribdName.str().c_str()))
+            {createNorthGates();}
+
+        cGate* gateRibdIn  = ribdModule->gateHalf(ribdName.str().c_str(), cGate::INPUT);
+        cGate* gateRibdOut = ribdModule->gateHalf(ribdName.str().c_str(), cGate::OUTPUT);
+        cGate* gateRibdSplitIn  = ribdSplitterModule->gateHalf(ribdName.str().c_str(), cGate::INPUT);
+        cGate* gateRibdSplitOut = ribdSplitterModule->gateHalf(ribdName.str().c_str(), cGate::OUTPUT);
+
+        //EFCPi.efcpio <--> RIBDaemon.efcpIo_ <--> RIBDaemon.ribdSplitter.efcpIo_
+        gateEfcpUpOut->connectTo(gateRibdIn);
+        gateRibdIn->connectTo(gateRibdSplitIn);
+        gateRibdSplitOut->connectTo(gateRibdOut);
+        gateRibdOut->connectTo(gateEfcpUpIn);
+    }
+    //Data flow
+    else {
+        std::ostringstream nameIpcDown;
+        nameIpcDown << GATE_NORTHIO_ << localPortId;
+
+        //IF called as consequence of AllocateRequest then createNorthGate
+        //ELSE (called as consequence of CreateRequestFlow) skip
+        if (!IPCModule->hasGate(nameIpcDown.str().c_str()))
+            {createNorthGates();}
+
+        cGate* gateIpcDownIn = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::INPUT);
+        cGate* gateIpcDownOut = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::OUTPUT);
+
+        //IPCModule.northIo <--> Efcp.fai
+        gateEfcpUpOut->connectTo(gateIpcDownOut);
+        gateIpcDownIn->connectTo(gateEfcpUpIn);
+    }
 
     //Create bindings in RMT
     RMT* rmtModule = (RMT*) IPCModule->getModuleByPath(".relayAndMux.rmt");
@@ -399,29 +437,50 @@
 bool FAI::deleteBindings() {
     EV << this->getFullPath() << " attempts to disconnect bindings between EFCP, IPC and RMT" << endl;
 
-    std::ostringstream nameIpcDown;
-    nameIpcDown << GATE_NORTHIO_ << localPortId;
-    cModule* IPCModule = FaModule->getParentModule()->getParentModule();
-    cGate* gateIpcDownIn = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::INPUT);
-    cGate* gateIpcDownOut = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::OUTPUT);
-
+    //Flush All messages in EFCPI
+    EfcpModule->deleteEFCPI(this->getFlow());
+
+    //Management flow
+    if (FlowObject->isManagementFlowLocalToIPCP()) {
+        std::ostringstream ribdName;
+        ribdName << GATE_EFCPIO_ << localPortId;
+        cModule* ribdModule = this->getModuleByPath("^.^.ribDaemon");
+        cModule* ribdSplitterModule = this->getModuleByPath("^.^.ribDaemon.ribdSplitter");
+
+        cGate* gateRibdIn  = ribdModule->gateHalf(ribdName.str().c_str(), cGate::INPUT);
+        cGate* gateRibdOut = ribdModule->gateHalf(ribdName.str().c_str(), cGate::OUTPUT);
+        cGate* gateRibdSplitIn  = ribdSplitterModule->gateHalf(ribdName.str().c_str(), cGate::INPUT);
+        cGate* gateRibdSplitOut = ribdSplitterModule->gateHalf(ribdName.str().c_str(), cGate::OUTPUT);
+
+        gateRibdIn->disconnect();
+        gateRibdOut->disconnect();
+        gateRibdSplitIn->disconnect();
+        gateRibdSplitOut->disconnect();
+    }
+    //Data flow
+    else {
+        cModule* IPCModule = FaModule->getParentModule()->getParentModule();
+        std::ostringstream nameIpcDown;
+        nameIpcDown << GATE_NORTHIO_ << localPortId;
+        cGate* gateIpcDownIn = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::INPUT);
+        cGate* gateIpcDownOut = IPCModule->gateHalf(nameIpcDown.str().c_str(), cGate::OUTPUT);
+
+        //IPCModule.northIo
+        gateIpcDownOut->disconnect();
+        gateIpcDownIn->disconnect();
+    }
+
+    //Delete EFCP bindings
     std::ostringstream nameEfcpNorth;
     nameEfcpNorth << GATE_APPIO_ << localPortId;
-    cModule* efcpModule = IPCModule->getModuleByPath(".efcp");
+    cModule* efcpModule = this->getModuleByPath("^.^.efcp");
     cGate* gateEfcpUpIn = efcpModule->gateHalf(nameEfcpNorth.str().c_str(), cGate::INPUT);
     cGate* gateEfcpUpOut = efcpModule->gateHalf(nameEfcpNorth.str().c_str(), cGate::OUTPUT);
-
-    //Flush All messages in EFCPI
-    efcp->deleteEFCPI(this->getFlow());
-
-    //IPCModule.northIo <- XX -> Efcp.fai
     gateEfcpUpIn->disconnect();
     gateEfcpUpOut->disconnect();
-    gateIpcDownOut->disconnect();
-    gateIpcDownIn->disconnect();
 
     //Delete bindings in RMT
-    RMT* rmtModule = (RMT*) IPCModule->getModuleByPath(".relayAndMux.rmt");
+    RMT* rmtModule = (RMT*) this->getModuleByPath("^.^.relayAndMux.rmt");
 
     std::ostringstream nameRmtUp;
     nameRmtUp << GATE_EFCPIO_ << localCEPId;
@@ -446,7 +505,7 @@
 
 bool FAI::invokeAllocateRetryPolicy() {
     //Increase CreateFlowRetries
-    cancelEvent(creReqTimer);
+    //cancelEvent(creReqTimer);
     return AllocRetryPolicy->run(*getFlow());
 }
 
@@ -471,7 +530,7 @@
     catcher3->subscribe(SIG_toFAI_AllocateRequest, this->lisAllocReq);
     //  AllocationRespNegative
     this->lisAllocResNega   = new LisFAIAllocResNega(this);
-    catcher3->subscribe(SIG_toFAI_AllocateResponseNegative, this->lisAllocResNega);
+    catcher3->subscribe(SIG_AERIBD_AllocateResponseNegative, this->lisAllocResNega);
     //  AllocationRespPositive
     this->lisAllocResPosi   = new LisFAIAllocResPosi(this);
     catcher3->subscribe(SIG_AERIBD_AllocateResponsePositive, this->lisAllocResPosi);
@@ -503,9 +562,9 @@
 }
 
 void FAI::signalizeCreateFlowRequest() {
-    creReqTimer = new cMessage(TIM_CREREQ);
+    //creReqTimer = new cMessage(TIM_CREREQ);
     //Start timer
-    scheduleAt(simTime() + creReqTimeout, creReqTimer);
+    //scheduleAt(simTime() + creReqTimeout, creReqTimer);
     //Signalize RIBd to send M_CREATE(flow)
     emit(this->sigFAICreReq, FlowObject);
 }
@@ -580,17 +639,29 @@
 }
 
 void FAI::createNorthGates() {
-    std::ostringstream nameIpcDown;
-    nameIpcDown << GATE_NORTHIO_ << localPortId;
-    cModule* IPCModule = FaModule->getParentModule()->getParentModule();
-    IPCModule->addGate(nameIpcDown.str().c_str(), cGate::INOUT, false);
+    //Management flow
+    if (FlowObject->isManagementFlowLocalToIPCP()) {
+        std::ostringstream ribdName;
+        ribdName << GATE_EFCPIO_ << localPortId;
+        cModule* ribdModule = this->getModuleByPath("^.^.ribDaemon");
+        cModule* ribdSplitterModule = this->getModuleByPath("^.^.ribDaemon.ribdSplitter");
+        ribdModule->addGate(ribdName.str().c_str(), cGate::INOUT, false);
+        ribdSplitterModule->addGate(ribdName.str().c_str(), cGate::INOUT, false);
+    }
+    //Data flow
+    else {
+        std::ostringstream nameIpcDown;
+        nameIpcDown << GATE_NORTHIO_ << localPortId;
+        cModule* IPCModule = FaModule->getParentModule()->getParentModule();
+        IPCModule->addGate(nameIpcDown.str().c_str(), cGate::INOUT, false);
+    }
     return;
 }
 
 void FAI::receiveCreateFlowResponsePositiveFromNminusOne() {
     Enter_Method("receiveCreFlowResPositiveFromNminusOne()");
     //Schedule M_Create(Flow)
-    this->signalizeCreateFlowRequest();
+    signalizeCreateFlowRequest();
 }
 
 void FAI::receiveCreateFlowResponseNegativeFromNminusOne() {