sensord: ternimate sensord instantly when signal is received
[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 <sys/stat.h>
24 #include <systemd/sd-daemon.h>
25 #include <sensor_log.h>
26 #include <command_types.h>
27 #include <ipc_server.h>
28
29 #include "sensor_manager.h"
30 #include "server_channel_handler.h"
31
32 #define MAX_CONFIG_PATH 255
33 #define CAL_CONFIG_PATH "/etc/sensor_cal.conf"
34 #define SET_CAL 1
35 //#define CAL_NODE_PATH "/sys/class/sensors/ssp_sensor/set_cal_data"
36
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
91         is_running.store(true);
92         sd_notify(0, "READY=1");
93
94         return true;
95 }
96
97 void server::deinit(void)
98 {
99         m_server->close();
100         m_manager->deinit();
101
102         delete m_server;
103         m_server = NULL;
104
105         delete m_manager;
106         m_manager = NULL;
107
108         delete m_handler;
109         m_handler = NULL;
110
111         is_running.store(false);
112 }
113
114 static void set_cal_data(const char *path)
115 {
116         struct stat file_stat;
117
118         if (lstat(path, &file_stat) != 0)
119                 return;
120
121         if (!S_ISREG(file_stat.st_mode))
122                 return;
123
124         FILE *fp = fopen(path, "w");
125         retm_if(!fp, "There is no calibration file[%s]", path);
126
127         fprintf(fp, "%d", SET_CAL);
128         fclose(fp);
129
130         _I("Succeeded to set calibration data");
131 }
132
133 void server::init_calibration(void)
134 {
135         char path[MAX_CONFIG_PATH];
136
137         FILE *fp = fopen(CAL_CONFIG_PATH, "r");
138         retm_if(!fp, "There is no config file[%s]", CAL_CONFIG_PATH);
139
140         while (!feof(fp)) {
141                 if (fgets(path, sizeof(path), fp) == NULL)
142                         break;
143                 set_cal_data(path);
144         }
145
146         fclose(fp);
147 }
148
149 void server::init_server(void)
150 {
151         m_manager->init();
152
153         /* TODO: setting socket option */
154         m_server->set_option("max_connection", MAX_CONNECTION);
155         m_server->set_option(SO_TYPE, SOCK_STREAM);
156         m_server->bind(m_handler, &m_loop);
157 }