Add sensor handle attribute
[platform/core/system/sensord.git] / src / client / 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 <sensor_log.h>
23 #include <sensor_info.h>
24 #include <sensor_utils.h>
25 #include <command_types.h>
26 #include <ipc_client.h>
27 #include <message.h>
28 #include <channel.h>
29
30 #include "sensor_manager_channel_handler.h"
31
32 using namespace sensor;
33
34 sensor_manager::sensor_manager()
35 : m_client(NULL)
36 , m_cmd_channel(NULL)
37 , m_mon_channel(NULL)
38 , m_connected(false)
39 , m_handler(NULL)
40 {
41         init();
42 }
43
44 sensor_manager::~sensor_manager()
45 {
46         deinit();
47 }
48
49 int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
50 {
51         if (!is_supported(uri)) {
52                 *sensor = NULL;
53                 _D("Not supported URI [%s]\n", uri);
54                 return -ENODATA;
55         }
56
57         sensor_info *info = get_info(uri);
58         retvm_if(!info, -EACCES, "There is no accessible sensor for uri[%s]", uri);
59
60         *sensor = (sensor_t)info;
61         return OP_SUCCESS;
62 }
63
64 int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
65 {
66         retv_if(!is_supported(uri), -ENODATA);
67
68         std::vector<sensor_info *> infos;
69         int size;
70
71         infos = get_infos(uri);
72         size = infos.size();
73         retvm_if(size == 0, -EACCES, "There is no accessible sensors for uri[%s]", uri);
74
75         *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
76         retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
77
78         for (int i = 0; i < size; ++i)
79                 *(*list + i) = infos[i];
80
81         *count = size;
82         return OP_SUCCESS;
83 }
84
85 bool sensor_manager::is_supported(sensor_t sensor)
86 {
87         retvm_if(!sensor, false, "Invalid sensor");
88
89         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
90                 if (&*it == sensor)
91                         return true;
92         }
93
94         return false;
95 }
96
97 bool sensor_manager::is_supported(const char *uri)
98 {
99         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
100                 return true;
101
102         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
103                 if ((*it).get_uri() == uri)
104                         return true;
105
106                 std::size_t found = (*it).get_uri().find_last_of("/");
107                 if (found == std::string::npos)
108                         continue;
109
110                 if ((*it).get_uri().substr(0, found) == uri)
111                         return true;
112         }
113
114         return false;
115 }
116
117 int sensor_manager::set_attribute(sensor_t sensor, int attribute, int value)
118 {
119         if (!sensor) {
120                 _E("Failed to validate the parameter");
121                 return -EINVAL;
122         }
123
124         if (!m_cmd_channel) {
125                 _E("Failed to connect to server");
126                 return -EIO;
127         }
128
129         ipc::message msg;
130         ipc::message reply;
131         cmd_manager_attr_int_t buf = {0, };
132
133         buf.attribute = attribute;
134         buf.value = value;
135
136         sensor_info *info = (sensor_info*)sensor;
137         memcpy(buf.sensor, info->get_uri().c_str(), info->get_uri().size());
138
139         msg.set_type(CMD_MANAGER_SET_ATTR_INT);
140         msg.enclose((char*)&buf, sizeof(buf));
141
142         bool ret = m_cmd_channel->send_sync(msg);
143         if (!ret) {
144                 _E("Failed to send command to set attribute");
145                 return -EIO;
146         }
147
148         ret = m_cmd_channel->read_sync(reply);
149         if (!ret) {
150                 _E("Failed to read reply to set attribute");
151                 return -EIO;
152         }
153
154         if (reply.header()->err < 0) {
155                 _E("Failed to set attribute");
156                 return reply.header()->err;
157         }
158
159         return OP_SUCCESS;
160 }
161
162 int sensor_manager::get_attribute(sensor_t sensor, int attribute, int *value)
163 {
164         if (!sensor || !value) {
165                 _E("Failed to validate the parameters");
166                 return -EINVAL;
167         }
168
169         if (!m_cmd_channel) {
170                 _E("Failed to connect to server");
171                 return -EIO;
172         }
173
174         ipc::message msg;
175         ipc::message reply;
176         cmd_manager_attr_int_t buf = {0, };
177
178         buf.attribute = attribute;
179
180         sensor_info *info = (sensor_info*)sensor;
181         memcpy(buf.sensor, info->get_uri().c_str(), info->get_uri().size());
182
183         msg.set_type(CMD_MANAGER_GET_ATTR_INT);
184         msg.enclose((char*)&buf, sizeof(buf));
185
186         bool ret = m_cmd_channel->send_sync(msg);
187         if (!ret) {
188                 _E("Failed to send command to get attribute");
189                 return -EIO;
190         }
191
192         ret = m_cmd_channel->read_sync(reply);
193         if (!ret) {
194                 _E("Failed to read reply to get attribute");
195                 return -EIO;
196         }
197
198         if (reply.header()->err < 0) {
199                 _E("Failed to get attribute");
200                 return reply.header()->err;
201         }
202
203         if (!reply.header()->length || !reply.body()) {
204                 _E("Failed to get attribute");
205                 return -EIO;
206         }
207
208         *value = ((cmd_manager_attr_int_t *)reply.body())->value;
209
210         return OP_SUCCESS;
211 }
212
213 int sensor_manager::add_sensor(sensor_info &info)
214 {
215         retv_if(is_supported(info.get_uri().c_str()), OP_ERROR);
216
217         m_sensors.push_back(info);
218
219         _I("Added sensor[%s]", info.get_uri().c_str());
220
221         return OP_SUCCESS;
222 }
223
224 int sensor_manager::add_sensor(sensor_provider *provider)
225 {
226         retvm_if(!provider, -EINVAL, "Invalid parameter");
227         return add_sensor(*(provider->get_sensor_info()));
228 }
229
230 int sensor_manager::remove_sensor(const char *uri)
231 {
232         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
233                 if ((*it).get_uri() == uri) {
234                         m_sensors.erase(it);
235                         _I("Removed sensor[%s]", uri);
236
237                         return OP_SUCCESS;
238                 }
239         }
240
241         return OP_ERROR;
242 }
243
244 int sensor_manager::remove_sensor(sensor_provider *provider)
245 {
246         retvm_if(!provider, -EINVAL, "Invalid parameter");
247         return remove_sensor(provider->get_uri());
248 }
249
250 void sensor_manager::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
251 {
252         m_handler->add_sensor_added_cb(cb, user_data);
253 }
254
255 void sensor_manager::remove_sensor_added_cb(sensord_added_cb cb)
256 {
257         m_handler->remove_sensor_added_cb(cb);
258 }
259
260 void sensor_manager::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
261 {
262         m_handler->add_sensor_removed_cb(cb, user_data);
263 }
264
265 void sensor_manager::remove_sensor_removed_cb(sensord_removed_cb cb)
266 {
267         m_handler->remove_sensor_removed_cb(cb);
268 }
269
270 bool sensor_manager::init(void)
271 {
272         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
273         retvm_if(!m_client, false, "Failed to allocate memory");
274
275         m_handler = new(std::nothrow) channel_handler(this);
276         if (!m_handler) {
277                 delete m_client;
278                 m_client = NULL;
279                 return false;
280         }
281
282         return true;
283 }
284
285 void sensor_manager::deinit(void)
286 {
287         disconnect();
288
289         delete m_handler;
290         m_handler = NULL;
291
292         delete m_client;
293         m_client = NULL;
294 }
295
296 bool sensor_manager::connect_channel(void)
297 {
298         ipc::message msg;
299
300         m_cmd_channel = m_client->connect(NULL);
301         retvm_if(!m_cmd_channel, false, "Failed to connect to server");
302
303         m_mon_channel = m_client->connect(m_handler, &m_loop);
304         retvm_if(!m_mon_channel, false, "Failed to connect to server");
305
306         msg.set_type(CMD_MANAGER_CONNECT);
307         m_mon_channel->send_sync(msg);
308
309         m_connected.store(true);
310
311         _D("Connected");
312         return true;
313 }
314
315 bool sensor_manager::connect(void)
316 {
317         retv_if(is_connected(), true);
318         retv_if(!connect_channel(), false);
319
320         return get_sensors_internal();
321 }
322
323 void sensor_manager::disconnect(void)
324 {
325         ret_if(!is_connected());
326         m_connected.store(false);
327
328         m_mon_channel->disconnect();
329         delete m_mon_channel;
330         m_mon_channel = NULL;
331
332         m_cmd_channel->disconnect();
333         delete m_cmd_channel;
334         m_cmd_channel = NULL;
335
336         _D("Disconnected");
337 }
338
339 bool sensor_manager::is_connected(void)
340 {
341         return m_connected.load();
342 }
343
344 void sensor_manager::restore(void)
345 {
346         ret_if(!is_connected());
347
348         m_cmd_channel->disconnect();
349         delete m_cmd_channel;
350         m_cmd_channel = NULL;
351
352         m_connected.store(false);
353         retm_if(!connect_channel(), "Failed to restore manager");
354
355         _D("Restored manager");
356 }
357
358 void sensor_manager::decode_sensors(const char *buf, std::list<sensor_info> &infos)
359 {
360         int count = 0;
361         sensor_info info;
362         const int32_t *size;
363         const char *data;
364         cmd_manager_sensor_list_t *raw;
365
366         raw = (cmd_manager_sensor_list_t *)buf;
367         count = raw->sensor_cnt;
368         size = (const int32_t *)raw->data;
369         data = (const char *)raw->data + sizeof(int32_t);
370
371         for (int i = 0; i < count; ++i) {
372                 info.clear();
373                 info.deserialize(data, size[0]);
374                 infos.push_back(info);
375
376                 size = (const int32_t *)((const char *)data + size[0]);
377                 data = (const char *)size + sizeof(int32_t);
378         }
379
380         _D("Sensor count : %d", count);
381 }
382
383 bool sensor_manager::get_sensors_internal(void)
384 {
385         retvm_if(!is_connected(), false, "Failed to get sensors");
386
387         bool ret;
388         ipc::message msg;
389         ipc::message reply;
390         char buf[MAX_BUF_SIZE];
391
392         msg.set_type(CMD_MANAGER_SENSOR_LIST);
393
394         ret = m_cmd_channel->send_sync(msg);
395         retvm_if(!ret, false, "Failed to send message");
396
397         ret = m_cmd_channel->read_sync(reply);
398         retvm_if(!ret, false, "Failed to receive message");
399
400         reply.disclose(buf, MAX_BUF_SIZE);
401
402         if (!m_sensors.empty())
403                 m_sensors.clear();
404
405         decode_sensors(buf, m_sensors);
406
407         return true;
408 }
409
410 bool sensor_manager::has_privilege(std::string &uri)
411 {
412         retvm_if(!is_connected(), false, "Failed to get sensors");
413
414         bool ret;
415         ipc::message msg;
416         ipc::message reply;
417         cmd_has_privilege_t buf = {0, };
418
419         msg.set_type(CMD_HAS_PRIVILEGE);
420         memcpy(buf.sensor, uri.c_str(), uri.size());
421         msg.enclose((const char *)&buf, sizeof(buf));
422
423         ret = m_cmd_channel->send_sync(msg);
424         retvm_if(!ret, false, "Failed to send message");
425
426         ret = m_cmd_channel->read_sync(reply);
427         retvm_if(!ret, false, "Failed to receive message");
428
429         if (reply.header()->err == OP_SUCCESS)
430                 return true;
431
432         _W("This client doesn't have the privilege for sensor[%s]", uri.c_str());
433
434         return false;
435 }
436
437 sensor_info *sensor_manager::get_info(const char *uri)
438 {
439         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
440                 return &m_sensors.front();
441
442         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
443                 if ((*it).get_uri() != uri)
444                         continue;
445
446                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
447                         return &*it;
448
449                 return NULL;
450         }
451
452         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
453                 std::size_t found = (*it).get_uri().find_last_of("/");
454                 if (found == std::string::npos)
455                         continue;
456                 if ((*it).get_uri().substr(0, found) != uri)
457                         continue;
458
459                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
460                         return &*it;
461         }
462
463         return NULL;
464 }
465
466 std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
467 {
468         std::vector<sensor_info *> infos;
469         bool all = false;
470
471         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
472                 all = true;
473
474         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
475                 if ((*it).get_uri() != uri)
476                         continue;
477
478                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
479                         infos.push_back(&*it);
480
481                 return infos;
482         }
483
484         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
485                 std::size_t found = (*it).get_uri().find_last_of("/");
486                 if (!all && found == std::string::npos)
487                         continue;
488                 if (!all && (*it).get_uri().substr(0, found) != uri)
489                         continue;
490
491                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
492                         infos.push_back(&*it);
493         }
494
495         return infos;
496 }
497