From 70359fc05cb7b9b7ba59828902e75cfc2fe3b314 Mon Sep 17 00:00:00 2001 From: Krzysztof Wieclaw Date: Tue, 25 Sep 2018 15:43:20 +0200 Subject: [PATCH] Ported messages from gear racing controller Change-Id: I42f3568d170e4c2349f546168da03d7d94657cc3 Signed-off-by: Krzysztof Wieclaw --- CMakeLists.txt | 13 ++ inc/messages/clock.h | 52 +++++++ inc/messages/macros.h | 21 +++ inc/messages/message.h | 233 ++++++++++++++++++++++++++++++++ inc/messages/message_ack.h | 82 +++++++++++ inc/messages/message_bye.h | 63 +++++++++ inc/messages/message_command.h | 82 +++++++++++ inc/messages/message_connect.h | 63 +++++++++ inc/messages/message_connect_accepted.h | 63 +++++++++ inc/messages/message_connect_refused.h | 64 +++++++++ inc/messages/message_factory.h | 55 ++++++++ inc/messages/message_keep_alive.h | 64 +++++++++ inc/messages/message_manager.h | 55 ++++++++ inc/messages/reader.h | 101 ++++++++++++++ inc/messages/writer.h | 115 ++++++++++++++++ src/messages/clock.c | 55 ++++++++ src/messages/message.c | 126 +++++++++++++++++ src/messages/message_ack.c | 86 ++++++++++++ src/messages/message_bye.c | 38 ++++++ src/messages/message_command.c | 191 ++++++++++++++++++++++++++ src/messages/message_connect.c | 38 ++++++ src/messages/message_connect_accepted.c | 39 ++++++ src/messages/message_connect_refused.c | 38 ++++++ src/messages/message_factory.c | 78 +++++++++++ src/messages/message_keep_alive.c | 38 ++++++ src/messages/message_manager.c | 144 ++++++++++++++++++++ src/messages/reader.c | 111 +++++++++++++++ src/messages/writer.c | 90 ++++++++++++ 28 files changed, 2198 insertions(+) create mode 100644 inc/messages/clock.h create mode 100644 inc/messages/macros.h create mode 100644 inc/messages/message.h create mode 100644 inc/messages/message_ack.h create mode 100644 inc/messages/message_bye.h create mode 100644 inc/messages/message_command.h create mode 100644 inc/messages/message_connect.h create mode 100644 inc/messages/message_connect_accepted.h create mode 100644 inc/messages/message_connect_refused.h create mode 100644 inc/messages/message_factory.h create mode 100644 inc/messages/message_keep_alive.h create mode 100644 inc/messages/message_manager.h create mode 100644 inc/messages/reader.h create mode 100644 inc/messages/writer.h create mode 100644 src/messages/clock.c create mode 100644 src/messages/message.c create mode 100644 src/messages/message_ack.c create mode 100644 src/messages/message_bye.c create mode 100644 src/messages/message_command.c create mode 100644 src/messages/message_connect.c create mode 100644 src/messages/message_connect_accepted.c create mode 100644 src/messages/message_connect_refused.c create mode 100644 src/messages/message_factory.c create mode 100644 src/messages/message_keep_alive.c create mode 100644 src/messages/message_manager.c create mode 100644 src/messages/reader.c create mode 100644 src/messages/writer.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b5dd3c..9a1554e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..7dec10b --- /dev/null +++ b/inc/messages/clock.h @@ -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 +#include + +/** + * @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 index 0000000..6b5a9a1 --- /dev/null +++ b/inc/messages/macros.h @@ -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 index 0000000..d4a2d96 --- /dev/null +++ b/inc/messages/message.h @@ -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 index 0000000..8d8c074 --- /dev/null +++ b/inc/messages/message_ack.h @@ -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 index 0000000..1a9b55a --- /dev/null +++ b/inc/messages/message_bye.h @@ -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 index 0000000..b0b1489 --- /dev/null +++ b/inc/messages/message_command.h @@ -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 index 0000000..8c16d18 --- /dev/null +++ b/inc/messages/message_connect.h @@ -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 index 0000000..069353f --- /dev/null +++ b/inc/messages/message_connect_accepted.h @@ -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 index 0000000..38ccec4 --- /dev/null +++ b/inc/messages/message_connect_refused.h @@ -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 index 0000000..4f3be20 --- /dev/null +++ b/inc/messages/message_factory.h @@ -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 index 0000000..d3552ce --- /dev/null +++ b/inc/messages/message_keep_alive.h @@ -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 index 0000000..0bcf33f --- /dev/null +++ b/inc/messages/message_manager.h @@ -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 index 0000000..07988b5 --- /dev/null +++ b/inc/messages/reader.h @@ -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 +#include + +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 index 0000000..b954517 --- /dev/null +++ b/inc/messages/writer.h @@ -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 +#include + +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 index 0000000..04d2130 --- /dev/null +++ b/src/messages/clock.c @@ -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 + +#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 index 0000000..b8bdffa --- /dev/null +++ b/src/messages/message.c @@ -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 + +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 index 0000000..d81b4c9 --- /dev/null +++ b/src/messages/message_ack.c @@ -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 index 0000000..135a8fa --- /dev/null +++ b/src/messages/message_bye.c @@ -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 index 0000000..d40e79b --- /dev/null +++ b/src/messages/message_command.c @@ -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 + +#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 index 0000000..935eb5e --- /dev/null +++ b/src/messages/message_connect.c @@ -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 index 0000000..81122c4 --- /dev/null +++ b/src/messages/message_connect_accepted.c @@ -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 index 0000000..4406f69 --- /dev/null +++ b/src/messages/message_connect_refused.c @@ -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 index 0000000..03ec278 --- /dev/null +++ b/src/messages/message_factory.c @@ -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 + +#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 index 0000000..e64aef4 --- /dev/null +++ b/src/messages/message_keep_alive.c @@ -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 index 0000000..4dcc7e1 --- /dev/null +++ b/src/messages/message_manager.c @@ -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 index 0000000..9e57b67 --- /dev/null +++ b/src/messages/reader.c @@ -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 +#include +#include + +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 index 0000000..6d5c737 --- /dev/null +++ b/src/messages/writer.c @@ -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 +#include +#include + +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); +} -- 2.7.4