4 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "sensor_listener.h"
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>
29 using namespace sensor;
33 class listener_handler : public ipc::channel_handler
36 listener_handler(sensor_listener *listener)
37 : m_listener(listener)
40 void connected(ipc::channel *ch) {}
41 void disconnected(ipc::channel *ch)
43 /* If channel->disconnect() is not explicitly called,
44 * listener will be restored */
45 m_listener->restore();
48 void read(ipc::channel *ch, ipc::message &msg)
50 switch (msg.header()->type) {
51 case CMD_LISTENER_EVENT:
52 if (m_listener->get_event_handler()) {
53 m_listener->get_event_handler()->read(ch, msg);
56 case CMD_LISTENER_ACC_EVENT:
57 if (m_listener->get_accuracy_handler()) {
58 m_listener->get_accuracy_handler()->read(ch, msg);
61 case CMD_LISTENER_SET_ATTR_INT: {
62 if (m_listener->get_attribute_int_changed_handler()) {
63 m_listener->get_attribute_int_changed_handler()->read(ch, msg);
66 case CMD_LISTENER_SET_ATTR_STR: {
67 if (m_listener->get_attribute_str_changed_handler()) {
68 m_listener->get_attribute_str_changed_handler()->read(ch, msg);
71 case CMD_LISTENER_CONNECTED: {
75 _W("Invalid command message");
79 void read_complete(ipc::channel *ch) {}
80 void error_caught(ipc::channel *ch, int error) {}
83 sensor_listener *m_listener;
86 sensor_listener::sensor_listener(sensor_t sensor)
88 , m_sensor(reinterpret_cast<sensor_info *>(sensor))
95 , m_attr_int_changed_handler(NULL)
96 , m_attr_str_changed_handler(NULL)
103 sensor_listener::sensor_listener(sensor_t sensor, ipc::event_loop *loop)
105 , m_sensor(reinterpret_cast<sensor_info *>(sensor))
107 , m_cmd_channel(NULL)
108 , m_evt_channel(NULL)
110 , m_evt_handler(NULL)
111 , m_acc_handler(NULL)
112 , m_attr_int_changed_handler(NULL)
113 , m_attr_str_changed_handler(NULL)
121 sensor_listener::~sensor_listener()
126 bool sensor_listener::init(void)
128 m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
129 retvm_if(!m_client, false, "Failed to allocate memory");
131 m_handler = new(std::nothrow) listener_handler(this);
148 void sensor_listener::deinit(void)
150 _D("Deinitializing..");
160 delete m_evt_handler;
161 m_evt_handler = NULL;
163 delete m_acc_handler;
164 m_acc_handler = NULL;
166 delete m_attr_int_changed_handler;
167 m_attr_int_changed_handler = NULL;
169 delete m_attr_str_changed_handler;
170 m_attr_str_changed_handler = NULL;
172 m_attributes_int.clear();
173 m_attributes_str.clear();
174 _D("Deinitialized..");
177 int sensor_listener::get_id(void)
182 sensor_t sensor_listener::get_sensor(void)
184 return static_cast<sensor_t>(m_sensor);
187 void sensor_listener::restore(void)
189 ret_if(!is_connected());
190 retm_if(!connect(), "Failed to restore listener");
192 _D("Restoring sensor listener");
194 /* Restore attributes/status */
195 if (m_started.load())
198 auto interval = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
199 if (interval != m_attributes_int.end())
200 set_interval(m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]);
202 auto latency = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
203 if (latency != m_attributes_int.end())
204 set_max_batch_latency(m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]);
206 auto power = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
207 if (power != m_attributes_int.end())
208 set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY]);
210 _D("Restored listener[%d]", get_id());
213 bool sensor_listener::connect(void)
215 m_cmd_channel = m_client->connect(NULL);
216 retvm_if(!m_cmd_channel, false, "Failed to connect to server");
218 m_evt_channel = m_client->connect(m_handler, m_loop, false);
219 retvm_if(!m_evt_channel, false, "Failed to connect to server");
223 cmd_listener_connect_t buf = {0, };
225 memcpy(buf.sensor, m_sensor->get_uri().c_str(), m_sensor->get_uri().size());
226 msg.set_type(CMD_LISTENER_CONNECT);
227 msg.enclose((const char *)&buf, sizeof(buf));
228 m_evt_channel->send_sync(msg);
230 m_evt_channel->read_sync(reply);
231 reply.disclose((char *)&buf, sizeof(buf));
233 m_id = buf.listener_id;
234 m_connected.store(true);
236 m_evt_channel->bind();
238 _I("Connected listener[%d] with sensor[%s]", get_id(), m_sensor->get_uri().c_str());
243 void sensor_listener::disconnect(void)
245 ret_if(!is_connected());
246 m_connected.store(false);
248 _D("Disconnecting..");
250 m_evt_channel->disconnect();
251 delete m_evt_channel;
252 m_evt_channel = NULL;
254 m_cmd_channel->disconnect();
255 delete m_cmd_channel;
256 m_cmd_channel = NULL;
258 _I("Disconnected[%d]", get_id());
261 bool sensor_listener::is_connected(void)
263 return m_connected.load();
266 ipc::channel_handler *sensor_listener::get_event_handler(void)
270 return m_evt_handler;
273 void sensor_listener::set_event_handler(ipc::channel_handler *handler)
277 delete m_evt_handler;
279 m_evt_handler = handler;
282 void sensor_listener::unset_event_handler(void)
286 delete m_evt_handler;
287 m_evt_handler = NULL;
290 ipc::channel_handler *sensor_listener::get_accuracy_handler(void)
293 return m_acc_handler;
296 void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler)
300 delete m_acc_handler;
302 m_acc_handler = handler;
305 void sensor_listener::unset_accuracy_handler(void)
308 delete m_acc_handler;
309 m_acc_handler = NULL;
312 ipc::channel_handler *sensor_listener::get_attribute_int_changed_handler(void)
315 return m_attr_int_changed_handler;
318 void sensor_listener::set_attribute_int_changed_handler(ipc::channel_handler *handler)
321 if (m_attr_int_changed_handler) {
322 delete m_attr_int_changed_handler;
324 m_attr_int_changed_handler = handler;
327 void sensor_listener::unset_attribute_int_changed_handler(void)
330 delete m_attr_int_changed_handler;
331 m_attr_int_changed_handler = NULL;
334 ipc::channel_handler *sensor_listener::get_attribute_str_changed_handler(void)
337 return m_attr_str_changed_handler;
340 void sensor_listener::set_attribute_str_changed_handler(ipc::channel_handler *handler)
343 if (m_attr_str_changed_handler) {
344 delete m_attr_str_changed_handler;
346 m_attr_str_changed_handler = handler;
349 void sensor_listener::unset_attribute_str_changed_handler(void)
352 delete m_attr_str_changed_handler;
353 m_attr_str_changed_handler = NULL;
356 int sensor_listener::start(void)
360 cmd_listener_start_t buf;
362 retvm_if(!m_cmd_channel, -EINVAL, "Failed to connect to server");
364 buf.listener_id = m_id;
365 msg.set_type(CMD_LISTENER_START);
366 msg.enclose((char *)&buf, sizeof(buf));
368 m_cmd_channel->send_sync(msg);
369 m_cmd_channel->read_sync(reply);
371 if (reply.header()->err < 0) {
372 _E("Failed to start listener[%d], sensor[%s]", get_id(), m_sensor->get_uri().c_str());
373 return reply.header()->err;
376 m_started.store(true);
378 _I("Listener[%d] started", get_id());
383 int sensor_listener::stop(void)
387 cmd_listener_stop_t buf;
389 retvm_if(!m_cmd_channel, -EINVAL, "Failed to connect to server");
390 retvm_if(!m_started.load(), -EAGAIN, "Already stopped");
392 buf.listener_id = m_id;
393 msg.set_type(CMD_LISTENER_STOP);
394 msg.enclose((char *)&buf, sizeof(buf));
396 m_cmd_channel->send_sync(msg);
397 m_cmd_channel->read_sync(reply);
399 if (reply.header()->err < 0) {
400 _E("Failed to stop listener[%d]", get_id());
401 return reply.header()->err;
404 m_started.store(false);
406 _I("Listener[%d] stopped", get_id());
411 int sensor_listener::get_interval(void)
413 auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
414 retv_if(it == m_attributes_int.end(), -1);
416 return m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL];
419 int sensor_listener::get_max_batch_latency(void)
421 auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
422 retv_if(it == m_attributes_int.end(), -1);
424 return m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
427 int sensor_listener::get_pause_policy(void)
429 auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
430 retv_if(it == m_attributes_int.end(), -1);
432 return m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY];
435 int sensor_listener::get_passive_mode(void)
437 auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
438 retv_if(it == m_attributes_int.end(), -1);
440 return m_attributes_int[SENSORD_ATTRIBUTE_PASSIVE_MODE];
443 int sensor_listener::set_interval(unsigned int interval)
447 /* TODO: move this logic to server */
449 _interval = DEFAULT_INTERVAL;
450 else if (interval < (unsigned int)m_sensor->get_min_interval())
451 _interval = m_sensor->get_min_interval();
453 _interval = interval;
455 _I("Listener[%d] set interval[%u]", get_id(), _interval);
457 /* If it is not started, store the value only */
458 if (!m_started.load()) {
459 m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL] = _interval;
463 return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval);
466 int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency)
468 _I("Listener[%d] set max batch latency[%u]", get_id(), max_batch_latency);
470 /* If it is not started, store the value only */
471 if (!m_started.load()) {
472 m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency;
476 return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency);
479 int sensor_listener::set_passive_mode(bool passive)
481 _I("Listener[%d] set passive mode[%d]", get_id(), passive);
483 return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive);
486 int sensor_listener::flush(void)
488 _I("Listener[%d] flushes", get_id());
490 return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1);
493 int sensor_listener::set_attribute(int attribute, int value)
497 cmd_listener_attr_int_t buf;
499 retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
501 buf.listener_id = m_id;
502 buf.attribute = attribute;
504 msg.set_type(CMD_LISTENER_SET_ATTR_INT);
505 msg.enclose((char *)&buf, sizeof(buf));
507 m_cmd_channel->send_sync(msg);
508 m_cmd_channel->read_sync(reply);
510 if (reply.header()->err < 0)
511 return reply.header()->err;
513 if (attribute != SENSORD_ATTRIBUTE_FLUSH) {
514 update_attribute(attribute, value);
520 int sensor_listener::get_attribute(int attribute, int* value)
524 cmd_listener_attr_int_t buf;
526 retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
528 buf.listener_id = m_id;
529 buf.attribute = attribute;
530 msg.set_type(CMD_LISTENER_GET_ATTR_INT);
531 msg.enclose((char *)&buf, sizeof(buf));
533 m_cmd_channel->send_sync(msg);
534 m_cmd_channel->read_sync(reply);
536 if (reply.header()->err < 0) {
537 return reply.header()->err;
540 if (reply.header()->length && reply.body()) {
541 *value = ((cmd_listener_attr_int_t *)reply.body())->value;
548 void sensor_listener::update_attribute(int attribute, int value)
551 m_attributes_int[attribute] = value;
552 _I("Update_attribute(int) listener[%d] attribute[%d] value[%d] attributes size[%d]", get_id(), attribute, value, m_attributes_int.size());
555 int sensor_listener::set_attribute(int attribute, const char *value, int len)
559 cmd_listener_attr_str_t *buf;
562 retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
564 size = sizeof(cmd_listener_attr_str_t) + len;
566 buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
567 retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
569 msg.set_type(CMD_LISTENER_SET_ATTR_STR);
570 buf->listener_id = m_id;
571 buf->attribute = attribute;
573 memcpy(buf->value, value, len);
576 msg.enclose((char *)buf, size);
578 m_cmd_channel->send_sync(msg);
579 m_cmd_channel->read_sync(reply);
581 /* Message memory is released automatically after sending message,
582 so it doesn't need to free memory */
586 if (reply.header()->err < 0)
587 return reply.header()->err;
589 update_attribute(attribute, value, len);
594 int sensor_listener::get_attribute(int attribute, char **value, int* len)
598 cmd_listener_attr_str_t buf;
600 buf.listener_id = m_id;
601 buf.attribute = attribute;
603 msg.set_type(CMD_LISTENER_GET_ATTR_STR);
604 msg.enclose((char *)&buf, sizeof(buf));
605 m_cmd_channel->send_sync(msg);
607 m_cmd_channel->read_sync(reply);
608 if (reply.header()->err < 0) {
609 return reply.header()->err;
612 if (reply.header()->length && reply.body()) {
613 cmd_listener_attr_str_t * recv_buf = (cmd_listener_attr_str_t *)reply.body();
614 char* p = (char *)recv_buf->value;
615 *len = recv_buf->len;
616 *value = (char *) malloc(*len);
617 std::copy(p, p + recv_buf->len, *value);
624 void sensor_listener::update_attribute(int attribute, const char *value, int len)
627 m_attributes_str[attribute].clear();
628 m_attributes_str[attribute].insert(m_attributes_str[attribute].begin(), value, value + len);
629 _I("Update_attribute(str) listener[%d] attribute[%d] value[%s] attributes size[%zu]", get_id(), attribute, value, m_attributes_int.size());
632 int sensor_listener::get_sensor_data(sensor_data_t *data)
636 cmd_listener_get_data_t buf;
638 retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
640 buf.listener_id = m_id;
641 msg.set_type(CMD_LISTENER_GET_DATA);
642 msg.enclose((char *)&buf, sizeof(buf));
644 m_cmd_channel->send_sync(msg);
645 m_cmd_channel->read_sync(reply);
647 reply.disclose((char *)&buf, sizeof(buf));
648 int size = sizeof(sensor_data_t);
650 if (buf.len > size || buf.len < 0) {
652 data->value_count = 0;
653 /* TODO: it should return OP_ERROR */
657 memcpy(data, &buf.data, buf.len);
659 _D("Listener[%d] read sensor data", get_id());
664 int sensor_listener::get_sensor_data_list(sensor_data_t **data, int *count)
668 cmd_listener_get_data_list_t buf;
670 retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
672 buf.listener_id = m_id;
673 msg.set_type(CMD_LISTENER_GET_DATA_LIST);
674 msg.enclose((char *)&buf, sizeof(buf));
676 m_cmd_channel->send_sync(msg);
677 m_cmd_channel->read_sync(reply);
679 if (reply.header()->err < 0) {
680 return reply.header()->err;
683 size_t size = reply.size();
684 cmd_listener_get_data_list_t* reply_buf = (cmd_listener_get_data_list_t *) new(std::nothrow) char[size];
686 retvm_if(!reply_buf, -ENOMEM, "Failed to allocate memory");
688 reply.disclose((char *)reply_buf, size);
690 if (reply_buf->len <= 0) {
695 *count = reply_buf->data_count;
696 *data = (sensor_data_t*) malloc(reply_buf->len);
699 _E("Memory allocation failed");
704 memcpy(*data, reply_buf->data, reply_buf->len);
706 _D("Listener[%d] read sensor data list", get_id());