[Tizen 5.0] Sensord: Fix memory leak
[platform/core/system/sensord.git] / src / client / sensor_provider.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_provider.h"
21
22 #include <message.h>
23 #include <channel.h>
24 #include <sensor_log.h>
25 #include <sensor_types.h>
26 #include <sensor_utils.h>
27 #include <ipc_client.h>
28 #include <command_types.h>
29 #include <cfloat>
30 #include <cmath>
31
32 #include "sensor_provider_channel_handler.h"
33
34 #define DEFAULT_RESOLUTION 0.1
35
36 using namespace sensor;
37
38 sensor_provider::sensor_provider(const char *uri)
39 : m_client(NULL)
40 , m_channel(NULL)
41 , m_handler(NULL)
42 , m_connected(false)
43 {
44         init(uri);
45 }
46
47 sensor_provider::~sensor_provider()
48 {
49         deinit();
50 }
51
52 bool sensor_provider::init(const char *uri)
53 {
54         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
55         retvm_if(!m_client, false, "Failed to allocate memory");
56
57         m_handler = new(std::nothrow) channel_handler(this);
58         if (!m_handler) {
59                 delete m_client;
60                 return false;
61         }
62
63         m_sensor.set_uri(uri);
64         m_sensor.set_min_range(-FLT_MAX);
65         m_sensor.set_max_range(FLT_MAX);
66         m_sensor.set_resolution(DEFAULT_RESOLUTION);
67         /* TODO: temporary walkaround */
68         const char *priv = sensor::utils::get_privilege(uri);
69         m_sensor.set_privilege(priv);
70
71         return true;
72 }
73
74 void sensor_provider::deinit(void)
75 {
76         disconnect();
77
78         delete m_handler;
79         m_handler = NULL;
80
81         delete m_client;
82         m_client = NULL;
83 }
84
85 const char *sensor_provider::get_uri(void)
86 {
87         return m_sensor.get_uri().c_str();
88 }
89
90 sensor_info *sensor_provider::get_sensor_info(void)
91 {
92         return &m_sensor;
93 }
94
95 int sensor_provider::serialize(sensor_info *info, char **bytes)
96 {
97         int size;
98         raw_data_t *raw = new(std::nothrow) raw_data_t;
99         retvm_if(!raw, -ENOMEM, "Failed to allocated memory");
100
101         info->serialize(*raw);
102
103         *bytes = new(std::nothrow) char[raw->size()];
104         retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory");
105
106         std::copy(raw->begin(), raw->end(), *bytes);
107
108         size = raw->size();
109         delete raw;
110
111         return size;
112 }
113
114 int sensor_provider::send_sensor_info(sensor_info *info)
115 {
116         char *bytes;
117         int size;
118
119         size = serialize(info, &bytes);
120
121         ipc::message msg((const char *)bytes, size);
122         msg.set_type(CMD_PROVIDER_CONNECT);
123
124         m_channel->send_sync(&msg);
125
126         return OP_SUCCESS;
127 }
128
129 int sensor_provider::connect(void)
130 {
131         m_channel = m_client->connect(m_handler, &m_loop);
132         retvm_if(!m_channel, -EIO, "Failed to connect to server");
133
134         /* serialize and send sensor info */
135         send_sensor_info(get_sensor_info());
136
137         /* check error */
138         ipc::message reply;
139         m_channel->read_sync(reply);
140         retv_if(reply.header()->err < 0, reply.header()->err);
141
142         m_connected.store(true);
143
144         _I("Provider URI[%s]", get_uri());
145
146         return OP_SUCCESS;
147 }
148
149 bool sensor_provider::disconnect(void)
150 {
151         retv_if(!is_connected(), false);
152         m_connected.store(false);
153
154         m_channel->disconnect();
155         delete m_channel;
156         m_channel = NULL;
157
158         _I("Disconnected[%s]", get_uri());
159
160         return true;
161 }
162
163 void sensor_provider::restore(void)
164 {
165         ret_if(!is_connected());
166         retm_if(!connect(), "Failed to restore provider");
167
168         _D("Restored provider[%s]", get_uri());
169 }
170
171 int sensor_provider::publish(sensor_data_t *data, int len)
172 {
173         for (int i = 0; i < data->value_count; ++i) {
174                 if (!(data->values[i] >= m_sensor.get_min_range() &&
175                       data->values[i] <= m_sensor.get_max_range())) {
176                         _E("Out of range");
177                         return OP_ERROR;
178                 }
179         }
180
181         ipc::message msg;
182         msg.set_type(CMD_PROVIDER_PUBLISH);
183         msg.enclose((const char *)data, len);
184
185         m_channel->send_sync(&msg);
186
187         return OP_SUCCESS;
188 }
189
190 bool sensor_provider::is_connected(void)
191 {
192         return m_connected.load();
193 }
194
195 void sensor_provider::set_start_cb(sensord_provider_start_cb cb, void *user_data)
196 {
197         m_handler->set_start_cb(cb, user_data);
198 }
199
200 void sensor_provider::set_stop_cb(sensord_provider_stop_cb cb, void *user_data)
201 {
202         m_handler->set_stop_cb(cb, user_data);
203 }
204
205 void sensor_provider::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data)
206 {
207         m_handler->set_interval_cb(cb, user_data);
208 }
209