4dcc7e138e818956edaede12bb96d8b6e665e92a
[apps/native/gear-racing-car.git] / src / messages / message_manager.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "messages/message_manager.h"
18 #include "messages/message_factory.h"
19 #include "udp_connection.h"
20 #include "messages/reader.h"
21 #include "messages/writer.h"
22 #include "messages/clock.h"
23
24 #define DEFAULT_PORT 4004
25
26 struct _message_mgr {
27         writer_t writer;
28         reader_t reader;
29         udp_connection_t *conn;
30         message_factory_t *factory;
31         receive_message_cb cb;
32         void *user_data;
33 };
34
35 static struct _message_mgr mgr;
36
37 static void msg_mgr_udp_receive_cb(const char *data, unsigned int size, const char *address, int port)
38 {
39         int32_t message_type;
40         message_t *message;
41
42         if (!mgr.cb)
43                 return;
44
45         reader_init_static(&mgr.reader, data, size);
46
47         if (reader_read_int32(&mgr.reader, &message_type)) {
48                 return;
49         }
50
51         message = message_factory_create_message(mgr.factory, message_type);
52         if (!message) {
53                 return;
54         }
55
56         if (message_deserialize(message, &mgr.reader)) {
57                 message_destroy(message);
58                 return;
59         }
60
61         message_set_sender(message, address, port);
62
63         if (mgr.cb) mgr.cb(message, mgr.user_data);
64
65         message_destroy(message);
66 }
67
68 int message_manager_init()
69 {
70         if (mgr.conn) {
71                 return 0;
72         }
73
74         mgr.conn = udp_connection_create(DEFAULT_PORT); //TODO load from config
75         if (!mgr.conn) {
76                 return -1;
77         }
78
79         mgr.factory = message_factory_create();
80         if (!mgr.factory) {
81                 message_manager_shutdown();
82                 return -1;
83         }
84
85         udp_connection_set_receive_cb(mgr.conn, msg_mgr_udp_receive_cb);
86         writer_init_sized(&mgr.writer, 256);
87
88         return 0;
89 }
90
91 int message_manager_send_message(message_t *message)
92 {
93         const char *address;
94         int port;
95         int32_t type;
96
97         if (!mgr.conn)
98                 return -1;
99
100         writer_reset(&mgr.writer, 0);
101
102         type = message_get_type(message);
103
104         if (writer_write_int32(&mgr.writer, type)) {
105                 return -1;
106         }
107
108         message_get_receiver(message, &address, &port);
109         message_set_timestamp(message, clock_realtime_get());
110
111         if (message_serialize(message, &mgr.writer))
112                 return -1;
113
114         int err = udp_connection_send(mgr.conn,
115                         mgr.writer.data,
116                         mgr.writer.length,
117                         address,
118                         port);
119
120         if (err)
121                 return -1;
122
123         return 0;
124 }
125
126 void message_manager_set_receive_message_cb(receive_message_cb callback, void *user_data)
127 {
128         if (!mgr.conn)
129                 return;
130
131         mgr.cb = callback;
132         mgr.user_data = user_data;
133 }
134
135 void message_manager_shutdown()
136 {
137         if (!mgr.conn)
138                 return;
139
140         writer_shutdown(&mgr.writer);
141         message_factory_destroy(mgr.factory);
142         udp_connection_destroy(mgr.conn);
143         mgr.conn = NULL;
144 }