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