-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Communication layer abstraction for expanding communication properties. #281
Comments
Hi, @erlingrj I would like some insights of this. Marten and Prof. Kim recommended you, because you handled the C code adding different target platforms. |
My initial thought is to make C-style inheritance. It would look like this:
Since the first field of I would then create a "virtual" API for the "abstract"
This would be implemented in the source files for each of different types of ports. E.g. for the socket:
The challenge here becomes the following: "Can you define a common abstract API for all the network types so that they all have the same interface to the LF codebase?" The different network types have different ways of being configured and such, but can all of that be hidden behind a single, network-agnostic API? So, in a sense, I agree with Prof Kim that we should use typecasts, but we should make it elaborate with inheritance and only do the typecasting to e.g. TLS socket inside of tls_socket.c and only include TLS specific header files there. Here is a nice resource for object-oriented programming in C: https://www.state-machine.com/oop |
I totally agree that the largest challenge is as what you mentioned. "Is it possible to have a single API for all the network types". I also think it may not be possible actually, because not only the sending and receiving APIs, there are many different initializing settings to do for each network type. I got your idea of separating each type into different files. Such as
Checking how the platforms works will be great. Thanks! |
Abstract socket layers
In federated execution, currently, many functions are directly using sockets. We plan to separate this by adding an abstract socket layer to simplify programming and enable scaling communication.
Plans
Many functions are handling sockets directly. Instead of passing sockets directly, struct pointers will be passed.
The main functions to be changed are the
read()
andwrite()
functions, which currently looks like this.Instead of directly passing sockets, I will pass a new
struct lf_network_port_t
.struct lf_network_port_t
Each functions will only put the
lf_network_port_t
into each functions, and it represents the destination of the message.The low level child socket inherits
lf_network_port_t
.Each functions are implemented inside the child.c files.
So, the
write()
function would look like this.Inside the
write()
it will write in different ways, by which socket it uses.If it is a normal socket, it would just send messages. If it's a TLS_socket, it will encrypt messages and send it, and if it's a DDS_socket, it will send it using DDS.
File structures
net_util.c
will be moved undernetworks
. Thenetworks
will future include network options such asnet_tls.c
. It is worked on #292.Challenges
1. read and writes
There have to be a lot of changes in the current code to make a
write()
andread()
function to work in multiple communication methods.The main problem is the
read()
function called multiple times, during only onewrite()
. The point is that the current codewrite()
the total buffer at once, but on the other side that receives the message, itread()
in sequences.So example, a federate sends a
MSG_TYPE_TIMESTAMP
message, which is a 9-byte message with one byte message type, and 8 bytes of payload. Then, the RTI first calls theread()
function reading one byte, and then calls theread()
function again reading 8 bytes.There are two problems with this.
2. Will it work for pub-sub protocols?
It may not work for pub-sub based protocols such as MQTT and DDS.
There must be QoS settings to ensure the order of messages.
The full example code of a DDS publisher is in here.
MQTT example code is in here.
Challenges for security
RTI needs to be able to read the message, to get the federate_id.
Does the RTI need to decrypt it? Then does the RTI have every federate’s keys?
Need to handle messages, which are longer than the maximum buffer size 256 bytes.
E.g. Let’s say the message sent was 300 bytes. The message will get encrypted and longer. How do we handle this?
Current functions related to sockets (Yet being updated)
These are the current functions that are using sockets or ports. It is listed in the order of execution of the RTI.
RTI
main()
void initialize_federate(federate_t* fed, uint16_t id)
rti_lib.cint32_t start_rti_server(uint16_t port)
rti_lib.cint create_server(int32_t specified_port, uint16_t port, socket_type_t socket_type)
rti_lib.cint create_real_time_tcp_socket_errexit()
net_util.cvoid wait_for_federates(int socket_descriptor)
rti_lib.cvoid connect_to_federates(int socket_descriptor)
rti_lib.cbool authenticate_federate(int socket)
rti_lib.cssize_t read_from_socket_errexit()
x2 net_util.cssize_t write_to_socket(int socket, size_t num_bytes, unsigned char* buffer)
net_util.cvoid send_reject(int socket_id, unsigned char error_code)
rti_lib.cssize_t write_to_socket_errexit(int socket, size_t num_bytes, unsigned char* buffer, char* format, ...)
net_util.cint32_t receive_and_check_fed_id_message(int socket_id, struct sockaddr_in* client_fd)
rti_lib.cread_from_socket_errexit()
,send_reject()
int receive_connection_information(int socket_id, uint16_t fed_id)
rti_lib.cread_from_socket_errexit()
,send_reject()
int receive_udp_message_and_set_up_clock_sync(int socket_id, uint16_t fed_id)
read_from_socket_errexit()
,send_reject()
void send_physical_clock(unsigned char message_type, federate_t* fed, socket_type_t socket_type)
write_to_socket_errexit()
void handle_physical_clock_sync_message(federate_t* my_fed, socket_type_t socket_type)
send_physical_clock()
void* federate_thread_TCP(void* fed)
rti_lib.cread_from_socket()
void handle_timestamp(federate_t *my_fed)
void handle_address_query(uint16_t fed_id)
void handle_address_ad(uint16_t federate_id)
void handle_timed_message(federate_t* sending_federate, unsigned char* buffer)
void handle_federate_resign(federate_t *my_fed)
void handle_next_event_tag(federate_t* fed)
void handle_logical_tag_complete(federate_t* fed)
void handle_stop_request_message(federate_t* fed)
void handle_stop_request_reply(federate_t* fed)
void handle_port_absent_message(federate_t* sending_federate, unsigned char* buffer)
shutdown()
rti_lib.cFederate
TODO List
Points to check
read()
it to get the federate_id (of B) .The text was updated successfully, but these errors were encountered: