sensord: fix warnings detected from static analysis
[platform/core/system/sensord.git] / src / client / sensor_listener.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_listener.h"
21
22 #include <channel_handler.h>
23 #include <sensor_log.h>
24 #include <sensor_types.h>
25 #include <command_types.h>
26 #include <ipc_client.h>
27
28 using namespace sensor;
29
30 class listener_handler : public ipc::channel_handler
31 {
32 public:
33         listener_handler(sensor_listener *listener)
34         : m_listener(listener)
35         {}
36         void connected(ipc::channel *ch) {}
37         void disconnected(ipc::channel *ch)
38         {
39                 /* If channel->disconnect() is not explicitly called,
40                  * listener will be restored */
41                 m_listener->restore();
42         }
43
44         void read(ipc::channel *ch, ipc::message &msg)
45         {
46                 switch (msg.header()->type) {
47                 case CMD_LISTENER_EVENT:
48                         if (m_listener->get_event_handler())
49                                 m_listener->get_event_handler()->read(ch, msg);
50                         break;
51                 case CMD_LISTENER_ACC_EVENT:
52                         if (m_listener->get_accuracy_handler())
53                                 m_listener->get_accuracy_handler()->read(ch, msg);
54                         break;
55                 }
56         }
57
58         void read_complete(ipc::channel *ch) {}
59         void error_caught(ipc::channel *ch, int error) {}
60
61 private:
62         sensor_listener *m_listener;
63 };
64
65 sensor_listener::sensor_listener(sensor_t sensor)
66 : m_id(0)
67 , m_sensor(reinterpret_cast<sensor_info *>(sensor))
68 , m_client(NULL)
69 , m_channel(NULL)
70 , m_handler(NULL)
71 , m_evt_handler(NULL)
72 , m_acc_handler(NULL)
73 , m_connected(false)
74 , m_started(false)
75 {
76         init();
77 }
78
79 sensor_listener::~sensor_listener()
80 {
81         deinit();
82 }
83
84 bool sensor_listener::init(void)
85 {
86         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
87         retvm_if(!m_client, false, "Failed to allocate memory");
88
89         m_handler = new(std::nothrow) listener_handler(this);
90         if (!m_handler) {
91                 delete m_client;
92                 return false;
93         }
94
95         if (!connect()) {
96                 delete m_handler;
97                 delete m_client;
98                 m_handler = NULL;
99                 m_client = NULL;
100                 return false;
101         }
102
103         return true;
104 }
105
106 void sensor_listener::deinit(void)
107 {
108         disconnect();
109
110         delete m_handler;
111         m_handler = NULL;
112
113         delete m_client;
114         m_client = NULL;
115
116         m_attributes.clear();
117 }
118
119 int sensor_listener::get_id(void)
120 {
121         return m_id;
122 }
123
124 sensor_t sensor_listener::get_sensor(void)
125 {
126         return static_cast<sensor_t>(m_sensor);
127 }
128
129 void sensor_listener::restore(void)
130 {
131         ret_if(!is_connected());
132         retm_if(!connect(), "Failed to restore listener");
133
134         /* Restore attributes/status */
135         if (m_started.load())
136                 start();
137
138         auto interval = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL);
139         if (interval != m_attributes.end())
140                 set_interval(m_attributes[SENSORD_ATTRIBUTE_INTERVAL]);
141
142         auto latency = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
143         if (latency != m_attributes.end())
144                 set_max_batch_latency(m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]);
145
146         _D("Restored listener[%d]", get_id());
147 }
148
149 bool sensor_listener::connect(void)
150 {
151         m_channel = m_client->connect(m_handler, &m_loop);
152         retvm_if(!m_channel, false, "Failed to connect to server");
153
154         ipc::message msg;
155         ipc::message reply;
156         cmd_listener_connect_t buf = {0, };
157
158         memcpy(buf.sensor, m_sensor->get_uri().c_str(), m_sensor->get_uri().size());
159         msg.set_type(CMD_LISTENER_CONNECT);
160         msg.enclose((const char *)&buf, sizeof(buf));
161         m_channel->send_sync(&msg);
162
163         m_channel->read_sync(reply);
164         reply.disclose((char *)&buf);
165
166         m_id = buf.listener_id;
167         m_connected.store(true);
168
169         _D("Listener ID[%d]", get_id());
170
171         return true;
172 }
173
174 void sensor_listener::disconnect(void)
175 {
176         ret_if(!is_connected());
177         m_connected.store(false);
178
179         ipc::message msg;
180         ipc::message reply;
181
182         msg.set_type(CMD_LISTENER_DISCONNECT);
183         m_channel->send_sync(&msg);
184
185         m_channel->read_sync(reply);
186         m_channel->disconnect();
187
188         delete m_channel;
189         m_channel = NULL;
190
191         _I("Disconnected[%d]", get_id());
192 }
193
194 bool sensor_listener::is_connected(void)
195 {
196         return m_connected.load();
197 }
198
199 ipc::channel_handler *sensor_listener::get_event_handler(void)
200 {
201         return m_evt_handler;
202 }
203
204 void sensor_listener::set_event_handler(ipc::channel_handler *handler)
205 {
206         m_evt_handler = handler;
207 }
208
209 void sensor_listener::unset_event_handler(void)
210 {
211         delete m_evt_handler;
212         m_evt_handler = NULL;
213 }
214
215 ipc::channel_handler *sensor_listener::get_accuracy_handler(void)
216 {
217         return m_acc_handler;
218 }
219
220 void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler)
221 {
222         m_acc_handler = handler;
223 }
224
225 void sensor_listener::unset_accuracy_handler(void)
226 {
227         delete m_acc_handler;
228         m_acc_handler = NULL;
229 }
230
231 int sensor_listener::start(void)
232 {
233         ipc::message msg;
234         ipc::message reply;
235         cmd_listener_start_t buf;
236
237         retvm_if(!m_channel, -EINVAL, "Failed to connect to server");
238
239         buf.listener_id = m_id;
240         msg.set_type(CMD_LISTENER_START);
241         msg.enclose((char *)&buf, sizeof(buf));
242
243         m_channel->send_sync(&msg);
244         m_channel->read_sync(reply);
245
246         if (reply.header()->err < 0)
247                 return reply.header()->err;
248
249         m_started.store(true);
250
251         return OP_SUCCESS;
252 }
253
254 int sensor_listener::stop(void)
255 {
256         ipc::message msg;
257         ipc::message reply;
258         cmd_listener_stop_t buf;
259
260         retvm_if(!m_channel, -EINVAL, "Failed to connect to server");
261         retvm_if(!m_started.load(), -EAGAIN, "Already stopped");
262
263         buf.listener_id = m_id;
264         msg.set_type(CMD_LISTENER_STOP);
265         msg.enclose((char *)&buf, sizeof(buf));
266
267         m_channel->send_sync(&msg);
268         m_channel->read_sync(reply);
269
270         if (reply.header()->err < 0)
271                 return reply.header()->err;
272
273         m_started.store(false);
274
275         return OP_SUCCESS;
276 }
277
278 int sensor_listener::get_interval(void)
279 {
280         auto it = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL);
281         retv_if(it == m_attributes.end(), -1);
282
283         return m_attributes[SENSORD_ATTRIBUTE_INTERVAL];
284 }
285
286 int sensor_listener::get_max_batch_latency(void)
287 {
288         auto it = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
289         retv_if(it == m_attributes.end(), -1);
290
291         return m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
292 }
293
294 int sensor_listener::get_pause_policy(void)
295 {
296         auto it = m_attributes.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
297         retv_if(it == m_attributes.end(), -1);
298
299         return m_attributes[SENSORD_ATTRIBUTE_PAUSE_POLICY];
300 }
301
302 int sensor_listener::get_passive_mode(void)
303 {
304         auto it = m_attributes.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
305         retv_if(it == m_attributes.end(), -1);
306
307         return m_attributes[SENSORD_ATTRIBUTE_PASSIVE_MODE];
308 }
309
310 int sensor_listener::set_interval(unsigned int interval)
311 {
312         int _interval;
313
314         /* TODO: move this logic to server */
315         if (interval == 0)
316                 _interval = DEFAULT_INTERVAL;
317         else if (interval < (unsigned int)m_sensor->get_min_interval())
318                 _interval = m_sensor->get_min_interval();
319         else
320                 _interval = interval;
321
322         return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval);
323 }
324
325 int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency)
326 {
327         return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency);
328 }
329
330 int sensor_listener::set_passive_mode(bool passive)
331 {
332         return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive);
333 }
334
335 int sensor_listener::flush(void)
336 {
337         return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1);
338 }
339
340 int sensor_listener::set_attribute(int attribute, int value)
341 {
342         ipc::message msg;
343         ipc::message reply;
344         cmd_listener_attr_int_t buf;
345
346         retvm_if(!m_channel, false, "Failed to connect to server");
347
348         buf.listener_id = m_id;
349         buf.attribute = attribute;
350         buf.value = value;
351         msg.set_type(CMD_LISTENER_ATTR_INT);
352         msg.enclose((char *)&buf, sizeof(buf));
353
354         m_channel->send_sync(&msg);
355         m_channel->read_sync(reply);
356
357         if (reply.header()->err < 0)
358                 return reply.header()->err;
359
360         m_attributes[attribute] = value;
361
362         return OP_SUCCESS;
363 }
364
365 int sensor_listener::set_attribute(int attribute, const char *value, int len)
366 {
367         ipc::message msg;
368         ipc::message reply;
369         cmd_listener_attr_str_t buf;
370
371         retvm_if(!m_channel, false, "Failed to connect to server");
372
373         msg.set_type(CMD_LISTENER_ATTR_STR);
374         buf.listener_id = m_id;
375         buf.attribute = attribute;
376         memcpy(buf.value, value, len);
377         buf.len = len;
378
379         msg.enclose((char *)&buf, sizeof(buf) + len);
380
381         m_channel->send_sync(&msg);
382         m_channel->read_sync(reply);
383
384         return reply.header()->err;
385 }
386
387 int sensor_listener::get_sensor_data(sensor_data_t *data)
388 {
389         ipc::message msg;
390         ipc::message reply;
391         cmd_listener_get_data_t buf;
392
393         retvm_if(!m_channel, false, "Failed to connect to server");
394
395         buf.listener_id = m_id;
396         msg.set_type(CMD_LISTENER_GET_DATA);
397         msg.enclose((char *)&buf, sizeof(buf));
398         m_channel->send_sync(&msg);
399
400         m_channel->read_sync(reply);
401         /* TODO */
402         /*
403         reply.disclose((char *)&buf);
404         memcpy(data, buf.data, sizeof(buf.len));
405         */
406
407         return OP_SUCCESS;
408 }
409