sensord: call external sensor service run
[platform/core/system/sensord.git] / src / server / server.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <sys/epoll.h>
21 #include <sys/socket.h>
22
23 #include <systemd/sd-daemon.h>
24 #include <server.h>
25 #include <sensor_loader.h>
26 #include <command_common.h>
27 #include <command_worker.h>
28 #include <external_sensor_worker.h>
29 #include <external_sensor_service.h>
30 #include <thread>
31 #include <sensor_event_poller.h>
32 #include <client_info_manager.h>
33
34 #define SYSTEMD_SOCKET_MAX 2
35
36 using std::thread;
37
38 server::server()
39 : m_mainloop(NULL)
40 , m_running(false)
41 {
42 }
43
44 server::~server()
45 {
46 }
47
48 int server::get_systemd_socket(const char *name)
49 {
50         int type = SOCK_STREAM;
51         int listening = 1;
52         size_t length = 0;
53         int fd = -1;
54         int fd_env = 1;
55         int fd_index;
56
57         if (!strcmp(name, EVENT_CHANNEL_PATH)) {
58                 type = SOCK_SEQPACKET;
59                 listening = -1;
60                 fd_env = 0;
61         }
62
63         if (sd_listen_fds(fd_env) < 0) {
64                 _E("Failed to listen fds from systemd");
65                 return -1;
66         }
67
68         for (fd_index = 0; fd_index < SYSTEMD_SOCKET_MAX; ++fd_index) {
69                 fd = SD_LISTEN_FDS_START + fd_index;
70
71                 if (sd_is_socket_unix(fd, type, listening, name, length) > 0)
72                         return fd;
73         }
74
75         return -1;
76 }
77
78 void server::accept_command_channel(void)
79 {
80         _I("Command channel acceptor is started");
81
82         while (m_running) {
83                 csocket client_command_socket;
84
85                 if (!m_command_channel_accept_socket.is_valid()) {
86                         _E("Failed to accept, event_channel_accept_socket is closed");
87                         break;
88                 }
89
90                 if (!m_command_channel_accept_socket.accept(client_command_socket)) {
91                         _E("Failed to accept command channel from a client");
92                         continue;
93                 }
94
95                 if (!m_running) {
96                         _E("server die");
97                         break;
98                 }
99
100                 _D("New client (socket_fd : %d) connected", client_command_socket.get_socket_fd());
101
102                 /* TODO: if socket is closed, it should be erased */
103                 client_command_sockets.push_back(client_command_socket);
104
105                 thread worker_dispatcher(&server::dispatch_worker, this, client_command_socket);
106                 worker_dispatcher.detach();
107         }
108
109         _I("Command channel acceptor is terminated");
110 }
111
112 void server::accept_event_channel(void)
113 {
114         _I("Event channel acceptor is started!");
115
116         while (m_running) {
117                 csocket client_event_socket;
118
119                 if (!m_event_channel_accept_socket.is_valid()) {
120                         _E("Failed to accept, event_channel_accept_socket is closed");
121                         break;
122                 }
123
124                 if (!m_event_channel_accept_socket.accept(client_event_socket)) {
125                         _E("Failed to accept event channel from a client");
126                         continue;
127                 }
128
129                 if (!m_running) {
130                         _E("server die");
131                         break;
132                 }
133
134                 /* TODO: if socket is closed, it should be erased */
135                 client_event_sockets.push_back(client_event_socket);
136
137                 _D("New client(socket_fd : %d) connected", client_event_socket.get_socket_fd());
138
139                 thread event_channel_creator(&server::dispatch_event_channel_creator, this, client_event_socket);
140                 event_channel_creator.detach();
141         }
142
143         _I("Event channel acceptor is terminated");
144 }
145
146 void server::dispatch_worker(csocket socket)
147 {
148         int worker_type;
149
150         if (socket.recv(&worker_type, sizeof(worker_type)) <= 0) {
151                 _E("Failed to get worker type");
152                 socket.close();
153                 return;
154         }
155
156         if (worker_type == CLIENT_TYPE_SENSOR_CLIENT) {
157                 command_worker *worker;
158                 worker = new(std::nothrow) command_worker(socket);
159
160                 if (!worker) {
161                         _E("Failed to allocate memory");
162                         socket.close();
163                         return;
164                 }
165
166                 if (!worker->start()) {
167                         _E("Failed to start command worker");
168                         delete worker;
169                 }
170         } else if (worker_type == CLIENT_TYPE_EXTERNAL_SOURCE) {
171                 external_sensor_worker *worker;
172                 worker = new(std::nothrow) external_sensor_worker(socket);
173
174                 if (!worker) {
175                         _E("Failed to allocate memory");
176                         socket.close();
177                         return;
178                 }
179
180                 if (!worker->start()) {
181                         _E("Failed to start external worker");
182                         delete worker;
183                 }
184         } else {
185                 _E("Not supported worker type: %d", worker_type);
186                 socket.close();
187         }
188 }
189
190 void server::dispatch_event_channel_creator(csocket socket)
191 {
192         int client_type;
193
194         if (socket.recv(&client_type, sizeof(client_type)) <= 0) {
195                 _E("Failed to get client type");
196                 socket.close();
197                 return;
198         }
199
200         if (client_type == CLIENT_TYPE_SENSOR_CLIENT) {
201                 sensor_event_dispatcher::get_instance().accept_event_connections(socket);
202         } else if (client_type == CLIENT_TYPE_EXTERNAL_SOURCE) {
203                 external_sensor_service::get_instance().accept_command_channel(socket);
204         } else {
205                 _E("Not supported client type: %d", client_type);
206                 socket.close();
207         }
208 }
209
210 void server::poll_event(void)
211 {
212         _I("Event poller is started");
213
214         sensor_event_poller poller;
215
216         if (!poller.poll()) {
217                 _E("Failed to poll event");
218                 return;
219         }
220 }
221
222 bool server::listen_command_channel(void)
223 {
224         int sock_fd = -1;
225         const int MAX_PENDING_CONNECTION = 10;
226
227         sock_fd = get_systemd_socket(COMMAND_CHANNEL_PATH);
228
229         if (sock_fd >= 0) {
230                 _I("Succeeded to get systemd socket(%d)", sock_fd);
231                 m_command_channel_accept_socket = csocket(sock_fd);
232                 return true;
233         }
234
235         INFO("Failed to get systemd socket, create it by myself!");
236         if (!m_command_channel_accept_socket.create(SOCK_STREAM)) {
237                 _E("Failed to create command channel");
238                 return false;
239         }
240
241         if (!m_command_channel_accept_socket.bind(COMMAND_CHANNEL_PATH)) {
242                 _E("Failed to bind command channel");
243                 m_command_channel_accept_socket.close();
244                 return false;
245         }
246
247         if (!m_command_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) {
248                 _E("Failed to listen command channel");
249                 return false;
250         }
251
252         return true;
253 }
254
255 bool server::listen_event_channel(void)
256 {
257         int sock_fd = -1;
258         const int MAX_PENDING_CONNECTION = 32;
259
260         sock_fd = get_systemd_socket(EVENT_CHANNEL_PATH);
261
262         if (sock_fd >= 0) {
263                 _I("Succeeded to get systemd socket(%d)", sock_fd);
264                 m_event_channel_accept_socket = csocket(sock_fd);
265                 return true;
266         }
267
268         INFO("Failed to get systemd socket, create it by myself!");
269
270         if (!m_event_channel_accept_socket.create(SOCK_SEQPACKET)) {
271                 _E("Failed to create event channel");
272                 return false;
273         }
274
275         if (!m_event_channel_accept_socket.bind(EVENT_CHANNEL_PATH)) {
276                 _E("Failed to bind event channel");
277                 m_event_channel_accept_socket.close();
278                 return false;
279         }
280
281         if (!m_event_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) {
282                 _E("Failed to listen event channel");
283                 m_event_channel_accept_socket.close();
284                 return false;
285         }
286
287         return true;
288 }
289
290 void server::close_socket(void)
291 {
292         m_command_channel_accept_socket.close();
293         m_event_channel_accept_socket.close();
294
295         for (unsigned int i = 0; i < client_command_sockets.size(); ++i)
296                 client_command_sockets[i].close();
297
298         for (unsigned int i = 0; i < client_event_sockets.size(); ++i)
299                 client_event_sockets[i].close();
300
301         client_command_sockets.clear();
302         client_event_sockets.clear();
303 }
304
305 void server::initialize(void)
306 {
307         m_running = true;
308         m_mainloop = g_main_loop_new(NULL, false);
309
310         sensor_event_dispatcher::get_instance().run();
311         external_sensor_service::get_instance().run();
312
313         listen_command_channel();
314         listen_event_channel();
315
316         std::thread event_channel_accepter(&server::accept_event_channel, this);
317         event_channel_accepter.detach();
318
319         std::thread command_channel_accepter(&server::accept_command_channel, this);
320         command_channel_accepter.detach();
321
322         std::thread event_poller(&server::poll_event, this);
323         event_poller.detach();
324
325         sd_notify(0, "READY=1");
326
327         g_main_loop_run(m_mainloop);
328 }
329
330 void server::terminate(void)
331 {
332         sensor_event_dispatcher::get_instance().stop();
333
334         close_socket();
335 }
336
337 void server::run(void)
338 {
339         initialize();
340         terminate();
341 }
342
343 void server::stop(void)
344 {
345         _I("Sensord server stopped");
346
347         m_running = false;
348
349         if (m_mainloop) {
350                 g_main_loop_quit(m_mainloop);
351                 g_main_loop_unref(m_mainloop);
352                 m_mainloop = NULL;
353         }
354 }
355
356 server& server::get_instance(void)
357 {
358         static server inst;
359         return inst;
360 }