sensord: modify sensor plugin interface
[platform/core/system/sensord.git] / src / server / sensor_manager.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 "sensor_manager.h"
21
22 #include <unistd.h>
23 #include <sensor_log.h>
24 #include <string>
25 #include <vector>
26 #include <memory>
27 #include <algorithm>
28
29 #include "sensor_event_handler.h"
30 #include "sensor_loader.h"
31 #include "physical_sensor_handler.h"
32 #include "fusion_sensor_handler.h"
33 #include "external_sensor_handler.h"
34 #include "fusion_sensor_handler.h"
35
36 using namespace sensor;
37
38 #define DEVICE_HAL_DIR_PATH_LEGACY LIBDIR "/sensor"
39 #define DEVICE_HAL_DIR_PATH LIBDIR "/sensor/hal"
40 #define PHYSICAL_SENSOR_DIR_PATH LIBDIR "/sensor/physical"
41 #define VIRTUAL_SENSOR_DIR_PATH LIBDIR "/sensor/fusion"
42 #define EXTERNAL_SENSOR_DIR_PATH LIBDIR "/sensor/external"
43
44 static device_sensor_registry_t devices;
45 static physical_sensor_registry_t physical_sensors;
46 static fusion_sensor_registry_t fusion_sensors;
47 static external_sensor_registry_t external_sensors;
48
49 sensor_manager::sensor_manager(ipc::event_loop *loop)
50 : m_loop(loop)
51 {
52 }
53
54 sensor_manager::~sensor_manager()
55 {
56 }
57
58 bool sensor_manager::init(void)
59 {
60         m_loader.load_hal(DEVICE_HAL_DIR_PATH_LEGACY, devices);
61         m_loader.load_hal(DEVICE_HAL_DIR_PATH, devices);
62         m_loader.load_physical_sensor(PHYSICAL_SENSOR_DIR_PATH, physical_sensors);
63         m_loader.load_fusion_sensor(VIRTUAL_SENSOR_DIR_PATH, fusion_sensors);
64         m_loader.load_external_sensor(EXTERNAL_SENSOR_DIR_PATH, external_sensors);
65
66         retvm_if(devices.empty(), false, "There is no sensors");
67
68         /* TODO: support dynamic sensor */
69         create_physical_sensors(devices, physical_sensors);
70         create_fusion_sensors(fusion_sensors);
71         create_external_sensors(external_sensors);
72
73         init_sensors();
74
75         show();
76
77         return true;
78 }
79
80 bool sensor_manager::deinit(void)
81 {
82         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it)
83                 delete it->second;
84         m_sensors.clear();
85
86         external_sensors.clear();
87         fusion_sensors.clear();
88         physical_sensors.clear();
89         devices.clear();
90
91         m_loader.unload();
92
93         return true;
94 }
95
96 bool sensor_manager::is_supported(std::string uri)
97 {
98         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
99                 sensor_info info = it->second->get_sensor_info();
100
101                 if (info.get_uri() == uri)
102                         return true;
103         }
104
105         return false;
106 }
107
108 bool sensor_manager::register_sensor(sensor_handler *sensor)
109 {
110         retvm_if(!sensor, false, "Invalid sensor");
111
112         sensor_info info = sensor->get_sensor_info();
113
114         auto it = m_sensors.find(info.get_uri());
115         retvm_if(it != m_sensors.end(), false, "There is already a sensor with the same name");
116
117         m_sensors[info.get_uri()] = sensor;
118
119         _I("Registered[%s]", info.get_uri().c_str());
120
121         return true;
122 }
123
124 void sensor_manager::deregister_sensor(const std::string uri)
125 {
126         auto it = m_sensors.find(uri);
127         ret_if(it == m_sensors.end());
128
129         delete it->second;
130         m_sensors.erase(it);
131
132         _I("Deregistered[%s]", uri.c_str());
133 }
134
135 sensor_handler *sensor_manager::get_sensor_by_type(const std::string uri)
136 {
137         auto it = m_sensors.begin();
138         for (; it != m_sensors.end(); ++it) {
139                 std::size_t found = it->first.rfind(uri);
140                 if (found != std::string::npos)
141                         return it->second;
142         }
143
144         return NULL;
145 }
146
147 sensor_handler *sensor_manager::get_sensor(const std::string uri)
148 {
149         auto it = m_sensors.find(uri);
150         retv_if(it == m_sensors.end(), NULL);
151
152         return m_sensors[uri];
153 }
154
155 std::vector<sensor_handler *> sensor_manager::get_sensors(void)
156 {
157         std::vector<sensor_handler *> sensors;
158
159         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it)
160                 sensors.push_back(it->second);
161
162         return sensors;
163 }
164
165 void sensor_manager::create_physical_sensors(device_sensor_registry_t &devices,
166                 physical_sensor_registry_t &psensors)
167 {
168         const sensor_info_t *info;
169         physical_sensor_handler *psensor;
170
171         for (auto it = devices.begin(); it != devices.end(); ++it) {
172                 int count = (*it)->get_sensors(&info);
173
174                 for (int i = 0; i < count; ++i) {
175                         /* TODO: psensors */
176                         psensor = new(std::nothrow) physical_sensor_handler(
177                                         info[i], it->get(), info[i].id, NULL);
178                         retm_if(!psensor, "Failed to allocate memory");
179
180                         sensor_info sinfo = psensor->get_sensor_info();
181                         m_sensors[sinfo.get_uri()] = psensor;
182                 }
183         }
184
185 }
186
187 void sensor_manager::create_fusion_sensors(fusion_sensor_registry_t &fsensors)
188 {
189         const sensor_info2_t *info;
190         const required_sensor_s *required_sensors;
191         fusion_sensor_handler *fsensor;
192         sensor_handler *sensor = NULL;
193
194         for (auto it = fsensors.begin(); it != fsensors.end(); ++it) {
195                 bool support = true;
196
197                 (*it)->get_sensor_info(&info);
198
199                 fsensor = new(std::nothrow) fusion_sensor_handler(info[0], it->get());
200                 retm_if(!fsensor, "Failed to allocate memory");
201
202                 int count = (*it)->get_required_sensors(&required_sensors);
203                 for (int i = 0; i < count; ++i) {
204                         sensor = get_sensor_by_type(required_sensors[i].uri);
205
206                         if (sensor == NULL) {
207                                 support = false;
208                                 break;
209                         }
210
211                         fsensor->add_required_sensor(required_sensors[i].id, sensor);
212                 }
213
214                 if (!support) {
215                         delete fsensor;
216                         continue;
217                 }
218
219                 sensor_info sinfo = fsensor->get_sensor_info();
220                 m_sensors[sinfo.get_uri()] = fsensor;
221         }
222 }
223
224 void sensor_manager::create_external_sensors(external_sensor_registry_t &esensors)
225 {
226         const sensor_info2_t *info;
227         external_sensor_handler *esensor;
228
229         for (auto it = esensors.begin(); it != esensors.end(); ++it) {
230                 (*it)->get_sensor_info(&info);
231
232                 esensor = new(std::nothrow) external_sensor_handler(info[0], it->get());
233                 retm_if(!esensor, "Failed to allocate memory");
234
235                 sensor_info sinfo = esensor->get_sensor_info();
236                 m_sensors[sinfo.get_uri()] = esensor;
237         }
238 }
239
240 static void put_int_to_vec(std::vector<char> &data, int value)
241 {
242         char buf[sizeof(value)];
243
244         int *temp = (int *)buf;
245         *temp = value;
246
247         std::copy(&buf[0], &buf[sizeof(buf)], back_inserter(data));
248 }
249
250 /* packet format :
251  * [count:4] {[size:4] [info:n] [size:4] [info:n] ...}
252  */
253 size_t sensor_manager::serialize(int sock_fd, char **bytes)
254 {
255         sensor_info info;
256         std::vector<char> raw_list;
257
258         put_int_to_vec(raw_list, m_sensors.size());
259
260         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
261                 info = it->second->get_sensor_info();
262
263                 raw_data_t *raw = new(std::nothrow) raw_data_t();
264                 retvm_if(!raw, -ENOMEM, "Failed to allocated memory");
265
266                 info.serialize(*raw);
267
268                 /* copy size */
269                 put_int_to_vec(raw_list, raw->size());
270
271                 /* copy info */
272                 std::copy(raw->begin(), raw->end(), std::back_inserter(raw_list));
273
274                 delete raw;
275         }
276
277         *bytes = new(std::nothrow) char[raw_list.size()];
278         retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory");
279
280         std::copy(raw_list.begin(), raw_list.end(), *bytes);
281
282         return raw_list.size();
283 }
284
285 void sensor_manager::init_sensors(void)
286 {
287         physical_sensor_handler *sensor;
288
289         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
290                 sensor = dynamic_cast<physical_sensor_handler *>(it->second);
291                 if (sensor == NULL)
292                         continue;
293
294                 /* it doesn't need to deregister handlers, they are consumed in event_loop */
295                 register_handler(sensor);
296         }
297 }
298
299 void sensor_manager::register_handler(physical_sensor_handler *sensor)
300 {
301         ret_if(sensor->get_poll_fd() < 0);
302
303         sensor_event_handler *handler = new(std::nothrow) sensor_event_handler(sensor);
304         retm_if(!handler, "Failed to allocate memory");
305
306         m_loop->add_event(sensor->get_poll_fd(),
307                         ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL, handler);
308 }
309
310 void sensor_manager::show(void)
311 {
312         int index = 0;
313
314         _I("========== Loaded sensor information ==========\n");
315         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
316                 sensor_info info = it->second->get_sensor_info();
317
318                 _I("Sensor #%d[%s]: ", ++index, it->first.c_str());
319                 info.show();
320         }
321         _I("===============================================\n");
322 }