From f614592ab240f7246fc964fbfc9dbabf87cfd724 Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Tue, 2 Aug 2022 17:28:54 +0200 Subject: [PATCH 1/8] test commit --- .../MecRequestBackgroundApp.cc | 24 +- .../MecRequestBackgroundApp.h | 12 +- .../MecRequestBackgroundGeneratorApp.cc | 25 +- .../MecRequestBackgroundGeneratorApp.h | 13 +- .../MecRequestForegroundApp.cc | 28 +- .../MecRequestForegroundApp.h | 12 +- .../MecApps/packets/ProcessingTimeMessage.msg | 14 + .../MecRequestResponseApp/MECResponseApp.cc | 306 ++++++++++++++++ .../MecRequestResponseApp/MECResponseApp.h | 100 ++++++ .../MecRequestResponseApp/MECResponseApp.ned | 56 +++ .../mec/MecRequestResponseApp/UERequestApp.cc | 333 ++++++++++++++++++ .../mec/MecRequestResponseApp/UERequestApp.h | 97 +++++ .../MecRequestResponseApp/UERequestApp.ned | 67 ++++ .../packets/RequestResponsePacket.msg | 37 ++ .../mec/WarningAlert/MECWarningAlertApp.cc | 114 ++++-- .../mec/WarningAlert/MECWarningAlertApp.h | 13 +- .../MECServiceBase/SocketManager.cc | 26 +- .../MECServiceBase/SocketManager.h | 1 + src/nodes/mec/utils/httpUtils/httpUtils.cc | 210 ++++++----- src/nodes/mec/utils/httpUtils/httpUtils.h | 2 +- 20 files changed, 1295 insertions(+), 195 deletions(-) create mode 100644 src/apps/mec/MecApps/packets/ProcessingTimeMessage.msg create mode 100644 src/apps/mec/MecRequestResponseApp/MECResponseApp.cc create mode 100644 src/apps/mec/MecRequestResponseApp/MECResponseApp.h create mode 100644 src/apps/mec/MecRequestResponseApp/MECResponseApp.ned create mode 100644 src/apps/mec/MecRequestResponseApp/UERequestApp.cc create mode 100644 src/apps/mec/MecRequestResponseApp/UERequestApp.h create mode 100644 src/apps/mec/MecRequestResponseApp/UERequestApp.ned create mode 100644 src/apps/mec/MecRequestResponseApp/packets/RequestResponsePacket.msg diff --git a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc index 301d4c3c2..25447f5eb 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc +++ b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc @@ -29,7 +29,7 @@ MecRequestBackgroundApp::~MecRequestBackgroundApp(){ cancelAndDelete(burstTimer); } -void MecRequestBackgroundApp::handleServiceMessage() +void MecRequestBackgroundApp::handleServiceMessage(int connId) { EV << "payload: " << serviceHttpMessage->getBody() << endl; // if(burstFlag) @@ -42,6 +42,7 @@ void MecRequestBackgroundApp::initialize(int stage){ if(stage != inet::INITSTAGE_APPLICATION_LAYER) return; MecAppBase::initialize(stage); + mp1Socket_ = addNewSocket(); cMessage *m = new cMessage("connectService"); sendBurst = new cMessage("sendBurst"); burstPeriod = new cMessage("burstPeriod"); @@ -62,7 +63,7 @@ void MecRequestBackgroundApp::sendRequest(){ * */ std::string payload = "BulkRequest: 1";// + std::to_string(numberOfApplications_); - Http::sendPacket(payload.c_str(), &serviceSocket_); + Http::sendPacket(payload.c_str(), serviceSocket_); EV << "sent 1 request to the server"<getSocketId()) { EV << "MecRequestBackgroundApp::established - Mp1Socket"<< endl; // get endPoint of the required service const char *uri = "/example/mec_service_mgmt/v1/services?ser_name=LocationService"; - std::string host = mp1Socket_.getRemoteAddress().str()+":"+std::to_string(mp1Socket_.getRemotePort()); + std::string host = mp1Socket_->getRemoteAddress().str()+":"+std::to_string(mp1Socket_->getRemotePort()); - Http::sendGetRequest(&mp1Socket_, host.c_str(), uri); + Http::sendGetRequest(mp1Socket_, host.c_str(), uri); return; } - else if (connId == serviceSocket_.getSocketId()) + else if (connId == serviceSocket_->getSocketId()) { EV << "MecRequestBackgroundApp::established - serviceSocket"<< endl; scheduleAt(simTime() + exponential(lambda, 2), burstTimer); @@ -100,13 +101,13 @@ void MecRequestBackgroundApp::handleSelfMessage(cMessage *msg){ else if(strcmp(msg->getName(), "connectMp1") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&mp1Socket_, mp1Address, mp1Port); + connect(mp1Socket_, mp1Address, mp1Port); } else if(strcmp(msg->getName(), "connectService") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; -// connect(&serviceSocket_, serviceAddress, servicePort); - connect(&serviceSocket_, mp1Address, mp1Port); +// connect(serviceSocket_, serviceAddress, servicePort); + connect(serviceSocket_, mp1Address, mp1Port); delete msg; } else @@ -116,7 +117,7 @@ void MecRequestBackgroundApp::handleSelfMessage(cMessage *msg){ } } -void MecRequestBackgroundApp::handleMp1Message() +void MecRequestBackgroundApp::handleMp1Message(int connId) { // throw cRuntimeError("QUiI"); EV << "MecRequestBackgroundApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; @@ -137,7 +138,8 @@ void MecRequestBackgroundApp::handleMp1Message() std::string address = endPoint["host"]; serviceAddress = L3AddressResolver().resolve(address.c_str());; servicePort = endPoint["port"]; - connect(&serviceSocket_, serviceAddress, servicePort); + serviceSocket_ = addNewSocket(); + connect(serviceSocket_, serviceAddress, servicePort); } } diff --git a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h index a9592e4cf..6bf30f46d 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h +++ b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h @@ -29,17 +29,25 @@ class MecRequestBackgroundApp : public MecAppBase cMessage *sendBurst; double lambda; // it is the mean, not the rate + inet::TcpSocket* serviceSocket_; + inet::TcpSocket* mp1Socket_; + + HttpBaseMessage* mp1HttpMessage; + HttpBaseMessage* serviceHttpMessage; virtual void handleSelfMessage(cMessage *msg) override; + virtual int numInitStages() const override { return inet::NUM_INIT_STAGES; } virtual void initialize(int stage) override; - virtual void handleServiceMessage() override; - virtual void handleMp1Message() override; + virtual void handleHttpMessage(int connId) override {} + virtual void handleServiceMessage(int connId) override; + virtual void handleMp1Message(int connId) override; virtual void handleUeMessage(omnetpp::cMessage *msg) override {}; + virtual void established(int connId) override; virtual void sendRequest(); diff --git a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc index 9c1fd8e8b..158f8c814 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc +++ b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc @@ -27,7 +27,7 @@ MecRequestBackgroundGeneratorApp::~MecRequestBackgroundGeneratorApp() cancelAndDelete(sendBurst); } -void MecRequestBackgroundGeneratorApp::handleServiceMessage() +void MecRequestBackgroundGeneratorApp::handleServiceMessage(int connId) { EV << "payload: " << serviceHttpMessage->getBody() << endl; if(burstFlag) @@ -37,24 +37,24 @@ void MecRequestBackgroundGeneratorApp::handleServiceMessage() void MecRequestBackgroundGeneratorApp::established(int connId) { - if(connId == mp1Socket_.getSocketId()) + if(connId == mp1Socket_->getSocketId()) { EV << "MecRequestBackgroundGeneratorApp::established - Mp1Socket"<< endl; // get endPoint of the required service const char *uri = "/example/mec_service_mgmt/v1/services?ser_name=LocationService"; - std::string host = mp1Socket_.getRemoteAddress().str()+":"+std::to_string(mp1Socket_.getRemotePort()); + std::string host = mp1Socket_->getRemoteAddress().str()+":"+std::to_string(mp1Socket_->getRemotePort()); - Http::sendGetRequest(&mp1Socket_, host.c_str(), uri); + Http::sendGetRequest(mp1Socket_, host.c_str(), uri); return; } - else if (connId == serviceSocket_.getSocketId()) + else if (connId == serviceSocket_->getSocketId()) { EV << "MecRequestBackgroundGeneratorApp::established - serviceSocket"<< endl; scheduleAt(simTime() + 5, burstTimer); } else { - throw cRuntimeError("MecRequestBackgroundGeneratorApp::socketEstablished - Socket %d not recognized", connId); + throw cRuntimeError("MecRequestBackgroundGeneratorApp::socketEstablished - Socket %s not recognized", connId); } } @@ -81,14 +81,14 @@ void MecRequestBackgroundGeneratorApp::handleSelfMessage(cMessage *msg){ else if(strcmp(msg->getName(), "connectMp1") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&mp1Socket_, mp1Address, mp1Port); + connect(mp1Socket_, mp1Address, mp1Port); delete msg; } else if(strcmp(msg->getName(), "connectService") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&serviceSocket_, serviceAddress, servicePort); + connect(serviceSocket_, serviceAddress, servicePort); } else { @@ -97,7 +97,7 @@ void MecRequestBackgroundGeneratorApp::handleSelfMessage(cMessage *msg){ } } -void MecRequestBackgroundGeneratorApp::handleMp1Message() +void MecRequestBackgroundGeneratorApp::handleMp1Message(int connId) { // throw cRuntimeError("QUiI"); EV << "MEWarningAlertApp_rest::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; @@ -118,7 +118,8 @@ void MecRequestBackgroundGeneratorApp::handleMp1Message() std::string address = endPoint["host"]; serviceAddress = L3AddressResolver().resolve(address.c_str());; servicePort = endPoint["port"]; - connect(&serviceSocket_, serviceAddress, servicePort); + serviceSocket_ = addNewSocket(); + connect(serviceSocket_, serviceAddress, servicePort); } } @@ -159,6 +160,8 @@ void MecRequestBackgroundGeneratorApp::initialize(int stage){ { EV << "MecRequestBackgroundGeneratorApp::initialize - MecRequestBackgroundGeneratorApp ["<< mecAppId <<"] does not allocate MEC host resources" << endl; } + + mp1Socket_ = addNewSocket(); cMessage *m = new cMessage("connectMp1"); sendBurst = new cMessage("sendBurst"); burstPeriod = new cMessage("burstPeriod"); @@ -175,7 +178,7 @@ void MecRequestBackgroundGeneratorApp::sendBulkRequest(){ int numRequests = truncnormal(numberOfApplications_, 20, 2); std::string payload = "BulkRequest: " + std::to_string(numRequests+1); - Http::sendPacket(payload.c_str(), &serviceSocket_); + Http::sendPacket(payload.c_str(), serviceSocket_); EV << "MecRequestBackgroundGeneratorApp: " << numRequests << " requests to the server"<getBody() << endl; scheduleAt(simTime() + 0.500, sendFGRequest); @@ -45,14 +45,14 @@ void MecRequestForegroundApp::handleSelfMessage(cMessage *msg){ else if(strcmp(msg->getName(), "connectMp1") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&mp1Socket_, mp1Address, mp1Port); + connect(mp1Socket_, mp1Address, mp1Port); delete msg; } else if(strcmp(msg->getName(), "connectService") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&serviceSocket_, serviceAddress, servicePort); + connect(serviceSocket_, serviceAddress, servicePort); } else { @@ -63,17 +63,17 @@ void MecRequestForegroundApp::handleSelfMessage(cMessage *msg){ void MecRequestForegroundApp::established(int connId) { - if(connId == mp1Socket_.getSocketId()) + if(connId == mp1Socket_->getSocketId()) { EV << "MecRequestBackgroundApp::established - Mp1Socket"<< endl; // get endPoint of the required service const char *uri = "/example/mec_service_mgmt/v1/services?ser_name=LocationService"; - std::string host = mp1Socket_.getRemoteAddress().str()+":"+std::to_string(mp1Socket_.getRemotePort()); + std::string host = mp1Socket_->getRemoteAddress().str()+":"+std::to_string(mp1Socket_->getRemotePort()); - Http::sendGetRequest(&mp1Socket_, host.c_str(), uri); + Http::sendGetRequest(mp1Socket_, host.c_str(), uri); return; } - else if (connId == serviceSocket_.getSocketId()) + else if (connId == serviceSocket_->getSocketId()) { EV << "MecRequestBackgroundApp::established - serviceSocket"<< endl; scheduleAt(simTime() + 0, sendFGRequest); @@ -88,7 +88,7 @@ void MecRequestForegroundApp::established(int connId) -void MecRequestForegroundApp::handleMp1Message() +void MecRequestForegroundApp::handleMp1Message(int connId) { // throw cRuntimeError("QUiI"); EV << "MecRequestBackgroundApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; @@ -109,9 +109,9 @@ void MecRequestForegroundApp::handleMp1Message() std::string address = endPoint["host"]; serviceAddress = L3AddressResolver().resolve(address.c_str());; servicePort = endPoint["port"]; - connect(&serviceSocket_, serviceAddress, servicePort); + serviceSocket_ = addNewSocket(); + connect(serviceSocket_, serviceAddress, servicePort); } - } } @@ -130,19 +130,23 @@ void MecRequestForegroundApp::initialize(int stage){ MecAppBase::initialize(stage); if(stage == inet::INITSTAGE_APPLICATION_LAYER) { + mp1Socket_ = addNewSocket(); cMessage *m = new cMessage("connectMp1"); mecAppId = getId(); scheduleAt(simTime() + 0, m); sendFGRequest = new cMessage("sendFGRequest"); lambda = par("lambda").doubleValue(); + + } } void MecRequestForegroundApp::sendRequest(){ + const char * body = ""; const char *uri = "/example/location/v2/queries/users"; - std::string host = serviceSocket_.getRemoteAddress().str()+":"+std::to_string(serviceSocket_.getRemotePort()); + std::string host = serviceSocket_->getRemoteAddress().str()+":"+std::to_string(serviceSocket_->getRemotePort()); - Http::sendGetRequest(&serviceSocket_, host.c_str(), uri); + Http::sendGetRequest(serviceSocket_, host.c_str(), uri); return; } diff --git a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h index ff7e82c29..2799ef437 100644 --- a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h +++ b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h @@ -24,13 +24,21 @@ class MecRequestForegroundApp : public MecAppBase cMessage *sendFGRequest; double lambda; + inet::TcpSocket* serviceSocket_; + inet::TcpSocket* mp1Socket_; + + HttpBaseMessage* mp1HttpMessage; + HttpBaseMessage* serviceHttpMessage; + virtual void handleSelfMessage(cMessage *msg) override; virtual int numInitStages() const override { return inet::NUM_INIT_STAGES; } virtual void initialize(int stage) override; - virtual void handleServiceMessage() override; - virtual void handleMp1Message() override; + + virtual void handleHttpMessage(int connId) override {} + virtual void handleServiceMessage(int connId) override; + virtual void handleMp1Message(int connId) override; virtual void handleUeMessage(omnetpp::cMessage *msg) override {}; diff --git a/src/apps/mec/MecApps/packets/ProcessingTimeMessage.msg b/src/apps/mec/MecApps/packets/ProcessingTimeMessage.msg new file mode 100644 index 000000000..861607dbd --- /dev/null +++ b/src/apps/mec/MecApps/packets/ProcessingTimeMessage.msg @@ -0,0 +1,14 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +message ProcessingTimeMessage { + int socketId; +} diff --git a/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc b/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc new file mode 100644 index 000000000..d260273c3 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc @@ -0,0 +1,306 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#include "apps/mec/MecRequestResponseApp/MECResponseApp.h" + +#include "nodes/mec/utils/httpUtils/httpUtils.h" +#include "nodes/mec/utils/httpUtils/json.hpp" +#include "nodes/mec/MECPlatform/MECServices/packets/HttpResponseMessage/HttpResponseMessage.h" + +#include "apps/mec/MecRequestResponseApp/packets/RequestResponsePacket_m.h" + +#include "inet/common/TimeTag_m.h" +#include "inet/common/packet/Packet_m.h" +#include "inet/networklayer/common/L3AddressTag_m.h" +#include "inet/transportlayer/common/L4PortTag_m.h" + +#include +#include "MECResponseApp.h" + +Define_Module(MECResponseApp); + + +using namespace inet; +using namespace omnetpp; + +MECResponseApp::MECResponseApp(): MecAppBase() +{ + mp1Socket_ = nullptr; + serviceSocket_ = nullptr; + currentRequestfMsg_ = nullptr; + processingTimer_ = nullptr; +} + +MECResponseApp::~MECResponseApp() +{ + delete currentRequestfMsg_; + cancelAndDelete(processingTimer_); +} + +void MECResponseApp::initialize(int stage) +{ + MecAppBase::initialize(stage); + + // avoid multiple initializations + if (stage != inet::INITSTAGE_APPLICATION_LAYER) + return; + + EV << "MECResponseApp::initialize - MEC application " << getClassName() << " with mecAppId[" << mecAppId << "] has started!" << endl; + + localUePort_ = par("localUePort"); + ueAppSocket_.setOutputGate(gate("socketOut")); + ueAppSocket_.bind(localUePort_); + + packetSize_ = par("responsePacketSize"); + + processingTimer_ = new cMessage("computeMsg"); + + minInstructions_ = par("minInstructions"); + maxInstructions_ = par("maxInstructions"); + + // connect with the service registry + EV << "MECResponseApp::initialize - Initialize connection with the Service Registry via Mp1" << endl; + mp1Socket_ = addNewSocket(); + + connect(mp1Socket_, mp1Address, mp1Port); +} + +void MECResponseApp::handleProcessedMessage(cMessage *msg) +{ + if (!msg->isSelfMessage()) { + if (ueAppSocket_.belongsToSocket(msg)) { + inet::Packet* packet = check_and_cast(msg); + auto req = packet->peekAtFront(); + if(req->getType() == UEAPP_REQUEST) + handleRequest(msg); + else if(req->getType() == UEAPP_STOP) + handleStopRequest(msg); + + else + throw cRuntimeError("MECResponseApp::handleProcessedMessage - Type not recognized!"); + return; + } + } + MecAppBase::handleProcessedMessage(msg); +} + +void MECResponseApp::finish() +{ + MecAppBase::finish(); + EV << "MECResponseApp::finish()" << endl; + if (gate("socketOut")->isConnected()) { + + } +} + +double MECResponseApp::scheduleNextMsg(cMessage *msg) +{ + return MecAppBase::scheduleNextMsg(msg); +} + +void MECResponseApp::handleSelfMessage(cMessage *msg) +{ + if(!strcmp(msg->getName(), "computeMsg")) + { + sendResponse(); + } +} + +void MECResponseApp::handleRequest(cMessage* msg) +{ + // this method pretends to perform some computation after having + //.request some info to the RNI + if(currentRequestfMsg_ != nullptr) + throw cRuntimeError("MECResponseApp::handleRequest - currentRequestfMsg_ not null!"); + + msgArrived_ = simTime(); + currentRequestfMsg_ = msg; + sendGetRequest(); + getRequestSent_ = simTime(); +} + + +void MECResponseApp::handleStopRequest(cMessage* msg) +{ + serviceSocket_->close(); +} +void MECResponseApp::sendResponse() +{ + inet::Packet* packet = check_and_cast(currentRequestfMsg_); + ueAppAddress = packet->getTag()->getSrcAddress(); + ueAppPort = packet->getTag()->getSrcPort(); + + auto req = packet->removeAtFront(); + req->setType(MECAPP_RESPONSE); + req->setRequestArrivedTimestamp(msgArrived_); + req->setServiceResponseTime(getRequestArrived_ - getRequestSent_); + req->setResponseSentTimestamp(simTime()); + req->setProcessingTime(processingTime_); + req->setChunkLength(B(packetSize_)); + inet::Packet* pkt = new inet::Packet("ResponseAppPacket"); + pkt->insertAtBack(req); + + ueAppSocket_.sendTo(pkt, ueAppAddress, ueAppPort); + + //clean current request + delete packet; + currentRequestfMsg_ = nullptr; + msgArrived_ = 0; + processingTime_ = 0; + getRequestArrived_ = 0; + getRequestSent_ = 0; +} + +void MECResponseApp::handleHttpMessage(int connId) +{ + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + handleMp1Message(connId); + } + else // if (connId == serviceSocket_->getSocketId()) + { + handleServiceMessage(connId); + } +} + +void MECResponseApp::handleMp1Message(int connId) +{ + // for now I only have just one Service Registry + HttpMessageStatus *msgStatus = (HttpMessageStatus*) mp1Socket_->getUserData(); + mp1HttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); + EV << "MECPlatooningApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; + + try { + nlohmann::json jsonBody = nlohmann::json::parse(mp1HttpMessage->getBody()); // get the JSON structure + if (!jsonBody.empty()) { + jsonBody = jsonBody[0]; + std::string serName = jsonBody["serName"]; + if (serName.compare("RNIService") == 0) { + if (jsonBody.contains("transportInfo")) { + nlohmann::json endPoint = jsonBody["transportInfo"]["endPoint"]["addresses"]; + EV << "address: " << endPoint["host"] << " port: " << endPoint["port"] << endl; + std::string address = endPoint["host"]; + serviceAddress_ = L3AddressResolver().resolve(address.c_str()); + servicePort_ = endPoint["port"]; + serviceSocket_ = addNewSocket(); + connect(serviceSocket_ , serviceAddress_, servicePort_); + } + } + else { + EV << "MECPlatooningApp::handleMp1Message - RNIService not found" << endl; + serviceAddress_ = L3Address(); + } + } + + //close service registry socket + mp1Socket_->close(); + + } + catch (nlohmann::detail::parse_error e) { + EV << e.what() << std::endl; + // body is not correctly formatted in JSON, manage it + return; + } +} + +void MECResponseApp::handleServiceMessage(int connId) +{ + HttpBaseMessage *httpMessage = nullptr; + HttpMessageStatus *msgStatus = (HttpMessageStatus*) serviceSocket_->getUserData(); + httpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); + + if (httpMessage == nullptr) { + throw cRuntimeError("MECResponseApp::handleServiceMessage() - httpMessage is null!"); + } + + if (httpMessage->getType() == RESPONSE) { + HttpResponseMessage *rspMsg = dynamic_cast(httpMessage); + if (rspMsg->getCode() == 200) // in response to a successful GET request + { + EV << "MECResponseApp::handleServiceMessage - response 200 from Socket with Id [" << connId << "]" << endl; + getRequestArrived_ = simTime(); + EV << "response time " << getRequestArrived_ - getRequestSent_ << endl; + doComputation(); + } + + // some error occured, show the HTTP code for now + else { + EV << "MECResponseApp::handleServiceMessage - response with HTTP code: " << rspMsg->getCode() << endl; + } + } +} + +void MECResponseApp::doComputation() +{ + processingTime_ = vim->calculateProcessingTime(mecAppId, uniform(minInstructions_, maxInstructions_)); + EV << "time " << processingTime_ << endl; + scheduleAt(simTime()+ processingTime_, processingTimer_); +} + +void MECResponseApp::sendGetRequest() +{ + //check if the ueAppAddress is specified + if (serviceSocket_->getState() == inet::TcpSocket::CONNECTED) { + EV << "MECResponseApp::sendGetRequest(): send request to the Location Service" << endl; + std::stringstream uri; + uri << "/example/rni/v2/queries/layer2_meas"; //TODO filter the request to get less data + EV << "MECResponseApp::requestLocation(): uri: " << uri.str() << endl; + std::string host = serviceSocket_->getRemoteAddress().str() + ":" + std::to_string(serviceSocket_->getRemotePort()); + Http::sendGetRequest(serviceSocket_, host.c_str(), uri.str().c_str()); + } + else { + EV << "MECResponseApp::sendGetRequest(): Location Service not connected" << endl; + } +} + +void MECResponseApp::established(int connId) +{ + EV << "MECResponseApp::established - connId [" << connId << "]" << endl; + + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + EV << "MECResponseApp::established - Mp1Socket" << endl; + + // once the connection with the Service Registry has been established, obtain the + // endPoint (address+port) of the Location Service + const char *uri = "/example/mec_service_mgmt/v1/services?ser_name=RNIService"; + std::string host = mp1Socket_->getRemoteAddress().str() + ":" + std::to_string(mp1Socket_->getRemotePort()); + + Http::sendGetRequest(mp1Socket_, host.c_str(), uri); + } + +} + +void MECResponseApp::socketClosed(inet::TcpSocket *sock) +{ + EV << "MECResponseApp::socketClosed" << endl; + std::cout << "MECResponseApp::socketClosed with sockId " << sock->getSocketId() << std::endl; + if(mp1Socket_!= nullptr && sock->getSocketId() == mp1Socket_->getSocketId()){ + removeSocket(sock); + mp1Socket_ = nullptr; + } + else + { + EV <<"Service socket closed" << endl; + removeSocket(sock); + sendStopAck(); + } + +} + +void MECResponseApp::sendStopAck() +{ + inet::Packet* pkt = new inet::Packet("RequestResponseAppPacket"); + auto req = inet::makeShared(); + req->setType(UEAPP_ACK_STOP);; + req->setChunkLength(B(packetSize_)); + pkt->insertAtBack(req); + + ueAppSocket_.sendTo(pkt, ueAppAddress, ueAppPort); +} diff --git a/src/apps/mec/MecRequestResponseApp/MECResponseApp.h b/src/apps/mec/MecRequestResponseApp/MECResponseApp.h new file mode 100644 index 000000000..87691bd36 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/MECResponseApp.h @@ -0,0 +1,100 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef __MECRESPONSEAPP_H_ +#define __MECRESPONSEAPP_H_ + +#include "omnetpp.h" + +#include + +#include "inet/networklayer/common/L3Address.h" +#include "inet/networklayer/common/L3AddressResolver.h" + +#include "apps/mec/MecApps/MecAppBase.h" +#include "nodes/mec/MECPlatform/ServiceRegistry/ServiceRegistry.h" + +#define UEAPP_REQUEST 0 +#define MECAPP_RESPONSE 1 +#define UEAPP_STOP 2 +#define UEAPP_ACK_STOP 3 + +class MECResponseApp : public MecAppBase +{ +protected: + inet::TcpSocket *mp1Socket_; + inet::TcpSocket *serviceSocket_; + + inet::UdpSocket ueAppSocket_; + int localUePort_; + + HttpBaseMessage* mp1HttpMessage; + + cMessage* currentRequestfMsg_; + cMessage* processingTimer_; + simtime_t msgArrived_; + simtime_t getRequestSent_; + simtime_t getRequestArrived_; + double processingTime_; + + int packetSize_; + + int minInstructions_; + int maxInstructions_; + + // address+port of the UeApp + inet::L3Address ueAppAddress; + int ueAppPort; + + // endpoint for contacting the Location Service + // this is obtained by sending a GET request to the Service Registry as soon as + // the connection with the latter has been established + inet::L3Address serviceAddress_; + int servicePort_; + + + virtual int numInitStages() const override { return inet::NUM_INIT_STAGES; } + virtual void initialize(int stage) override; + virtual void handleProcessedMessage(cMessage *msg) override; + virtual void finish() override; + virtual void handleSelfMessage(cMessage *msg) override; + virtual void handleHttpMessage(int connId) override; + virtual void handleUeMessage(omnetpp::cMessage *msg) override {} + + virtual double scheduleNextMsg(cMessage* msg) override; + + // @brief handler for data received from the service registry + virtual void handleMp1Message(int connId) override; + + // @brief handler for data received from a MEC service + virtual void handleServiceMessage(int connId) override; + + virtual void handleRequest(cMessage* msg); + virtual void handleStopRequest(cMessage* msg); + virtual void sendStopAck(); + virtual void sendResponse(); + + virtual void doComputation(); + + // @brief used to require the position of the cars of a platoon to the Location Service + void sendGetRequest(); + + /* TCPSocket::CallbackInterface callback methods */ + virtual void established(int connId) override; + virtual void socketClosed(inet::TcpSocket *socket) override; + + + public: + MECResponseApp(); + virtual ~MECResponseApp(); +}; + +#endif diff --git a/src/apps/mec/MecRequestResponseApp/MECResponseApp.ned b/src/apps/mec/MecRequestResponseApp/MECResponseApp.ned new file mode 100644 index 000000000..2c11f44c2 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/MECResponseApp.ned @@ -0,0 +1,56 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +package simu5g.apps.mec.MecRequestResponseApp; + +import inet.applications.contract.IApp; +import simu5g.nodes.mec.MECPlatform.IMECApp; + +// +// This is a MEC app that ... TBC +// +simple MECResponseApp like IMECApp, IApp +{ + parameters: + @display("i=block/app;is=s"); + + int responsePacketSize = default(50); + string interfaceTableModule = default(""); + int mecAppIndex; + int mecAppId; + int localUePort; + + int minInstructions = default(9000000); + int maxInstructions = default(11000000); + + + string mp1Address = default(""); + int mp1Port = default(10021); + + //resource required info + double requiredRam @unit("B"); + double requiredDisk @unit("B"); + double requiredCpu; + + // IApp parameters + int timeToLive = default(-1); // if not -1, set the TTL (IPv4) or Hop Limit (IPv6) field of sent packets to this value + int dscp = default(-1); // if not -1, set the DSCP (IPv4/IPv6) field of sent packets to this value + int tos = default(-1); // if not -1, set the Type Of Service (IPv4) / Traffic Class (IPv6) field of sent packets to this value + + gates: + input mePlatformIn; + output mePlatformOut; + + input socketIn; + output socketOut; + +} + diff --git a/src/apps/mec/MecRequestResponseApp/UERequestApp.cc b/src/apps/mec/MecRequestResponseApp/UERequestApp.cc new file mode 100644 index 000000000..8c32b9976 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/UERequestApp.cc @@ -0,0 +1,333 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#include "apps/mec/MecRequestResponseApp/UERequestApp.h" +#include "apps/mec/DeviceApp/DeviceAppMessages/DeviceAppPacket_m.h" +#include "apps/mec/DeviceApp/DeviceAppMessages/DeviceAppPacket_Types.h" +#include "nodes/mec/MECPlatform/MEAppPacket_Types.h" + +#include "apps/mec/MecRequestResponseApp/packets/RequestResponsePacket_m.h" + +#include "inet/common/TimeTag_m.h" +#include "inet/common/packet/chunk/BytesChunk.h" +#include "inet/networklayer/common/L3AddressTag_m.h" +#include "inet/transportlayer/common/L4PortTag_m.h" + +#include + +#include + +using namespace inet; +using namespace std; + +Define_Module(UERequestApp); + +UERequestApp::UERequestApp() +{ + selfStart_ = nullptr; + selfStop_ = nullptr; +} + +UERequestApp::~UERequestApp() +{ + cancelAndDelete(selfStart_); + cancelAndDelete(selfStop_); +} + +void UERequestApp::initialize(int stage) +{ + EV << "UERequestApp::initialize - stage " << stage << endl; + cSimpleModule::initialize(stage); + // avoid multiple initializations + if (stage!=inet::INITSTAGE_APPLICATION_LAYER) + return; + + + sno_ = 0; + + //retrieve parameters + requestPacketSize_ = par("requestPacketSize"); + requestPeriod_ = par("period"); + + localPort_ = par("localPort"); + deviceAppPort_ = par("deviceAppPort"); + + char* deviceAppAddressStr = (char*)par("deviceAppAddress").stringValue(); + deviceAppAddress_ = inet::L3AddressResolver().resolve(deviceAppAddressStr); + + //binding socket + socket.setOutputGate(gate("socketOut")); + socket.bind(localPort_); + + int tos = par("tos"); + if (tos != -1) + socket.setTos(tos); + + mecAppName = par("mecAppName").stringValue(); + + //initializing the auto-scheduling messages + selfStart_ = new cMessage("selfStart"); + selfStop_ = new cMessage("selfStop"); + sendRequest_ = new cMessage("sendRequest"); + unBlockingMsg_ = new cMessage("unBlockingMsg"); + + //starting UERequestApp + simtime_t startTime = par("startTime"); + EV << "UERequestApp::initialize - starting sendStartMEWarningAlertApp() in " << startTime << " seconds " << endl; + scheduleAt(simTime() + startTime, selfStart_); + + //testing + EV << "UERequestApp::initialize - binding to port: local:" << localPort_ << " , dest:" << deviceAppPort_ << endl; + + // register signals for stats + processingTime_ = registerSignal("processingTime"); + serviceResponseTime_ = registerSignal("serviceResponseTime"); + upLinkTime_ = registerSignal("upLinkTime"); + downLinkTime_ = registerSignal("downLinkTime"); + responseTime_ = registerSignal("responseTime"); + + +} + +void UERequestApp::handleMessage(cMessage *msg) +{ + EV << "UERequestApp::handleMessage" << endl; + // Sender Side + if (msg->isSelfMessage()) + { + if(!strcmp(msg->getName(), "selfStart")) + sendStartMECRequestApp(); + else if(!strcmp(msg->getName(), "selfStop")) + sendStopApp(); + else if(!strcmp(msg->getName(), "sendRequest") || !strcmp(msg->getName(), "unBlockingMsg")) + sendRequest(); + else + throw cRuntimeError("UERequestApp::handleMessage - \tWARNING: Unrecognized self message"); + } + // Receiver Side + else + { + inet::Packet* packet = check_and_cast(msg); + inet::L3Address ipAdd = packet->getTag()->getSrcAddress(); + + /* + * From Device app + * device app usually runs in the UE (loopback), but it could also run in other places + */ + if(ipAdd == deviceAppAddress_ || ipAdd == inet::L3Address("127.0.0.1")) // dev app + { + auto mePkt = packet->peekAtFront(); + + if (mePkt == 0) + throw cRuntimeError("UERequestApp::handleMessage - \tFATAL! Error when casting to DeviceAppPacket"); + + if( !strcmp(mePkt->getType(), ACK_START_MECAPP) ) + handleAckStartMECRequestApp(msg); + else if(!strcmp(mePkt->getType(), ACK_STOP_MECAPP)) + handleAckStopMECRequestApp(msg); + else + throw cRuntimeError("UERequestApp::handleMessage - \tFATAL! Error, DeviceAppPacket type %s not recognized", mePkt->getType()); + } + // From MEC application + else + { + auto mePkt = packet->peekAtFront(); + if (mePkt == 0) + throw cRuntimeError("UERequestApp::handleMessage - \tFATAL! Error when casting to RequestAppPacket"); + + if(mePkt->getType() == MECAPP_RESPONSE) + recvResponse(msg); + else if(mePkt->getType() == UEAPP_ACK_STOP) + handleStopApp(msg); + else + throw cRuntimeError("UERequestApp::handleMessage - \tFATAL! Error, RequestAppPacket type %d not recognized", mePkt->getType()); + } + } +} + +void UERequestApp::finish() +{ +} + +void UERequestApp::sendStartMECRequestApp() +{ + EV << "UERequestApp::sendStartMECRequestApp - Sending " << START_MEAPP <<" type RequestPacket\n"; + + inet::Packet* packet = new inet::Packet("RequestAppStart"); + auto start = inet::makeShared(); + + //instantiation requirements and info + start->setType(START_MECAPP); + start->setMecAppName(mecAppName.c_str()); + start->setChunkLength(inet::B(2+mecAppName.size()+1)); + start->addTagIfAbsent()->setCreationTime(simTime()); + packet->insertAtBack(start); + + socket.sendTo(packet, deviceAppAddress_, deviceAppPort_); + + //rescheduling + scheduleAt(simTime() + 0.5, selfStart_); +} + +void UERequestApp::sendStopMECRequestApp() +{ + EV << "UERequestApp::sendStopMECRequestApp - Sending " << STOP_MEAPP <<" type RequestPacket\n"; + + inet::Packet* packet = new inet::Packet("DeviceAppStopPacket"); + auto stop = inet::makeShared(); + + //termination requirements and info + stop->setType(STOP_MECAPP); + stop->setChunkLength(inet::B(10)); + stop->addTagIfAbsent()->setCreationTime(simTime()); + packet->insertAtBack(stop); + + socket.sendTo(packet, deviceAppAddress_, deviceAppPort_); + + if(sendRequest_->isScheduled()) + { + cancelEvent(sendRequest_); + } + + //rescheduling + if(selfStop_->isScheduled()) + cancelEvent(selfStop_); + scheduleAt(simTime() + 0.5, selfStop_); +} + +void UERequestApp::handleAckStartMECRequestApp(cMessage* msg) +{ + EV << "UERequestApp::handleAckStartMECRequestApp - Received Start ACK packet" << endl; + inet::Packet* packet = check_and_cast(msg); + auto pkt = packet->peekAtFront(); + + if(pkt->getResult() == true) + { + mecAppAddress_ = L3AddressResolver().resolve(pkt->getIpAddress()); + mecAppPort_ = pkt->getPort(); + EV << "UERequestApp::handleAckStartMECRequestApp - Received " << pkt->getType() << " type RequestPacket. mecApp instance is at: "<< mecAppAddress_<< ":" << mecAppPort_ << endl; + cancelEvent(selfStart_); + //scheduling sendStopMEWarningAlertApp() + if(!selfStop_->isScheduled()){ + simtime_t stopTime = par("stopTime"); + scheduleAt(simTime() + stopTime, selfStop_); + EV << "UERequestApp::handleAckStartMECRequestApp - Starting sendStopMECRequestApp() in " << stopTime << " seconds " << endl; + } + //send the first reuqest to the MEC app + sendRequest(); + } + else + { + EV << "UERequestApp::handleAckStartMECRequestApp - MEC application cannot be instantiated! Reason: " << pkt->getReason() << endl; + simtime_t startTime = par("startTime"); + EV << "UERequestApp::initialize - starting sendStartMEWarningAlertApp() in " << startTime << " seconds " << endl; + if(!selfStart_->isScheduled()) + scheduleAt(simTime() + startTime, selfStart_); + } + + + + delete packet; +} + +void UERequestApp::handleAckStopMECRequestApp(cMessage* msg) +{ + EV << "UERequestApp::handleAckStopMECRequestApp - Received Stop ACK packet" << endl; + + inet::Packet* packet = check_and_cast(msg); + auto pkt = packet->peekAtFront(); + + EV << "UERequestApp::handleAckStopMECRequestApp - Received " << pkt->getType() << " type RequestPacket with result: "<< pkt->getResult() << endl; + if(pkt->getResult() == false) + EV << "Reason: "<< pkt->getReason() << endl; + + cancelEvent(selfStop_); +} + + +void UERequestApp::sendRequest() +{ + inet::Packet* pkt = new inet::Packet("RequestResponseAppPacket"); + auto req = inet::makeShared(); + req->setType(UEAPP_REQUEST); + req->setSno(sno_++); + req->setRequestSentTimestamp(simTime()); + req->setChunkLength(inet::B(requestPacketSize_)); + req->addTagIfAbsent()->setCreationTime(simTime()); + pkt->insertAtBack(req); + + start_ = simTime(); + + socket.sendTo(pkt, mecAppAddress_ , mecAppPort_); + +// if(!unBlockingMsg_->isScheduled()) + /// scheduleAfter(1, unBlockingMsg_); +} + + +void UERequestApp::handleStopApp(cMessage* msg) +{ + EV << "UERequestApp::handleStopApp" << endl; + inet::Packet* packet = check_and_cast(msg); + auto res = packet->peekAtFront(); + + sendStopMECRequestApp(); +} + +void UERequestApp::sendStopApp() +{ + inet::Packet* pkt = new inet::Packet("RequestResponseAppPacket"); + auto req = inet::makeShared(); + req->setType(UEAPP_STOP ); + req->setRequestSentTimestamp(simTime()); + req->setChunkLength(inet::B(requestPacketSize_)); + req->addTagIfAbsent()->setCreationTime(simTime()); + pkt->insertAtBack(req); + +// start_ = simTime(); + + socket.sendTo(pkt, mecAppAddress_ , mecAppPort_); + +} + +void UERequestApp::recvResponse(cMessage* msg) +{ + EV << "UERequestApp::recvResponse" << endl; + inet::Packet* packet = check_and_cast(msg); + auto res = packet->peekAtFront(); + + simtime_t upLinkDelay = res->getRequestArrivedTimestamp() - res->getRequestSentTimestamp(); + simtime_t downLinkDelay = simTime()- res->getResponseSentTimestamp(); + simtime_t respTime = simTime()- res->getRequestSentTimestamp(); + + EV << "UERequestApp::recvResponse - message with sno [" << res->getSno() << "] " << + "upLinkDelay [" << upLinkDelay << "ms]\t" << + "downLinkDelay [" << downLinkDelay << "ms]\t" << + "processingTime [" << res->getProcessingTime() << "ms]\t" << + "serviceResponseTime [" << res->getServiceResponseTime() << "ms]\t" << + "responseTime [" << respTime << "ms]" << endl; + + //emit stats + emit(upLinkTime_, upLinkDelay); + emit(downLinkTime_, downLinkDelay); + emit(processingTime_, res->getProcessingTime()); + emit(serviceResponseTime_, res->getServiceResponseTime()); + emit(responseTime_, respTime); + + delete packet; + + if(unBlockingMsg_->isScheduled()) + cancelEvent(unBlockingMsg_); + if(!sendRequest_->isScheduled()) + scheduleAt(simTime() + requestPeriod_, sendRequest_); +} + + diff --git a/src/apps/mec/MecRequestResponseApp/UERequestApp.h b/src/apps/mec/MecRequestResponseApp/UERequestApp.h new file mode 100644 index 000000000..05c79dd12 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/UERequestApp.h @@ -0,0 +1,97 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef __UEREQUESTAPP_H_ +#define __UEREQUESTAPP_H_ + +#define UEAPP_REQUEST 0 +#define MECAPP_RESPONSE 1 +#define UEAPP_STOP 2 +#define UEAPP_ACK_STOP 3 + + +#include "inet/transportlayer/contract/udp/UdpSocket.h" +#include "inet/networklayer/common/L3Address.h" +#include "inet/networklayer/common/L3AddressResolver.h" + +#include "common/binder/Binder.h" + + +using namespace omnetpp; + +class UERequestApp: public cSimpleModule +{ + //communication to device app and mec app + inet::UdpSocket socket; + + unsigned int sno_; + int requestPacketSize_; + double requestPeriod_; + + simtime_t start_; + simtime_t end_; + + + // DeviceApp info + int localPort_; + int deviceAppPort_; + inet::L3Address deviceAppAddress_; + + // MEC application endPoint (returned by the device app) + inet::L3Address mecAppAddress_; + int mecAppPort_; + + std::string mecAppName; + + + //scheduling + cMessage *selfStart_; + cMessage *selfStop_; + cMessage *sendRequest_; + cMessage *unBlockingMsg_; //it prevents to stop the send/response pattern if msg gets lost + + + // signals for statistics + simsignal_t processingTime_; + simsignal_t serviceResponseTime_; + simsignal_t upLinkTime_; + simsignal_t downLinkTime_; + simsignal_t responseTime_; + + public: + ~UERequestApp(); + UERequestApp(); + + protected: + + virtual int numInitStages() const { return inet::NUM_INIT_STAGES; } + void initialize(int stage); + virtual void handleMessage(cMessage *msg); + virtual void finish(); + + void emitStats(); + + // --- Functions to interact with the DeviceApp --- // + void sendStartMECRequestApp(); + void sendStopMECRequestApp(); + void handleStopApp(cMessage* msg); + void sendStopApp(); + + void handleAckStartMECRequestApp(cMessage* msg); + void handleAckStopMECRequestApp(cMessage* msg); + + // --- Functions to interact with the MECPlatooningApp --- // + void sendRequest(); + void recvResponse(cMessage* msg); + +}; + +#endif diff --git a/src/apps/mec/MecRequestResponseApp/UERequestApp.ned b/src/apps/mec/MecRequestResponseApp/UERequestApp.ned new file mode 100644 index 000000000..4e8cc6a7f --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/UERequestApp.ned @@ -0,0 +1,67 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + + +package simu5g.apps.mec.MecRequestResponseApp; + +import inet.applications.contract.IApp; + +// +// This is a UE app that asks to a Device App to obtain the endpoint of a MECResponseApp. +// After a successful response, it ... TBC +// +simple UERequestApp like IApp +{ + parameters: + @display("i=block/source"); + + //connection infos + int localPort = default(4000); + int deviceAppPort = default(4000); // ipAddress of the DeviceApp + string deviceAppAddress; // port of the DeviceApp + + int requestPacketSize = default(10); + + int tos = default(-1); // if not -1, set the Type Of Service (IPv4) / Traffic Class (IPv6) field of sent packets to this value + + //autoscheduling infos + double period @unit("s") = default(0.2s); + double startTime @unit("s") = default(0s); + double stopTime @unit("s") = default(120s); + + string mecAppName = default("MecResponseApp"); + + string interfaceTableModule; + + // stats + + @signal[responseTime]; + @statistic[responseTime](title="responseTime"; unit="s"; source="responseTime"; record=stats, mean, vector); + + @signal[processingTime]; + @statistic[processingTime](title="processingTime"; unit="s"; source="processingTime"; record=stats, mean, vector); + + @signal[serviceResponseTime]; + @statistic[serviceResponseTime](title="serviceResponseTime"; unit="s"; source="serviceResponseTime"; record=stats, mean, vector); + + @signal[upLinkTime]; + @statistic[upLinkTime](title="upLinkTime"; unit="s"; source="upLinkTime"; record=stats, mean, vector); + + @signal[downLinkTime]; + @statistic[downLinkTime](title="downLinkTime"; unit="s"; source="downLinkTime"; record=stats, mean, vector); + + + + gates: + output socketOut; + input socketIn; +} + diff --git a/src/apps/mec/MecRequestResponseApp/packets/RequestResponsePacket.msg b/src/apps/mec/MecRequestResponseApp/packets/RequestResponsePacket.msg new file mode 100644 index 000000000..020f6d5d9 --- /dev/null +++ b/src/apps/mec/MecRequestResponseApp/packets/RequestResponsePacket.msg @@ -0,0 +1,37 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + + +import nodes.mec.MECPlatform.MECPackets; +import inet.networklayer.common.L3Address; +import inet.common.INETDefs; +import inet.common.packet.chunk.Chunk; + + +class RequestResponseAppPacket extends inet::FieldsChunk +{ + int type; + unsigned int sno; + + // request side + simtime_t requestSentTimestamp; + + // response side + simtime_t requestArrivedTimestamp; + double processingTime; + simtime_t serviceResponseTime; + simtime_t responseSentTimestamp; +} + + + + + diff --git a/src/apps/mec/WarningAlert/MECWarningAlertApp.cc b/src/apps/mec/WarningAlert/MECWarningAlertApp.cc index 490915a2d..4a50557ca 100644 --- a/src/apps/mec/WarningAlert/MECWarningAlertApp.cc +++ b/src/apps/mec/WarningAlert/MECWarningAlertApp.cc @@ -68,27 +68,30 @@ void MECWarningAlertApp::initialize(int stage) //testing EV << "MECWarningAlertApp::initialize - Mec application "<< getClassName() << " with mecAppId["<< mecAppId << "] has started!" << endl; + mp1Socket_ = addNewSocket(); + + // connect with the service registry cMessage *msg = new cMessage("connectMp1"); scheduleAt(simTime() + 0, msg); } -void MECWarningAlertApp::handleMessage(cMessage *msg) -{ -// MecAppBase::handleMessage(msg); - if (!msg->isSelfMessage()) - { - if(ueSocket.belongsToSocket(msg)) - { - handleUeMessage(msg); - delete msg; - return; - } - } - MecAppBase::handleMessage(msg); - -} +//void MECWarningAlertApp::handleMessage(cMessage *msg) +//{ +//// MecAppBase::handleMessage(msg); +// if (!msg->isSelfMessage()) +// { +// if(ueSocket.belongsToSocket(msg)) +// { +// handleUeMessage(msg); +// delete msg; +// return; +// } +// } +// MecAppBase::handleMessage(msg); +// +//} void MECWarningAlertApp::finish(){ MecAppBase::finish(); @@ -165,8 +168,8 @@ void MECWarningAlertApp::modifySubscription() "}" "}\r\n"; std::string uri = "/example/location/v2/subscriptions/area/circle/" + subId; - std::string host = serviceSocket_.getRemoteAddress().str()+":"+std::to_string(serviceSocket_.getRemotePort()); - Http::sendPutRequest(&serviceSocket_, body.c_str(), host.c_str(), uri.c_str()); + std::string host = serviceSocket_->getRemoteAddress().str()+":"+std::to_string(serviceSocket_->getRemotePort()); + Http::sendPutRequest(serviceSocket_, body.c_str(), host.c_str(), uri.c_str()); } void MECWarningAlertApp::sendSubscription() @@ -187,7 +190,7 @@ void MECWarningAlertApp::sendSubscription() "}" "}\r\n"; std::string uri = "/example/location/v2/subscriptions/area/circle"; - std::string host = serviceSocket_.getRemoteAddress().str()+":"+std::to_string(serviceSocket_.getRemotePort()); + std::string host = serviceSocket_->getRemoteAddress().str()+":"+std::to_string(serviceSocket_->getRemotePort()); if(par("logger").boolValue()) { @@ -200,29 +203,29 @@ void MECWarningAlertApp::sendSubscription() } } - Http::sendPostRequest(&serviceSocket_, body.c_str(), host.c_str(), uri.c_str()); + Http::sendPostRequest(serviceSocket_, body.c_str(), host.c_str(), uri.c_str()); } void MECWarningAlertApp::sendDeleteSubscription() { std::string uri = "/example/location/v2/subscriptions/area/circle/" + subId; - std::string host = serviceSocket_.getRemoteAddress().str()+":"+std::to_string(serviceSocket_.getRemotePort()); - Http::sendDeleteRequest(&serviceSocket_, host.c_str(), uri.c_str()); + std::string host = serviceSocket_->getRemoteAddress().str()+":"+std::to_string(serviceSocket_->getRemotePort()); + Http::sendDeleteRequest(serviceSocket_, host.c_str(), uri.c_str()); } void MECWarningAlertApp::established(int connId) { - if(connId == mp1Socket_.getSocketId()) + if(connId == mp1Socket_->getSocketId()) { EV << "MECWarningAlertApp::established - Mp1Socket"<< endl; // get endPoint of the required service const char *uri = "/example/mec_service_mgmt/v1/services?ser_name=LocationService"; - std::string host = mp1Socket_.getRemoteAddress().str()+":"+std::to_string(mp1Socket_.getRemotePort()); + std::string host = mp1Socket_->getRemoteAddress().str()+":"+std::to_string(mp1Socket_->getRemotePort()); - Http::sendGetRequest(&mp1Socket_, host.c_str(), uri); + Http::sendGetRequest(mp1Socket_, host.c_str(), uri); return; } - else if (connId == serviceSocket_.getSocketId()) + else if (connId == serviceSocket_->getSocketId()) { EV << "MECWarningAlertApp::established - serviceSocket"<< endl; // the connectService message is scheduled after a start mec app from the UE app, so I can @@ -242,8 +245,23 @@ void MECWarningAlertApp::established(int connId) } } -void MECWarningAlertApp::handleMp1Message() + +void MECWarningAlertApp::handleHttpMessage(int connId) { + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + handleMp1Message(connId); + } + else + { + handleServiceMessage(connId); + } +} + +void MECWarningAlertApp::handleMp1Message(int connId) +{ + // for now I only have just one Service Registry + HttpMessageStatus *msgStatus = (HttpMessageStatus*) mp1Socket_->getUserData(); + mp1HttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "MECWarningAlertApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; try @@ -260,8 +278,9 @@ void MECWarningAlertApp::handleMp1Message() nlohmann::json endPoint = jsonBody["transportInfo"]["endPoint"]["addresses"]; EV << "address: " << endPoint["host"] << " port: " << endPoint["port"] << endl; std::string address = endPoint["host"]; - serviceAddress = L3AddressResolver().resolve(address.c_str());; + serviceAddress = L3AddressResolver().resolve(address.c_str()); servicePort = endPoint["port"]; + serviceSocket_ = addNewSocket(); } } else @@ -281,13 +300,16 @@ void MECWarningAlertApp::handleMp1Message() } -void MECWarningAlertApp::handleServiceMessage() +void MECWarningAlertApp::handleServiceMessage(int connId) { + HttpMessageStatus *msgStatus = (HttpMessageStatus*) serviceSocket_->getUserData(); + serviceHttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); + if(serviceHttpMessage->getType() == REQUEST) { - Http::send204Response(&serviceSocket_); // send back 204 no content + Http::send204Response(serviceSocket_); // send back 204 no content nlohmann::json jsonBody; - EV << "MEClusterizeService::handleTcpMsg - REQUEST " << serviceHttpMessage->getBody()<< endl; + EV << "MECWarningAlertApp::handleTcpMsg - REQUEST " << serviceHttpMessage->getBody()<< endl; try { jsonBody = nlohmann::json::parse(serviceHttpMessage->getBody()); // get the JSON structure @@ -309,7 +331,7 @@ void MECWarningAlertApp::handleServiceMessage() if(criteria == "Entering") { - EV << "MEClusterizeService::handleTcpMsg - Ue is Entered in the danger zone "<< endl; + EV << "MECWarningAlertApp::handleTcpMsg - Ue is Entered in the danger zone "<< endl; alert->setDanger(true); if(par("logger").boolValue()) @@ -329,7 +351,7 @@ void MECWarningAlertApp::handleServiceMessage() } else if (criteria == "Leaving") { - EV << "MEClusterizeService::handleTcpMsg - Ue left from the danger zone "<< endl; + EV << "MECWarningAlertApp::handleTcpMsg - Ue left from the danger zone "<< endl; alert->setDanger(false); if(par("logger").boolValue()) { @@ -362,15 +384,15 @@ void MECWarningAlertApp::handleServiceMessage() if(rspMsg->getCode() == 204) // in response to a DELETE { - EV << "MEClusterizeService::handleTcpMsg - response 204, removing circle" << rspMsg->getBody()<< endl; - serviceSocket_.close(); + EV << "MECWarningAlertApp::handleTcpMsg - response 204, removing circle" << rspMsg->getBody()<< endl; + serviceSocket_->close(); getSimulation()->getSystemModule()->getCanvas()->removeFigure(circle); } else if(rspMsg->getCode() == 201) // in response to a POST { nlohmann::json jsonBody; - EV << "MEClusterizeService::handleTcpMsg - response 201 " << rspMsg->getBody()<< endl; + EV << "MECWarningAlertApp::handleTcpMsg - response 201 " << rspMsg->getBody()<< endl; try { jsonBody = nlohmann::json::parse(rspMsg->getBody()); // get the JSON structure @@ -412,21 +434,21 @@ void MECWarningAlertApp::handleSelfMessage(cMessage *msg) if(strcmp(msg->getName(), "connectMp1") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(&mp1Socket_, mp1Address, mp1Port); + connect(mp1Socket_, mp1Address, mp1Port); } else if(strcmp(msg->getName(), "connectService") == 0) { EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - if(!serviceAddress.isUnspecified() && serviceSocket_.getState() != inet::TcpSocket::CONNECTED) + if(!serviceAddress.isUnspecified() && serviceSocket_->getState() != inet::TcpSocket::CONNECTED) { - connect(&serviceSocket_, serviceAddress, servicePort); + connect(serviceSocket_, serviceAddress, servicePort); } else { if(serviceAddress.isUnspecified()) EV << "MECWarningAlertApp::handleSelfMessage - service IP address is unspecified (maybe response from the service registry is arriving)" << endl; - else if(serviceSocket_.getState() == inet::TcpSocket::CONNECTED) + else if(serviceSocket_->getState() == inet::TcpSocket::CONNECTED) EV << "MECWarningAlertApp::handleSelfMessage - service socket is already connected" << endl; auto nack = inet::makeShared(); // the connectService message is scheduled after a start mec app from the UE app, so I can @@ -443,3 +465,17 @@ void MECWarningAlertApp::handleSelfMessage(cMessage *msg) delete msg; } + +void MECWarningAlertApp::handleProcessedMessage(cMessage *msg) +{ + if (!msg->isSelfMessage()) { + if(ueSocket.belongsToSocket(msg)) + { + handleUeMessage(msg); + delete msg; + return; + } + } + MecAppBase::handleProcessedMessage(msg); +} + diff --git a/src/apps/mec/WarningAlert/MECWarningAlertApp.h b/src/apps/mec/WarningAlert/MECWarningAlertApp.h index bfda5e60b..c2174f4ac 100644 --- a/src/apps/mec/WarningAlert/MECWarningAlertApp.h +++ b/src/apps/mec/WarningAlert/MECWarningAlertApp.h @@ -59,6 +59,11 @@ class MECWarningAlertApp : public MecAppBase inet::L3Address ueAppAddress; int ueAppPort; + inet::TcpSocket* serviceSocket_; + inet::TcpSocket* mp1Socket_; + + HttpBaseMessage* mp1HttpMessage; + HttpBaseMessage* serviceHttpMessage; int size_; std::string subId; @@ -72,13 +77,13 @@ class MECWarningAlertApp : public MecAppBase protected: virtual int numInitStages() const override { return inet::NUM_INIT_STAGES; } virtual void initialize(int stage) override; - virtual void handleMessage(cMessage *msg) override; - virtual void finish() override; - virtual void handleServiceMessage() override; - virtual void handleMp1Message() override; + virtual void handleProcessedMessage(omnetpp::cMessage *msg) override; + virtual void handleHttpMessage(int connId) override; + virtual void handleServiceMessage(int connId) override; + virtual void handleMp1Message(int connId) override; virtual void handleUeMessage(omnetpp::cMessage *msg) override; virtual void modifySubscription(); diff --git a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.cc b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.cc index 84e937944..1614d6656 100644 --- a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.cc +++ b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.cc @@ -74,26 +74,22 @@ void SocketManager::dataArrived(inet::Packet *msg, bool urgent){ } // ######################## - bool res = Http::parseReceivedMsg(packet, &bufferedData, ¤tHttpMessage); + bool res = Http::parseReceivedMsg(sock->getSocketId(), packet, httpMessageQueue, &bufferedData, ¤tHttpMessage); + if(res) { - currentHttpMessage->setSockId(sock->getSocketId()); - if(currentHttpMessage->getType() == REQUEST) +// currentHttpMessage->setSockId(sock->getSocketId()); + while(!httpMessageQueue.isEmpty()) { + // TODO handle response in service!! service->emitRequestQueueLength(); - currentHttpMessage->setArrivalTime(simTime()); - service->newRequest(check_and_cast(currentHttpMessage)); - } - else - { - delete currentHttpMessage; + HttpBaseMessage* msg = (HttpBaseMessage*)httpMessageQueue.pop(); + msg->setArrivalTime(simTime()); + if(msg->getType() == REQUEST) + service->newRequest(check_and_cast(msg)); + else + delete msg; } - - if(currentHttpMessage != nullptr) - { - currentHttpMessage = nullptr; - } - } delete msg; return; diff --git a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.h b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.h index 011ddfe54..78b7e25e2 100644 --- a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.h +++ b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/SocketManager.h @@ -33,6 +33,7 @@ class SocketManager : public omnetpp::cSimpleModule, public inet::TcpSocket::ICa MecServiceBase *service; inet::TcpSocket *sock; // ptr into socketMap managed by TCPSrvHostApp HttpBaseMessage* currentHttpMessage; + cQueue httpMessageQueue; std::string bufferedData; // internal: inet::TcpSocket::CallbackInterface methods diff --git a/src/nodes/mec/utils/httpUtils/httpUtils.cc b/src/nodes/mec/utils/httpUtils/httpUtils.cc index 7ad471e66..87cea27d5 100644 --- a/src/nodes/mec/utils/httpUtils/httpUtils.cc +++ b/src/nodes/mec/utils/httpUtils/httpUtils.cc @@ -346,101 +346,121 @@ namespace Http { return false; } - void parseReceivedMsg(int socketId, std::string& packet, omnetpp::cQueue& messageQueue, std::string* storedData, HttpBaseMessage** currentHttpMessage) - { - EV_INFO << "httpUtils::parseReceivedMsg" << endl; - std::string delimiter = "\r\n\r\n"; - size_t pos = 0; - std::string header; -// int remainingData; - - if(*currentHttpMessage != nullptr && (*currentHttpMessage)->isReceivingMsg()) - { - EV << "MecAppBase::parseReceivedMsg - Continue receiving data for the current HttpMessage" << endl; - Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); -// double time; - switch (res) - { - case (Http::COMPLETE_NO_DATA): - EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; - (*currentHttpMessage)->setSockId(socketId); - messageQueue.insert(*currentHttpMessage); - *currentHttpMessage = nullptr; - return; - break; - case (Http::COMPLETE_DATA): - EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; - (*currentHttpMessage)->setSockId(socketId); - messageQueue.insert(*currentHttpMessage); - *currentHttpMessage = nullptr; - break; - case (Http::INCOMPLETE_DATA): - throw cRuntimeError("httpUtils parseReceivedMsg - current Http Message is incomplete, but there is still data to read"); - case (Http::INCOMPLETE_NO_DATA): - return; - - } - } - - /* - * If I get here OR: - * - I am not receiving an http message - * - I was receiving an http message but I still have data (i.e a new HttpMessage) to manage. - * Start reading the header - */ - - std::string temp; - if(storedData->length() > 0) - { - EV << "MecAppBase::parseReceivedMsg - buffered data" << endl; - temp = packet; - packet = *storedData + temp; - - } - - while ((pos = packet.find(delimiter)) != std::string::npos) { - header = packet.substr(0, pos); - packet.erase(0, pos+delimiter.length()); //remove header -// HttpBaseMessage* newHttpMessage = Http::parseHeader(header); - *currentHttpMessage = Http::parseHeader(header); - - Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); - // double time; - switch (res) - { - case (Http::COMPLETE_NO_DATA): - EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; - (*currentHttpMessage)->setSockId(socketId); - messageQueue.insert( *currentHttpMessage); - *currentHttpMessage = nullptr; - return; - break; - case (Http::COMPLETE_DATA): - EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; - (*currentHttpMessage)->setSockId(socketId); - messageQueue.insert( *currentHttpMessage); - *currentHttpMessage = nullptr; - break; - case (Http::INCOMPLETE_DATA): - throw cRuntimeError("httpUtils parseReceivedMsg - current Http Message is incomplete, but there is still data to read"); - case (Http::INCOMPLETE_NO_DATA): - return; - } - } - - - /* - * If I did not find the delimiter ("\r\n\r\n") - * it could mean that the HTTP message is fragmented at the header, so the data - * should be saved and aggregated with the subsequent fragmented - */ - if(packet.length() != 0) - { - *storedData = packet; - return; - } - return; - } + bool parseReceivedMsg(int socketId, std::string& packet, omnetpp::cQueue& messageQueue, std::string* storedData, HttpBaseMessage** currentHttpMessage) + { + EV_INFO << "httpUtils::parseReceivedMsg" << endl; + //std::cout << "MecAppBase::parseReceivedMsg" << std::endl; + //std::cout << "MecAppBase::parseReceivedMsg MSG :" << packet << std::endl; + + + std::string delimiter = "\r\n\r\n"; + size_t pos = 0; + std::string header; + int remainingData; + bool completeMsg = false; + + // continue receiving the message + if(*currentHttpMessage != nullptr && (*currentHttpMessage)->isReceivingMsg()) + { + // EV << "MecAppBase::parseReceivedMsg - Continue receiving data for the current HttpMessage" << endl; + Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); + double time; + switch (res) + { + case (Http::COMPLETE_NO_DATA): + // EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; + (*currentHttpMessage)->setSockId(socketId); + messageQueue.insert(*currentHttpMessage); + completeMsg = true; + *currentHttpMessage = nullptr; + return completeMsg; + break; + case (Http::COMPLETE_DATA): + // EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; + (*currentHttpMessage)->setSockId(socketId); + messageQueue.insert(*currentHttpMessage); + completeMsg = true; + *currentHttpMessage = nullptr; + break; + case (Http::INCOMPLETE_DATA): + throw cRuntimeError("httpUtils parseReceivedMsg - current Http Message is incomplete, but there is still data to read"); + case (Http::INCOMPLETE_NO_DATA): + return completeMsg; + + } + } + + /* + * If I get here OR: + * - I am not receiving an http message + * - I was receiving an http message but I still have data (i.e a new HttpMessage) to manage. + * Start reading the header + */ + + std::string temp; + if(storedData->length() > 0) + { + // EV << "MecAppBase::parseReceivedMsg - buffered data" << endl; + //std::cout << "MecAppBase::parseReceivedMsg - buffered data" << std::endl; + //std::cout << "MecAppBase::parseReceivedMsgbuffered data aprim" << *storedData << std::endl; + + + temp = packet; + packet = *storedData + temp; + storedData->clear(); + //std::cout << "MecAppBase::parseReceivedMsgbuffered data dopo " << packet << std::endl; + + } + + while ((pos = packet.find(delimiter)) != std::string::npos) { + //std::cout << "MecAppBase::parseReceivedMsg" << std::endl; + header = packet.substr(0, pos); + packet.erase(0, pos+delimiter.length()); //remove header + // HttpBaseMessage* newHttpMessage = Http::parseHeader(header); + *currentHttpMessage = Http::parseHeader(header); + + Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); + double time; + switch (res) + { + case (Http::COMPLETE_NO_DATA): + // EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; + (*currentHttpMessage)->setSockId(socketId); + messageQueue.insert( *currentHttpMessage); + completeMsg = true; + *currentHttpMessage = nullptr; + return completeMsg; + break; + case (Http::COMPLETE_DATA): + // EV << "MecAppBase::parseReceivedMsg - passing HttpMessage to application: " << res << endl; + (*currentHttpMessage)->setSockId(socketId); + messageQueue.insert( *currentHttpMessage); + completeMsg = true; + *currentHttpMessage = nullptr; + break; + case (Http::INCOMPLETE_DATA): + throw cRuntimeError("httpUtils parseReceivedMsg - current Http Message is incomplete, but there is still data to read"); + case (Http::INCOMPLETE_NO_DATA): + return completeMsg; + } + } + + + /* + * If I did not find the delimiter ("\r\n\r\n") + * it could mean that the HTTP message is fragmented at the header, so the data + * should be saved and aggregated with the subsequent fragmented + */ + if(packet.length() != 0) + { + //std::cout << "MecAppBase::parseReceivedMsg packet.length() " << packet << std::endl; + *storedData = packet; + //std::cout << "##############" << std::endl; + + return completeMsg; + } + return completeMsg = true;; + } void addBodyChunk(std::string* data, HttpBaseMessage* httpMessage) { diff --git a/src/nodes/mec/utils/httpUtils/httpUtils.h b/src/nodes/mec/utils/httpUtils/httpUtils.h index bb4423dab..28f82bf9e 100644 --- a/src/nodes/mec/utils/httpUtils/httpUtils.h +++ b/src/nodes/mec/utils/httpUtils/httpUtils.h @@ -129,7 +129,7 @@ namespace Http { * @param currentHttpMessage variable for storing the current HTTP message * @param messageQueue queue where to insert completed Http Messages */ - void parseReceivedMsg(int socketId, std::string& packet, omnetpp::cQueue& messageQueue, std::string* storedData, HttpBaseMessage** currentHttpMessage = nullptr ); + bool parseReceivedMsg(int socketId, std::string& packet, omnetpp::cQueue& messageQueue, std::string* storedData, HttpBaseMessage** currentHttpMessage = nullptr ); /*************************************************************************************/ From 0cb368a748bb6b7aabf58e7518745fa1919e2756 Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 09:35:32 +0200 Subject: [PATCH 2/8] update MecApp socket management --- src/apps/mec/MecApps/MecAppBase.cc | 225 ++++++++++++------ src/apps/mec/MecApps/MecAppBase.h | 55 +++-- src/nodes/mec/MECPlatform/IMECApp.ned | 1 + .../MECServiceBase/MecServiceBase.cc | 15 +- .../VirtualisationInfrastructureManager.cc | 3 +- 5 files changed, 204 insertions(+), 95 deletions(-) diff --git a/src/apps/mec/MecApps/MecAppBase.cc b/src/apps/mec/MecApps/MecAppBase.cc index 536a16ba4..b881a3f3d 100644 --- a/src/apps/mec/MecApps/MecAppBase.cc +++ b/src/apps/mec/MecApps/MecAppBase.cc @@ -12,8 +12,15 @@ #include "apps/mec/MecApps/MecAppBase.h" #include "nodes/mec/utils/httpUtils/httpUtils.h" #include "nodes/mec/utils/MecCommon.h" +#include "apps/mec/MecApps/packets/ProcessingTimeMessage_m.h" + #include "common/utils/utils.h" +#include "inet/common/ProtocolTag_m.h" +#include "inet/common/ProtocolGroup.h" +#include "inet/common/Protocol.h" + + using namespace omnetpp; using namespace inet; @@ -24,13 +31,14 @@ MecAppBase::MecAppBase() mecPlatform = nullptr;; serviceRegistry = nullptr; sendTimer = nullptr; - serviceHttpMessage = nullptr; - mp1HttpMessage = nullptr; vim = nullptr; + processMessage_ = nullptr; + currentProcessedMsg_ = nullptr; } MecAppBase::~MecAppBase() { + std::cout << "MecAppBase::~MecAppBase()" << std::endl; if(sendTimer != nullptr) { if(sendTimer->isSelfMessage()) @@ -39,20 +47,17 @@ MecAppBase::~MecAppBase() delete sendTimer; } - if(serviceHttpMessage != nullptr) + // delete all the messages + for(auto &sock : sockets_.getMap()) { - delete serviceHttpMessage; - } - if(mp1HttpMessage != nullptr) - { - delete mp1HttpMessage; + TcpSocket* tcpSock = (TcpSocket*)sock.second; + // removeSocket(tcpSock); } + // it calls delete, too + sockets_.deleteSockets(); - - cancelAndDelete(processedServiceResponse); - cancelAndDelete(processedMp1Response); - + cancelAndDelete(processMessage_); } void MecAppBase::initialize(int stage) @@ -65,13 +70,26 @@ void MecAppBase::initialize(int stage) mp1Address = L3AddressResolver().resolve(mp1Ip); mp1Port = par("mp1Port"); - serviceSocket_.setOutputGate(gate("socketOut")); - mp1Socket_.setOutputGate(gate("socketOut")); - - serviceSocket_.setCallback(this); - mp1Socket_.setCallback(this); +// TcpSocket* serviceSocket = new TcpSocket(); +// serviceSocket->setOutputGate(gate("socketOut")); +// serviceSocket->setCallback(this); +// HttpMessageStatus* msg = new HttpMessageStatus; +// msg = nullptr; +// serviceSocket->setUserData(msg); +// +// sockets_["serviceSocket"] = serviceSocket; +// +// TcpSocket* mp1Socket = new TcpSocket(); +// mp1Socket->setOutputGate(gate("socketOut")); +// mp1Socket->setCallback(this); +// HttpMessageStatus* msg1 = new HttpMessageStatus; +// msg1 = nullptr; +// mp1Socket->setUserData(msg1); +// +// sockets_["mp1Socket"] = mp1Socket; mecAppId = par("mecAppId"); // FIXME mecAppId is the deviceAppId (it does not change anything, though) + mecAppIndex_ = par("mecAppIndex"); requiredRam = par("requiredRam").doubleValue(); requiredDisk = par("requiredDisk").doubleValue(); requiredCpu = par("requiredCpu").doubleValue(); @@ -82,15 +100,13 @@ void MecAppBase::initialize(int stage) serviceRegistry = check_and_cast(mecPlatform->getSubmodule("serviceRegistry")); - processedServiceResponse = new cMessage("processedServiceResponse"); - processedMp1Response = new cMessage("processedMp1Response"); - + processMessage_ = new cMessage("processedMessage"); } void MecAppBase::connect(inet::TcpSocket* socket, const inet::L3Address& address, const int port) { // we need a new connId if this is not the first connection - socket->renewSocket(); + //socket->renewSocket(); int timeToLive = par("timeToLive"); if (timeToLive != -1) @@ -118,23 +134,38 @@ void MecAppBase::handleMessage(cMessage *msg) { if (msg->isSelfMessage()) { - EV << "MecAppBase::handleMessage" << endl; - if(strcmp(msg->getName(), "processedServiceResponse") == 0) + if(strcmp(msg->getName(), "processedMessage") == 0) { - handleServiceMessage(); - if(serviceHttpMessage != nullptr) + handleProcessedMessage((cMessage*)packetQueue_.pop()); + //delete packetQueue_.pop(); + if(!packetQueue_.isEmpty()) { - delete serviceHttpMessage; - serviceHttpMessage = nullptr; + double processingTime = scheduleNextMsg((cMessage *)packetQueue_.front()); + EV <<"MecAppBase::scheduleNextMsg() - next msg is processed in " << processingTime << "s" << endl; + scheduleAt(simTime() + processingTime, processMessage_); + } + else + { + EV << "MecAppBase::handleMessage - no more messages are present in the queue" << endl; } } - else if (strcmp(msg->getName(), "processedMp1Response") == 0) + else if(strcmp(msg->getName(), "processedHttpMsg") == 0) { - handleMp1Message(); - if(mp1HttpMessage != nullptr) + EV << "MecAppBase::handleMessage(): processedHttpMsg " << endl; + ProcessingTimeMessage * procMsg = check_and_cast(msg); + int connId = procMsg->getSocketId(); + TcpSocket* sock = (TcpSocket*)sockets_.getSocketById(connId); + if(sock != nullptr) { - delete mp1HttpMessage; - mp1HttpMessage = nullptr; + HttpMessageStatus* msgStatus = (HttpMessageStatus *)sock->getUserData(); + handleHttpMessage(connId); + delete msgStatus->httpMessageQueue.pop(); + if(!msgStatus->httpMessageQueue.isEmpty()) + { + EV << "MecAppBase::handleMessage(): processedHttpMsg - the httpMessageQueue is not empty, schedule next HTTP message" << endl; + double time = vim->calculateProcessingTime(mecAppId, 150); + scheduleAt(simTime()+time, msg); + } } } else @@ -144,16 +175,53 @@ void MecAppBase::handleMessage(cMessage *msg) } else { - // from service or from ue app? - if(serviceSocket_.belongsToSocket(msg)) + if(!processMessage_->isScheduled() && packetQueue_.isEmpty()) + { + packetQueue_.insert(msg); + double processingTime; + if(strcmp(msg->getFullName(), "data") == 0) + processingTime = MecAppBase::scheduleNextMsg(msg); + else + processingTime = scheduleNextMsg(msg); + EV <<"MecAppBase::scheduleNextMsg() - next msg is processed in " << processingTime << "s" << endl; + scheduleAt(simTime() + processingTime, processMessage_); + + } + else if (processMessage_->isScheduled() && !packetQueue_.isEmpty()) { - serviceSocket_.processMessage(msg); + packetQueue_.insert(msg); } - else if(mp1Socket_.belongsToSocket(msg)) + else { - mp1Socket_.processMessage(msg); + throw cRuntimeError("MecAppBase::handleMessage - This situation is not possible"); } + } +} + +double MecAppBase::scheduleNextMsg(cMessage* msg) +{ + double processingTime = vim->calculateProcessingTime(mecAppId, 20);// int(uniform(200, 400))); this cause machines to invert orders! + return processingTime; +} +void MecAppBase::handleProcessedMessage(cMessage *msg) +{ + if (msg->isSelfMessage()) + { + handleSelfMessage(msg); + } + else + { + TcpSocket* sock = (TcpSocket*)sockets_.findSocketFor(msg); + if(sock != nullptr) + { + EV << "MecAppBase::handleProcessedMessage(): message for socket with ID: " << sock->getSocketId() << endl; + sock->processMessage(msg); + } + else + { + delete msg; + } } } @@ -166,7 +234,6 @@ void MecAppBase::socketDataArrived(inet::TcpSocket *socket, inet::Packet *msg, b { EV << "MecAppBase::socketDataArrived" << endl; - // In progress. Trying to handle an app message coming from different tcp segments in a better way // bool res = msg->hasAtFront(); // auto pkc = msg->peekAtFront(b(-1), Chunk::PF_ALLOW_EMPTY | Chunk::PF_ALLOW_SERIALIZATION | Chunk::PF_ALLOW_INCOMPLETE); @@ -182,41 +249,24 @@ void MecAppBase::socketDataArrived(inet::TcpSocket *socket, inet::Packet *msg, b // // EV << "MecAppBase::socketDataArrived - payload: " << endl; // + std::vector bytes = msg->peekDataAsBytes()->getBytes(); std::string packet(bytes.begin(), bytes.end()); // EV << packet << endl; + HttpMessageStatus* msgStatus = (HttpMessageStatus*) socket->getUserData(); - if(serviceSocket_.belongsToSocket(msg)) + bool res = Http::parseReceivedMsg(socket->getSocketId(), packet, msgStatus->httpMessageQueue , &(msgStatus->bufferedData), &(msgStatus->currentMessage)); + if(res) { - bool res = Http::parseReceivedMsg(packet, &bufferedData, &serviceHttpMessage); - if(res) - { - serviceHttpMessage->setSockId(serviceSocket_.getSocketId()); - if(vim == nullptr) - throw cRuntimeError("MecAppBase::socketDataArrived - vim is null!"); - double time = vim->calculateProcessingTime(mecAppId, 150); - scheduleAt(simTime()+time, processedServiceResponse); - } + //msgStatus->currentMessage->setSockId(socket->getSocketId()); + if(vim == nullptr) + throw cRuntimeError("MecAppBase::socketDataArrived - vim is null!"); + double time = vim->calculateProcessingTime(mecAppId, 150); + if(!msgStatus->processMsgTimer->isScheduled()) + scheduleAt(simTime()+time, msgStatus->processMsgTimer); } - else if (mp1Socket_.belongsToSocket(msg)) - { - bool res = Http::parseReceivedMsg(packet, &bufferedData, &mp1HttpMessage); - if(res) - { - mp1HttpMessage->setSockId(mp1Socket_.getSocketId()); - if(vim == nullptr) - throw cRuntimeError("MecAppBase::socketDataArrived - vim is null!"); - double time = vim->calculateProcessingTime(mecAppId, 150); - scheduleAt(simTime()+time, processedMp1Response); - } - } - else - { - throw cRuntimeError("MecAppBase::socketDataArrived - Socket %d not recognized", socket->getSocketId()); - } delete msg; - } void MecAppBase::socketPeerClosed(TcpSocket *socket_) @@ -235,14 +285,51 @@ void MecAppBase::socketFailure(TcpSocket *sock, int code) // subclasses may override this function, and add code try to reconnect after a delay. } + +TcpSocket* MecAppBase::addNewSocket() +{ + TcpSocket* newSocket = new TcpSocket(); + newSocket->setOutputGate(gate("socketOut")); + newSocket->setCallback(this); + HttpMessageStatus* msg = new HttpMessageStatus; + msg->processMsgTimer = new ProcessingTimeMessage("processedHttpMsg"); + msg->processMsgTimer->setSocketId(newSocket->getSocketId()); + newSocket->setUserData(msg); + + sockets_.addSocket(newSocket); + EV << "MecAppBase::addNewSocket(): added socket with ID: " << newSocket->getSocketId() << endl; + return newSocket; +} + + +void MecAppBase::removeSocket(inet::TcpSocket* tcpSock) +{ + HttpMessageStatus* msgStatus = (HttpMessageStatus *) tcpSock->getUserData(); + std::cout << "Deleting httpMessages in socket with sockId " << tcpSock->getSocketId() << std::endl; + while(!msgStatus->httpMessageQueue.isEmpty()) + { + std::cout << "Deleting httpMessages message" << std::endl; + delete msgStatus->httpMessageQueue.pop(); + } + if(msgStatus->currentMessage != nullptr ) + delete msgStatus->currentMessage; + if(msgStatus->processMsgTimer != nullptr) + { + cancelAndDelete(msgStatus->processMsgTimer); + } + delete sockets_.removeSocket(tcpSock); +} + void MecAppBase::finish() { EV << "MecAppBase::finish()" << endl; - if(serviceSocket_.getState() == inet::TcpSocket::CONNECTED) - serviceSocket_.close(); - if(mp1Socket_.getState() == inet::TcpSocket::CONNECTED) - mp1Socket_.close(); +// if(serviceSocket_.getState() == inet::TcpSocket::CONNECTED) +// serviceSocket_.close(); +// if(mp1Socket_.getState() == inet::TcpSocket::CONNECTED) +// mp1Socket_.close(); } + + diff --git a/src/apps/mec/MecApps/MecAppBase.h b/src/apps/mec/MecApps/MecAppBase.h index cab79a36a..9124f6fae 100644 --- a/src/apps/mec/MecApps/MecAppBase.h +++ b/src/apps/mec/MecApps/MecAppBase.h @@ -16,11 +16,13 @@ #include #include "inet/networklayer/common/L3AddressResolver.h" #include "inet/transportlayer/contract/tcp/TcpSocket.h" +#include "inet/transportlayer/contract/udp/UdpSocket.h" +#include "inet/common/socket/SocketMap.h" + + #include "nodes/mec/MECPlatform/MECServices/packets/HttpRequestMessage/HttpRequestMessage.h" #include "nodes/mec/MECPlatform/MECServices/packets/HttpResponseMessage/HttpResponseMessage.h" #include "nodes/mec/MECPlatform/MECServices/packets/HttpMessages_m.h" -#include "inet/transportlayer/contract/udp/UdpSocket.h" - #include "nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h" #include "nodes/mec/MECPlatform/ServiceRegistry/ServiceRegistry.h" @@ -37,17 +39,36 @@ */ class VirtualisationInfrastructureManager; +class ProcessingTimeMessage; class ServiceRegistry; +typedef struct +{ + HttpBaseMessage *currentMessage = nullptr; + std::string bufferedData; + cQueue httpMessageQueue; + ProcessingTimeMessage* processMsgTimer; +} HttpMessageStatus; + class MecAppBase : public omnetpp::cSimpleModule, public inet::TcpSocket::ICallback { protected: - - inet::TcpSocket serviceSocket_; - inet::TcpSocket mp1Socket_; - + /* TCP sockets are dynamically create by the user according to her needs + * the HttpBaseMessage* will be linked to the userData variable in TCPSocket class + * The base implementation already provides on socket to the ServiceRegistry and one socket to a MEC service + * key is the name of the socket, just to std::string,. E.g. LocServiceSocket, RNISSocket + * NOTE: remember to delete the HttpBaseMessage* pointer! + */ + inet::SocketMap sockets_; + + cQueue packetQueue_; + cMessage* currentProcessedMsg_; + cMessage* processMessage_;; + + // endpoint for contacting the Service Registry inet::L3Address mp1Address; int mp1Port; + inet::L3Address serviceAddress; int servicePort; @@ -55,12 +76,6 @@ class MecAppBase : public omnetpp::cSimpleModule, public inet::TcpSocket::ICall omnetpp::cQueue serviceHttpMessages_; omnetpp::cQueue mp1HttpMessages_; - HttpBaseMessage* serviceHttpMessage; - HttpBaseMessage* mp1HttpMessage; - - - std::string bufferedData; - VirtualisationInfrastructureManager* vim; omnetpp::cMessage *sendTimer; @@ -71,14 +86,12 @@ class MecAppBase : public omnetpp::cSimpleModule, public inet::TcpSocket::ICall ServiceRegistry * serviceRegistry; int mecAppId; + int mecAppIndex_; double requiredRam; double requiredDisk; double requiredCpu; - omnetpp::cMessage* processedServiceResponse; - omnetpp::cMessage* processedMp1Response; - protected: virtual void initialize(int stage) override; @@ -87,14 +100,22 @@ class MecAppBase : public omnetpp::cSimpleModule, public inet::TcpSocket::ICall virtual void finish() override; /* Method to be implemented for real MEC apps */ + virtual void handleProcessedMessage(omnetpp::cMessage *msg); virtual void handleSelfMessage(omnetpp::cMessage *msg) = 0; - virtual void handleServiceMessage() = 0; - virtual void handleMp1Message() = 0; + virtual void handleServiceMessage(int connId) = 0; + virtual void handleMp1Message(int connId) = 0; + virtual void handleHttpMessage(int connId) = 0; virtual void handleUeMessage(omnetpp::cMessage *msg) = 0; virtual void established(int connId) = 0; + virtual double scheduleNextMsg(cMessage* msg); + + virtual inet::TcpSocket* addNewSocket(); + virtual void connect(inet::TcpSocket* socket, const inet::L3Address& address, const int port); + virtual void removeSocket(inet::TcpSocket* tcpSock); + /* inet::TcpSocket::CallbackInterface callback methods */ virtual void socketDataArrived(inet::TcpSocket *socket, inet::Packet *msg, bool urgent) override; virtual void socketAvailable(inet::TcpSocket *socket, inet::TcpAvailableInfo *availableInfo) override { socket->accept(availableInfo->getNewSocketId()); } diff --git a/src/nodes/mec/MECPlatform/IMECApp.ned b/src/nodes/mec/MECPlatform/IMECApp.ned index 70ee123fb..c7710d2ae 100644 --- a/src/nodes/mec/MECPlatform/IMECApp.ned +++ b/src/nodes/mec/MECPlatform/IMECApp.ned @@ -17,6 +17,7 @@ moduleinterface IMECApp parameters: @display("i=block/app"); int mecAppId; + int mecAppIndex; string mp1Address; int mp1Port; diff --git a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/MecServiceBase.cc b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/MecServiceBase.cc index 383817bf0..f4999698a 100644 --- a/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/MecServiceBase.cc +++ b/src/nodes/mec/MECPlatform/MECServices/MECServiceBase/MecServiceBase.cc @@ -403,7 +403,7 @@ void MecServiceBase::newRequest(HttpRequestMessage *msg) * When the FG request queue is empty, upon a FG arrive the number of requests * already in the system is calculated supposing a M/M/1 system with service mu. */ - if(loadGenerator_ && currentRequestMessageServed_ != nullptr && !currentRequestMessageServed_->isBackgroundRequest()) + if(loadGenerator_) { int numOfBGReqs; @@ -421,19 +421,18 @@ void MecServiceBase::newRequest(HttpRequestMessage *msg) // debug EV << "MecServiceBase::newRequest - number of BG requests between this and the last FG request: " << numOfBGReqs << endl; } - double responseTime = erlang_k(numOfBGReqs+1, requestServiceTime_, REQUEST_RNG); - double sunOfresponseTimes = 0; + + double sumOfresponseTimes = 0; for(int i = 0 ; i < numOfBGReqs+1; ++i) { - sunOfresponseTimes += exponential(requestServiceTime_, REQUEST_RNG); + sumOfresponseTimes += exponential(requestServiceTime_, REQUEST_RNG); } - EV << "MecServiceBase::newRequest - FG request service time is (sunOfresponseTimes): " << sunOfresponseTimes << endl; - EV << "MecServiceBase::newRequest - FG request service time is: " << responseTime << endl; + EV << "MecServiceBase::newRequest - FG request service time is (sumOfresponseTimes): " << sumOfresponseTimes << endl; - msg->setResponseTime(sunOfresponseTimes); + msg->setResponseTime(sumOfresponseTimes); lastFGRequestArrived_ = simTime(); - emit(requestQueueSizeSignal_, numOfBGReqs+1); + emit(requestQueueSizeSignal_, numOfBGReqs); } requests_.insert(msg); diff --git a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc index dee73ee7d..11d4b5581 100644 --- a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc +++ b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc @@ -255,7 +255,7 @@ MecAppInstanceInfo* VirtualisationInfrastructureManager::instantiateMEApp(Create cModuleType *moduleType = cModuleType::get(msg->getMEModuleType()); //MEAPP module package (i.e. path!) cModule *module = moduleType->create(meModuleName, mecHost); //MEAPP module-name & its Parent Module std::stringstream appName; - appName << meModuleName << "[" << msg->getContextId() << "]"; + appName << meModuleName << "\n" << module->getId(); module->setName(appName.str().c_str()); EV << "VirtualisationInfrastructureManager::instantiateMEApp - meModuleName: " << appName.str() << endl; //creating the mecAppMap map entry @@ -283,6 +283,7 @@ MecAppInstanceInfo* VirtualisationInfrastructureManager::instantiateMEApp(Create //initialize IMECApp Parameters + module->par("mecAppIndex") = index; module->par("mecAppId") = ueAppID; module->par("requiredRam") = ram; module->par("requiredDisk") = disk; From d45971398731f4aa30d1a68f8a8b28d330f4c057 Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 09:36:25 +0200 Subject: [PATCH 3/8] update BgApps --- simulations/NR/mec/multiMecHost/omnetpp.ini | 10 ++- simulations/NR/mec/singleMecHost/omnetpp.ini | 85 ++++++++++--------- .../MecRequestBackgroundApp.cc | 29 ++++++- .../MecRequestBackgroundApp.h | 4 +- .../RequestBackgroundApp.ned | 1 + .../MecRequestBackgroundGeneratorApp.cc | 31 ++++++- .../MecRequestBackgroundGeneratorApp.h | 4 +- .../RequestBackgroundGeneratorApp.ned | 1 + .../MecRequestForegroundApp.cc | 43 +++++----- .../MecRequestForegroundApp.h | 2 +- .../RequestForegroundApp.ned | 2 +- .../mec/WarningAlert/MECWarningAlertApp.ned | 1 + 12 files changed, 137 insertions(+), 76 deletions(-) diff --git a/simulations/NR/mec/multiMecHost/omnetpp.ini b/simulations/NR/mec/multiMecHost/omnetpp.ini index c55af1372..ed23730c9 100644 --- a/simulations/NR/mec/multiMecHost/omnetpp.ini +++ b/simulations/NR/mec/multiMecHost/omnetpp.ini @@ -134,10 +134,16 @@ network = simu5g.simulations.NR.mec.multiMecHost.MultiMecHost # MEC Services # MEC host 1 services configurations -*.mecHost1.mecPlatform.numMecServices = 0 +*.mecHost1.mecPlatform.numMecServices = 1 +*.mecHost1.mecPlatform.mecService[0].typename = "LocationService" +*.mecHost1.mecPlatform.mecService[0].localAddress = "mecHost1.virtualisationInfrastructure" +*.mecHost1.mecPlatform.mecService[0].localPort = 10020 +*.mecHost1.mecPlatform.serviceRegistry.localAddress = "mecHost1.virtualisationInfrastructure" +*.mecHost1.mecPlatform.serviceRegistry.localPort = 10021 + # MEC host 2 services configurations -*.mecHost2.mecPlatform.numMecServices = 1 +*.mecHost2.mecPlatform.numMecServices = 0 *.mecHost2.mecPlatform.mecService[0].typename = "LocationService" *.mecHost2.mecPlatform.mecService[0].localAddress = "mecHost2.virtualisationInfrastructure" *.mecHost2.mecPlatform.mecService[0].localPort = 10020 diff --git a/simulations/NR/mec/singleMecHost/omnetpp.ini b/simulations/NR/mec/singleMecHost/omnetpp.ini index 77692ccf2..ecc65e634 100755 --- a/simulations/NR/mec/singleMecHost/omnetpp.ini +++ b/simulations/NR/mec/singleMecHost/omnetpp.ini @@ -7,7 +7,7 @@ cmdenv-autoflush = true # Output Format Results # ########################################################## num-rngs = 3 -repeat = 15 +repeat = 1 seed-set = ${repetition} output-scalar-file = ${resultdir}/${configname}/${repetition}.sca output-vector-file = ${resultdir}/${configname}/${repetition}.vec @@ -164,7 +164,7 @@ network = simu5g.simulations.NR.mec.singleMecHost.singleMecHost # ----------------------------------------------------------------------------- # -# Config "OneFg_NBgApps" +# Config "OneFg_NindependentMecApps" # # This configuration has one foreground MEC app and one generator of requests in order to create # contention at the MEC services @@ -173,65 +173,66 @@ extends = SingleMec *.mecHost.mecPlatform.mecService[0].**.vector-recording = true *.mecHost.mecPlatform.mecService[0].**.scalar-recording = true -**.numBGMecApp = 2 -*.mecHost.bgApp[0].typename = "MecRequestBackgroundGeneratorApp" -*.mecHost.bgApp[0].numberOfApplications = ${numApp = 0, 200, 400, 600, 800, 1000, 2000} -*.mecHost.bgApp[0].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[0].mp1Port = 10021 +**.numIndependentMecApp = 2 +*.mecHost.independentMecApp[0].typename = "MecRequestBackgroundGeneratorApp" +*.mecHost.independentMecApp[0].numberOfApplications = ${numApp = 0, 200, 400, 600, 800, 1000, 2000} +*.mecHost.independentMecApp[0].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[0].mp1Port = 10021 -*.mecHost.bgApp[1].typename = "MecRequestForegroundApp" -*.mecHost.bgApp[1].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[1].mp1Port = 10021 +*.mecHost.independentMecApp[1].typename = "MecRequestForegroundApp" +*.mecHost.independentMecApp[1].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[1].mp1Port = 10021 output-scalar-file = ${resultdir}/${configname}/${configname}_${numApp}.sca output-vector-file = ${resultdir}/${configname}/${configname}_${numApp}.vec # ----------------------------------------------------------------------------- # -# Config "OneFg_NBgApps" +# Config "OneFg_NindependentMecApps" # # This configuration has one foreground MEC app and N background apps in order to create # contention at the MEC services -[Config OneFg_NBgApps] +[Config OneFg_NindependentMecApps] extends = SingleMec + *.mecHost.mecPlatform.mecService[0].**.vector-recording = true *.mecHost.mecPlatform.mecService[0].**.scalar-recording = true -#**.numBGMecApp = 1 + ${numApp = 1, 10, 100, 200, 400, 600, 800, 1000, 2000} -**.numBGMecApp = 1 + ${numApp = 10, 100, 200, 300, 400} -*.mecHost.bgApp[0].typename = "MecRequestForegroundApp" -*.mecHost.bgApp[0].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[0].mp1Port = 10021 -*.mecHost.bgApp[0].lambda = 42ms +#**.numIndependentMecApp = 1 + ${numApp = 1, 10, 100, 200, 400, 600, 800, 1000, 2000} +**.numIndependentMecApp = 1 + ${numApp = 10, 100, 200, 300, 400} +*.mecHost.independentMecApp[0].typename = "MecRequestForegroundApp" +*.mecHost.independentMecApp[0].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[0].mp1Port = 10021 +*.mecHost.independentMecApp[0].lambda = 42ms -*.mecHost.bgApp[1..].typename = "MecRequestBackgroundApp" -*.mecHost.bgApp[1..].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[1..].mp1Port = 10020 # MecRequestBackgroundApp connects directly to the service -*.mecHost.bgApp[1..].lambda = 42ms +*.mecHost.independentMecApp[1..].typename = "MecRequestBackgroundApp" +*.mecHost.independentMecApp[1..].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[1..].mp1Port = 10021 +*.mecHost.independentMecApp[1..].lambda = 42ms # ----------------------------------------------------------------------------- # -# Config "ThreeFg_NBgApps" +# Config "ThreeFg_NindependentMecApps" # # This configuration has three foreground MEC apps and N background apps in order to create # contention at the MEC services -[Config ThreeFg_NBgApps] +[Config ThreeFg_NindependentMecApps] extends = SingleMec *.mecHost.mecPlatform.mecService[0].**.vector-recording = true *.mecHost.mecPlatform.mecService[0].**.scalar-recording = true -#**.numBGMecApp = 1 + ${numApp = 1, 10, 100, 200, 400, 600, 800, 1000, 2000} -**.numBGMecApp = 3 + ${numApp = 10, 100, 200, 300, 400} -*.mecHost.bgApp[0..2].typename = "MecRequestForegroundApp" -*.mecHost.bgApp[0..2].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[0..2].mp1Port = 10021 -*.mecHost.bgApp[0..2].lambda = 42ms +#**.numIndependentMecApp = 1 + ${numApp = 1, 10, 100, 200, 400, 600, 800, 1000, 2000} +**.numIndependentMecApp = 3 + ${numApp = 10, 100, 200, 300, 400} +*.mecHost.independentMecApp[0..2].typename = "MecRequestForegroundApp" +*.mecHost.independentMecApp[0..2].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[0..2].mp1Port = 10021 +*.mecHost.independentMecApp[0..2].lambda = 42ms -*.mecHost.bgApp[3..].typename = "MecRequestBackgroundApp" -*.mecHost.bgApp[3..].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[3..].mp1Port = 10020 # MecRequestBackgroundApp connects directly to the service -*.mecHost.bgApp[3..].lambda = 42ms +*.mecHost.independentMecApp[3..].typename = "MecRequestBackgroundApp" +*.mecHost.independentMecApp[3..].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[3..].mp1Port = 10021 +*.mecHost.independentMecApp[3..].lambda = 42ms output-scalar-file = ${resultdir}/${configname}/${configname}_${numApp}_${repetition}.sca @@ -251,16 +252,16 @@ extends = SingleMec *.mecHost.mecPlatform.mecService[0].loadGenerator = true *.mecHost.mecPlatform.mecService[0].betaa = 0.042 -#*.mecHost.mecPlatform.mecService[0].numBGApps = ${numApp = 10, 100, 200, 400, 600, 800, 1000, 2000} -*.mecHost.mecPlatform.mecService[0].numBGApps = ${numApp = 10, 100, 200, 300, 400} +#*.mecHost.mecPlatform.mecService[0].numindependentMecApps = ${numApp = 10, 100, 200, 400, 600, 800, 1000, 2000} +*.mecHost.mecPlatform.mecService[0].numindependentMecApps = ${numApp = 10, 100, 200, 300, 400} -#**.numBGMecApp = 1 + ${numApp = 0, 200, 400, 600, 800, 1000, 2000} -**.numBGMecApp = 3 -*.mecHost.bgApp[*].typename = "MecRequestForegroundApp" -*.mecHost.bgApp[*].mp1Address= "mecHost.virtualisationInfrastructure" -*.mecHost.bgApp[*].mp1Port = 10021 -*.mecHost.bgApp[*].lambda = 42ms +#**.numIndependentMecApp = 1 + ${numApp = 0, 200, 400, 600, 800, 1000, 2000} +**.numIndependentMecApp = 3 +*.mecHost.independentMecApp[*].typename = "MecRequestForegroundApp" +*.mecHost.independentMecApp[*].mp1Address= "mecHost.virtualisationInfrastructure" +*.mecHost.independentMecApp[*].mp1Port = 10021 +*.mecHost.independentMecApp[*].lambda = 42ms output-scalar-file = ${resultdir}/${configname}/${configname}_${numApp}_${repetition}.sca diff --git a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc index 25447f5eb..d4747bfe6 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc +++ b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.cc @@ -29,8 +29,21 @@ MecRequestBackgroundApp::~MecRequestBackgroundApp(){ cancelAndDelete(burstTimer); } +MecRequestBackgroundApp::MecRequestBackgroundApp() +{ + burstTimer = nullptr; + burstPeriod = nullptr; + sendBurst = nullptr; + serviceSocket_ = nullptr; + mp1Socket_ = nullptr; + mp1HttpMessage = nullptr; + serviceHttpMessage = nullptr; +} + void MecRequestBackgroundApp::handleServiceMessage(int connId) { + HttpMessageStatus *msgStatus = (HttpMessageStatus*) serviceSocket_->getUserData(); + serviceHttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "payload: " << serviceHttpMessage->getBody() << endl; // if(burstFlag) // scheduleAt(simTime() + exponential(lambda, 2)); @@ -43,7 +56,7 @@ void MecRequestBackgroundApp::initialize(int stage){ return; MecAppBase::initialize(stage); mp1Socket_ = addNewSocket(); - cMessage *m = new cMessage("connectService"); + cMessage *m = new cMessage("connectMp1"); sendBurst = new cMessage("sendBurst"); burstPeriod = new cMessage("burstPeriod"); burstTimer = new cMessage("burstTimer"); @@ -117,9 +130,21 @@ void MecRequestBackgroundApp::handleSelfMessage(cMessage *msg){ } } + +void MecRequestBackgroundApp::handleHttpMessage(int connId) +{ + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + handleMp1Message(connId); + } + else + { + handleServiceMessage(connId); + } +} void MecRequestBackgroundApp::handleMp1Message(int connId) { -// throw cRuntimeError("QUiI"); + HttpMessageStatus *msgStatus = (HttpMessageStatus*) mp1Socket_->getUserData(); + mp1HttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "MecRequestBackgroundApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; try diff --git a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h index 6bf30f46d..f38cab557 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h +++ b/src/apps/mec/MecApps/MecRequestBackgroundApp/MecRequestBackgroundApp.h @@ -41,7 +41,7 @@ class MecRequestBackgroundApp : public MecAppBase virtual void initialize(int stage) override; - virtual void handleHttpMessage(int connId) override {} + virtual void handleHttpMessage(int connId) override; virtual void handleServiceMessage(int connId) override; virtual void handleMp1Message(int connId) override; @@ -55,7 +55,7 @@ class MecRequestBackgroundApp : public MecAppBase virtual void finish() override; public: - MecRequestBackgroundApp() {} + MecRequestBackgroundApp(); virtual ~MecRequestBackgroundApp(); }; diff --git a/src/apps/mec/MecApps/MecRequestBackgroundApp/RequestBackgroundApp.ned b/src/apps/mec/MecApps/MecRequestBackgroundApp/RequestBackgroundApp.ned index b280ed5f8..50c2abf31 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundApp/RequestBackgroundApp.ned +++ b/src/apps/mec/MecApps/MecRequestBackgroundApp/RequestBackgroundApp.ned @@ -24,6 +24,7 @@ simple MecRequestBackgroundApp like IMECApp, IApp int packetSize = default(10); string interfaceTableModule = default(""); + int mecAppIndex = default(0); int mecAppId = default(0); // it will be override by getId() in initialize int localUePort = default(0); // not used in MecRequestBackgroundGeneratorApp diff --git a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc index 158f8c814..4a5a3c53e 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc +++ b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc @@ -21,20 +21,33 @@ using namespace inet; Define_Module(MecRequestBackgroundGeneratorApp); +MecRequestBackgroundGeneratorApp::MecRequestBackgroundGeneratorApp() +{ + burstTimer = nullptr; + burstPeriod = nullptr; + sendBurst = nullptr; + serviceSocket_ = nullptr; + mp1Socket_ = nullptr; + mp1HttpMessage = nullptr; + serviceHttpMessage = nullptr; +} MecRequestBackgroundGeneratorApp::~MecRequestBackgroundGeneratorApp() { - cancelAndDelete(burstPeriod); cancelAndDelete(sendBurst); + cancelAndDelete(burstPeriod); } void MecRequestBackgroundGeneratorApp::handleServiceMessage(int connId) { + HttpMessageStatus *msgStatus = (HttpMessageStatus*) serviceSocket_->getUserData(); + serviceHttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "payload: " << serviceHttpMessage->getBody() << endl; if(burstFlag) scheduleAt(simTime() + 0, sendBurst); } + void MecRequestBackgroundGeneratorApp::established(int connId) { if(connId == mp1Socket_->getSocketId()) @@ -97,9 +110,21 @@ void MecRequestBackgroundGeneratorApp::handleSelfMessage(cMessage *msg){ } } +void MecRequestBackgroundGeneratorApp::handleHttpMessage(int connId) +{ + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + handleMp1Message(connId); + } + else + { + handleServiceMessage(connId); + } +} + void MecRequestBackgroundGeneratorApp::handleMp1Message(int connId) { -// throw cRuntimeError("QUiI"); + HttpMessageStatus *msgStatus = (HttpMessageStatus*) mp1Socket_->getUserData(); + mp1HttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "MEWarningAlertApp_rest::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; try @@ -121,10 +146,8 @@ void MecRequestBackgroundGeneratorApp::handleMp1Message(int connId) serviceSocket_ = addNewSocket(); connect(serviceSocket_, serviceAddress, servicePort); } - } } - } catch(nlohmann::detail::parse_error e) { diff --git a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.h b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.h index dab2ed739..3be2d8e18 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.h +++ b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.h @@ -40,7 +40,7 @@ class MecRequestBackgroundGeneratorApp : public MecAppBase virtual void initialize(int stage) override; virtual void handleSelfMessage(cMessage *msg) override; - virtual void handleHttpMessage(int connId) override {} + virtual void handleHttpMessage(int connId) override; virtual void handleServiceMessage(int connId) override; virtual void handleMp1Message(int connId) override; @@ -54,7 +54,7 @@ class MecRequestBackgroundGeneratorApp : public MecAppBase virtual void finish() override; public: - MecRequestBackgroundGeneratorApp() {} + MecRequestBackgroundGeneratorApp(); virtual ~MecRequestBackgroundGeneratorApp(); }; diff --git a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/RequestBackgroundGeneratorApp.ned b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/RequestBackgroundGeneratorApp.ned index 335e34102..1fe8cc416 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/RequestBackgroundGeneratorApp.ned +++ b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/RequestBackgroundGeneratorApp.ned @@ -28,6 +28,7 @@ simple MecRequestBackgroundGeneratorApp like IMECApp, IApp int packetSize = default(10); string interfaceTableModule = default(""); + int mecAppIndex = default(0); int mecAppId = default(0); // it will be override by getId() in initialize int localUePort = default(0); // not used in MecRequestBackgroundGeneratorApp diff --git a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.cc b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.cc index 11faec2e6..d8b936b25 100644 --- a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.cc +++ b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.cc @@ -27,12 +27,25 @@ MecRequestForegroundApp::~MecRequestForegroundApp(){ cancelAndDelete(sendFGRequest); } +void MecRequestForegroundApp::initialize(int stage){ + MecAppBase::initialize(stage); + if(stage == inet::INITSTAGE_APPLICATION_LAYER) + { + mp1Socket_ = addNewSocket(); + cMessage *m = new cMessage("connectMp1"); + mecAppId = getId(); + scheduleAt(simTime() + 0, m); + sendFGRequest = new cMessage("sendFGRequest"); + lambda = par("lambda").doubleValue(); + } +} void MecRequestForegroundApp::handleServiceMessage(int connId) { + HttpMessageStatus *msgStatus = (HttpMessageStatus*) serviceSocket_->getUserData(); + serviceHttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "payload: " << serviceHttpMessage->getBody() << endl; scheduleAt(simTime() + 0.500, sendFGRequest); - } void MecRequestForegroundApp::handleSelfMessage(cMessage *msg){ @@ -48,12 +61,6 @@ void MecRequestForegroundApp::handleSelfMessage(cMessage *msg){ connect(mp1Socket_, mp1Address, mp1Port); delete msg; } - - else if(strcmp(msg->getName(), "connectService") == 0) - { - EV << "MecAppBase::handleMessage- " << msg->getName() << endl; - connect(serviceSocket_, serviceAddress, servicePort); - } else { EV << "MecRequestBackgroundApp::handleSelfMessage - selfMessage not recognized" << endl; @@ -90,7 +97,8 @@ void MecRequestForegroundApp::established(int connId) void MecRequestForegroundApp::handleMp1Message(int connId) { -// throw cRuntimeError("QUiI"); + HttpMessageStatus *msgStatus = (HttpMessageStatus*) mp1Socket_->getUserData(); + mp1HttpMessage = (HttpBaseMessage*) msgStatus->httpMessageQueue.front(); EV << "MecRequestBackgroundApp::handleMp1Message - payload: " << mp1HttpMessage->getBody() << endl; try @@ -126,23 +134,18 @@ void MecRequestForegroundApp::handleMp1Message(int connId) } -void MecRequestForegroundApp::initialize(int stage){ - MecAppBase::initialize(stage); - if(stage == inet::INITSTAGE_APPLICATION_LAYER) +void MecRequestForegroundApp::handleHttpMessage(int connId) +{ + if (mp1Socket_ != nullptr && connId == mp1Socket_->getSocketId()) { + handleMp1Message(connId); + } + else { - mp1Socket_ = addNewSocket(); - cMessage *m = new cMessage("connectMp1"); - mecAppId = getId(); - scheduleAt(simTime() + 0, m); - sendFGRequest = new cMessage("sendFGRequest"); - lambda = par("lambda").doubleValue(); - - + handleServiceMessage(connId); } } void MecRequestForegroundApp::sendRequest(){ - const char * body = ""; const char *uri = "/example/location/v2/queries/users"; std::string host = serviceSocket_->getRemoteAddress().str()+":"+std::to_string(serviceSocket_->getRemotePort()); diff --git a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h index 2799ef437..89e470da4 100644 --- a/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h +++ b/src/apps/mec/MecApps/MecRequestForegroundApp/MecRequestForegroundApp.h @@ -36,7 +36,7 @@ class MecRequestForegroundApp : public MecAppBase virtual void initialize(int stage) override; - virtual void handleHttpMessage(int connId) override {} + virtual void handleHttpMessage(int connId) override; virtual void handleServiceMessage(int connId) override; virtual void handleMp1Message(int connId) override; diff --git a/src/apps/mec/MecApps/MecRequestForegroundApp/RequestForegroundApp.ned b/src/apps/mec/MecApps/MecRequestForegroundApp/RequestForegroundApp.ned index 19267f2a5..74bb99e69 100644 --- a/src/apps/mec/MecApps/MecRequestForegroundApp/RequestForegroundApp.ned +++ b/src/apps/mec/MecApps/MecRequestForegroundApp/RequestForegroundApp.ned @@ -31,7 +31,7 @@ simple MecRequestForegroundApp like IMECApp, IApp int packetSize = default(10); string interfaceTableModule = default(""); - + int mecAppIndex = default(0); int mecAppId = default(0); // it will be override by getId() in initialize int localUePort = default(0); // not used in MecRequestBackgroundGeneratorApp diff --git a/src/apps/mec/WarningAlert/MECWarningAlertApp.ned b/src/apps/mec/WarningAlert/MECWarningAlertApp.ned index c77f2e963..2f4ff890a 100644 --- a/src/apps/mec/WarningAlert/MECWarningAlertApp.ned +++ b/src/apps/mec/WarningAlert/MECWarningAlertApp.ned @@ -38,6 +38,7 @@ simple MECWarningAlertApp like IMECApp, IApp int packetSize = default(10); string interfaceTableModule = default(""); + int mecAppIndex; int mecAppId; int localUePort; From ccd76d89ed04d2b654d7a9c73dbcc0d8c36f9a48 Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 12:13:14 +0200 Subject: [PATCH 4/8] add mec host selection policies --- .../mec/MECOrchestrator/MecOrchestrator.cc | 37 +++++---- .../mec/MECOrchestrator/MecOrchestrator.h | 10 +++ .../mec/MECOrchestrator/MecOrchestrator.ned | 2 + .../AvailableResourcesSelectionBased.cc | 47 +++++++++++ .../AvailableResourcesSelectionBased.h | 29 +++++++ .../MecHostSelectionBased.cc | 39 ++++++++++ .../MecHostSelectionBased.h | 30 ++++++++ .../MecServiceSelectionBased.cc | 77 +++++++++++++++++++ .../MecServiceSelectionBased.h | 28 +++++++ .../SelectionPolicyBase.h | 33 ++++++++ 10 files changed, 318 insertions(+), 14 deletions(-) create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.cc create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.cc create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.h create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.cc create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h create mode 100644 src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h diff --git a/src/nodes/mec/MECOrchestrator/MecOrchestrator.cc b/src/nodes/mec/MECOrchestrator/MecOrchestrator.cc index 496fceea3..3b458caa4 100644 --- a/src/nodes/mec/MECOrchestrator/MecOrchestrator.cc +++ b/src/nodes/mec/MECOrchestrator/MecOrchestrator.cc @@ -11,7 +11,6 @@ #include "nodes/mec/MECOrchestrator/MecOrchestrator.h" - #include "nodes/mec/MECPlatformManager/MecPlatformManager.h" #include "nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h" @@ -24,6 +23,12 @@ #include "nodes/mec/UALCMP/UALCMPMessages/CreateContextAppMessage.h" #include "nodes/mec/UALCMP/UALCMPMessages/CreateContextAppAckMessage.h" + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h" +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h" +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.h" + + //emulation debug #include @@ -33,6 +38,7 @@ MecOrchestrator::MecOrchestrator() { meAppMap.clear(); mecApplicationDescriptors_.clear(); + mecHostSelectionPolicy_ = nullptr; } void MecOrchestrator::initialize(int stage) @@ -45,6 +51,15 @@ void MecOrchestrator::initialize(int stage) binder_ = getBinder(); + if(!strcmp(par("selectionPolicy"), "MecServiceBased")) + mecHostSelectionPolicy_ = new MecServiceSelectionBased(this); + else if(!strcmp(par("selectionPolicy"), "AvailableResourcesBased")) + mecHostSelectionPolicy_ = new AvailableResourcesSelectionBased(this); + else if(!strcmp(par("selectionPolicy"), "MecHostBased")) + mecHostSelectionPolicy_ = new MecHostSelectionBased(this, par("mecHostIndex")); + else + throw cRuntimeError("MecOrchestrator::initialize - Selection policy %s not present!" , par("selectionPolicy").stringValue()); + onboardingTime = par("onboardingTime").doubleValue(); instantiationTime = par("instantiationTime").doubleValue(); terminationTime = par("terminationTime").doubleValue(); @@ -156,11 +171,12 @@ void MecOrchestrator::startMECApp(UALCMPMessage* msg) { EV << "MecOrchestrator::startMECApp - Application package with AppDId["<< contAppMsg->getAppDId() << "] not onboarded." << endl; sendCreateAppContextAck(false, contAppMsg->getRequestId()); +// throw cRuntimeError("MecOrchestrator::startMECApp - Application package with AppDId[%s] not onboarded", contAppMsg->getAppDId()); } const ApplicationDescriptor& desc = it->second; - cModule* bestHost = findBestMecHost(desc); + cModule* bestHost = mecHostSelectionPolicy_->findBestMecHost(desc); if(bestHost != nullptr) { @@ -200,11 +216,6 @@ void MecOrchestrator::startMECApp(UALCMPMessage* msg) MecPlatformManager* mecpm = check_and_cast(newMecApp.mecpm); - // double reqRam = desc.getVirtualResources().ram; - // double reqDisk = desc.getVirtualResources().disk; - // double reqCpu = desc.getVirtualResources().cpu; - - /* * If the application descriptor refers to a simulated mec app, the system eventually instances the mec app object. * If the application descriptor refers to a mec application running outside the simulator, i.e emulation mode, @@ -225,9 +236,6 @@ void MecOrchestrator::startMECApp(UALCMPMessage* msg) appInfo->instanceId = "emulated_" + desc.getAppName(); newMecApp.isEmulated = true; - // register the address of the MEC app to the Binder, so as the GTP knows the endpoint (UPF_MEC) where to forward packets to - inet::L3Address gtpAddress = inet::L3AddressResolver().resolve(newMecApp.mecHost->getSubmodule("upf_mec")->getFullPath().c_str()); - binder_->registerMecHostUpfAddress(appInfo->endPoint.addr, gtpAddress); } else { @@ -311,6 +319,7 @@ void MecOrchestrator::stopMECApp(UALCMPMessage* msg){ if(meAppMap[contextId].isEmulated) { isTerminated = mecpm->terminateEmulatedMEApp(deleteAppMsg); + std::cout << "terminateEmulatedMEApp with result: " << isTerminated << std::endl; } else { @@ -439,8 +448,9 @@ void MecOrchestrator::getConnectedMecHosts() { //getting the list of mec hosts associated to this mec system from parameter if(this->hasPar("mecHostList") && strcmp(par("mecHostList").stringValue(), "")){ + std::string mecHostList = par("mecHostList").stdstringValue(); EV <<"MecOrchestrator::getConnectedMecHosts - mecHostList: "<< par("mecHostList").stringValue() << endl; - char* token = strtok ( (char*) par("mecHostList").stringValue(), ", "); // split by commas + char* token = strtok ( (char*)mecHostList.c_str(), ", "); // split by commas while (token != NULL) { @@ -496,17 +506,16 @@ void MecOrchestrator::onboardApplicationPackages() if(this->hasPar("mecApplicationPackageList") && strcmp(par("mecApplicationPackageList").stringValue(), "")){ char* token = strtok ( (char*) par("mecApplicationPackageList").stringValue(), ", "); // split by commas + while (token != NULL) { int len = strlen(token); - char* buf = new char[len+strlen(".json")+strlen("ApplicationDescriptors/")+1]; - //char buf[len+strlen(".json")+strlen("ApplicationDescriptors/")+1]; + char buf[len+strlen(".json")+strlen("ApplicationDescriptors/")+1]; strcpy(buf,"ApplicationDescriptors/"); strcat(buf,token); strcat(buf,".json"); onboardApplicationPackage(buf); token = strtok (NULL, ", "); - delete[] buf; } } else{ diff --git a/src/nodes/mec/MECOrchestrator/MecOrchestrator.h b/src/nodes/mec/MECOrchestrator/MecOrchestrator.h index f7e9d9627..5f585939c 100644 --- a/src/nodes/mec/MECOrchestrator/MecOrchestrator.h +++ b/src/nodes/mec/MECOrchestrator/MecOrchestrator.h @@ -56,6 +56,7 @@ struct mecAppMapEntry class UALCMPMessage; class MECOrchestratorMessage; +class SelectionPolicyBase; // // This module implements the MEC orchestrator of a MEC system. @@ -71,6 +72,15 @@ class MECOrchestratorMessage; class MecOrchestrator : public cSimpleModule { + // Selection Policies modules access grants + friend class SelectionPolicyBase; + friend class MecServiceSelectionBased; + friend class AvailableResourcesSelectionBased; + friend class MecHostSelectionBased; + + + SelectionPolicyBase* mecHostSelectionPolicy_; + //------------------------------------ //Binder module Binder* binder_; diff --git a/src/nodes/mec/MECOrchestrator/MecOrchestrator.ned b/src/nodes/mec/MECOrchestrator/MecOrchestrator.ned index 06b916918..25826f499 100644 --- a/src/nodes/mec/MECOrchestrator/MecOrchestrator.ned +++ b/src/nodes/mec/MECOrchestrator/MecOrchestrator.ned @@ -27,6 +27,8 @@ simple MecOrchestrator { parameters: @display("i=device/mainframe;bgb=1006.50995,692.76"); + string selectionPolicy = default("MecServiceBased"); // available policies: "MecHostBased", "MecServiceBased", "AvailableResourcesBased" + int mecHostIndex = default(0); // to be used with the MecHostBased policybased string mecHostList = default(""); string mecApplicationPackageList = default(""); diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.cc b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.cc new file mode 100644 index 000000000..fab981f0e --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.cc @@ -0,0 +1,47 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h" +#include "nodes/mec/MECPlatformManager/MecPlatformManager.h" +#include "nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h" + +cModule* AvailableResourcesSelectionBased::findBestMecHost(const ApplicationDescriptor& appDesc) +{ + EV << "AvailableResourcesSelectionBased::findBestMecHost - finding best MecHost..." << endl; + cModule* bestHost = nullptr; + double maxCpuSpeed = -1; + + for(auto mecHost : mecOrchestrator_->mecHosts) + { + VirtualisationInfrastructureManager *vim = check_and_cast (mecHost->getSubmodule("vim")); + ResourceDescriptor resources = appDesc.getVirtualResources(); + bool res = vim->isAllocable(resources.ram, resources.disk, resources.cpu); + if(!res) + { + EV << "AvailableResourcesSelectionBased::findBestMecHost - MEC host ["<< mecHost->getName() << "] has not got enough resources. Searching again..." << endl; + continue; + } + if(vim->getAvailableResources().cpu > maxCpuSpeed) + { + // Temporally select this mec host as the best + EV << "AvailableResourcesSelectionBased::findBestMecHost - MEC host ["<< mecHost->getName() << "] temporally chosen as bet MEC host. Available resources: " << endl; + vim->printResources(); + bestHost = mecHost; + maxCpuSpeed = vim->getAvailableResources().cpu; + } + } + if(bestHost != nullptr) + EV << "AvailableResourcesSelectionBased::findBestMecHost - MEC host ["<< bestHost->getName() << "] has been chosen as the best Mec Host" << endl; + else + EV << "AvailableResourcesSelectionBased::findBestMecHost - No Mec Host found" << endl; + return bestHost; +} + diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h new file mode 100644 index 000000000..a930943f1 --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/AvailableResourcesSelectionBased.h @@ -0,0 +1,29 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_AVAILABLERESOURCESELECTION_H_ +#define NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_AVAILABLERESOURCESELECTION_H_ + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h" + +//class MecOrchestrator; + +class AvailableResourcesSelectionBased : public SelectionPolicyBase +{ + protected: + virtual cModule* findBestMecHost(const ApplicationDescriptor&) override; + public: + AvailableResourcesSelectionBased(MecOrchestrator* mecOrchestrator):SelectionPolicyBase(mecOrchestrator){} + virtual ~AvailableResourcesSelectionBased(){} +}; + + +#endif /* NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_AVAILABLERESOURCESELECTION_H_ */ diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.cc b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.cc new file mode 100644 index 000000000..bcdb3aa6c --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.cc @@ -0,0 +1,39 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#include "MecHostSelectionBased.h" +#include "nodes/mec/MECPlatformManager/MecPlatformManager.h" +#include "nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h" + + +MecHostSelectionBased::MecHostSelectionBased(MecOrchestrator* mecOrchestrator, int index):SelectionPolicyBase(mecOrchestrator) +{ + mecHostIndex_ = index; +} + +cModule* MecHostSelectionBased::findBestMecHost(const ApplicationDescriptor& appDesc) +{ + EV << "MecHostSelectionBased::findBestMecHost - finding best MecHost..." << endl; + cModule* bestHost = nullptr; + + int size = mecOrchestrator_->mecHosts.size(); + if(size < mecHostIndex_) + { + EV << "MecHostSelectionBased::findBestMecHost - No Mec Host with index [" << mecHostIndex_ << "] found" << endl; + } + else + { + bestHost = mecOrchestrator_->mecHosts.at(mecHostIndex_); + EV << "MecHostSelectionBased::findBestMecHost - MEC host ["<< bestHost->getName() << "] has been chosen as the best Mec Host" << endl; + } + return bestHost; +} + diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.h b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.h new file mode 100644 index 000000000..cce404408 --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecHostSelectionBased.h @@ -0,0 +1,30 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECHOSTSELECTIONBASED_H_ +#define NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECHOSTSELECTIONBASED_H_ + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h" + +//class MecOrchestrator; + +class MecHostSelectionBased : public SelectionPolicyBase +{ + protected: + int mecHostIndex_; + virtual cModule* findBestMecHost(const ApplicationDescriptor&) override; + public: + MecHostSelectionBased(MecOrchestrator* mecOrchestrator, int index); + virtual ~MecHostSelectionBased(){} +}; + + +#endif /* NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECHOSTSELECTIONBASED_H_ */ diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.cc b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.cc new file mode 100644 index 000000000..5ac139569 --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.cc @@ -0,0 +1,77 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h" +#include "nodes/mec/MECPlatformManager/MecPlatformManager.h" +#include "nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h" + +cModule* MecServiceSelectionBased::findBestMecHost(const ApplicationDescriptor& appDesc) +{ + EV << "MecServiceSelectionBased::findBestMecHost - finding best MecHost..." << endl; + cModule* bestHost = nullptr; + bool found = false; + + for(auto mecHost : mecOrchestrator_->mecHosts) + { + EV << "MecServiceSelectionBased::findBestMecHost - MEC host ["<< mecHost->getName() << "] size of mecHost " << mecOrchestrator_->mecHosts.size() << endl; + VirtualisationInfrastructureManager *vim = check_and_cast (mecHost->getSubmodule("vim")); + ResourceDescriptor resources = appDesc.getVirtualResources(); + bool res = vim->isAllocable(resources.ram, resources.disk, resources.cpu); + if(!res) + { + EV << "MecServiceSelectionBased::findBestMecHost - MEC host ["<< mecHost->getName() << "] has not got enough resources. Searching again..." << endl; + continue; + } + + // Temporally select this mec host as the best + EV << "MecServiceSelectionBased::findBestMecHost - MEC host ["<< mecHost->getName() << "] temporally chosen as bet MEC host, checking for the required MEC services.." << endl; + bestHost = mecHost; + + MecPlatformManager *mecpm = check_and_cast (mecHost->getSubmodule("mecPlatformManager")); + auto mecServices = mecpm ->getAvailableMecServices(); + std::string serviceName; + + /* I assume the app requires only one mec service */ + if(appDesc.getAppServicesRequired().size() > 0) + { + serviceName = appDesc.getAppServicesRequired()[0]; + EV << "MecServiceSelectionBased::findBestMecHost - required Mec Service: " << serviceName << endl; + } + else + { + EV << "MecServiceSelectionBased::findBestMecHost - the Mec App does not require any MEC service. Choose the temporary Mec Host as the best one"<< endl; + found = true; + break; + } + auto it = mecServices->begin(); + for(; it != mecServices->end() ; ++it) + { + if(serviceName.compare(it->getName()) == 0 && it->getMecHost().compare(bestHost->getName()) == 0) + { + EV << "MecServiceSelectionBased::findBestMecHost - The temporary Mec Host has the MEC service "<< it->getName() << " required by the Mec App. It has been chosen as the best one"<< endl; + bestHost = mecHost; + found = true; + break; + } + } + if(found) + break; + } + + if(bestHost != nullptr && !found) + EV << "MecServiceSelectionBased::findBestMecHost - The best Mec Host hasn't got the required service. Best MEC host: " << bestHost << endl; + else if(bestHost == nullptr) + EV << "MecServiceSelectionBased::findBestMecHost - no MEC host found"<< endl; + + return bestHost; + +} + diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h new file mode 100644 index 000000000..12d8238ec --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/MecServiceSelectionBased.h @@ -0,0 +1,28 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECSERVICESELECTIONBASED_H_ +#define NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECSERVICESELECTIONBASED_H_ + +#include "nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h" + +//class MecOrchestrator; + +class MecServiceSelectionBased : public SelectionPolicyBase +{ + protected: + virtual cModule* findBestMecHost(const ApplicationDescriptor&) override; + public: + MecServiceSelectionBased(MecOrchestrator* mecOrchestrator):SelectionPolicyBase(mecOrchestrator){} + virtual ~MecServiceSelectionBased(){} +}; + +#endif /* NODES_MEC_MECORCHESTRATOR_MECHOSTSELECTIONPOLICIES_MECSERVICESELECTIONBASED_H_ */ diff --git a/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h new file mode 100644 index 000000000..15aa13def --- /dev/null +++ b/src/nodes/mec/MECOrchestrator/mecHostSelectionPolicies/SelectionPolicyBase.h @@ -0,0 +1,33 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// + +#ifndef NODES_MEC_MECORCHESTRATOR_SELECTIONPOLICYBASE_H_ +#define NODES_MEC_MECORCHESTRATOR_SELECTIONPOLICYBASE_H_ + +#include "nodes/mec/MECOrchestrator/MecOrchestrator.h" +#include "nodes/mec/MECOrchestrator/ApplicationDescriptor/ApplicationDescriptor.h" + +class MecOrchestrator; + +class SelectionPolicyBase +{ + friend class MecOrchestrator; + + protected: + MecOrchestrator* mecOrchestrator_; + virtual cModule* findBestMecHost(const ApplicationDescriptor&) = 0; + + public: + SelectionPolicyBase(MecOrchestrator* mecOrchestrator){mecOrchestrator_ = mecOrchestrator;} + virtual ~SelectionPolicyBase() {} +}; + +#endif /* NODES_MEC_MECORCHESTRATOR_SELECTIONPOLICYBASE_H_ */ From d8184301756b7c6c2f6afb935f65b41b1d01e8ba Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 12:14:00 +0200 Subject: [PATCH 5/8] refactor BgApps --- src/nodes/mec/MECHost.ned | 17 +++++++----- .../VirtualisationInfrastructure.ned | 12 ++++----- .../BackgroundApp.ned | 23 ++++++++++++++++ .../VirtualisationInfrastructureManager.cc | 23 ++++++++++++++-- .../VirtualisationInfrastructureManager.h | 27 ++++++++++--------- 5 files changed, 75 insertions(+), 27 deletions(-) create mode 100644 src/nodes/mec/VirtualisationInfrastructureManager/BackgroundApp.ned diff --git a/src/nodes/mec/MECHost.ned b/src/nodes/mec/MECHost.ned index ef294107f..91b677e35 100644 --- a/src/nodes/mec/MECHost.ned +++ b/src/nodes/mec/MECHost.ned @@ -15,6 +15,7 @@ import simu5g.nodes.mec.VirtualisationInfrastructure.VirtualisationInfrastructur import simu5g.nodes.mec.MECPlatform.MECPlatform; import simu5g.nodes.mec.MECPlatformManager.MecPlatformManager; import simu5g.nodes.mec.VirtualisationInfrastructureManager.VirtualisationInfrastructureManager; +import simu5g.nodes.mec.VirtualisationInfrastructureManager.BackgroundApp; import simu5g.nodes.Upf; import inet.node.ethernet.Eth10G; import inet.applications.contract.IApp; @@ -38,6 +39,7 @@ module MECHost double maxCpuSpeed = default(300000); // CPU's clock speed in Million Instruction per Seconds (MIPS) int numBGMecApp = default(0); + int numIndependentMecApp = default(0); //# List of Base Stations associated to the MEC host // This is a string of comma-separated values @@ -80,9 +82,12 @@ module MECHost nodeType = "UPF_MEC"; } - - bgApp[numBGMecApp]: <> like IApp { - @display("p=362.69498,156.875,row,140"); + bgApp[numBGMecApp]: BackgroundApp { + @display("p=865.94995,326.3,row,140"); + } + + independentMecApp[numIndependentMecApp]: <> like IApp { + @display("p=371.47998,156.875,row,140"); } connections allowunconnected: @@ -103,9 +108,9 @@ module MECHost //# virtualisationInfrastructure.ppp++ <--> Eth10G <--> upf_mec.filterGate; - for i=0..numBGMecApp-1 { - bgApp[i].socketIn <-- virtualisationInfrastructure.meBGAppOut[i]; - bgApp[i].socketOut --> virtualisationInfrastructure.meBGAppIn[i]; + for i=0..numIndependentMecApp-1 { + independentMecApp[i].socketIn <-- virtualisationInfrastructure.independentMecAppOut[i]; + independentMecApp[i].socketOut --> virtualisationInfrastructure.independentMecAppIn[i]; } for i=0..mecPlatform.numMecServices { diff --git a/src/nodes/mec/VirtualisationInfrastructure/VirtualisationInfrastructure.ned b/src/nodes/mec/VirtualisationInfrastructure/VirtualisationInfrastructure.ned index 3c763cc65..346c00d48 100644 --- a/src/nodes/mec/VirtualisationInfrastructure/VirtualisationInfrastructure.ned +++ b/src/nodes/mec/VirtualisationInfrastructure/VirtualisationInfrastructure.ned @@ -48,15 +48,15 @@ module VirtualisationInfrastructure *.interfaceTableModule = default(absPath(".interfaceTable")); *.routingTableModule = default("^.ipv4.routingTable"); - int numBGMecApp = default(0); + int numIndependentMecApp = default(0); int numExtEthInterfaces = default(0); gates: inout ppp[]; // connection with GtpEndpoint and local/external networks - output meBGAppOut[numBGMecApp]; // connection to the ME App input gate - input meBGAppIn[numBGMecApp]; // connection to the ME App output gate + output independentMecAppOut[numIndependentMecApp]; // connection to the ME App input gate + input independentMecAppIn[numIndependentMecApp]; // connection to the ME App output gate output meAppOut[]; // connection to the ME App input gate input meAppIn[]; // connection to the ME App output gate @@ -134,9 +134,9 @@ module VirtualisationInfrastructure connections allowunconnected: - for i=0..numBGMecApp-1 { - at.out++ --> meBGAppOut++; - at.in++ <-- meBGAppIn++; + for i=0..numIndependentMecApp -1 { + at.out++ --> independentMecAppOut++; + at.in++ <-- independentMecAppIn++; } for i=0..sizeof(mecPlatform)-1 { diff --git a/src/nodes/mec/VirtualisationInfrastructureManager/BackgroundApp.ned b/src/nodes/mec/VirtualisationInfrastructureManager/BackgroundApp.ned new file mode 100644 index 000000000..8b21fa9ea --- /dev/null +++ b/src/nodes/mec/VirtualisationInfrastructureManager/BackgroundApp.ned @@ -0,0 +1,23 @@ +// +// 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/. +// + +package simu5g.nodes.mec.VirtualisationInfrastructureManager; + +module BackgroundApp +{ + double ram @unit("B") = default(10MB); + double cpu = default(500); + double disk @unit("B") = default(10MB); +} \ No newline at end of file diff --git a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc index 11d4b5581..4d489fc22 100644 --- a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc +++ b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.cc @@ -45,7 +45,7 @@ void VirtualisationInfrastructureManager::initialize(int stage) maxRam = mecHost->par("maxRam").doubleValue(); maxDisk = mecHost->par("maxDisk").doubleValue(); - maxCPU = mecHost->par("maxCpuSpeed").doubleValue(); + maxCPU = mecHost->par("maxCpuSpeed").doubleValue()*pow(10,6); allocatedRam = 0.0; allocatedDisk = 0.0; @@ -120,6 +120,9 @@ void VirtualisationInfrastructureManager::initialize(int stage) // } } mecAppPortCounter = 4001; + + //reserve resources of the bgApps! + reserveResourcesBGApps(); } void VirtualisationInfrastructureManager::handleMessage(cMessage *msg) @@ -495,7 +498,8 @@ bool VirtualisationInfrastructureManager::registerMecApp(int ueAppID, int reqRam appEntry.ueAppID = ueAppID; appEntry.resources.ram = reqRam; appEntry.resources.disk = reqDisk; - appEntry.resources.cpu = reqCpu; + double cpu = (double)reqCpu * pow(10,6); + appEntry.resources.cpu = cpu; mecAppMap.insert({ueAppID, appEntry}); EV << "VirtualisationInfrastructureManager::handleMEAppResources - resources ALLOCATED for independent MecApp with module id " << ueAppID << endl; @@ -565,7 +569,22 @@ ResourceDescriptor VirtualisationInfrastructureManager::getAvailableResources() return avRes; } +void VirtualisationInfrastructureManager::reserveResourcesBGApps() +{ + int numMecApps = mecHost->par("numBGMecApp"); + EV << "VirtualisationInfrastructureManager::reserveResourcesBGApps - reserving resources for "<< numMecApps << " BG apps..." << endl; + for(int i = 0 ; i < numMecApps ; ++i) + { + cModule* bgApp = mecHost->getSubmodule("bgApp", i); + if(bgApp == nullptr) + throw cRuntimeError("VirtualisationInfrastructureManager::reserveResourcesBGApps - Background Mec App bgApp[%d] not found!", i); + double ram = bgApp->par("ram"); + double disk = bgApp->par("disk"); + double cpu = bgApp->par("cpu"); + registerMecApp(bgApp->getId(), ram, disk, cpu); + } +} diff --git a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h index a0995a1e6..fb529b641 100644 --- a/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h +++ b/src/nodes/mec/VirtualisationInfrastructureManager/VirtualisationInfrastructureManager.h @@ -183,19 +183,6 @@ class VirtualisationInfrastructureManager : public cSimpleModule cpu < maxCPU - allocatedCPU); } - protected: - - virtual int numInitStages() const { return inet::NUM_INIT_STAGES; } - void initialize(int stage); - virtual void handleMessage(cMessage *msg); - - // OMNeT++-like MEC service management - //finding the MEC Service requested by UE App among the MEC Services available on the MEC Host - //return: the index of service (in mePlatform.udpService) or SERVICE_NOT_AVAILABLE or NO_SERVICE - int findService(const char* serviceName); - - //------------------------------------ - /* * This method returns the available resources of the MEC host * @return ResourceDescriptor with the available ram, disk and CPU @@ -211,6 +198,18 @@ class VirtualisationInfrastructureManager : public cSimpleModule EV << "VirtualisationInfrastructureManager::printResources - allocated CPU: " << allocatedCPU << " / " << maxCPU << endl; } + protected: + + virtual int numInitStages() const { return inet::NUM_INIT_STAGES; } + void initialize(int stage); + virtual void handleMessage(cMessage *msg); + + // OMNeT++-like MEC service management + //finding the MEC Service requested by UE App among the MEC Services available on the MEC Host + //return: the index of service (in mePlatform.udpService) or SERVICE_NOT_AVAILABLE or NO_SERVICE + int findService(const char* serviceName); + + //------------------------------------ void allocateResources(double ram, double disk, double cpu){ allocatedRam += ram; @@ -225,6 +224,8 @@ class VirtualisationInfrastructureManager : public cSimpleModule allocatedCPU -= cpu; printResources(); } + + void reserveResourcesBGApps(); }; #endif From 3940315efbfa4d28ee403d2bf8294d34e00af01b Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 12:14:46 +0200 Subject: [PATCH 6/8] add req/res scenario --- .../NR/mec/requestResponseApp/.cmdenv-log | 0 .../ApplicationDescriptors/ResponseApp.json | 21 ++ .../requestResponseApp/MultiMecHost_delay.ned | 113 ++++++++ .../NR/mec/requestResponseApp/demo.xml | 14 + .../NR/mec/requestResponseApp/omnetpp.ini | 261 ++++++++++++++++++ simulations/NR/mec/requestResponseApp/run | 4 + .../MecRequestResponseApp/MECResponseApp.cc | 3 + .../mec/MecRequestResponseApp/UERequestApp.cc | 3 + 8 files changed, 419 insertions(+) create mode 100644 simulations/NR/mec/requestResponseApp/.cmdenv-log create mode 100644 simulations/NR/mec/requestResponseApp/ApplicationDescriptors/ResponseApp.json create mode 100644 simulations/NR/mec/requestResponseApp/MultiMecHost_delay.ned create mode 100644 simulations/NR/mec/requestResponseApp/demo.xml create mode 100644 simulations/NR/mec/requestResponseApp/omnetpp.ini create mode 100644 simulations/NR/mec/requestResponseApp/run diff --git a/simulations/NR/mec/requestResponseApp/.cmdenv-log b/simulations/NR/mec/requestResponseApp/.cmdenv-log new file mode 100644 index 000000000..e69de29bb diff --git a/simulations/NR/mec/requestResponseApp/ApplicationDescriptors/ResponseApp.json b/simulations/NR/mec/requestResponseApp/ApplicationDescriptors/ResponseApp.json new file mode 100644 index 000000000..59f4c5dc6 --- /dev/null +++ b/simulations/NR/mec/requestResponseApp/ApplicationDescriptors/ResponseApp.json @@ -0,0 +1,21 @@ +{ +"appDid" : "RESPONSEMECAPP", +"appName" : "MECResponseApp", +"appProvider" : "simu5g.apps.mec.MecRequestResponseApp.MECResponseApp", +"appInfoName" : "appInfoName_", +"appDescription" : "appDescription_", +"virtualComputeDescriptor" :{ + "virtualDisk": 10, + "virtualCpu" : 500, + "virtualMemory":10 + }, +"appServiceRequired": [ + { + "ServiceDependency" :{ + "serName" : "RNIService", + "version" : "v1", + "serCategory": "Network" + } + } +] +} diff --git a/simulations/NR/mec/requestResponseApp/MultiMecHost_delay.ned b/simulations/NR/mec/requestResponseApp/MultiMecHost_delay.ned new file mode 100644 index 000000000..f8ccd480d --- /dev/null +++ b/simulations/NR/mec/requestResponseApp/MultiMecHost_delay.ned @@ -0,0 +1,113 @@ +// +// Simu5G +// +// Authors: Giovanni Nardini, Giovanni Stea, Antonio Virdis (University of Pisa) +// +// This file is part of a software released under the license included in file +// "license.pdf". Please read LICENSE and README files before using it. +// The above files and the present reference are part of the software itself, +// and cannot be removed from it. +// +package simu5g.simulations.NR.mec.requestResponseApp; + +import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; +import inet.networklayer.ipv4.RoutingTableRecorder; +import inet.node.ethernet.Eth10G; +import inet.node.inet.Router; +import inet.node.inet.StandardHost; +import simu5g.common.binder.Binder; +import simu5g.common.carrierAggregation.CarrierAggregation; +import simu5g.nodes.Upf; +import simu5g.nodes.mec.MECHost; +import simu5g.nodes.mec.MECOrchestrator.MecOrchestrator; +import simu5g.nodes.mec.UALCMP.UALCMP; +import simu5g.nodes.NR.gNodeB; +import simu5g.nodes.NR.NRUe; +import simu5g.nodes.backgroundCell.BackgroundCell; +import simu5g.world.radio.LteChannelControl; + +// MultiMecHost +// +// This network includes two gNBs and two MEC hosts +// +network MultiMecHost_delay +{ + parameters: + int numUe = default(1); + int numBgCells = default(0); + double routersDelay @unit(m) = default(0m); +// volatile double routersDelay @unit(m) = default(normal(2m, 0.8m)); + + @display("i=block/network2;bgb=1088.032,678.896;");//bgi=background/pisa"); + submodules: + channelControl: LteChannelControl { + @display("p=50,25;is=s"); + } + routingRecorder: RoutingTableRecorder { + @display("p=50,75;is=s"); + } + configurator: Ipv4NetworkConfigurator { + @display("p=50,125"); + } + binder: Binder { + @display("p=50,175;is=s"); + } + carrierAggregation: CarrierAggregation { + @display("p=50.993748,258.7;is=s"); + } + upf: Upf { + @display("p=495,132.405"); + } + iUpf1: Upf { + @display("p=400,247.06499"); + } + iUpf2: Upf { + @display("p=590,247.06499"); + } + gnb1: gNodeB { + @display("p=283.91998,421.785;is=vl"); + } + gnb2: gNodeB { + @display("p=749.385,397.215;is=vl"); + } + bgCell[numBgCells]: BackgroundCell { + @display("p=79.17,576.02997;is=vl"); + } + ue[numUe]: NRUe { + @display("p=353.535,481.845"); + } + + //# MEC modules + mecHost1: MECHost { + @display("p=248.43,247.06499"); + } + mecHost2: MECHost { + @display("p=748.01996,247.06499"); + } + mecOrchestrator: MecOrchestrator { + @display("p=749.385,132.405"); + } + ualcmp: UALCMP { + @display("p=603.33,131.04"); + } + + connections: + + //# 5G Core Network connections + upf.pppg++ <--> Eth10G <--> iUpf1.pppg++; + upf.pppg++ <--> Eth10G <--> iUpf2.pppg++; + iUpf1.pppg++ <--> Eth10G <--> gnb1.ppp; + iUpf2.pppg++ <--> Eth10G <--> gnb2.ppp; + iUpf2.pppg++ <--> Eth10G { length = parent.routersDelay*2e5; } <--> iUpf1.pppg++; + + + //# MEC-related connections + ualcmp.ppp++ <--> Eth10G <--> upf.filterGate; + ualcmp.toMecOrchestrator --> mecOrchestrator.fromUALCMP; + ualcmp.fromMecOrchestrator <-- mecOrchestrator.toUALCMP; + mecHost1.ppp++ <--> Eth10G <--> iUpf1.pppg++; + mecHost2.ppp++ <--> Eth10G <--> iUpf2.pppg++; + + + +} diff --git a/simulations/NR/mec/requestResponseApp/demo.xml b/simulations/NR/mec/requestResponseApp/demo.xml new file mode 100644 index 000000000..ac37471cb --- /dev/null +++ b/simulations/NR/mec/requestResponseApp/demo.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simulations/NR/mec/requestResponseApp/omnetpp.ini b/simulations/NR/mec/requestResponseApp/omnetpp.ini new file mode 100644 index 000000000..af8995772 --- /dev/null +++ b/simulations/NR/mec/requestResponseApp/omnetpp.ini @@ -0,0 +1,261 @@ +[General] +image-path=../../../images +output-scalar-file-append = false +**.routingRecorder.enabled = false + +############### Statistics ################## +output-scalar-file = ${resultdir}/${configname}/${configname}-${iterationvars}-${repetition}.sca +output-vector-file = ${resultdir}/${configname}/${configname}-${iterationvars}-${repetition}.vec +seed-set = ${repetition} +num-rngs = 3 +repeat = 31 +**.sctp.**.scalar-recording = false # remove annoying statistics from SCTP +**.sctp.**.vector-recording = false # remove annoying statistics from SCTP +**.mecHost*.**.vector-recording = true +**.ue[*].app[1].**.vector-recording = true +**.vector-recording = false + +warmup-period = 10s + +############### SCTP configuration ################## +**.sctp.nagleEnabled = false # if true, transmission of small packets will be delayed on the X2 +**.sctp.enableHeartbeats = false + +############### General PHY parameters ############## +**.downlink_interference = true +**.uplink_interference = true +**.ueTxPower = 26 +**.eNodeBTxPower = 46 +**.targetBler = 0.01 +**.blerShift = 5 +**.fbPeriod = 40 # reports CQI every 40ms + +############### IPv4 configurator config ################# +*.configurator.config = xmldoc("./demo.xml") + + +#------------------------------------# +# Config MultiMec +# +# General configuration for the for a multicell, multi-MEC system +# +[Config MultiMec] +sim-time-limit=160s +network = simu5g.simulations.NR.mec.requestResponseApp.MultiMecHost_delay + +############# Floorplan parameters ################ +**.mobility.constraintAreaMaxX = 1000m +**.mobility.constraintAreaMaxY = 750m +**.mobility.constraintAreaMinX = 0m +**.mobility.constraintAreaMinY = 250m +**.mobility.constraintAreaMinZ = 0m +**.mobility.constraintAreaMaxZ = 0m +**.mobility.initFromDisplayString = false + +############### CA configuration ################# +*.carrierAggregation.numComponentCarriers = 1 +*.carrierAggregation.componentCarrier[0].numerologyIndex = 0 +*.carrierAggregation.componentCarrier[0].carrierFrequency = 4GHz +*.carrierAggregation.componentCarrier[0].numBands = 50#${numRbs=50} + +*.gnb*.cellularNic.numCarriers = 1 +*.gnb*.cellularNic.channelModel[0].componentCarrierIndex = 0 +*.ue[*].cellularNic.numCarriers = 1 +*.ue[*].cellularNic.nrChannelModel[0].componentCarrierIndex = 0 + +############### BS position ################# +*.gnb1.mobility.initialX = 250m +*.gnb1.mobility.initialY = 500m +*.gnb2.mobility.initialX = 750m +*.gnb2.mobility.initialY = 500m + +############### X2 configuration ################# +#*.gnb*.numX2Apps = 1 # one x2App per peering node +#*.gnb*.x2App[*].server.localPort = 5000 + ancestorIndex(1) # Server ports (x2App[0]=5000, x2App[1]=5001, ...) +#*.gnb1.x2App[0].client.connectAddress = "gnb2%x2ppp0" +#*.gnb2.x2App[0].client.connectAddress = "gnb1%x2ppp0" + +############## UE configuration ################## +*.numUe = 1 + +# UEs associates to the best BS at the beginning of the simulation +*.ue[*].macCellId = 0 +*.ue[*].masterId = 0 +*.ue[*].nrMacCellId = 1 +*.ue[*].nrMasterId = 1 +**.dynamicCellAssociation = false +**.enableHandover = false + +############ UEs position ################# +*.ue[0].mobility.initialX = 280m +*.ue[*].mobility.initialY = 500m + +############ MEC Configuration ############ +**.hasRNISupport = true + +# tcp settings +**.tcp.typename = "Tcp" +**.tcp.advertisedWindow = 65535 # in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) +**.tcp.tcpAlgorithmClass = "TcpReno" # TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl/DumbTcp +**.tcp.sackSupport = true # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.nagleEnabled = false +**.tcp.mss = 1452 + +# MEC Hosts +**.mecHost*.virtualisationInfrastructure.ipv4.forwarding = true +**.mecHost*.vim.scheduling = "fair" +*.mecHost*.maxMECApps = 1000 # max ME Apps to instantiate +*.mecHost*.maxRam = 32GB # max KBytes of Ram +*.mecHost*.maxDisk = 100TB # max KBytes of Disk Space +*.mecHost1.maxCpuSpeed = 330000 # max CPU +*.mecHost2.maxCpuSpeed = 990000 # max CPU + +*.mecHost*.eNBList = "gnb1, gnb2" + +# MEC Services +# MEC host 1 services configurations +*.mecHost1.mecPlatform.numMecServices = 1 +*.mecHost1.mecPlatform.mecService[0].typename = "RNIService" +*.mecHost1.mecPlatform.mecService[0].localAddress = "mecHost1.virtualisationInfrastructure" +*.mecHost1.mecPlatform.mecService[0].localPort = 10020 +*.mecHost1.mecPlatform.serviceRegistry.localAddress = "mecHost1.virtualisationInfrastructure" +*.mecHost1.mecPlatform.serviceRegistry.localPort = 10021 + +# MEC host 2 services configurations +*.mecHost2.mecPlatform.numMecServices = 1 +*.mecHost2.mecPlatform.mecService[0].typename = "RNIService" +*.mecHost2.mecPlatform.mecService[0].localAddress = "mecHost2.virtualisationInfrastructure" +*.mecHost2.mecPlatform.mecService[0].localPort = 10020 +*.mecHost2.mecPlatform.serviceRegistry.localAddress = "mecHost2.virtualisationInfrastructure" +*.mecHost2.mecPlatform.serviceRegistry.localPort = 10021 + +# random number generators configuration +*.mecHost*.mecPlatform.serviceRegistry.rng-0 = 0 # request service time +*.mecHost*.mecPlatform.serviceRegistry.rng-1 = 1 # subscription service time +*.mecHost*.mecPlatform.mecService[0].rng-0 = 1 # request service time +*.mecHost*.mecPlatform.mecService[0].rng-1 = 2 # subscription service time +*.mecHost*.mecPlatform.mecService[0].requestServiceTime = 4ms +*.mecHost*.mecPlatform.mecService[0].subscriptionServiceTime = 11us + +# MEC Orchestrator configuration +*.mecOrchestrator.mecHostList = "mecHost1, mecHost2" # MEC hosts associated to the MEC system +*.mecOrchestrator.mecApplicationPackageList = "ResponseApp" # List of MEC app descriptors to be onboarded at +*.mecHost*.mecPlatformManager.mecOrchestrator = "mecOrchestrator" # the MECPM needs to know the MEC orchestrator + + +############# Client App configuration ################ + +#------------UEWarningAlertApp--------------- +*.ue[*].numApps = 2 +*.ue[*].app[0].typename = "DeviceApp" +*.ue[*].app[0].localPort = 4500 +*.ue[*].app[0].UALCMPAddress = "ualcmp" +*.ue[*].app[0].UALCMPPort = 1000 +*.ue[*].app[0].appPackageSource = "ApplicationDescriptors/ResponseApp.json" + +*.ue[*].app[1].typename = "UERequestApp" +*.ue[*].app[1].deviceAppAddress = "ue["+string(ancestorIndex(1))+"]" +*.ue[*].app[1].deviceAppPort = 4500 +*.ue[*].app[1].startTime = 5s +*.ue[*].app[1].stopTime = 190s + +*.ue[*].app[1].positionX = 600 +*.ue[*].app[1].positionY = 600 +#------------------------------------# + +*.routersDelay = 2m# ${delay = 1ms, 5ms, 10ms} + +# Do not use the following configurations! +[Config nearRNI] +extends = MultiMec +*.mecHost2.mecPlatform.numMecServices = 0 + +[Config farRNI] +extends = MultiMec +*.mecHost1.mecPlatform.numMecServices = 0 + +[Config lightTask] +**.minInstructions = 20000 +**.maxInstructions = 40000 + +[Config heavyTask] +**.minInstructions = 5000000 +**.maxInstructions = 6000000 + +[Config bgUEs_gnb1] +extends = MultiMec +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].mobility.initialX = uniform(100m,500m) +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].mobility.initialY = uniform(250m,750m) + +# --- Background UEs in the central cell --- # +*.gnb1.cellularNic.bgTrafficGenerator[0].enablePeriodicCqiUpdate = true +*.gnb1.cellularNic.bgTrafficGenerator[0].useProbabilisticCqi = true#${probCqi=false} +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].trafficGeneratorType = "TrafficGeneratorCbr" +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.startTimeDl = uniform(0s,0.05s) +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.packetSizeDl = 250B +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.startTimeUl = uniform(0s,0.05s) +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.packetSizeUl = 200B +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.periodDl =uniform(100ms,150ms) +*.gnb1.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.periodUl =uniform(100ms,150ms) + +[Config bgUEs_gnb2] +extends = MultiMec +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].mobility.initialX = uniform(100m,500m) +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].mobility.initialY = uniform(250m,750m) + +# --- Background UEs in the central cell --- # +*.gnb2.cellularNic.bgTrafficGenerator[0].enablePeriodicCqiUpdate = true +*.gnb2.cellularNic.bgTrafficGenerator[0].useProbabilisticCqi = true#${probCqi=false} +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].trafficGeneratorType = "TrafficGeneratorCbr" +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.startTimeDl = uniform(0s,0.05s) +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.packetSizeDl = 50B +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.startTimeUl = uniform(0s,0.05s) +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.packetSizeUl = 10B +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.periodDl =uniform(100ms,200ms) +*.gnb2.cellularNic.bgTrafficGenerator[0].bgUE[*].generator.periodUl =uniform(100ms,200ms) + +[Config nearRNI_bgUEs_gnb1] +extends = bgUEs_gnb1 , nearRNI + +[Config nearRNI_bgUEs_gnb2] +extends = bgUEs_gnb2 , nearRNI +# ----------------------------------------------------- + +# Use only the following configurations! +[Config best_case] +extends = nearRNI, bgUEs_gnb1, bgUEs_gnb2 +*.mecOrchestrator.selectionPolicy = "MecServiceBased"#MecServiceBased or AvailableResourcesBased + +*.gnb1.cellularNic.bgTrafficGenerator[0].numBgUes = ${numBgUEs1= 50, 100..650 step 50} +*.mecHost1.numBGMecApp = ${numBgUEs1} + +*.gnb2.cellularNic.bgTrafficGenerator[0].numBgUes = ${numBgUEs2= 50} +*.mecHost2.numBGMecApp = ${numBgUEs2} + +[Config best_case_load_gen] +extends = best_case +*.mecHost*.mecPlatform.mecService[0].loadGenerator = true +*.mecHost*.mecPlatform.mecService[0].betaa = 0.34 +#*.mecHost.mecPlatform.mecService[0].numBGApps = ${numApp = 10, 100, 200, 400, 600, 800, 1000, 2000} +*.mecHost*.mecPlatform.mecService[0].numBGApps = ${numBgUEs1} +*.mecHost*.mecPlatform.mecService[0].requestServiceTime = 0.5ms + +[Config worst_case] +extends = nearRNI, bgUEs_gnb1, bgUEs_gnb2 +*.mecOrchestrator.selectionPolicy = "AvailableResourcesBased" +#*.mecOrchestrator.mecHostIndex = 1 + +*.gnb2.cellularNic.bgTrafficGenerator[0].numBgUes = ${numBgUEs1= 50}#, 100..650 step 100} +*.mecHost1.numBGMecApp = ${numBgUEs1} + +*.gnb1.cellularNic.bgTrafficGenerator[0].numBgUes = ${numBgUEs2= 50, 100..650 step 50} +*.mecHost2.numBGMecApp = ${numBgUEs2} + +[Config worst_case_load_gen] +extends = worst_case +*.mecHost*.mecPlatform.mecService[0].loadGenerator = true +*.mecHost*.mecPlatform.mecService[0].betaa = 0.34 +#*.mecHost.mecPlatform.mecService[0].numBGApps = ${numApp = 10, 100, 200, 400, 600, 800, 1000, 2000} +*.mecHost*.mecPlatform.mecService[0].numBGApps = ${numBgUEs2} +*.mecHost*.mecPlatform.mecService[0].requestServiceTime = 0.5ms +# ------------------------------------------------------------------------ diff --git a/simulations/NR/mec/requestResponseApp/run b/simulations/NR/mec/requestResponseApp/run new file mode 100644 index 000000000..b7021eeb6 --- /dev/null +++ b/simulations/NR/mec/requestResponseApp/run @@ -0,0 +1,4 @@ +#!/bin/sh +# make sure you run '. setenv' in the Simu5G root directory before running this script + +simu5g $* diff --git a/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc b/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc index d260273c3..13dcb39de 100644 --- a/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc +++ b/src/apps/mec/MecRequestResponseApp/MECResponseApp.cc @@ -77,6 +77,7 @@ void MECResponseApp::handleProcessedMessage(cMessage *msg) { if (!msg->isSelfMessage()) { if (ueAppSocket_.belongsToSocket(msg)) { + EV << "MECResponseApp::handleProcessedMessage: received message from UE" << endl; inet::Packet* packet = check_and_cast(msg); auto req = packet->peekAtFront(); if(req->getType() == UEAPP_REQUEST) @@ -116,6 +117,7 @@ void MECResponseApp::handleSelfMessage(cMessage *msg) void MECResponseApp::handleRequest(cMessage* msg) { + EV << "MECResponseApp::handleRequest" << endl; // this method pretends to perform some computation after having //.request some info to the RNI if(currentRequestfMsg_ != nullptr) @@ -130,6 +132,7 @@ void MECResponseApp::handleRequest(cMessage* msg) void MECResponseApp::handleStopRequest(cMessage* msg) { + EV << "MECResponseApp::handleStopRequest" << endl; serviceSocket_->close(); } void MECResponseApp::sendResponse() diff --git a/src/apps/mec/MecRequestResponseApp/UERequestApp.cc b/src/apps/mec/MecRequestResponseApp/UERequestApp.cc index 8c32b9976..f3e7bbf1e 100644 --- a/src/apps/mec/MecRequestResponseApp/UERequestApp.cc +++ b/src/apps/mec/MecRequestResponseApp/UERequestApp.cc @@ -40,6 +40,8 @@ UERequestApp::~UERequestApp() { cancelAndDelete(selfStart_); cancelAndDelete(selfStop_); + cancelAndDelete(unBlockingMsg_); + cancelAndDelete(sendRequest_); } void UERequestApp::initialize(int stage) @@ -255,6 +257,7 @@ void UERequestApp::handleAckStopMECRequestApp(cMessage* msg) void UERequestApp::sendRequest() { + EV << "UERequestApp::sendRequest()" << endl; inet::Packet* pkt = new inet::Packet("RequestResponseAppPacket"); auto req = inet::makeShared(); req->setType(UEAPP_REQUEST); From 844960802a04180f7df5878c5d736cbc724d7b71 Mon Sep 17 00:00:00 2001 From: linofex Date: Wed, 3 Aug 2022 12:14:56 +0200 Subject: [PATCH 7/8] minor fix --- simulations/NR/mec/multiMecHost/omnetpp.ini | 6 ++++-- .../mec/MECPlatform/MECServices/RNIService/RNIService.ned | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/simulations/NR/mec/multiMecHost/omnetpp.ini b/simulations/NR/mec/multiMecHost/omnetpp.ini index ed23730c9..6a870bd41 100644 --- a/simulations/NR/mec/multiMecHost/omnetpp.ini +++ b/simulations/NR/mec/multiMecHost/omnetpp.ini @@ -134,7 +134,7 @@ network = simu5g.simulations.NR.mec.multiMecHost.MultiMecHost # MEC Services # MEC host 1 services configurations -*.mecHost1.mecPlatform.numMecServices = 1 +*.mecHost1.mecPlatform.numMecServices = 0 *.mecHost1.mecPlatform.mecService[0].typename = "LocationService" *.mecHost1.mecPlatform.mecService[0].localAddress = "mecHost1.virtualisationInfrastructure" *.mecHost1.mecPlatform.mecService[0].localPort = 10020 @@ -143,7 +143,7 @@ network = simu5g.simulations.NR.mec.multiMecHost.MultiMecHost # MEC host 2 services configurations -*.mecHost2.mecPlatform.numMecServices = 0 +*.mecHost2.mecPlatform.numMecServices = 1 *.mecHost2.mecPlatform.mecService[0].typename = "LocationService" *.mecHost2.mecPlatform.mecService[0].localAddress = "mecHost2.virtualisationInfrastructure" *.mecHost2.mecPlatform.mecService[0].localPort = 10020 @@ -160,6 +160,8 @@ network = simu5g.simulations.NR.mec.multiMecHost.MultiMecHost # MEC Orchestrator configuration *.mecOrchestrator.mecHostList = "mecHost1, mecHost2" # MEC hosts associated to the MEC system +*.mecOrchestrator.selectionPolicy = "MecHostBased" +*.mecOrchestrator.mecHostIndex = 1 *.mecOrchestrator.mecApplicationPackageList = "WarningAlertApp" # List of MEC app descriptors to be onboarded at *.mecHost*.mecPlatformManager.mecOrchestrator = "mecOrchestrator" # the MECPM needs to know the MEC orchestrator diff --git a/src/nodes/mec/MECPlatform/MECServices/RNIService/RNIService.ned b/src/nodes/mec/MECPlatform/MECServices/RNIService/RNIService.ned index dab6ded7c..adc5f8857 100644 --- a/src/nodes/mec/MECPlatform/MECServices/RNIService/RNIService.ned +++ b/src/nodes/mec/MECPlatform/MECServices/RNIService/RNIService.ned @@ -35,7 +35,7 @@ simple RNIService like IMECService, IApp int numBGApps = default(0); // used only if loadGenerator is true - string serverThreadClass = default("simu5g.nodes.mec.MEPlatform.MeServices.MeServiceBase.SocketManager"); + string serverThreadClass = default("simu5g.nodes.mec.MECPlatform.MECServices.MECServiceBase.SocketManager"); string serviceName = default("RNIService"); string serviceVersion = default("v2"); @@ -57,6 +57,8 @@ simple RNIService like IMECService, IApp @display("i=block/app"); @signal[requestQueueSize]; @statistic[requestQueueSizeStat](title="Request queue size"; source="requestQueueSize"; record=mean,vector); + @signal[responseTime]; + @statistic[responseTimeStat](title="Response time of foreground requests"; source="responseTime"; record=mean,vector); gates: input socketIn @labels(TcpCommand/up); From f9024a70837d8d0d21f5297ca488b995386e69ed Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Wed, 3 Aug 2022 15:34:25 +0200 Subject: [PATCH 8/8] update mec fingerprints --- .../MecRequestBackgroundGeneratorApp.cc | 2 +- src/nodes/mec/utils/httpUtils/httpUtils.cc | 3 --- tests/fingerprint/mec/mec.csv | 4 ++-- tests/fingerprint/mec/mec_wResults.csv | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc index 4a5a3c53e..399d80cb5 100644 --- a/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc +++ b/src/apps/mec/MecApps/MecRequestBackgroundGeneratorApp/MecRequestBackgroundGeneratorApp.cc @@ -67,7 +67,7 @@ void MecRequestBackgroundGeneratorApp::established(int connId) } else { - throw cRuntimeError("MecRequestBackgroundGeneratorApp::socketEstablished - Socket %s not recognized", connId); + throw cRuntimeError("MecRequestBackgroundGeneratorApp::socketEstablished - Socket %d not recognized", connId); } } diff --git a/src/nodes/mec/utils/httpUtils/httpUtils.cc b/src/nodes/mec/utils/httpUtils/httpUtils.cc index 87cea27d5..2594c667b 100644 --- a/src/nodes/mec/utils/httpUtils/httpUtils.cc +++ b/src/nodes/mec/utils/httpUtils/httpUtils.cc @@ -356,7 +356,6 @@ namespace Http { std::string delimiter = "\r\n\r\n"; size_t pos = 0; std::string header; - int remainingData; bool completeMsg = false; // continue receiving the message @@ -364,7 +363,6 @@ namespace Http { { // EV << "MecAppBase::parseReceivedMsg - Continue receiving data for the current HttpMessage" << endl; Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); - double time; switch (res) { case (Http::COMPLETE_NO_DATA): @@ -420,7 +418,6 @@ namespace Http { *currentHttpMessage = Http::parseHeader(header); Http::HttpMsgState res = Http::parseTcpData(&packet, *currentHttpMessage); - double time; switch (res) { case (Http::COMPLETE_NO_DATA): diff --git a/tests/fingerprint/mec/mec.csv b/tests/fingerprint/mec/mec.csv index 664e6f450..c8922c054 100644 --- a/tests/fingerprint/mec/mec.csv +++ b/tests/fingerprint/mec/mec.csv @@ -1,4 +1,4 @@ # workingdir, args, simtimelimit, fingerprint, -/simulations/NR/mec/singleMecHost, -f omnetpp.ini -c SingleMec -r 0, 20s, e520-1cbb/tlx,PASS, -/simulations/NR/mec/multiMecHost, -f omnetpp.ini -c MultiMec -r 0, 20s, 6af1-67fa/tlx,PASS, +/simulations/NR/mec/singleMecHost, -f omnetpp.ini -c SingleMec -r 0, 20s, 105e-03d6/tlx,PASS, +/simulations/NR/mec/multiMecHost, -f omnetpp.ini -c MultiMec -r 0, 20s, 4cf8-bd34/tlx,PASS, /simulations/NR/mec/RNIDelay, -f omnetpp.ini -c Test -r 0, 5s, eadb-62b5/tlx,PASS, diff --git a/tests/fingerprint/mec/mec_wResults.csv b/tests/fingerprint/mec/mec_wResults.csv index 60e7940df..4084a9815 100644 --- a/tests/fingerprint/mec/mec_wResults.csv +++ b/tests/fingerprint/mec/mec_wResults.csv @@ -1,4 +1,4 @@ # workingdir, args, simtimelimit, fingerprint, -/simulations/NR/mec/singleMecHost, -f omnetpp.ini -c SingleMec -r 0, 20s, 761f-9909/s,PASS, -/simulations/NR/mec/multiMecHost, -f omnetpp.ini -c MultiMec -r 0, 20s, 30ca-1292/s,PASS, +/simulations/NR/mec/singleMecHost, -f omnetpp.ini -c SingleMec -r 0, 20s, 01d5-fbcc/s,PASS, +/simulations/NR/mec/multiMecHost, -f omnetpp.ini -c MultiMec -r 0, 20s, 3846-7943/s,PASS, /simulations/NR/mec/RNIDelay, -f omnetpp.ini -c Test -r 0, 5s, 5c1d-c27c/s,PASS,