background
What about the interactive transmission of a large amount of data (such as images)?
Ah, this is a problem for AP. We need to transfer a lot of binary data between applications and sensors via Ethernet (and high efficiency, such as image transmission for ADAS).
We know that service - oriented communication, such as son's home / IP and DDS (very popular but not used by people) are not very efficient. Because they have long headers.
And some sensors can only send original binary data.
Here, the AP provides an API for transmitting byte streams that do not have a data type format. (transmit video or map data through "Raw data format"). Behind it is the network socket.
This is an alien. It is not Adaptive, that is to say, it is static. Under the namespace of ara::com, but not part of the service middleware.
What are the functions of this API?
Both client and server can be used. Both sides can send and receive. The difference is that the client can only actively find the server to establish a link.
The server can only wait for a link and cannot ask the client to establish a link.
The client can only ask the server to establish a link and cannot wait for the server to connect.
Workflow:
• As client
-
Connect: Establishes connection to sensor
-
ReadData/WriteData: Receives or sends data
-
Shutdown: Connection is closed.
• As server
-
WaitForConnection: Waits for incoming connections from clients
-
ReadData/WriteData: Receives or sends data
-
Shutdown: Connection is closed and stops waiting for connections.
code implementation
class
ara::com::raw defines a set of classes to interact.
client: ara::com::raw::RawDataStreamClient
server: ara::com::raw::RawDataStreamServer
Constructor:
RawDataStreamClient(const ara::com::InstanceSpecifier& instance);
RawDataStreamServer(const ara::com::InstanceSpecifier& instance);
The parameter is a binding descriptor. (old friend).
Destructor:
~RawDataStreamClient();
~RawDataStreamServer();
Manifest
Describes the deployment information of raw data transmission
-
The specific transmission method used by RawDataStreamMapping
-
The communication connector (Ethernet communication connector) defines the IP address.
-
socketOption defines some socket configurations (non-standard) that are valid for a specific platform
Theoretically, this API can mobilize any layer of transmission protocol to transmit data (now only TCP and UDP are used). (I might as well use TCP/UDP directly. Oh, it's not AUTOSAR. Sorry)
Positive integer parameters available for subclass EthernetRawDataStreamMapping:
-
multicastUdpPort
-
tcpPort
-
udpPort
At least one of the above three parameters is required.
EthernetRawDataStreamMapping also has security related parameters:
tlsSecureComProps
Class method
Timeout parameter
All methods take an optional timeout parameter. The type is std::chrono::milliseconds.
If you do not feed this parameter or write 0, the class method will block before returning.
If there are parameters, the method will return a timeout error after timeout.
methods
All methods are synchronous API s. The returned results are described in the previous section.
WaitForConnection
Dedicated to the server. After calling, start waiting for the server to connect.
Connect
Client side dedicated.
This method initializes the socket and then establishes a link with the TCP server.
For UDP, no link will be established. Incoming and outgoing packets are restricted to specific addresses.
ara::core:Result<void> Connect(); ara::core:Result<void> Connect(std::chrono::milliseconds timeout);
Shutdown
Turn off communication.
Both client and server can be used.
ara::core:Result<void> Shutdown(); ara::core:Result<void> Shutdown(std::chrono::milliseconds timeout);
ReadData
Read data from socket. The number of bytes read is input as a parameter. Delay optional.
ara::core::Result<ReadDataResult> ReadData(size_t length); ara::core::Result<ReadDataResult> ReadData(size_t length, std::chrono::milliseconds timeout);
If the execution is successful, a structure is returned, including a pointer to the read data and the data length.
struct ReadDataResult{ ara::com::SamplePtr<uint8_t> data; size_t numberOfBytes; }
If it fails, return ara::core::ErrorCode. Communication is not established or timed out.
WriteData
Write data to socket.
ara::core:Result<size_t> WriteData(ara::com::SamplePtr<uint8_t> data, size_t length); ara::core:Result<size_t> WriteData(ara::com::SamplePtr<uint8_t> data, size_t length, std::chrono::milliseconds timeout);
If the call is successful, the number of bytes successfully sent will be returned. If it fails, return ara::core::ErrorCode. As above.
Use example
RawDataStreamServer
// NOTE! For simplicity the example does not use ara::core::Result. #include "ara/core/instance_specifier.h" #include "raw_data_stream.h" int main() { size_t rval; ara::com::raw::RawDataStream::ReadDataResult result; // Instance Specifier from model ara::core::InstanceSpecifier instspec {...} // Create RawDataStream Server instance ara::com::raw::RawDataStreamServer server{instspec}; // Wait for incoming connections server.WaitForConnection(); // Read data from the RawData stream in chunks of 10 bytes do{ result = server.ReadData(10); rval = result.numberOfBytes; if (rval > 0) { // assumes the data is printable std::cout << "-->" << result.data.get() << std::endl; } } while (rval > 0); // Write data to the RawData stream in chunks of 16 bytes int i=0; do{ std::unique_ptr<uint8_t> write_buf (new uint8_t[1024] \{....}); rval = server.WriteData(std::move(write_buf), 16); ++i; }while (i<1000); // Shutdown RawDataStream connection server.Shutdown(); return 0; }
RawDataStreamClient
// NOTE! For simplicity the example does not use ara::core::Result. #include "ara/core/instance_specifier.h" #include "raw_data_stream.h" int main() { size_t rval; ara::com::raw::RawDataStream::ReadDataResult result; // Instance Specifier from model ara::core::InstanceSpecifier instspec {...} // Create a RawDataStreamClient instance ara::com::raw::RawDataStreamClient client {instspec}; // Connect to RawDataStream Server client.Connect(); // Write data to RawData stream in chunks of 40 bytes int i=0; do { std::unique_ptr<uint8_t> write_buf (new uint8_t[1024]{.....}); rval = client.WriteData(std::move(write_buf), 40); ++i; } while (i<1000); // Read data from the RawData stream in chunks of 4 bytes do { result = client.ReadData(4); rval = result.numberOfBytes; if (rval > 0){ // assumes the data is printable std::cout << "-->" << result.data.get() << std::endl; } } while (rval > 0); // Shutdown RawDataStream connection client.Shutdown(); return 0; }
Security
Currently the security protocols TLS, DTLS and IPSec are available.
Access control to Raw Data Streams can also be defined by the IAM.
All security functions are configurable in the deployment and mapping model of Raw Data Streaming Interface.
Information security: raw data itself does not contain format. If information security is concerned, I think it needs to be encrypted and decrypted in the Application.