Ported messages from gear racing controller 90/189990/5
authorKrzysztof Wieclaw <k.wieclaw@samsung.com>
Tue, 25 Sep 2018 13:43:20 +0000 (15:43 +0200)
committerKrzysztof Wieclaw <k.wieclaw@samsung.com>
Thu, 4 Oct 2018 13:36:47 +0000 (15:36 +0200)
Change-Id: I42f3568d170e4c2349f546168da03d7d94657cc3
Signed-off-by: Krzysztof Wieclaw <k.wieclaw@samsung.com>
28 files changed:
CMakeLists.txt
inc/messages/clock.h [new file with mode: 0644]
inc/messages/macros.h [new file with mode: 0644]
inc/messages/message.h [new file with mode: 0644]
inc/messages/message_ack.h [new file with mode: 0644]
inc/messages/message_bye.h [new file with mode: 0644]
inc/messages/message_command.h [new file with mode: 0644]
inc/messages/message_connect.h [new file with mode: 0644]
inc/messages/message_connect_accepted.h [new file with mode: 0644]
inc/messages/message_connect_refused.h [new file with mode: 0644]
inc/messages/message_factory.h [new file with mode: 0644]
inc/messages/message_keep_alive.h [new file with mode: 0644]
inc/messages/message_manager.h [new file with mode: 0644]
inc/messages/reader.h [new file with mode: 0644]
inc/messages/writer.h [new file with mode: 0644]
src/messages/clock.c [new file with mode: 0644]
src/messages/message.c [new file with mode: 0644]
src/messages/message_ack.c [new file with mode: 0644]
src/messages/message_bye.c [new file with mode: 0644]
src/messages/message_command.c [new file with mode: 0644]
src/messages/message_connect.c [new file with mode: 0644]
src/messages/message_connect_accepted.c [new file with mode: 0644]
src/messages/message_connect_refused.c [new file with mode: 0644]
src/messages/message_factory.c [new file with mode: 0644]
src/messages/message_keep_alive.c [new file with mode: 0644]
src/messages/message_manager.c [new file with mode: 0644]
src/messages/reader.c [new file with mode: 0644]
src/messages/writer.c [new file with mode: 0644]

index 0b5dd3c..9a1554e 100644 (file)
@@ -32,6 +32,19 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
 INCLUDE_DIRECTORIES(${PROJECT_ROOT_DIR}/inc)
 
 ADD_EXECUTABLE(${PROJECT_NAME}
+       ${PROJECT_ROOT_DIR}/src/messages/clock.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_command.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_factory.c
+       ${PROJECT_ROOT_DIR}/src/messages/writer.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_ack.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_connect_accepted.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_keep_alive.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_bye.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_connect.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_manager.c
+       ${PROJECT_ROOT_DIR}/src/messages/message.c
+       ${PROJECT_ROOT_DIR}/src/messages/message_connect_refused.c
+       ${PROJECT_ROOT_DIR}/src/messages/reader.c
        ${PROJECT_ROOT_DIR}/src/udp_connection.c
        ${PROJECT_ROOT_DIR}/src/config.c
        ${PROJECT_ROOT_DIR}/src/app.c
diff --git a/inc/messages/clock.h b/inc/messages/clock.h
new file mode 100644 (file)
index 0000000..7dec10b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_MONOTONIC_H
+#define _CLOCK_MONOTONIC_H
+
+#include <time.h>
+#include <stdbool.h>
+
+/**
+ * @brief Check if platform supports all required clock types
+ *
+ * @return true if supported, false otherwise.
+ */
+bool clock_is_supported();
+
+/**
+ * @brief Gets current time using monotonic clock
+ *
+ * @note the func will abort if monotonic clock is not supported.
+ * call @clock_is_supported beforehead to validate if platform
+ * supports all clock types.
+ *
+ * @return: seconds since unspecified time point.
+ */
+float clock_monotonic_get();
+
+/**
+ * @brief Gets current time using realtime clock
+ *
+ * @note the func will abort if realtime clock is not supported.
+ * call @clock_is_supported beforehead to validate if platform
+ * supports all clock types.
+ *
+ * @return: number of seconds since Epoch
+ */
+time_t clock_realtime_get();
+
+#endif
diff --git a/inc/messages/macros.h b/inc/messages/macros.h
new file mode 100644 (file)
index 0000000..6b5a9a1
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
diff --git a/inc/messages/message.h b/inc/messages/message.h
new file mode 100644 (file)
index 0000000..d4a2d96
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+* Copyright (c) 2018 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Flora License, Version 1.1 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef MESSAGE_H_
+#define MESSAGE_H_
+
+#include "messages/writer.h"
+#include "messages/reader.h"
+
+/**
+ * @brief message types
+ */
+typedef enum message_type {
+       MESSAGE_NONE,
+       MESSAGE_CONNECT,          /** Connection request */
+       MESSAGE_CONNECT_ACCEPTED, /** Connection accepted reply */
+       MESSAGE_CONNECT_REFUSED,  /** Connection refused reply */
+       MESSAGE_KEEP_ALIVE,       /** Keep alive request */
+       MESSAGE_ACK,              /** Message delivery confirmation */
+       MESSAGE_COMMAND,          /** Message with command data */
+       MESSAGE_BYE               /** Connection end request */
+} message_type_e;
+
+#define IP_ADDRESS_LEN 15
+
+typedef struct message message_t;
+
+/**
+ * @brief message data
+ */
+struct message {
+       int64_t serial;
+       int64_t timestamp;
+       int32_t type;
+       int sender_port;
+       int receiver_port;
+       char sender_ip[IP_ADDRESS_LEN+1];
+       char receiver_ip[IP_ADDRESS_LEN+1];
+       struct {
+               int (*deserialize)(message_t *msg, reader_t *reader);
+               int (*serialize)(message_t *msg, writer_t *writer);
+               void (*destroy)(message_t *msg);
+       } vtable;
+};
+
+/**
+ * @brief Destroys message.
+ *
+ * @param[in] message message object.
+ *
+ * @note this function is implementing polymorphic behaviour of
+ * message_t object. The the destroy is made via vtable->destroy pointer.
+ */
+void message_destroy(message_t *message);
+
+/**
+ * @brief Serializes message into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ *
+ * @note this function is implementing polymorphic behaviour of
+ * message_t object. The serialization is made via vtable->serialize pointer.
+ */
+int message_serialize(message_t *message, writer_t *writer);
+
+/**
+ * @brief Deserializes message from reader's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ *
+ * @note this function is implementing polymorphic behaviour of
+ * message_t object. The deserialization is made via vtable->serialize pointer.
+ */
+int message_deserialize(message_t *message, reader_t *reader);
+
+/**
+ * @brief Get reciever of the message
+ *
+ * @param[in] message message object.
+ * @param[out] ip address of reciever.
+ * @param[out] port port of the reciever.
+ *
+ * @note if reciever is not set the @ip will be empty string.
+ */
+void message_get_receiver(message_t *messsage, const char **ip, int *port);
+
+/**
+ * @brief Set reciever of the message.
+ *
+ * @param[in] message message object.
+ * @param[in] ip address of reciever.
+ * @param[in] port port of the reciever.
+ */
+void message_set_receiver(message_t *messsage, const char *ip, int port);
+
+/**
+ * @brief Get sender of the message.
+ *
+ * @param[in] message message object.
+ * @param[out] ip address of sender.
+ * @param[out] port port of the sender.
+ *
+ * @note if sender is not set the @ip will be empty string.
+ */
+void message_get_sender(message_t *message, const char **ip, int *port);
+
+/**
+ * @brief Set sender of the message.
+ *
+ * @param[in] message message object.
+ * @param[in] ip address of sender.
+ * @param[in] port port of the sender.
+ */
+void message_set_sender(message_t *message, const char *ip, int port);
+
+/**
+ * @brief Get timestamp of the message.
+ *
+ * @param[in] message message object.
+ *
+ * @return Unix timestamp.
+ */
+time_t message_get_timestamp(message_t *messsage);
+
+/**
+ * @brief Set timestamp of the message.
+ *
+ * @param[in] message message object.
+ * @param[in] time Unix timestamp.
+ */
+void message_set_timestamp(message_t *messsage, time_t time);
+
+/**
+ * @brief Get type of the message.
+ *
+ * @param[in] message message object.
+ *
+ * @return message type.
+ */
+message_type_e message_get_type(message_t *message);
+
+/**
+ * @brief Set type of the message.
+ *
+ * @param[in] message message object.
+ * @param[in] type message type.
+ */
+void message_set_type(message_t *message, message_type_e type);
+
+/**
+ * @brief Get serial number of the message. Serial numbers
+ * can be used to verify order of the messages.
+ *
+ * @param[in] message message object.
+ *
+ * @return message serial number.
+ */
+int64_t message_get_serial(message_t *message);
+
+/**
+ * @brief Initializes base message object. The main
+ * reponsibilities of this functions are:
+ * - zeroing memory.
+ * - assigning serial number.
+ *
+ * @param[in] message message object.
+ *
+ * @note the purpose of this function is to be used in
+ * derived classes.
+ */
+void message_base_init(message_t *msg);
+
+/**
+ * @brief Destroys base message object.
+ *
+ * @param[in] message message object.
+ *
+ * @note unlike @message_destroy, this function is performing
+ * real destroy on message_t object.
+ *
+ * @note the purpose of this function is to be used in
+ * derived classes.
+ */
+void message_base_destroy(message_t *msg);
+
+/**
+ * @brief Deserializes base message from reader's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] reader reader object.
+ *
+ * @note unlike @message_deserialize, this function is performing
+ * real deserialzation on message_t object.
+ *
+ * @note the purpose of this function is to be used in
+ * derived classes.
+ */
+int message_base_deserialize(message_t *msg, reader_t *reader);
+
+/**
+ * @brief Serializes base message into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @note unlike @message_serialize, this function is performing
+ * real serialzation on message_t object.
+ *
+ * @note the purpose of this function is to be used in
+ * derived classes.
+ */
+int message_base_serialize(message_t *msg, writer_t *writer);
+
+#endif /* MESSAGE_H_ */
diff --git a/inc/messages/message_ack.h b/inc/messages/message_ack.h
new file mode 100644 (file)
index 0000000..8d8c074
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2018 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Flora License, Version 1.1 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef MESSAGE_ACK_H
+#define MESSAGE_ACK_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Ack message data
+ */
+typedef struct message_ack {
+       message_t base;       /** Base class */
+       int64_t ack_serial;   /** The serial of message which reception is confirmed */
+} message_ack_t;
+
+/**
+ * @brief Initializes message_ack_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_ack_init(message_ack_t *message);
+
+/**
+ * @brief initializes message_ack_t message form other message.
+ * The serial number returned by @message_ack_get_ack_serial will
+ * be set to @request's serial.
+ *
+ * @param[in] message ack message.
+ * @param[in] request the message which reception will be confirmed by
+ * message_ack_t.
+ */
+void message_ack_init_from_request(message_ack_t *message, message_t *request);
+
+/**
+ * @brief Gets serial number of confirmed message.
+ *
+ * @return the serial number.
+ */
+int64_t message_ack_get_ack_serial(message_ack_t *message);
+
+/**
+ * @brief Destroys message_ack_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_ack_destroy(message_ack_t *message);
+
+/**
+ * @brief Deserializes message_ack_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_ack_deserialize(message_ack_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_ack_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_ack_serialize(message_ack_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_ACK_H */
diff --git a/inc/messages/message_bye.h b/inc/messages/message_bye.h
new file mode 100644 (file)
index 0000000..1a9b55a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_BYE_H
+#define MESSAGE_BYE_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Connect message data
+ */
+typedef struct message_bye {
+       message_t base; /** Base class */
+} message_bye_t;
+
+/**
+ * @brief Initializes message_bye_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_bye_init(message_bye_t *message);
+
+/**
+ * @brief Destroys message_bye_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_bye_destroy(message_bye_t *message);
+
+/**
+ * @brief Deserializes message_bye_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_bye_deserialize(message_bye_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_bye_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_bye_serialize(message_bye_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_BYE_H */
diff --git a/inc/messages/message_command.h b/inc/messages/message_command.h
new file mode 100644 (file)
index 0000000..b0b1489
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_COMMAND_H
+#define MESSAGE_COMMAND_H
+
+#include "command.h"
+#include "messages/message.h"
+
+/**
+ * @brief Command message data
+ */
+typedef struct message_command {
+       message_t base;    /** Base class */
+       command_s command; /** Command carried by message */
+} message_command_t;
+
+/**
+ * @brief Initializes message_command_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_command_init(message_command_t *message);
+
+/**
+ * @brief Get command for mesage.
+ *
+ * @param[in] message ack message.
+ *
+ * @return command const pointer.
+ */
+const command_s *message_command_get_command(message_command_t *message);
+
+/**
+ * @brief Set command for mesage.
+ *
+ * @param[in] message ack message.
+ * @param[in] command command to be set.
+ */
+void message_command_set_command(message_command_t *message, const command_s *cmd);
+
+/**
+ * @brief Destroys message_command_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_command_destroy(message_command_t *message);
+
+/**
+ * @brief Deserializes message_command_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_command_deserialize(message_command_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_command_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_command_serialize(message_command_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_COMMAND_H */
diff --git a/inc/messages/message_connect.h b/inc/messages/message_connect.h
new file mode 100644 (file)
index 0000000..8c16d18
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_CONNECT_H
+#define MESSAGE_CONNECT_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Connect message data
+ */
+typedef struct message_connect {
+       message_t base; /** Base class */
+} message_connect_t;
+
+/**
+ * @brief Initializes message_connect_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_init(message_connect_t *message);
+
+/**
+ * @brief Destroys message_connect_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_destroy(message_connect_t *message);
+
+/**
+ * @brief Deserializes message_connect_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_deserialize(message_connect_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_connect_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_serialize(message_connect_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_CONNECT_H */
diff --git a/inc/messages/message_connect_accepted.h b/inc/messages/message_connect_accepted.h
new file mode 100644 (file)
index 0000000..069353f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_CONNECT_ACCEPTED_H
+#define MESSAGE_CONNECT_ACCEPTED_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Connect accepted message data
+ */
+typedef struct message_connect_accepted {
+       message_t base; /** Base class */
+} message_connect_accepted_t;
+
+/**
+ * @brief Initializes message_connect_accepted_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_accepted_init(message_connect_accepted_t *message);
+
+/**
+ * @brief Destroys message_connect_accepted_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_accepted_destroy(message_connect_accepted_t *message);
+
+/**
+ * @brief Deserializes message_connect_accepted_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_accepted_deserialize(message_connect_accepted_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_connect_accepted_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_accepted_serialize(message_connect_accepted_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_CONNECT_ACCEPTED_H */
diff --git a/inc/messages/message_connect_refused.h b/inc/messages/message_connect_refused.h
new file mode 100644 (file)
index 0000000..38ccec4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_CONNECT_REFUSED_H
+#define MESSAGE_CONNECT_REFUSED_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Connect refused message data
+ */
+typedef struct message_connect_refused {
+       message_t base; /** Base class */
+} message_connect_refused_t;
+
+/**
+ * @brief Initializes message_connect_refused_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_refused_init(message_connect_refused_t *message);
+
+/**
+ * @brief Destroys message_connect_refused_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_connect_refused_destroy(message_connect_refused_t *message);
+
+/**
+ * @brief Deserializes message_connect_refused_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_refused_deserialize(message_connect_refused_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_connect_refused_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_connect_refused_serialize(message_connect_refused_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_CONNECT_REFUSED_H */
+
diff --git a/inc/messages/message_factory.h b/inc/messages/message_factory.h
new file mode 100644 (file)
index 0000000..4f3be20
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_FACTORY_H
+#define MESSAGE_FACTORY_H
+
+#include "messages/message.h"
+
+/**
+ * @brief the factory handle.
+ */
+typedef struct _message_factory message_factory_t;
+
+/**
+ * @brief Creates new instance of message factory.
+ *
+ * @return new factory pointer or NULL on error.
+ */
+message_factory_t *message_factory_create();
+
+/**
+ * @brief Destroys factory instance.
+ *
+ * @param[in] factory factory pointer.
+ */
+void message_factory_destroy(message_factory_t *factory);
+
+/**
+ * @brief Returns message poiner.
+ *
+ * @param[in] factory factory pointer.
+ * @param[in] type of message to be created.
+ *
+ * @note only ONE message instance returned by a factory is considered
+ * valid at time. User should destroy previous message returned by
+ * this function with @message_destroy function.
+ *
+ * @return message pointer or NULL on error.
+ */
+message_t *message_factory_create_message(message_factory_t *factory, message_type_e type);
+
+#endif /* end of include guard: MESSAGE_FACTORY_H */
diff --git a/inc/messages/message_keep_alive.h b/inc/messages/message_keep_alive.h
new file mode 100644 (file)
index 0000000..d3552ce
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_KEEP_ALIVE_H
+#define MESSAGE_KEEP_ALIVE_H
+
+#include "messages/message.h"
+
+/**
+ * @brief Keep alive message data
+ */
+typedef struct message_keep_alive {
+       message_t base; /** Base class */
+} message_keep_alive_t;
+
+/**
+ * @brief Initializes message_keep_alive_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_keep_alive_init(message_keep_alive_t *message);
+
+/**
+ * @brief Destroys message_keep_alive_t object.
+ *
+ * @param[in] message ack message.
+ */
+void message_keep_alive_destroy(message_keep_alive_t *message);
+
+/**
+ * @brief Deserializes message_keep_alive_t from reader's buffer.
+ *
+ * @param[in] message ack message.
+ * @param[in] reader reader object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_keep_alive_deserialize(message_keep_alive_t *message, reader_t *reader);
+
+/**
+ * @brief Serializes message_keep_alive_t into writer's buffer.
+ *
+ * @param[in] message message object.
+ * @param[in] writer writer object.
+ *
+ * @return 0 on success, other value on failure.
+ */
+int message_keep_alive_serialize(message_keep_alive_t *message, writer_t *writer);
+
+#endif /* end of include guard: MESSAGE_KEEP_ALIVE_H */
+
diff --git a/inc/messages/message_manager.h b/inc/messages/message_manager.h
new file mode 100644 (file)
index 0000000..0bcf33f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2018 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Flora License, Version 1.1 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef MESSAGE_MANAGER_H_
+#define MESSAGE_MANAGER_H_
+
+#include "messages/message.h"
+
+typedef void (*receive_message_cb)(message_t *message, void *user_data);
+
+/**
+ * @brief Initializes message manager module.
+ *
+ * @return 0 on success, other value on error.
+ */
+int message_manager_init();
+
+/**
+ * @brief Send message using message manager conenction.
+ *
+ * @return 0 on success, other value on error.
+ *
+ * @note the @message_manager_init should be called beforehead.
+ */
+int message_manager_send_message(message_t *message);
+
+/**
+ * @brief Set message recieved callback.
+ *
+ * @param[in] callback user callback.
+ * @param[in] user_data user data.
+ */
+void message_manager_set_receive_message_cb(receive_message_cb callback, void *user_data);
+
+/**
+ * @brief Shutdowns message manager module.
+ *
+ * @return 0 on success, other value on error.
+ */
+void message_manager_shutdown();
+
+#endif /* MESSAGE_MANAGER_H_ */
diff --git a/inc/messages/reader.h b/inc/messages/reader.h
new file mode 100644 (file)
index 0000000..07988b5
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef READER_H
+#define READER_H
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+typedef struct _reader reader_t;
+
+/**
+ * @brief reader object
+ */
+struct _reader
+{
+       const char *data;
+       size_t offset;
+       size_t len;
+};
+
+/**
+ * @brief Initialzies reader over buffer
+ *
+ * @param[in] reader reader object
+ * @param[in] data buffer
+ * @param[in] length length of the @data
+ */
+void reader_init_static(reader_t *reader, const char *data, size_t length);
+
+/**
+ * @brief Start reading buffer from the begining
+ *
+ * @param[in] reader reader object
+ */
+void reader_reset(reader_t *reader);
+
+/** * @brief Reads 32-bit integer value from buffer
+ *
+ * @param[in] reader reader object
+ * @param[out] value output value
+ *
+ * @return 0 on success, other value on failure.
+ */
+int reader_read_int32(reader_t *reader, int32_t *value);
+
+/**
+ * @brief Reads 64-bit integer value from buffer
+ *
+ * @param[in] reader reader object
+ * @param[out] value output value
+ *
+ * @return 0 on success, other value on failure.
+ */
+int reader_read_int64(reader_t *reader, int64_t *value);
+
+/**
+ * @brief Reads character value from buffer
+ *
+ * @param[in] reader reader object
+ * @param[out] value output value
+ *
+ * @return 0 on success, other value on failure.
+ */
+int reader_read_char(reader_t *reader, char *value);
+
+/**
+ * @brief Reads boolean value from buffer
+ *
+ * @param[in] reader reader object
+ * @param[out] value output value
+ *
+ * @return 0 on success, other value on failure.
+ */
+int reader_read_bool(reader_t *reader, bool *value);
+
+/**
+ * @brief Reads string value from buffer
+ *
+ * @param[in] reader reader object
+ * @param[out] value output value
+ *
+ * @return 0 on success, other value on failure.
+ * @note value should be released with @free
+ */
+int reader_read_string(reader_t *reader, char **value);
+
+#endif /* end of include guard: READER_H */
diff --git a/inc/messages/writer.h b/inc/messages/writer.h
new file mode 100644 (file)
index 0000000..b954517
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WRITER_H
+#define WRITER_H
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+typedef struct _writer writer_t;
+
+/**
+ * @brief writer object
+ */
+struct _writer
+{
+       char *data;
+       size_t length;
+       size_t cap;
+};
+
+/**
+ * @brief Initializes writer object
+ *
+ * @param[in] writer writer object.
+ * @param[in] length the initial lenght of data buffer.
+ *
+ * @return 0 on success, other value on error
+ */
+int writer_init_sized(writer_t *writer, size_t length);
+
+/**
+ * @brief Shutdowns writer object
+ *
+ * @param[in] writer writer object.
+ */
+void writer_shutdown(writer_t *writer);
+
+/**
+ * @brief Resets writer object
+ *
+ * Resetting means that next call to write_write_* functions
+ * will write content from the begining of the buffer, overwriting
+ * any previously stored data.
+ *
+ * @param[in] writer writer object.
+ * @param[in] the position in the buffer after which next
+ *            write data will be placed.
+ */
+void writer_reset(writer_t *buf, size_t position);
+
+/**
+ * @brief Writes value into writer's buffer
+ *
+ * @param[in] writer writer object
+ * @param[in] value value to write into the writer's buffer
+ *
+ * @return 0 on success, other value on error.
+ */
+int writer_write_int32(writer_t *writer, int32_t value);
+
+/**
+ * @brief Writes value into writer's buffer
+ *
+ * @param[in] writer writer object
+ * @param[in] value value to write into the writer's buffer
+ *
+ * @return 0 on success, other value on error.
+ */
+int writer_write_int64(writer_t *writer, int64_t value);
+
+/**
+ * @brief Writes value into writer's buffer
+ *
+ * @param[in] writer writer object
+ * @param[in] value value to write into the writer's buffer
+ *
+ * @return 0 on success, other value on error.
+ */
+int writer_write_bool(writer_t *writer, bool value);
+
+/**
+ * @brief Writes value into writer's buffer
+ *
+ * @param[in] writer writer object
+ * @param[in] value value to write into the writer's buffer
+ *
+ * @return 0 on success, other value on error.
+ */
+int writer_write_char(writer_t *writer, char value);
+
+/**
+ * @brief Writes value into writer's buffer
+ *
+ * @param[in] writer writer object
+ * @param[in] value value to write into the writer's buffer
+ *
+ * @return 0 on success, other value on error.
+ */
+int writer_write_string(writer_t *writer, const char *value);
+
+#endif /* end of include guard: WRITER_H */
diff --git a/src/messages/clock.c b/src/messages/clock.c
new file mode 100644 (file)
index 0000000..04d2130
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+#include "messages/clock.h"
+
+float clock_monotonic_get()
+{
+       struct timespec ret = {0,};
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ret) != 0) {
+               abort();
+       }
+
+       return ret.tv_sec + (float)ret.tv_nsec / 1000000000.0f;
+}
+
+time_t clock_realtime_get()
+{
+       struct timespec ret = {0,};
+
+       if (clock_gettime(CLOCK_REALTIME, &ret) != 0) {
+               abort();
+       }
+
+       return ret.tv_sec;
+}
+
+bool clock_is_supported()
+{
+       struct timespec ret = {0,};
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ret) != 0) {
+               return false;
+       }
+       if (clock_gettime(CLOCK_REALTIME, &ret) != 0) {
+               return false;
+       }
+       return true;
+}
+
diff --git a/src/messages/message.c b/src/messages/message.c
new file mode 100644 (file)
index 0000000..b8bdffa
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 2018 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Flora License, Version 1.1 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "messages/message.h"
+
+#include <string.h>
+
+static int64_t current_serial;
+
+void message_destroy(message_t *message)
+{
+       if (message->vtable.destroy)
+               message->vtable.destroy(message);
+}
+
+int message_serialize(message_t *message, writer_t *writer)
+{
+       if (message->vtable.serialize)
+               return message->vtable.serialize(message, writer);
+       return -1;
+}
+
+int message_deserialize(message_t *message, reader_t *reader)
+{
+       if (message->vtable.deserialize)
+               return message->vtable.deserialize(message, reader);
+       return -1;
+}
+
+void message_set_receiver(message_t *message, const char *ip, int port)
+{
+       if (ip) strncpy(message->receiver_ip, ip, IP_ADDRESS_LEN);
+       message->receiver_port = port;
+}
+
+void message_get_receiver(message_t *message, const char **ip, int *port)
+{
+       if (ip) *ip = message->receiver_ip;
+       if (port) *port = message->receiver_port;
+}
+
+time_t message_get_timestamp(message_t *message)
+{
+       return message->timestamp;
+}
+
+void message_set_timestamp(message_t *message, time_t time)
+{
+       message->timestamp = time;
+}
+
+void message_get_sender(message_t *message, const char **ip, int *port)
+{
+       if (ip) *ip = message->sender_ip;
+       if (port) *port = message->sender_port;
+}
+
+void message_set_sender(message_t *message, const char *ip, int port)
+{
+       if (ip) strncpy(message->sender_ip, ip, IP_ADDRESS_LEN);
+       message->sender_port = port;
+}
+
+message_type_e message_get_type(message_t *message)
+{
+       return message->type;
+}
+
+void message_set_type(message_t *message, message_type_e type)
+{
+       message->type = type;
+}
+
+int64_t message_get_serial(message_t *message)
+{
+       return message->serial;
+}
+
+void message_base_init(message_t *msg)
+{
+       memset(msg, 0x0, sizeof(message_t));
+
+       msg->vtable.serialize = message_base_serialize;
+       msg->vtable.deserialize = message_base_deserialize;
+       msg->vtable.destroy = message_base_destroy;
+       msg->serial = current_serial++;
+}
+
+void message_base_destroy(message_t *msg)
+{
+}
+
+int message_base_deserialize(message_t *msg, reader_t *reader)
+{
+       int err = 0;
+
+       err |= reader_read_int64(reader, &msg->serial);
+       err |= reader_read_int32(reader, &msg->type);
+       err |= reader_read_int64(reader, &msg->timestamp);
+
+       return err;
+}
+
+int message_base_serialize(message_t *msg, writer_t *writer)
+{
+       int err = 0;
+
+       err |= writer_write_int64(writer, msg->serial);
+       err |= writer_write_int32(writer, msg->type);
+       err |= writer_write_int64(writer, msg->timestamp);
+
+       return err;
+}
diff --git a/src/messages/message_ack.c b/src/messages/message_ack.c
new file mode 100644 (file)
index 0000000..d81b4c9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_ack.h"
+#include "messages/macros.h"
+
+static int _message_ack_serialze_vcall(message_t *msg, writer_t *writer)
+{
+       message_ack_t *ack_msg = container_of(msg, message_ack_t, base);
+       return message_ack_serialize(ack_msg, writer);
+}
+
+static int _message_ack_deserialize_vcall(message_t *msg, reader_t *reader)
+{
+       message_ack_t *ack_msg = container_of(msg, message_ack_t, base);
+       return message_ack_deserialize(ack_msg, reader);
+}
+
+static void _message_ack_destroy_vcall(message_t *msg)
+{
+       message_ack_t *ack_msg = container_of(msg, message_ack_t, base);
+       message_ack_destroy(ack_msg);
+}
+
+void message_ack_init(message_ack_t *message)
+{
+       message_base_init(&message->base);
+
+       message_set_type(&message->base, MESSAGE_ACK);
+
+       message->base.vtable.serialize = _message_ack_serialze_vcall;
+       message->base.vtable.deserialize = _message_ack_deserialize_vcall;
+       message->base.vtable.destroy = _message_ack_destroy_vcall;
+
+       message->ack_serial = -1; // ack_serial not set
+}
+
+void message_ack_init_from_request(message_ack_t *message, message_t *request)
+{
+       message_ack_init(message);
+
+       message->ack_serial = message_get_serial(request);
+}
+
+void message_ack_destroy(message_ack_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int64_t message_ack_get_ack_serial(message_ack_t *message)
+{
+       return message->ack_serial;
+}
+
+int message_ack_deserialize(message_ack_t *message, reader_t *reader)
+{
+       int err = 0;
+
+       err |= message_base_deserialize(&message->base, reader);
+       err |= reader_read_int64(reader, &message->ack_serial);
+
+       return err;
+}
+
+int message_ack_serialize(message_ack_t *message, writer_t *writer)
+{
+       int err = 0;
+
+       err |= message_base_serialize(&message->base, writer);
+       err |= writer_write_int64(writer, message->ack_serial);
+
+       return err;
+}
diff --git a/src/messages/message_bye.c b/src/messages/message_bye.c
new file mode 100644 (file)
index 0000000..135a8fa
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_bye.h"
+
+void message_bye_init(message_bye_t *message)
+{
+       message_base_init(&message->base);
+       message_set_type(&message->base, MESSAGE_BYE);
+}
+
+void message_bye_destroy(message_bye_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int message_bye_deserialize(message_bye_t *message, reader_t *reader)
+{
+       return message_base_deserialize(&message->base, reader);
+}
+
+int message_bye_serialize(message_bye_t *message, writer_t *writer)
+{
+       return message_base_serialize(&message->base, writer);
+}
diff --git a/src/messages/message_command.c b/src/messages/message_command.c
new file mode 100644 (file)
index 0000000..d40e79b
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGE_COMMAND_C
+#define MESSAGE_COMMAND_C
+
+#include <string.h>
+
+#include "messages/message_command.h"
+#include "messages/macros.h"
+
+static int _message_command_serialze_vcall(message_t *msg, writer_t *writer)
+{
+       message_command_t *command_msg = container_of(msg, message_command_t, base);
+       return message_command_serialize(command_msg, writer);
+}
+
+static int _message_command_deserialize_vcall(message_t *msg, reader_t *reader)
+{
+       message_command_t *command_msg = container_of(msg, message_command_t, base);
+       return message_command_deserialize(command_msg, reader);
+}
+
+static void _message_command_destroy_vcall(message_t *msg)
+{
+       message_command_t *command_msg = container_of(msg, message_command_t, base);
+       message_command_destroy(command_msg);
+}
+
+void message_command_init(message_command_t *message)
+{
+       message_base_init(&message->base);
+
+       message_set_type(&message->base, MESSAGE_COMMAND);
+
+       message->base.vtable.serialize = _message_command_serialze_vcall;
+       message->base.vtable.deserialize = _message_command_deserialize_vcall;
+       message->base.vtable.destroy = _message_command_destroy_vcall;
+
+       memset(&message->command, 0x0, sizeof(command_s));
+}
+
+void message_command_destroy(message_command_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+static int _camera_command_deserialize(command_s *cmd, reader_t *reader)
+{
+       int32_t speed, dir;
+       int err = 0;
+
+       err |= reader_read_int32(reader, &speed);
+       err |= reader_read_int32(reader, &dir);
+
+       if (err) return err;
+
+       cmd->data.steering.speed = speed;
+       cmd->data.steering.direction = dir;
+
+       return 0;
+}
+
+static int _drive_command_deserialize(command_s *cmd, reader_t *reader)
+{
+       int32_t elevation, azimuth;
+       int err = 0;
+
+       err |= reader_read_int32(reader, &elevation);
+       err |= reader_read_int32(reader, &azimuth);
+
+       if (err) return err;
+
+       cmd->data.camera_position.camera_elevation = elevation;
+       cmd->data.camera_position.camera_azimuth = azimuth;
+
+       return 0;
+}
+
+static int _command_deserialize(command_s *cmd, reader_t *reader)
+{
+       int32_t type;
+
+       if (reader_read_int32(reader, &type)) {
+               return -1;
+       }
+
+       cmd->type = type;
+
+       switch (type) {
+               case COMMAND_TYPE_DRIVE:
+                       return _drive_command_deserialize(cmd, reader);
+               case COMMAND_TYPE_CAMERA:
+                       return _camera_command_deserialize(cmd, reader);
+                       break;
+               case COMMAND_TYPE_NONE:
+                       return 0;
+               default:
+                       return -1;
+       }
+}
+
+static int _camera_command_serialize(command_s *cmd, writer_t *writer)
+{
+       int32_t speed = cmd->data.steering.speed;
+       int32_t dir = cmd->data.steering.direction;
+       int err = 0;
+
+       err |= writer_write_int32(writer, speed);
+       err |= writer_write_int32(writer, dir);
+
+       return err;
+}
+
+static int _drive_command_serialize(command_s *cmd, writer_t *writer)
+{
+       int32_t elevation = cmd->data.camera_position.camera_elevation;
+       int32_t azimuth = cmd->data.camera_position.camera_azimuth;
+       int err = 0;
+
+       err |= writer_write_int32(writer, elevation);
+       err |= writer_write_int32(writer, azimuth);
+
+       return err;
+}
+
+static int _command_serialize(command_s *cmd, writer_t *writer)
+{
+       int32_t type = cmd->type;
+
+       if (writer_write_int32(writer, type)) {
+               return -1;
+       }
+
+       switch (cmd->type) {
+               case COMMAND_TYPE_DRIVE:
+                       return _drive_command_serialize(cmd, writer);
+               case COMMAND_TYPE_CAMERA:
+                       return _camera_command_serialize(cmd, writer);
+                       break;
+               case COMMAND_TYPE_NONE:
+                       return 0;
+               default:
+                       return -1;
+       }
+}
+
+int message_command_deserialize(message_command_t *message, reader_t *reader)
+{
+       int err = 0;
+
+       err |= message_base_deserialize(&message->base, reader);
+       err |= _command_deserialize(&message->command, reader);
+
+       return err;
+}
+
+int message_command_serialize(message_command_t *message, writer_t *writer)
+{
+       int err = 0;
+
+       err |= message_base_serialize(&message->base, writer);
+       err |= _command_serialize(&message->command, writer);
+
+       return err;
+}
+
+const command_s *message_command_get_command(message_command_t *message)
+{
+       return &message->command;
+}
+
+void message_command_set_command(message_command_t *message, const command_s *cmd)
+{
+       memcpy(&message->command, cmd, sizeof(command_s));
+}
+
+#endif /* end of include guard: MESSAGE_COMMAND_C */
diff --git a/src/messages/message_connect.c b/src/messages/message_connect.c
new file mode 100644 (file)
index 0000000..935eb5e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_connect.h"
+
+void message_connect_init(message_connect_t *message)
+{
+       message_base_init(&message->base);
+       message_set_type(&message->base, MESSAGE_CONNECT);
+}
+
+void message_connect_destroy(message_connect_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int message_connect_deserialize(message_connect_t *message, reader_t *reader)
+{
+       return message_base_deserialize(&message->base, reader);
+}
+
+int message_connect_serialize(message_connect_t *message, writer_t *writer)
+{
+       return message_base_serialize(&message->base, writer);
+}
diff --git a/src/messages/message_connect_accepted.c b/src/messages/message_connect_accepted.c
new file mode 100644 (file)
index 0000000..81122c4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_connect_accepted.h"
+
+void message_connect_accepted_init(message_connect_accepted_t *message)
+{
+       message_base_init(&message->base);
+       message_set_type(&message->base, MESSAGE_CONNECT_ACCEPTED);
+}
+
+void message_connect_accepted_destroy(message_connect_accepted_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int message_connect_accepted_deserialize(message_connect_accepted_t *message, reader_t *reader)
+{
+       return message_base_deserialize(&message->base, reader);
+}
+
+int message_connect_accepted_serialize(message_connect_accepted_t *message, writer_t *writer)
+{
+       return message_base_serialize(&message->base, writer);
+}
+
diff --git a/src/messages/message_connect_refused.c b/src/messages/message_connect_refused.c
new file mode 100644 (file)
index 0000000..4406f69
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_connect_refused.h"
+
+void message_connect_refused_init(message_connect_refused_t *message)
+{
+       message_base_init(&message->base);
+       message_set_type(&message->base, MESSAGE_CONNECT_REFUSED);
+}
+
+void message_connect_refused_destroy(message_connect_refused_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int message_connect_refused_deserialize(message_connect_refused_t *message, reader_t *reader)
+{
+       return message_base_deserialize(&message->base, reader);
+}
+
+int message_connect_refused_serialize(message_connect_refused_t *message, writer_t *writer)
+{
+       return message_base_serialize(&message->base, writer);
+}
diff --git a/src/messages/message_factory.c b/src/messages/message_factory.c
new file mode 100644 (file)
index 0000000..03ec278
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+#include "messages/message_factory.h"
+
+#include "messages/message_ack.h"
+#include "messages/message_bye.h"
+#include "messages/message_command.h"
+#include "messages/message_connect.h"
+#include "messages/message_connect_accepted.h"
+#include "messages/message_connect_refused.h"
+#include "messages/message_keep_alive.h"
+
+struct _message_factory {
+       union {
+               message_ack_t ack;
+               message_bye_t bye;
+               message_command_t command;
+               message_connect_t connect;
+               message_connect_accepted_t connect_accepted;
+               message_connect_refused_t connect_refused;
+               message_keep_alive_t keep_alive;
+       } messages;
+};
+
+message_t *message_factory_create_message(message_factory_t *factory, message_type_e type)
+{
+       switch(type) {
+       case MESSAGE_CONNECT:
+               message_connect_init(&factory->messages.connect);
+               return &factory->messages.connect.base;
+       case MESSAGE_CONNECT_ACCEPTED:
+               message_connect_accepted_init(&factory->messages.connect_accepted);
+               return &factory->messages.connect_accepted.base;
+       case MESSAGE_CONNECT_REFUSED:
+               message_connect_refused_init(&factory->messages.connect_refused);
+               return &factory->messages.connect_refused.base;
+       case MESSAGE_KEEP_ALIVE:
+               message_keep_alive_init(&factory->messages.keep_alive);
+               return &factory->messages.keep_alive.base;
+       case MESSAGE_ACK:
+               message_ack_init(&factory->messages.ack);
+               return &factory->messages.ack.base;
+       case MESSAGE_COMMAND:
+               message_command_init(&factory->messages.command);
+               return &factory->messages.command.base;
+       case MESSAGE_BYE:
+               message_bye_init(&factory->messages.bye);
+               return &factory->messages.bye.base;
+       default:
+               return NULL;
+       }
+}
+
+message_factory_t *message_factory_create()
+{
+       return malloc(sizeof(message_factory_t));
+}
+
+void message_factory_destroy(message_factory_t *factory)
+{
+       free(factory);
+}
diff --git a/src/messages/message_keep_alive.c b/src/messages/message_keep_alive.c
new file mode 100644 (file)
index 0000000..e64aef4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_keep_alive.h"
+
+void message_keep_alive_init(message_keep_alive_t *message)
+{
+       message_base_init(&message->base);
+       message_set_type(&message->base, MESSAGE_KEEP_ALIVE);
+}
+
+void message_keep_alive_destroy(message_keep_alive_t *message)
+{
+       message_base_destroy(&message->base);
+}
+
+int message_keep_alive_deserialize(message_keep_alive_t *message, reader_t *reader)
+{
+       return message_base_deserialize(&message->base, reader);
+}
+
+int message_keep_alive_serialize(message_keep_alive_t *message, writer_t *writer)
+{
+       return message_base_serialize(&message->base, writer);
+}
diff --git a/src/messages/message_manager.c b/src/messages/message_manager.c
new file mode 100644 (file)
index 0000000..4dcc7e1
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/message_manager.h"
+#include "messages/message_factory.h"
+#include "udp_connection.h"
+#include "messages/reader.h"
+#include "messages/writer.h"
+#include "messages/clock.h"
+
+#define DEFAULT_PORT 4004
+
+struct _message_mgr {
+       writer_t writer;
+       reader_t reader;
+       udp_connection_t *conn;
+       message_factory_t *factory;
+       receive_message_cb cb;
+       void *user_data;
+};
+
+static struct _message_mgr mgr;
+
+static void msg_mgr_udp_receive_cb(const char *data, unsigned int size, const char *address, int port)
+{
+       int32_t message_type;
+       message_t *message;
+
+       if (!mgr.cb)
+               return;
+
+       reader_init_static(&mgr.reader, data, size);
+
+       if (reader_read_int32(&mgr.reader, &message_type)) {
+               return;
+       }
+
+       message = message_factory_create_message(mgr.factory, message_type);
+       if (!message) {
+               return;
+       }
+
+       if (message_deserialize(message, &mgr.reader)) {
+               message_destroy(message);
+               return;
+       }
+
+       message_set_sender(message, address, port);
+
+       if (mgr.cb) mgr.cb(message, mgr.user_data);
+
+       message_destroy(message);
+}
+
+int message_manager_init()
+{
+       if (mgr.conn) {
+               return 0;
+       }
+
+       mgr.conn = udp_connection_create(DEFAULT_PORT); //TODO load from config
+       if (!mgr.conn) {
+               return -1;
+       }
+
+       mgr.factory = message_factory_create();
+       if (!mgr.factory) {
+               message_manager_shutdown();
+               return -1;
+       }
+
+       udp_connection_set_receive_cb(mgr.conn, msg_mgr_udp_receive_cb);
+       writer_init_sized(&mgr.writer, 256);
+
+       return 0;
+}
+
+int message_manager_send_message(message_t *message)
+{
+       const char *address;
+       int port;
+       int32_t type;
+
+       if (!mgr.conn)
+               return -1;
+
+       writer_reset(&mgr.writer, 0);
+
+       type = message_get_type(message);
+
+       if (writer_write_int32(&mgr.writer, type)) {
+               return -1;
+       }
+
+       message_get_receiver(message, &address, &port);
+       message_set_timestamp(message, clock_realtime_get());
+
+       if (message_serialize(message, &mgr.writer))
+               return -1;
+
+       int err = udp_connection_send(mgr.conn,
+                       mgr.writer.data,
+                       mgr.writer.length,
+                       address,
+                       port);
+
+       if (err)
+               return -1;
+
+       return 0;
+}
+
+void message_manager_set_receive_message_cb(receive_message_cb callback, void *user_data)
+{
+       if (!mgr.conn)
+               return;
+
+       mgr.cb = callback;
+       mgr.user_data = user_data;
+}
+
+void message_manager_shutdown()
+{
+       if (!mgr.conn)
+               return;
+
+       writer_shutdown(&mgr.writer);
+       message_factory_destroy(mgr.factory);
+       udp_connection_destroy(mgr.conn);
+       mgr.conn = NULL;
+}
diff --git a/src/messages/reader.c b/src/messages/reader.c
new file mode 100644 (file)
index 0000000..9e57b67
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/reader.h"
+
+#include <endian.h>
+#include <stdint.h>
+#include <string.h>
+
+void reader_init_static(reader_t *reader, const char *data, size_t length)
+{
+       reader->data = data;
+       reader->offset = 0;
+       reader->len = length;
+}
+
+void reader_reset(reader_t *reader)
+{
+       reader->offset = 0;
+}
+
+int reader_read_int32(reader_t *reader, int32_t *value)
+{
+       if (reader->offset + sizeof(*value) > reader->len)
+               return -1;
+
+       *value = be32toh(*(uint32_t*)&reader->data[reader->offset]);
+
+       reader->offset += sizeof(*value);
+       return 0;
+}
+
+int reader_read_int64(reader_t *reader, int64_t *value)
+{
+       if (reader->offset + sizeof(*value) > reader->len)
+               return -1;
+
+       *value = be64toh(*(int64_t*)&reader->data[reader->offset]);
+
+       reader->offset += sizeof(*value);
+       return 0;
+}
+
+int reader_read_bool(reader_t *reader, bool *value)
+{
+       char val;
+
+       if (reader_read_char(reader, &val)) {
+               return -1;
+       }
+
+       *value = val ? true : false;
+       return 0;
+}
+
+int reader_read_char(reader_t *reader, char *value)
+{
+       if (reader->offset + sizeof(*value) > reader->len)
+               return -1;
+
+       *value = *(char*)&reader->data[reader->offset];
+
+       reader->offset += sizeof(*value);
+       return 0;
+}
+
+int reader_read_string(reader_t *reader, char **value)
+{
+       int32_t len;
+       char *ret;
+
+       if (reader_read_int32(reader, &len)) {
+               return -1;
+       }
+
+       if (len < 0)
+               return -1;
+
+       if (len == 0) {
+               *value = strdup("");
+               return 0;
+       }
+
+       if (reader->offset + len > reader->len)
+               return -1;
+
+       ret = (char*)malloc(sizeof(char) * (len + 1));
+       if (!ret) {
+               return -1;
+       }
+
+       memcpy(ret, &reader->data[reader->offset], len);
+       reader->offset += len;
+
+       ret[len] = '\0';
+       *value = ret;
+       return 0;
+}
diff --git a/src/messages/writer.c b/src/messages/writer.c
new file mode 100644 (file)
index 0000000..6d5c737
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/writer.h"
+
+#include <endian.h>
+#include <stdint.h>
+#include <string.h>
+
+int writer_init_sized(writer_t *writer, size_t length)
+{
+       writer->data = malloc(length);
+       writer->length = 0;
+       writer->cap = length;
+
+       return writer->data ? 0 : -1;
+}
+
+static int _writer_resize_buffer(writer_t *writer, size_t new_size)
+{
+       writer->data = realloc(writer->data, new_size);
+       writer->cap = new_size;
+
+       return writer->data ? 0 : -1;
+}
+
+static int _writer_bytes_append(writer_t *writer, void *buf, size_t len)
+{
+       if (writer->length + len >= writer->cap)
+               if (_writer_resize_buffer(writer, writer->cap + len))
+                       return -1;
+
+       memcpy(&writer->data[writer->length], (char*)buf, len);
+       writer->length += len;
+       return 0;
+}
+
+void writer_shutdown(writer_t *writer)
+{
+       free(writer->data);
+}
+
+void writer_reset(writer_t *writer, size_t position)
+{
+       writer->length = position > writer->cap ? writer->cap : position;
+}
+
+int writer_write_int32(writer_t *writer, int32_t value)
+{
+       int32_t converted = htobe32(value);
+       return _writer_bytes_append(writer, &converted, sizeof(converted));
+}
+
+int writer_write_int64(writer_t *writer, int64_t value)
+{
+       int64_t converted = htobe64(value);
+       return _writer_bytes_append(writer, &converted, sizeof(converted));
+}
+
+int writer_write_bool(writer_t *writer, bool value)
+{
+       return writer_write_char(writer, value ? 1 : 0);
+}
+
+int writer_write_char(writer_t *writer, char value)
+{
+       return _writer_bytes_append(writer, &value, sizeof(value));
+}
+
+int writer_write_string(writer_t *writer, const char *value)
+{
+       size_t len = strlen(value);
+       if (writer_write_int32(writer, len)) {
+               return -1;
+       }
+       return _writer_bytes_append(writer, (void*)value, sizeof(char) * len);
+}