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