--- a
+++ b/src/DIF/RIB/RIBd.cc
@@ -0,0 +1,470 @@
+//
+// Copyright Š 2014 PRISTINE Consortium (http://ict-pristine.eu)
+//
+// 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/.
+//
+/**
+ * @file RIBd.cc
+ * @author Vladimir Vesely (ivesely@fit.vutbr.cz)
+ * @date Apr 30, 2014
+ * @brief Kind of a Notification Board for DIF
+ * @detail
+ */
+
+#include "RIBd.h"
+
+const char* MSG_FLO = "Flow";
+const char* MSG_FLOPOSI = "Flow+";
+const char* MSG_FLONEGA = "Flow-";
+const char* CLS_FLOW = "Flow";
+const int VAL_DEFINSTANCE = -1;
+const int VAL_FLOWPOSI = 1;
+const int VAL_FLOWNEGA = 0;
+const char* VAL_FLREQ = "Request ";
+const char* VAL_FLREQPOSI = "Response+ ";
+const char* VAL_FLREQNEGA = "Response- ";
+
+Define_Module(RIBd);
+
+void RIBd::initialize() {
+ //Init signals and listeners
+ initSignalsAndListeners();
+ //Init CDAP gates and connections
+ initCdapBindings();
+ //Init MyAddress
+ initMyAddress();
+
+ invokeIdCounter = 0;
+}
+
+void RIBd::handleMessage(cMessage *msg) {
+
+}
+
+void RIBd::initCdapBindings() {
+
+ //Get RIBDaemon gates
+ cModule* RibD = this->getParentModule();
+ cGate* gRibdIn = RibD->gateHalf(GATE_RMTIO, cGate::INPUT);
+ cGate* gRibdOut = RibD->gateHalf(GATE_RMTIO, cGate::OUTPUT);
+
+ //CDAPParent Module gates
+ cModule* Cdap = RibD->getSubmodule(MOD_CDAP);
+ cGate* gCdapParentIn;
+ cGate* gCdapParentOut;
+ Cdap->getOrCreateFirstUnconnectedGatePair(GATE_SOUTHIO, false, true, *&gCdapParentIn, *&gCdapParentOut);
+
+ //CDAPSplitter gates
+ cModule* CdapSplit = Cdap->getSubmodule(MOD_CDAPSPLIT);
+ cGate* gSplitIn;
+ cGate* gSplitOut;
+ CdapSplit->getOrCreateFirstUnconnectedGatePair(GATE_SOUTHIO, false, true, *&gSplitIn, *&gSplitOut);
+ cGate* gSplitCaceIn;
+ cGate* gSplitCaceOut;
+ CdapSplit->getOrCreateFirstUnconnectedGatePair(GATE_CACEIO, false, true, *&gSplitCaceIn, *&gSplitCaceOut);
+ cGate* gSplitAuthIn;
+ cGate* gSplitAuthOut;
+ CdapSplit->getOrCreateFirstUnconnectedGatePair(GATE_AUTHIO, false, true, *&gSplitAuthIn, *&gSplitAuthOut);
+ cGate* gSplitCdapIn;
+ cGate* gSplitCdapOut;
+ CdapSplit->getOrCreateFirstUnconnectedGatePair(GATE_CDAPIO, false, true, *&gSplitCdapIn, *&gSplitCdapOut);
+
+ //CACE Module gates
+ cModule* CdapCace = Cdap->getSubmodule(MOD_CDAPCACE);
+ cGate* gCaceIn;
+ cGate* gCaceOut;
+ CdapCace->getOrCreateFirstUnconnectedGatePair(GATE_SPLITIO, false, true, *&gCaceIn, *&gCaceOut);
+
+ //AUTH Module gates
+ cModule* CdapAuth = Cdap->getSubmodule(MOD_CDAPAUTH);
+ cGate* gAuthIn;
+ cGate* gAuthOut;
+ CdapAuth->getOrCreateFirstUnconnectedGatePair(GATE_SPLITIO, false, true, *&gAuthIn, *&gAuthOut);
+
+ //CDAP Module gates
+ cModule* CdapCdap = Cdap->getSubmodule(MOD_CDAPCDAP);
+ cGate* gCdapIn;
+ cGate* gCdapOut;
+ CdapCdap->getOrCreateFirstUnconnectedGatePair(GATE_SPLITIO, false, true, *&gCdapIn, *&gCdapOut);
+
+ //Connect gates together
+ gRibdIn->connectTo(gCdapParentIn);
+ gCdapParentIn->connectTo(gSplitIn);
+
+ gSplitOut->connectTo(gCdapParentOut);
+ gCdapParentOut->connectTo(gRibdOut);
+
+ gSplitCaceOut->connectTo(gCaceIn);
+ gCaceOut->connectTo(gSplitCaceIn);
+
+ gSplitAuthOut->connectTo(gAuthIn);
+ gAuthOut->connectTo(gSplitAuthIn);
+
+ gSplitCdapOut->connectTo(gCdapIn);
+ gCdapOut->connectTo(gSplitCdapIn);
+
+}
+
+void RIBd::sendCreateRequestFlow(Flow* flow) {
+ Enter_Method("sendCreateRequestFlow()");
+
+ //Prepare M_CREATE Flow
+ CDAP_M_Create* mcref = new CDAP_M_Create(MSG_FLO);
+
+ //Prepare object
+ std::ostringstream os;
+ os << flow->getFlowName();
+ object_t flowobj;
+ flowobj.objectClass = flow->getClassName();
+ flowobj.objectName = os.str();
+ flowobj.objectVal = flow;
+ //TODO: Vesely - Assign appropriate values
+ flowobj.objectInstance = VAL_DEFINSTANCE;
+ mcref->setObject(flowobj);
+
+ //Append destination address for RMT "routing"
+ mcref->setDstAddr(flow->getDstNeighbor());
+
+ //TODO: Vesely - Work more on InvokeId
+ mcref->setInvokeID(invokeIdCounter++);
+
+ //Send it
+ signalizeSendData(mcref);
+}
+
+void RIBd::processMCreate(CDAPMessage* msg) {
+ CDAP_M_Create* msg1 = check_and_cast<CDAP_M_Create*>(msg);
+
+ EV << "Received M_Create";
+ object_t object = msg1->getObject();
+ EV << " with object '" << object.objectClass << "'" << endl;
+
+ //CreateRequest Flow
+ if (dynamic_cast<Flow*>(object.objectVal)) {
+ Flow* fl = (check_and_cast<Flow*>(object.objectVal))->dup();
+ //EV << fl->info();
+ fl->swapFlow();
+ //EV << "\n===========\n" << fl->info();
+ signalizeCreateRequestFlow(fl);
+ }
+}
+
+void RIBd::sendDeleteRequestFlow(Flow* flow) {
+ Enter_Method("sendDeleteRequestFlow()");
+
+ //Prepare M_CREATE Flow
+ CDAP_M_Delete* mdereqf = new CDAP_M_Delete(MSG_FLO);
+
+ //Prepare object
+ std::ostringstream os;
+ os << flow->getFlowName();
+ object_t flowobj;
+ flowobj.objectClass = flow->getClassName();
+ flowobj.objectName = os.str();
+ flowobj.objectVal = flow;
+ //TODO: Vesely - Assign appropriate values
+ flowobj.objectInstance = VAL_DEFINSTANCE;
+ mdereqf->setObject(flowobj);
+
+ //Append destination address for RMT "routing"
+ mdereqf->setDstAddr(flow->getDstAddr());
+
+ //TODO: Vesely - Work more on InvokeId
+ mdereqf->setInvokeID(invokeIdCounter++);
+
+ //Send it
+ signalizeSendData(mdereqf);
+}
+
+void RIBd::processMCreateR(CDAPMessage* msg) {
+ CDAP_M_Create_R* msg1 = check_and_cast<CDAP_M_Create_R*>(msg);
+
+ EV << "Received M_Create_R";
+ object_t object = msg1->getObject();
+ EV << " with object '" << object.objectClass << "'" << endl;
+
+ //CreateResponseFlow
+ if (dynamic_cast<Flow*>(object.objectVal)) {
+ Flow* flow = (check_and_cast<Flow*>(object.objectVal))->dup();
+ flow->swapFlow();
+ //Positive response
+ if (!msg1->getResult().resultValue) {
+ signalizeCreateResponseFlowPositive(flow);
+ }
+ //Negative response
+ else
+ signalizeCreateResponseFlowNegative(flow);
+ }
+}
+
+void RIBd::receiveData(CDAPMessage* msg) {
+ Enter_Method("receiveData()");
+ //M_CREATE_Request
+ if (dynamic_cast<CDAP_M_Create*>(msg)) {
+ processMCreate(msg);
+ }
+ //M_CREATE_Response
+ else if (dynamic_cast<CDAP_M_Create_R*>(msg)) {
+ processMCreateR(msg);
+ }
+ //M_DELETE_Request
+ else if (dynamic_cast<CDAP_M_Delete*>(msg)) {
+ processMDelete(msg);
+ }
+ //M_DELETE_Request
+ else if (dynamic_cast<CDAP_M_Delete_R*>(msg)) {
+ processMDeleteR(msg);
+ }
+
+
+ delete msg;
+}
+
+void RIBd::initSignalsAndListeners() {
+ cModule* catcher1 = this->getParentModule();
+ cModule* catcher2 = this->getParentModule()->getParentModule();
+ cModule* catcher3 = this->getParentModule()->getParentModule()->getParentModule();
+
+ //Signals that this module is emitting
+ sigRIBDSendData = registerSignal(SIG_RIBD_DataSend);
+ sigRIBDCreReqFlo = registerSignal(SIG_RIBD_CreateRequestFlow);
+ sigRIBDDelReqFlo = registerSignal(SIG_RIBD_DeleteRequestFlow);
+ sigRIBDDelResFlo = registerSignal(SIG_RIBD_DeleteResponseFlow);
+ sigRIBDAllocResPosi = registerSignal(SIG_AERIBD_AllocateResponsePositive);
+ sigRIBDAllocResNega = registerSignal(SIG_AERIBD_AllocateResponseNegative);
+ sigRIBDCreFlow = registerSignal(SIG_RIBD_CreateFlow);
+ sigRIBDCreResFloPosi = registerSignal(SIG_RIBD_CreateFlowResponsePositive);
+ sigRIBDCreResFloNega = registerSignal(SIG_RIBD_CreateFlowResponseNegative);
+
+ //Signals that this module is processing
+
+ lisRIBDCreReqByForward = new LisRIBDCreReq(this);
+ catcher2->subscribe(SIG_FA_CreateFlowRequestForward, lisRIBDCreReqByForward);
+ lisRIBDCreReq = new LisRIBDCreReq(this);
+ catcher2->subscribe(SIG_FAI_CreateFlowRequest, lisRIBDCreReq);
+
+ lisRIBDDelReq = new LisRIBDDelReq(this);
+ catcher2->subscribe(SIG_FAI_DeleteFlowRequest, lisRIBDDelReq);
+ lisRIBDDelRes = new LisRIBDDelRes(this);
+ catcher2->subscribe(SIG_FAI_DeleteFlowResponse, lisRIBDDelRes);
+
+ lisRIBDCreResNegaFromFa = new LisRIBDCreResNega(this);
+ catcher2->subscribe(SIG_FA_CreateFlowResponseNegative, lisRIBDCreResNegaFromFa);
+ lisRIBDCreResNega = new LisRIBDCreResNega(this);
+ catcher2->subscribe(SIG_FAI_CreateFlowResponseNegative, lisRIBDCreResNega);
+
+ lisRIBDCreResPosi = new LisRIBDCreResPosi(this);
+ catcher2->subscribe(SIG_FAI_CreateFlowResponsePositive, lisRIBDCreResPosi);
+ lisRIBDCreResPosiForward = new LisRIBDCreResPosi(this);
+ catcher2->subscribe(SIG_FA_CreateFlowResponseForward, lisRIBDCreResPosiForward);
+
+ lisRIBDRcvData = new LisRIBDRcvData(this);
+ catcher1->subscribe(SIG_CDAP_DateReceive, lisRIBDRcvData);
+
+ lisRIBDAllReqFromFai = new LisRIBDAllReqFromFai(this);
+ catcher3->subscribe(SIG_FAI_AllocateRequest, lisRIBDAllReqFromFai);
+
+ lisRIBDCreFloPosi = new LisRIBDCreFloPosi(this);
+ catcher2->subscribe(SIG_RA_CreateFlowPositive, lisRIBDCreFloPosi);
+ lisRIBDCreFloNega = new LisRIBDCreFloNega(this);
+ catcher2->subscribe(SIG_RA_CreateFlowNegative, lisRIBDCreFloNega);
+}
+
+void RIBd::receiveAllocationRequestFromFai(Flow* flow) {
+ Enter_Method("receiveAllocationRequestFromFai()");
+ //Execute flow allocate
+ signalizeCreateFlow(flow);
+}
+
+void RIBd::sendCreateResponseNegative(Flow* flow) {
+ Enter_Method("sendCreateResponseFlowNegative()");
+
+ //Prepare M_CREATE_R Flow-
+ CDAP_M_Create_R* mcref = new CDAP_M_Create_R(MSG_FLONEGA);
+
+ //Prepare object
+ std::ostringstream os;
+ os << flow->getFlowName();
+ object_t flowobj;
+ flowobj.objectClass = flow->getClassName();
+ flowobj.objectName = os.str();
+ flowobj.objectVal = flow;
+ //TODO: Vesely - Assign appropriate values
+ flowobj.objectInstance = VAL_DEFINSTANCE;
+ mcref->setObject(flowobj);
+
+ //Prepare result object
+ result_t resultobj;
+ resultobj.resultValue = R_FAIL;
+ mcref->setResult(resultobj);
+
+ //TODO: Vesely - Work more on InvokeId
+
+ //Append destination address for RMT "routing"
+ mcref->setDstAddr(flow->getDstAddr());
+
+ //Send it
+ signalizeSendData(mcref);
+}
+
+void RIBd::sendCreateResponsePostive(Flow* flow) {
+ Enter_Method("sendCreateResponseFlowPositive()");
+
+ //Prepare M_CREATE_R Flow+
+ CDAP_M_Create_R* mcref = new CDAP_M_Create_R(MSG_FLOPOSI);
+
+ //Prepare object
+ std::ostringstream os;
+ os << flow->getFlowName();
+ object_t flowobj;
+ flowobj.objectClass = flow->getClassName();
+ flowobj.objectName = os.str();
+ flowobj.objectVal = flow;
+ //TODO: Vesely - Assign appropriate values
+ flowobj.objectInstance = VAL_DEFINSTANCE;
+ mcref->setObject(flowobj);
+
+ //Prepare result object
+ result_t resultobj;
+ resultobj.resultValue = R_SUCCESS;
+ mcref->setResult(resultobj);
+
+ //TODO: Vesely - Work more on InvokeId
+
+ //Append destination address for RMT "routing"
+ mcref->setDstAddr(flow->getDstAddr());
+
+ //Send it
+ signalizeSendData(mcref);
+}
+
+void RIBd::signalizeSendData(CDAPMessage* msg) {
+ //Setup handle which is for RIBd always 0
+ msg->setHandle(0);
+ //Pass message to CDAP
+ EV << "Emits SendData signal for message " << msg->getName() << endl;
+ emit(sigRIBDSendData, msg);
+}
+
+void RIBd::signalizeAllocateResponsePositive(Flow* flow) {
+ EV << "Emits AllocateResponsePositive signal for flow" << endl;
+ emit(sigRIBDAllocResPosi, flow);
+}
+
+void RIBd::signalizeCreateRequestFlow(Flow* flow) {
+ EV << "Emits CreateRequestFlow signal for flow" << endl;
+ emit(sigRIBDCreReqFlo, flow);
+}
+
+void RIBd::signalizeCreateResponseFlowPositive(Flow* flow) {
+ EV << "Emits CreateResponsetFlowPositive signal for flow" << endl;
+ emit(sigRIBDCreResFloPosi, flow);
+}
+
+void RIBd::signalizeCreateResponseFlowNegative(Flow* flow) {
+ EV << "Emits CreateResponsetFlowNegative signal for flow" << endl;
+ emit(sigRIBDCreResFloNega, flow);
+}
+
+void RIBd::signalizeCreateFlow(Flow* flow) {
+ EV << "Emits CreateFlow signal for flow" << endl;
+ emit(sigRIBDCreFlow, flow);
+}
+
+void RIBd::processMDelete(CDAPMessage* msg) {
+ CDAP_M_Delete* msg1 = check_and_cast<CDAP_M_Delete*>(msg);
+
+ EV << "Received M_Delete";
+ object_t object = msg1->getObject();
+ EV << " with object '" << object.objectClass << "'" << endl;
+
+ //DeleteRequest Flow
+ if (dynamic_cast<Flow*>(object.objectVal)) {
+ Flow* fl = (check_and_cast<Flow*>(object.objectVal))->dup();
+ fl->swapFlow();
+ signalizeDeleteRequestFlow(fl);
+ }
+
+}
+
+void RIBd::signalizeDeleteRequestFlow(Flow* flow) {
+ EV << "Emits DeleteRequestFlow signal for flow" << endl;
+ emit(sigRIBDDelReqFlo, flow);
+}
+
+void RIBd::sendDeleteResponseFlow(Flow* flow) {
+ Enter_Method("sendDeleteResponseFlow()");
+
+ //Prepare M_CREATE_R Flow+
+ CDAP_M_Delete_R* mderesf = new CDAP_M_Delete_R(MSG_FLOPOSI);
+
+ //Prepare object
+ std::ostringstream os;
+ os << flow->getFlowName();
+ object_t flowobj;
+ flowobj.objectClass = flow->getClassName();
+ flowobj.objectName = os.str();
+ flowobj.objectVal = flow;
+ //TODO: Vesely - Assign appropriate values
+ flowobj.objectInstance = VAL_DEFINSTANCE;
+ mderesf->setObject(flowobj);
+
+ //Prepare result object
+ result_t resultobj;
+ resultobj.resultValue = R_SUCCESS;
+ mderesf->setResult(resultobj);
+
+ //TODO: Vesely - Work more on InvokeId
+
+ //Append destination address for RMT "routing"
+ mderesf->setDstAddr(flow->getDstAddr());
+
+ //Send it
+ signalizeSendData(mderesf);
+
+}
+
+void RIBd::signalizeDeleteResponseFlow(Flow* flow) {
+ EV << "Emits DeleteResponseFlow signal for flow" << endl;
+ emit(sigRIBDDelResFlo, flow);
+}
+
+void RIBd::receiveCreateFlowPositiveFromRa(Flow* flow) {
+ signalizeAllocateResponsePositive(flow);
+}
+
+void RIBd::receiveCreateFlowNegativeFromRa(Flow* flow) {
+ signalizeAllocateResponseNegative(flow);
+}
+
+void RIBd::signalizeAllocateResponseNegative(Flow* flow) {
+ EV << "Emits AllocateResponseNegative signal for flow" << endl;
+ emit(sigRIBDAllocResNega, flow);
+}
+
+void RIBd::processMDeleteR(CDAPMessage* msg) {
+ CDAP_M_Delete_R* msg1 = check_and_cast<CDAP_M_Delete_R*>(msg);
+
+ EV << "Received M_Delete_R";
+ object_t object = msg1->getObject();
+ EV << " with object '" << object.objectClass << "'" << endl;
+
+ //DeleteResponseFlow
+ if (dynamic_cast<Flow*>(object.objectVal)) {
+ Flow* flow = (check_and_cast<Flow*>(object.objectVal))->dup();
+ flow->swapFlow();
+ signalizeDeleteResponseFlow(flow);
+ }
+
+}