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