Closed raul-parada closed 1 year 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.
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
?
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
).
Ok. I've seen how both services CamReceived
and CamSent
are 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 CamSent
withintransfusionService.h
file?
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.
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?
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.
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?
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.
Is there a way to create an standard CAM message accepted by Vanetza (socktap) or Wireshark?
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?
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.
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
TransfusionService
, i.e. use the AsioScheduler
and the AsioTask
as shown in TransfusionService
RsuCaService
CamReceived
signals emitted by the RsuCaService
s
receiveSignalhandler for the
CamReceivedsignals sends the byte encoded CAM via
AsioTask::writeto your external application. Tipp:
CaObjectprovides you a
vanetza::asn1::Camobject via its
asn1()method. The
vanetza::asn1::Camobject has an
encodemethod returning a
ByteBuffer`.decode
method of vanetza::asn1::Cam
to decode raw bytes into a CAM data structureTransfusionService
uses TCP as transport protocol, i.e. one needs to mark where single messages start and end in TCP's data stream. TransfusionService
uses this mechanism: The transmitter inserts the number of bytes of the following message as a 32bit integer first, then the actual message. The receiver reads this number and then as many bytes as given by this number. Alternatively, you may switch to UDP.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.
What am I doing wrong?
Thanks
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.
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!