Unipisa / Simu5G

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

Multiple MEC applications recursively #49

Closed juansebastiani2cat closed 2 years ago

juansebastiani2cat commented 2 years ago

Hello,

I'm testing an scenario with multiple MEC hosts and a couple of MEC Orchestrators and I need to instantiate a high amount of MEC applications. For a few number of Apps, I would just create an app descriptor in JSON with the characteristics of the App and then import it with the rest of the app's parameters:

*.car[*].app[1].typename = "UEWarningAlertApp"
*.car[*].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[*].app[1].deviceAppPort = 4500
*.car[*].app[1].startTime = 1s                                      
*.car[*].app[1].stopTime = 30s                                      

However, doing this for more than a handful of apps is tedious and error-prone. I was planning on doing it recursively, creating a loop cycle and changing the app parameters and start-stop time for each of the apps, but I don't think this can be done in the .ini file.

Could you give me some advice on how to instantiate a high number of MEC apps recursively please?

Thanks a lot for your time and answers.

linofex commented 2 years ago

Hi, If I understood your question, the only thing it comes to my mind is that you can use range values to select subsets of the applications. For example: suppose you have 100 car modules, you could configure the first 25, then the others 25 and so on in this way:

*.car[0..24].app[1].typename = "UEWarningAlertApp"
*.car[0..24].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0..24].app[1].deviceAppPort = 4500
*.car[0..24].app[1].startTime = 1s                                      
*.car[0..24].app[1].stopTime = 30s      

*.car[25..50].app[1].typename = "UECustomApp"
*.car[25..50].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[25..50].app[1].deviceAppPort = 4500
*.car[25..50].app[1].startTime = 3s                                     
*.car[25..50].app[1].stopTime = 20s     

# from 51 to 100 
*.car[51..]app[1].typename = "UECustomAppB"  
*.car[51..].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[51..].app[1].deviceAppPort = 4500
*.car[51..].app[1].startTime = 23s                                      
*.car[51..].app[1].stopTime = 60s   

See more in the OMNeT++ manual.

Maybe this doesn't answer your question, but it can speed up your configuration

AN

juansebastiani2cat commented 2 years ago

Hello, thanks for your answer.

Well, yeah that was my question, but then, there's no way to do it "automatically" with an small script. I'm going to have to write all the apps instantiation orders one by one apparently.

linofex commented 2 years ago

The first rough idea that comes to my mind could be writing a script (e.g in python) that generates the following lines

*.car[51..]app[1].typename = "UECustomAppB"  
*.car[51..].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[51..].app[1].deviceAppPort = 4500
*.car[51..].app[1].startTime = 23s                                      
*.car[51..].app[1].stopTime = 60s   

according to some arguments and then copypaste the output in the ini file.

giovanninardini commented 2 years ago

The first rough idea that comes to my mind could be writing a script (e.g in python) that generates the following lines

*.car[51..]app[1].typename = "UECustomAppB"  
*.car[51..].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[51..].app[1].deviceAppPort = 4500
*.car[51..].app[1].startTime = 23s                                        
*.car[51..].app[1].stopTime = 60s 

according to some arguments and then copypaste the output in the ini file.

Just to complete @linofex’s answer… instead of copy-pasting, you can use the script to generate the above lines and output them to a INI file, e.g., applications.ini. Then, from the omnetpp.ini file you can include the former: include applications.ini

juansebastiani2cat commented 2 years ago

Ok, thanks for your answer. I have written the python program and included the output in the configuration.ini of the simulation, and it works great.

However, I have found an issue. The code I have generated is the following:

*.car[0].numApps = 3

*.car[0].app[0].typename = "DeviceApp"
*.car[0].app[0].localPort = 4500
*.car[0].app[0].UALCMPAddress = "ualcmp"
*.car[0].app[0].UALCMPPort = 1000
*.car[0].app[0].appPackageSource = "ApplicationDescriptors/WarningAlertApp.json"

*.car[0].app[1].typename = "UEWarningAlertApp"
*.car[0].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[1].deviceAppPort = 4500
*.car[0].app[1].startTime = 1.1s
*.car[0].app[1].stopTime = 30s

*.car[0].app[2].typename = "UEWarningAlertApp"
*.car[0].app[2].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[2].deviceAppPort = 4500
*.car[0].app[2].startTime = 2s
*.car[0].app[2].stopTime = 30s

My idea is to create several applications (hence, the need for recursivity) over the same car so that I don't end up with a bunch of different car UEs with one application each. However, when I run the code, I get the following error:

bind: local address/port <none>:4000 already taken -- in module (inet::Udp) MecTwoMecHosts.car[0].udp (id=138), at t=0s, event #10

I have tried changing the port number of each application but the error code remains the same.

linofex commented 2 years ago

port 4000 is the default local port of the UEWarningAlertApp parameter: int localPort = default(4000);. In the configuration you generated, car[0] has two apps of the "UEWarningAlertApp". None of them set the "localPort" parameter and so both have the default value, i.e. 4000. You can't bind two different sockets to the same port. To solve you have to set a different port number to one of the two apps, like *.car[0].app[2].localPort = 4001

juansebastiani2cat commented 2 years ago

Ok thanks. Now the simulation runs, but it only instantiates the first application that is requested, for example:

*.car[0].app[0].typename = "DeviceApp"
*.car[0].app[0].localPort = 4500
*.car[0].app[0].UALCMPAddress = "ualcmp"
*.car[0].app[0].UALCMPPort = 1000
*.car[0].app[0].appPackageSource = "ApplicationDescriptors/WarningAlertApp.json"

*.car[0].app[1].typename = "UEWarningAlertApp"
*.car[0].app[1].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[1].deviceAppPort = 4500
*.car[0].app[1].localPort = 4501
*.car[0].app[1].startTime = 1s
*.car[0].app[1].stopTime = 30s

*.car[0].app[2].typename = "UEWarningAlertApp"
*.car[0].app[2].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[2].deviceAppPort = 4500
*.car[0].app[2].localPort = 4502
*.car[0].app[2].startTime = 2s
*.car[0].app[2].stopTime = 30s

In this code, it would only ask the MEC Orchestrator for instantiating the app[1] at time = 1s. At time = 2s, I was expecting for the App to generate a request for instantiation to the MEC Orchestrator again, but it doesn't do anything. I am trying to instantiate several apps into the MEC Orchestrator and that's why I need it to request the instantiation at different times.

Thanks a lot for your help

linofex commented 2 years ago

The current implementation only allows one-to-one device app - ue app "connection". If you want that a single ue instantiates more than one MEC app, you have to add a "device app" for each of them.

juansebastiani2cat commented 2 years ago

Ok I think I have it. So, the next code generates three apps over the same car and they are properly instantiated on the MEC Orchestrator at the correct times:

*.car[0].numApps = 6
*.car[0].app[0].typename = "DeviceApp"
*.car[0].app[0].localPort = 4500
*.car[0].app[0].UALCMPAddress = "ualcmp"
*.car[0].app[0].UALCMPPort = 1000
*.car[0].app[0].appPackageSource = "ApplicationDescriptors/WarningAlertApp.json"

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

*.car[0].app[2].typename = "DeviceApp"
*.car[0].app[2].localPort = 4501
*.car[0].app[2].UALCMPAddress = "ualcmp"
*.car[0].app[2].UALCMPPort = 1000
*.car[0].app[2].appPackageSource = "ApplicationDescriptors/WarningAlertApp.json"

*.car[0].app[3].typename = "UEWarningAlertApp"
*.car[0].app[3].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[3].deviceAppPort = 4501
*.car[0].app[3].localPort = 4001
*.car[0].app[3].startTime = 3s #when sending start warning alert app #period to sending messages
*.car[0].app[3].stopTime = 30s #when sending stop MEC warning alert app

*.car[0].app[4].typename = "DeviceApp"
*.car[0].app[4].localPort = 4502
*.car[0].app[4].UALCMPAddress = "ualcmp"
*.car[0].app[4].UALCMPPort = 1000
*.car[0].app[4].appPackageSource = "ApplicationDescriptors/WarningAlertApp.json"

*.car[0].app[5].typename = "UEWarningAlertApp"
*.car[0].app[5].deviceAppAddress = "car["+string(ancestorIndex(1))+"]"
*.car[0].app[5].deviceAppPort = 4502
*.car[0].app[5].localPort = 4002
*.car[0].app[5].startTime = 4s #when sending start warning alert app #period to sending messages
*.car[0].app[5].stopTime = 30s #when sending stop MEC warning alert app

The only question I have now is, how are the Device Apps related to the UEWarningAlertApp ?? I mean, they're not using the same port or anything, and they'are all using the same name. So, how can you know that the DeviceApp in app[0] is linked with the UEWarningAlertApp of app[1] (for example) ?

giovanninardini commented 2 years ago

deviceAppAddress and deviceAppPort parameters of the UEWarningAlertApp specify which DeviceApp is associated with it. According to your configuration:

juansebastiani2cat commented 2 years ago

Ok, got it. Thanks a lot for your answers.