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