Merge branch 'devel/tizen' into tizen
[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                 return -ENODATA;
54         }
55
56         sensor_info *info = get_info(uri);
57         retv_if(!info, -EACCES);
58
59         *sensor = (sensor_t)info;
60         return OP_SUCCESS;
61 }
62
63 int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
64 {
65         retv_if(!is_supported(uri), -ENODATA);
66
67         std::vector<sensor_info *> infos;
68         int size;
69
70         infos = get_infos(uri);
71         size = infos.size();
72         retv_if(size == 0, -EACCES);
73
74         *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
75         retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
76
77         for (int i = 0; i < size; ++i)
78                 *(*list + i) = infos[i];
79
80         *count = size;
81         return OP_SUCCESS;
82 }
83
84 bool sensor_manager::is_supported(sensor_t sensor)
85 {
86         retvm_if(!sensor, false, "Invalid parameter[%#x]", sensor);
87
88         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
89                 if (&*it == sensor)
90                         return true;
91         }
92
93         return false;
94 }
95
96 bool sensor_manager::is_supported(const char *uri)
97 {
98         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
99                 return true;
100
101         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
102                 if ((*it).get_uri() == uri)
103                         return true;
104
105                 std::size_t found = (*it).get_uri().find_last_of("/");
106                 if (found == std::string::npos)
107                         continue;
108
109                 if ((*it).get_uri().substr(0, found) == uri)
110                         return true;
111         }
112
113         return false;
114 }
115
116 int sensor_manager::add_sensor(sensor_info &info)
117 {
118         retv_if(is_supported(info.get_uri().c_str()), OP_ERROR);
119
120         m_sensors.push_back(info);
121
122         return OP_SUCCESS;
123 }
124
125 int sensor_manager::add_sensor(sensor_provider *provider)
126 {
127         retvm_if(!provider, -EINVAL, "Invalid parameter");
128         return add_sensor(*(provider->get_sensor_info()));
129 }
130
131 int sensor_manager::remove_sensor(const char *uri)
132 {
133         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
134                 if ((*it).get_uri() == uri) {
135                         m_sensors.erase(it);
136                         return OP_SUCCESS;
137                 }
138         }
139
140         return OP_ERROR;
141 }
142
143 int sensor_manager::remove_sensor(sensor_provider *provider)
144 {
145         retvm_if(!provider, -EINVAL, "Invalid parameter");
146         return remove_sensor(provider->get_uri());
147 }
148
149 void sensor_manager::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
150 {
151         m_handler->add_sensor_added_cb(cb, user_data);
152 }
153
154 void sensor_manager::remove_sensor_added_cb(sensord_added_cb cb)
155 {
156         m_handler->remove_sensor_added_cb(cb);
157 }
158
159 void sensor_manager::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
160 {
161         m_handler->add_sensor_removed_cb(cb, user_data);
162 }
163
164 void sensor_manager::remove_sensor_removed_cb(sensord_removed_cb cb)
165 {
166         m_handler->remove_sensor_removed_cb(cb);
167 }
168
169 bool sensor_manager::init(void)
170 {
171         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
172         retvm_if(!m_client, false, "Failed to allocate memory");
173
174         m_handler = new(std::nothrow) channel_handler(this);
175         if (!m_handler) {
176                 delete m_client;
177                 m_client = NULL;
178                 return false;
179         }
180
181         return true;
182 }
183
184 void sensor_manager::deinit(void)
185 {
186         disconnect();
187
188         delete m_handler;
189         m_handler = NULL;
190
191         delete m_client;
192         m_client = NULL;
193 }
194
195 bool sensor_manager::connect_channel(void)
196 {
197         ipc::message msg;
198
199         m_cmd_channel = m_client->connect(NULL);
200         retvm_if(!m_cmd_channel, false, "Failed to connect to server");
201
202         m_mon_channel = m_client->connect(m_handler, &m_loop);
203         retvm_if(!m_mon_channel, false, "Failed to connect to server");
204
205         msg.set_type(CMD_MANAGER_CONNECT);
206         m_mon_channel->send_sync(&msg);
207
208         m_connected.store(true);
209
210         _D("Connected");
211         return true;
212 }
213
214 bool sensor_manager::connect(void)
215 {
216         retv_if(is_connected(), true);
217         retv_if(!connect_channel(), false);
218
219         return get_sensors_internal();
220 }
221
222 void sensor_manager::disconnect(void)
223 {
224         ret_if(!is_connected());
225         m_connected.store(false);
226
227         m_mon_channel->disconnect();
228         delete m_mon_channel;
229         m_mon_channel = NULL;
230
231         m_cmd_channel->disconnect();
232         delete m_cmd_channel;
233         m_cmd_channel = NULL;
234
235         _D("Disconnected");
236 }
237
238 bool sensor_manager::is_connected(void)
239 {
240         return m_connected.load();
241 }
242
243 void sensor_manager::restore(void)
244 {
245         ret_if(!is_connected());
246
247         m_connected.store(false);
248         retm_if(!connect_channel(), "Failed to restore manager");
249
250         _D("Restored manager");
251 }
252
253 void sensor_manager::decode_sensors(const char *buf, std::vector<sensor_info> &infos)
254 {
255         int count = 0;
256         sensor_info info;
257         const int32_t *size;
258         const char *data;
259         cmd_manager_sensor_list_t *raw;
260
261         raw = (cmd_manager_sensor_list_t *)buf;
262         count = raw->sensor_cnt;
263         size = (const int32_t *)raw->data;
264         data = (const char *)raw->data + sizeof(int32_t);
265
266         for (int i = 0; i < count; ++i) {
267                 info.clear();
268                 info.deserialize(data, size[0]);
269                 infos.push_back(info);
270
271                 size = (const int32_t *)((const char *)data + size[0]);
272                 data = (const char *)size + sizeof(int32_t);
273         }
274
275         _D("Sensor count : %d", count);
276 }
277
278 bool sensor_manager::get_sensors_internal(void)
279 {
280         retvm_if(!is_connected(), false, "Failed to get sensors");
281
282         bool ret;
283         ipc::message msg;
284         ipc::message reply;
285         char buf[MAX_BUF_SIZE];
286
287         msg.set_type(CMD_MANAGER_SENSOR_LIST);
288
289         ret = m_cmd_channel->send_sync(&msg);
290         retvm_if(!ret, false, "Failed to send message");
291
292         ret = m_cmd_channel->read_sync(reply);
293         retvm_if(!ret, false, "Failed to receive message");
294
295         reply.disclose(buf);
296
297         decode_sensors(buf, m_sensors);
298
299         return true;
300 }
301
302 bool sensor_manager::has_privilege(std::string &uri)
303 {
304         retvm_if(!is_connected(), false, "Failed to get sensors");
305
306         bool ret;
307         ipc::message msg;
308         ipc::message reply;
309         cmd_has_privilege_t buf = {0, };
310
311         msg.set_type(CMD_HAS_PRIVILEGE);
312         memcpy(buf.sensor, uri.c_str(), uri.size());
313         msg.enclose((const char *)&buf, sizeof(buf));
314
315         ret = m_cmd_channel->send_sync(&msg);
316         retvm_if(!ret, false, "Failed to send message");
317
318         ret = m_cmd_channel->read_sync(reply);
319         retvm_if(!ret, false, "Failed to receive message");
320
321         if (reply.header()->err == OP_SUCCESS)
322                 return true;
323
324         return false;
325 }
326
327 sensor_info *sensor_manager::get_info(const char *uri)
328 {
329         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
330                 return &m_sensors[0];
331
332         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
333                 if ((*it).get_uri() != uri)
334                         continue;
335
336                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
337                         return &*it;
338
339                 return NULL;
340         }
341
342         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
343                 std::size_t found = (*it).get_uri().find_last_of("/");
344                 if (found == std::string::npos)
345                         continue;
346                 if ((*it).get_uri().substr(0, found) != uri)
347                         continue;
348
349                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
350                         return &*it;
351         }
352
353         return NULL;
354 }
355
356 std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
357 {
358         std::vector<sensor_info *> infos;
359         bool all = false;
360
361         if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
362                 all = true;
363
364         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
365                 if ((*it).get_uri() != uri)
366                         continue;
367
368                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
369                         infos.push_back(&*it);
370
371                 return infos;
372         }
373
374         for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
375                 std::size_t found = (*it).get_uri().find_last_of("/");
376                 if (!all && found == std::string::npos)
377                         continue;
378                 if (!all && (*it).get_uri().substr(0, found) != uri)
379                         continue;
380
381                 if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
382                         infos.push_back(&*it);
383         }
384
385         return infos;
386 }
387