Merge branch 'devel/tizen' into tizen
[platform/core/system/sensord.git] / src / server / server.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2017 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 "server.h"
21
22 #include <unistd.h>
23 #include <systemd/sd-daemon.h>
24 #include <sensor_log.h>
25 #include <command_types.h>
26 #include <ipc_server.h>
27
28 #include "sensor_manager.h"
29 #include "server_channel_handler.h"
30
31 #define MAX_CONFIG_PATH 255
32 #define CAL_CONFIG_PATH "/etc/sensor_cal.conf"
33 #define SET_CAL 1
34 //#define CAL_NODE_PATH "/sys/class/sensors/ssp_sensor/set_cal_data"
35
36 #define TIMEOUT_TERM 10
37 #define MAX_CONNECTION 1000
38
39 using namespace sensor;
40
41 ipc::event_loop server::m_loop;
42 std::atomic<bool> server::is_running(false);
43
44 server::server()
45 : m_server(NULL)
46 , m_manager(NULL)
47 , m_handler(NULL)
48 {
49 }
50
51 server &server::instance(void)
52 {
53         static server inst;
54         return inst;
55 }
56
57 void server::run(void)
58 {
59         _I("Starting..");
60
61         retm_if(is_running.load(), "Server is running");
62         retm_if(!instance().init(), "Failed to initialize server");
63
64         m_loop.run();
65 }
66
67 void server::stop(void)
68 {
69         _I("Stopping..");
70
71         retm_if(!is_running.load(), "Server is not running");
72
73         m_loop.stop();
74         instance().deinit();
75 }
76
77 bool server::init(void)
78 {
79         m_server = new(std::nothrow) ipc::ipc_server(SENSOR_CHANNEL_PATH);
80         retvm_if(!m_server, false, "Failed to allocate memory");
81
82         m_manager = new(std::nothrow) sensor_manager(&m_loop);
83         retvm_if(!m_manager, false, "Failed to allocate memory");
84
85         m_handler = new(std::nothrow) server_channel_handler(m_manager);
86         retvm_if(!m_handler, false, "Failed to allocate memory");
87
88         init_calibration();
89         init_server();
90         init_termination();
91
92         is_running.store(true);
93         sd_notify(0, "READY=1");
94
95         return true;
96 }
97
98 void server::deinit(void)
99 {
100         m_manager->deinit();
101         m_server->close();
102
103         delete m_server;
104         m_server = NULL;
105
106         delete m_manager;
107         m_manager = NULL;
108
109         delete m_handler;
110         m_handler = NULL;
111
112         is_running.store(false);
113 }
114
115 static void set_cal_data(const char *path)
116 {
117         FILE *fp = fopen(path, "w");
118         retm_if(!fp, "There is no calibration file[%s]", path);
119
120         fprintf(fp, "%d", SET_CAL);
121         fclose(fp);
122
123         _I("Succeeded to set calibration data");
124 }
125
126 void server::init_calibration(void)
127 {
128         char path[MAX_CONFIG_PATH];
129
130         FILE *fp = fopen(CAL_CONFIG_PATH, "r");
131         retm_if(!fp, "There is no config file[%s]", CAL_CONFIG_PATH);
132
133         while (!feof(fp)) {
134                 if (fgets(path, sizeof(path), fp) == NULL)
135                         break;
136                 set_cal_data(path);
137         }
138
139         fclose(fp);
140 }
141
142 void server::init_server(void)
143 {
144         m_manager->init();
145
146         /* TODO: setting socket option */
147         m_server->set_option("max_connection", MAX_CONNECTION);
148         m_server->set_option(SO_TYPE, SOCK_STREAM);
149         m_server->bind(m_handler, &m_loop);
150 }
151
152 static gboolean terminate(gpointer data)
153 {
154         sensor_manager *mgr = reinterpret_cast<sensor_manager *>(data);
155         std::vector<sensor_handler *> sensors = mgr->get_sensors();
156
157         if (sensors.size() <= 0) {
158                 _I("Terminating.. because there is no sensors");
159                 server::stop();
160         }
161
162         return FALSE;
163 }
164
165 void server::init_termination(void)
166 {
167         g_timeout_add_seconds(TIMEOUT_TERM, terminate, m_manager);
168 }