riebl / artery

OMNeT++ V2X simulation framework for ETSI ITS-G5
GNU General Public License v2.0
203 stars 131 forks source link

Transfusion function #230

Closed raul-parada closed 1 year ago

raul-parada commented 2 years ago

Hi,

As I've read in section 12.5 from the "Artery: Large Scale Simulation Enrionment for ITS Applications". Using the function "artery.transfusion.TransfusionService" it is possible to send V2X messages to external devices via TCP/IP. I've seen an example inside scenarios folder "transfusion" where inside omnetpp.ini file there is a line with remote port == 33080. That means CA messages can be checked sniffing such port (using Wireshark)? Messages goes to localhost? I would like to send the generated CA and DEN messages to an external machine (could be a VM with specific IP).

Thanks!

riebl commented 2 years ago

TransfusionService has been designed to attach an external application easily via TCP/IP. Such an external application simply has to send TransfusionMsg (encoded by Protobuf) to the TransfusionService of Artery; the ITS-G5 stack in Artery will then take care that the passed payload is sent according to the passed parameters. You can also equip several vehicles with such a service, however, each needs a distinct TCP port number.

In principle, you can encode whatever message you want as TransfusionMsg's payload, including CAMs. Since Wireshark does not understand the Protobuf TransfusionMsg, however, it cannot dissect those packets: You will just the plain bytes.

raul-parada commented 2 years ago

Should I specify inside TransfusionService.h the content of the CAM message (p.e. ASN1)? If my destination is VM where Vanetza is running, how should I set up the TransfusionMsg?

riebl commented 2 years ago

I suggest that your modified TransfusionService subscribes to either the "CamReceived" (if you want to forward received CAMs) or "CamSent" (if you want to forward the CAMs generated by the hosting vehicle) signal emitted by the CaService. Those signals convey a CaObject containing the full vanteza::asn1::Cam, which can be serialized to bytes (see vanetza::ByteBuffer).

raul-parada commented 2 years ago

Ok. I've seen how both services CamReceivedand CamSentare defined inside CaService.cc static const simsignal_t scSignalCamReceived = cComponent::registerSignal("CamReceived"); static const simsignal_t scSignalCamSent = cComponent::registerSignal("CamSent");. However, how do I subscribe to CamSentwithintransfusionService.h file?

riebl commented 2 years ago

See the ExampleService, which subscribes to CAMs received by its sibling CaService: https://github.com/riebl/artery/blob/bc7013066c2f00aa84324d71cf0a9e9ffdf07b00/src/artery/application/ExampleService.cc#L57

The reception of a CAM is then handled here: https://github.com/riebl/artery/blob/bc7013066c2f00aa84324d71cf0a9e9ffdf07b00/src/artery/application/ExampleService.cc#L113-L116 You can cast the cObject* passed to receiveSignal to a CaObject* and get thus full access to the received CA message structure.

raul-parada commented 2 years ago

I've C&P the files ExampleService.cc /.h and /.ned inside my scenario project, modified the file CMakeLists.txt with line add_artery_feature(ctc ExampleService.cc). It compiles perfectly. I guess I need to set up the destination IP to the Vanetza environment in order to receive the CAM messages, right? otherwise, how can I visualize the CAMs content?

riebl commented 2 years ago

Yes, the remote_ip parameter of the TransfusionService is the IP address of the external application, e.g. your application based on Vanetza. You may be able to dissect the custom protocol based on Google Protobuf and the TransfusionMsg.proto in Wireshark and attach Wireshark's CAM dissector to the TransfusionMsg's payload. I have never tried this before, though. You can also just print some essential CAM fields in your receiving application to the terminal.

raul-parada commented 2 years ago

I configure the remote IP and execute the scenario. In the Vanetza side I've run a socktap based application using the udp command (previously joined the multicast IP 239.118.122.97. In Artery, I receive UDP frames (50 bytes length) from the Vanetza machine with destination IP 239.118.122.97. However, the Artery machine doesn't look to send any CAM message. Do I need to modify the Wireshark (as you mentioned above) in order to receive it using socktap?

riebl commented 2 years ago

Wireshark should see any sent packets. Without specific configuration, Wireshark may simply not be able to dissect your custom packets properly and just display them as raw bytes.

raul-parada commented 2 years ago

Is there a way to create an standard CAM message accepted by Vanetza (socktap) or Wireshark?

riebl commented 2 years ago

Sure, you can do pretty much do anything because all sources are open and at your hands :-)

Please note that via CaObject you get the CAM but nothing else, i.e. it is not a full ITS-G5 packet but only the CA application layer payload. To be honest, I only vaguely understand what you are trying to achieve ultimately. I may give you better advice with some more details: What is the purpose of the external application? Why does it have to be external anyway? Is the external application just a processor of CAMs or more like network gateway?

raul-parada commented 2 years ago

The main idea is to simulate a collision avoidance service by analysing CAM messages content, mainly, latitude, longitude, vehicle ID and timestamp. We would like to send those messges to an external device acting as RSU. Since we already have a Vanetza-based environment (VM) we can re-use it and simulate a semi real scenario. Try diferent devices to check their performance, etc.

riebl commented 2 years ago

In my understanding of your description, you only need the CAM without any ITS-G5 headers to calculate the collision avoidance risk at the receiver. I assume you have a simulated RSU in Artery, and all CAMs received by this simulated RSU shall be streamed to your external application. My suggestion to realize this CAM streaming is as follows

enot24 commented 1 year ago

Hi @riebl, I've a problem related to trasfusion. I'm working not only on exporting CAM, but also on exporting the enteire packet (including BTP&GN headers). I noticed the emit(scLinkReceptionSignal, packet) in Router.cc and thought that I can exploit this signal to get the packet. https://github.com/riebl/artery/blob/4bc468e372091fa392d43c5fc3358821a21534c9/src/artery/networking/Router.cc#L111 But I see that, in my ExportService, the condition if(signal == scLinkReceptionSignal) isn't triggered, while other condition on signals like scSignalCamReceived/scSignalCamSent work correctly. Of course, I checked that the code where the emit method is located is reached (so the emit should work) and that the declaration of the signal and the related subscription were done.

image

What am I doing wrong?

Thanks

riebl commented 1 year ago

You call the subscribe method provided by the ItsG5BaseService which subscribes to signals emitted by the middleware module or any of its submodules: https://github.com/riebl/artery/blob/4bc468e372091fa392d43c5fc3358821a21534c9/src/artery/application/ItsG5BaseService.cc#L101 Thus, signals emitted by the router never reach the middleware you have subscribed to because they are only propagated "upwards" in the module tree. Calling something like inet::getContainingNode(this)->subscribe(scLinkReceptionSignal, this) in your CaExportService::initialize should do the trick.

PS: Please open a new issue ticket for new issues. Reviving old and closed issue tickets is a bad practice.