Unipisa / Simu5G

Simu5G - 5G NR and LTE/LTE-A user-plane simulation model for OMNeT++ & INET
https://simu5g.org
Other
146 stars 83 forks source link

Measure Delay from Car to multiple MecHosts #71

Closed juansebastiani2cat closed 1 year ago

juansebastiani2cat commented 2 years ago

Dear all,

I am working in a project with multiple MecHosts and a time sensitive application. Using as a base the simulation in singleMecHost.ned, I want to be able to measure the delay from the Car to each of the MEC Hosts. As some issues have suggested, the best method to measure the end-to-end delay is using a timestamp over a VoIP application (As the VoIP application example present in SIMU5G). I want to use this same method, but I'm a bit stuck in the implementation.

My question is, is it possible to instantiate the VoIP application into one of the MEC Hosts instead of the traditional server (As done in the examples)?

If so, could you guide me or provide me some example of how to do it?

Thanks in advance for your help.

linofex commented 1 year ago

Hi @juansebastiani2cat, in response to the question: is it possible to instantiate the VoIP application into one of the MEC Hosts instead of the traditional server (As done in the examples)? The answer is yes.

How to do that The only constraint for deploying a MEC application in a MEC host is that its .ned module must implement the IMECApp module interface (other than the inet IApp). The latter has some parameters set by the VIM module of the MEC host to configure the addresses and ports. If you want make the VoIPReceiver App a MEC app you have only to create a .ned file like the following:

package simu5g.apps.mec.MECVoIPReceiver;

import inet.applications.contract.IApp;
import simu5g.nodes.mec.MECPlatform.IMECApp;
import simu5g.apps.voip.VoIPReceiver;

simple MECVoIPReceiverApp extends VoIPReceiver like IMECApp
{
    parameters:
        @display("i=block/app;is=s");
        @class("VoIPReceiver"); 

        int packetSize = default(10);
        string interfaceTableModule = default("");

        int mecAppIndex;
        int mecAppId;
        int localUePort;
        localPort = localUePort; // VoIP receiver app must bind the socket to the port set by the VIM!

        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

        bool logger = default(false);

    gates:
      input mePlatformIn;
      output mePlatformOut;
}

simple MECVoIPReceiverApp extends VoIPReceiver like IMECApp just creates a module that extends the VoipReceiver app with the IMECApp interface. Note the line (in this example) localPort = localUePort. It is necessary to force the VoipReceiver app to bind the socket (from its localPort parameter) with the value set by the VIM module of the MEC host (loalUePort). Otherwise, if more than one MECVoIPReceiverApp apps were deployed in the same MEC host they would use the same default port. The .h/.cc files of the VoIPReceiver app will be used for the behavior of the app.

The .ned file is saved under apps/mec/MECVoIPReceiver folder (you can choose the folder you prefer).

Then you have to create the Application descriptor as for every MEC App you have. In the same way as for the WarningAlertApp.json, the MECVoIPReceiver.json file is:

{
"appDid" : "VOIPAPP",
"appName" : "MECVoIPReceiverApp",
"appProvider" : "simu5g.apps.mec.MECVoIPReceiver.MECVoIPReceiverApp",
"appInfoName" : "appInfoName_",
"appDescription" : "appDescription_",
"virtualComputeDescriptor" :{
    "virtualDisk": 10,
    "virtualCpu" : 1500,
    "virtualMemory":10
    }
}

This should complete the operations for creating a MEC app from a standart tcp/ip app.

Best regards, Alessandro

juansebastiani2cat commented 1 year ago

Thanks a lot for your answer...I will give it a try and let you know.

juansebastiani2cat commented 1 year ago

Sorry to unearth this after so long, but finally I gave it a try and I'm having some issues:

I did the steps as you suggested, while working under the SingleMecHost example:

  1. Created a folder under Simu5G/src/apps/mec/MECVoIPReceiver/MECVoIPReceiverApp.ned and included the code as you described it before.
  2. Created a new json file under Simu5G/simulations/mec/singleMecHost/ApplicationDescriptors/MECVoIPReceiver.json and also included the json descriptor as you suggested.
  3. Additionally, I modified the SingleMecHost omnetpp.ini as follows:

I configured the VoIPSender app in the UE:

*.ue[*].numApps = 1
*.ue[*].app[0].typename = "VoIPSender"
*.ue[*].app[0].destAddress = "mecHost"
*.ue[*].app[0].destPort = 3000
*.ue[*].app[*].PacketSize = 1000
*.ue[*].app[*].sampling_time = 0.05s
*.ue[*].app[*].localPort = 3088
*.ue[*].app[*].startTime = uniform(0.02s, 0.05s)
*.ue[*].app[*].finishTime = 30s
*.ue[*].app[*].tos = 10

Afterward, I configured the MEC Services with the new MECVoIPReceiverApp:

**.mecHost.mecPlatform.numMecServices = 1
**.mecHost.mecPlatform.mecService[0].typename = "MECVoIPReceiverApp"
**.mecHost.mecPlatform.mecService[0].localAddress = "mecHost.virtualisationInfrastructure"
**.mecHost.mecPlatform.mecService[0].localPort = 3000

After trying to run it like that, the simulator asked for additional parameters to configure, so I included all the parameters as needed:

**.mecHost.mecPlatform.mecService[0].mecAppIndex = 1
**.mecHost.mecPlatform.mecService[0].mecAppId = 1
**.mecHost.mecPlatform.mecService[0].localUePort = 3000
**.mecHost.mecPlatform.mecService[0].requiredRam = 1500b
**.mecHost.mecPlatform.mecService[0].requiredDisk = 1000b
**.mecHost.mecPlatform.mecService[0].requiredCpu = 2000

The code runs but it closes right before instantiating the UE application without any visible error (Simulation terminated with exit code: 8b). I'm sure that I'm configuring something wrong, but I cannot see what and there is no error code to guide me. Could you help me with some insights about how to configure the app within the MEC host (and the UE) properly please ? Thanks a lot for your help and again sorry for the delay in my answer.

linofex commented 1 year ago

Hi @juansebastiani2cat. The configuration you described is not correct. The MECVoIPReceiverApp has to be instantiated by the UE via a Device App. Your configuration treats the MECApp as a MEC service. The latter is handled in a different wat by the simulator, so it is possible that some structure is missing and the simulation fails. I suggest you try starting from the simulations/NR/mec/singleMecHost SingleMec example and change the parameters to meet your needs. More in particular this section:

#------------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/WarningAlertApp.json"

*.ue[*].app[1].typename = "UEWarningAlertApp"
*.ue[*].app[1].deviceAppAddress = "ue["+string(ancestorIndex(1))+"]"
*.ue[*].app[1].deviceAppPort = 4500
*.ue[*].app[1].startTime = 1s                                       #when sending start warning alert app                                   #period to sending messages
*.ue[*].app[1].stopTime = 30s   

Let us know, regards

Alessandro

juansebastiani2cat commented 1 year ago

I seem to be a bit confused. I understand that first we need to create a DeviceApp in the UE to be able to communicate with the MEC Host. And then, on the second array (ue[*].app[1] in this example) we actually instantiate the proper UE application. In the example of the VoIP Server, we instantiate two applications (The sender in the UE and the receiver in the server). For me, the following configuration instantiates the "sender in the UE":

#------------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/MECVoIPReceiver.json"

*.ue[*].app[1].typename = "VoIPSender"
*.ue[*].app[1].deviceAppAddress = "ue["+string(ancestorIndex(1))+"]"
*.ue[*].app[1].deviceAppPort = 4500
*.ue[*].app[1].startTime = 1s                                       #when sending start warning alert app                                   #period to sending messages
*.ue[*].app[1].stopTime = 30s                                       #when sending stop MEC warning alert app

But I'm failing to see how the "receiver app" is actually instantiated in the MEC host. My main goal is, in a multi MEC Host topology to send to the MEC Orchestrator the delay from the UE to each of the existing MEC Hosts. Perhaps I'm trying to do an overkill and there's an easier way to do what I need to do.

Thanks a lot for your comments and I hope you could enlighten me in this.

giovanninardini commented 1 year ago

If you are not really interested in instantiating the MEC app on demand, you can also avoid using the "UE app + device app" approach. In the MEC host module you find the independentMecApp vector. Basically, you can implement a MEC app in the MEC host as any other app in a normal server, i.e.:

*.mecHost1.numIndependentMecApp = 1
*.mecHost1.independentMecApp[0] = "VoIPReceiver"
...  
juansebastiani2cat commented 1 year ago

Thanks for your reply. I tested it and I think I'm almost there. I tried the following configuration, but for some reason, when the UE needs to start the app, the simulation crashes:

#============= Application Setup =============
**.numIndependentMecApp = 1
*.mecHost.independentMecApp[0].typename = "VoIPReceiver"
*.mecHost.independentMecApp[0].localPort = 3000+ancestorIndex(0)

*.ue[*].numApps = 1
*.ue[*].app[*].PacketSize = 40
# obtain the address of the client by reading its index in the array of udp Apps
*.ue[*].app[*].destAddress = "mecHost" 
*.ue[*].app[*].localPort = 3088+ancestorIndex(0)
*.ue[*].app[*].typename = "VoIPSender"
*.ue[*].app[*].startTime = uniform(0s,0.02s)
*.ue[*].app[*].sampling_time = 1s
#------------------------------------#

I'm guessing the simulation fails because of the destination address of the UE application, as I have changed it to "server" for example and the simulation doesn't crash. There must be something that I'm not seeing but don't really know what. I have checked the Simu5G/simulations/NR/standalone VoIP project and the configuration is simple enough, so don't really know where the problem might be (beyond using the MecHost instead of a traditional server).

Thanks a lot for your comments and answers.

giovanninardini commented 1 year ago

Try to use "mecHost.virtualisationInfrastructure" as destAddress field.

juansebastiani2cat commented 1 year ago

Ok, now it's working. But I have a question, I managed to get the timestamp of the VoIP Message and subtract it from the current sim time. The issue is that the value is always the same (110 nanoseconds), no matter where the UE was positioned in the map (I was expecting some difference due to transmission or propagation delays). Could you help me understand what's happening please ? is there any way to change the propagation, transmission or queuing delay ?

Thanks a lot for your help in this.

Ali-K-Abbas commented 1 year ago

Hello Dear, @giovanninardini I followed the above Construction and was able to get results with a MEC Cbr App, using the independentMecApp for 1 UE, However when I try to use multiple instances of the independentMecApp to multiple UEs (tested with 2 & 3 UEs) , Results only shows for independentMecApp[0] , below is the parameters I am using for the app in .ini:

#########################_UE Side_#######################
*.ue[*].numApps = 1
*.ue[*].app[0].typename = "CbrSender"
*.ue[*].app[0].destAddress = "mecHost.virtualisationInfrastructure"
*.ue[*].app[0].localPort = 3000+ancestorIndex(0)

*.ue[*].app[0].PacketSize =${Pk=100,300,500,600, 1000}
*.ue[*].app[0].startTime = 0s
#*.ue[*].app[*].sampling_time = 1s
**.ue[*].app[0].finishTime = 38s
#*.ue[*].app[*].startTime = uniform(0s,0.02s)

#------------------------------------#

#============= Application Setup MEC receiver =============
**.numIndependentMecApp = ${nInApps}
*.mecHost.independentMecApp[*].typename = "MecCbrReceiverApp"
*.mecHost.independentMecApp[*].localUePort = 3000#+ancestorIndex(0)
*.mecHost.independentMecApp[*].mecAppIndex = 0
*.mecHost.independentMecApp[*].mecAppId = 0

#*.mecHost.independentMecApp[0].PacketSize = 500

**.numUe = ${nInApps=1,2,3}#,50,100,200}

*.mecHost.independentMecApp[*].requiredRam = 1B
*.mecHost.independentMecApp[*].requiredDisk = 1B
*.mecHost.independentMecApp[*].requiredCpu = 1}