From 13892c69f04c688c8fc40aaaec4abb3197639720 Mon Sep 17 00:00:00 2001 From: TaeminYeom Date: Wed, 27 Jul 2022 10:11:09 +0900 Subject: [PATCH] Refactoring: sensor_provider class Remove sensor_provider_channel_handler class Change not to use g_io_handler callback Change-Id: I308d614feaa5a32fd3f292c20a5661802d834799 Signed-off-by: TaeminYeom --- src/api/CMakeLists.txt | 1 - src/api/sensor-provider-channel-handler.cpp | 116 -------------- src/api/sensor-provider-channel-handler.h | 63 -------- src/api/sensor-provider.cpp | 237 ++++++++++++++++++++++++---- src/api/sensor-provider.h | 35 ++-- 5 files changed, 229 insertions(+), 223 deletions(-) delete mode 100644 src/api/sensor-provider-channel-handler.cpp delete mode 100644 src/api/sensor-provider-channel-handler.h diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index a71efe4..3a3745c 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -50,7 +50,6 @@ SET(SOURCES sensor-listener.cpp sensor-manager-channel-handler.cpp sensor-manager.cpp - sensor-provider-channel-handler.cpp sensor-provider.cpp sensor-reader.cpp) diff --git a/src/api/sensor-provider-channel-handler.cpp b/src/api/sensor-provider-channel-handler.cpp deleted file mode 100644 index 079b863..0000000 --- a/src/api/sensor-provider-channel-handler.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sensor-provider-channel-handler.h" - -#include -#include -#include "sensor-provider.h" - -using namespace sensor; - -sensor_provider::channel_handler::channel_handler(sensor_provider *provider) -: m_provider(provider) -, m_start_cb(NULL) -, m_stop_cb(NULL) -, m_interval_changed_cb(NULL) -, m_attribute_str_cb(NULL) -, m_start_user_data(NULL) -, m_stop_user_data(NULL) -, m_interval_changed_user_data(NULL) -, m_attribute_str_user_data(NULL) -{ -} - -void sensor_provider::channel_handler::connected(ipc::channel *ch) -{ - _I("Connected"); -} - -void sensor_provider::channel_handler::disconnected(ipc::channel *ch) -{ - /* TODO */ - /* m_provider->restore(); */ -} - -void sensor_provider::channel_handler::read(ipc::channel *ch, ipc::message &msg) -{ - switch (msg.type()) { - case CMD_PROVIDER_START: - if (m_start_cb) - m_start_cb(m_provider, m_start_user_data); - break; - case CMD_PROVIDER_STOP: - if (m_stop_cb) - m_stop_cb(m_provider, m_stop_user_data); - break; - case CMD_PROVIDER_ATTR_INT: - cmd_provider_attr_int_t buf; - msg.disclose((char *)&buf, sizeof(buf)); - - if (buf.attribute == SENSORD_ATTRIBUTE_INTERVAL && m_interval_changed_cb) - m_interval_changed_cb(m_provider, buf.value, m_interval_changed_user_data); - break; - case CMD_PROVIDER_ATTR_STR: - cmd_provider_attr_str_t *attr; - - attr = (cmd_provider_attr_str_t *) new(std::nothrow) char[msg.size()]; - retm_if(!attr, "Failed to allocate memory"); - - msg.disclose((char *)attr, msg.size()); - - if (m_attribute_str_cb) - m_attribute_str_cb(m_provider, attr->attribute, attr->value, attr->len, m_attribute_str_user_data); - - delete [] attr; - break; - } -} - -void sensor_provider::channel_handler::read_complete(ipc::channel *ch) -{ -} - -void sensor_provider::channel_handler::error_caught(ipc::channel *ch, int error) -{ -} - -void sensor_provider::channel_handler::set_start_cb(sensord_provider_start_cb cb, void *user_data) -{ - m_start_cb = cb; - m_start_user_data = user_data; -} - -void sensor_provider::channel_handler::set_stop_cb(sensord_provider_stop_cb cb, void *user_data) -{ - m_stop_cb = cb; - m_stop_user_data = user_data; -} - -void sensor_provider::channel_handler::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data) -{ - m_interval_changed_cb = cb; - m_interval_changed_user_data = user_data; -} - -void sensor_provider::channel_handler::set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data) -{ - m_attribute_str_cb = cb; - m_attribute_str_user_data = user_data; -} diff --git a/src/api/sensor-provider-channel-handler.h b/src/api/sensor-provider-channel-handler.h deleted file mode 100644 index 5435118..0000000 --- a/src/api/sensor-provider-channel-handler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef __SENSOR_PROVIDER_CHANNEL_HANDLER__ -#define __SENSOR_PROVIDER_CHANNEL_HANDLER__ - -#include -#include -#include "sensor-provider.h" - -namespace sensor { - -class sensor_provider::channel_handler : public ipc::channel_handler -{ -public: - channel_handler(sensor_provider *provider); - - void connected(ipc::channel *ch); - void disconnected(ipc::channel *ch); - void read(ipc::channel *ch, ipc::message &msg); - - void read_complete(ipc::channel *ch); - void error_caught(ipc::channel *ch, int error); - - void set_start_cb(sensord_provider_start_cb cb, void *user_data); - void set_stop_cb(sensord_provider_stop_cb cb, void *user_data); - void set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data); - void set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data); - void set_handler(int num, ipc::channel_handler* handler) {} - void disconnect(void) {} -private: - sensor_provider *m_provider; - - sensord_provider_start_cb m_start_cb; - sensord_provider_stop_cb m_stop_cb; - sensord_provider_interval_changed_cb m_interval_changed_cb; - sensord_provider_attribute_str_cb m_attribute_str_cb; - - void *m_start_user_data; - void *m_stop_user_data; - void *m_interval_changed_user_data; - void *m_attribute_str_user_data; -}; - -} - -#endif /* __SENSOR_PROVIDER_CHANNEL_HANDLER__ */ diff --git a/src/api/sensor-provider.cpp b/src/api/sensor-provider.cpp index 2ad2492..2dd9832 100644 --- a/src/api/sensor-provider.cpp +++ b/src/api/sensor-provider.cpp @@ -19,41 +19,71 @@ #include "sensor-provider.h" +#include #include -#include +#include #include #include #include #include +#include + #include #include -#include "sensor-provider-channel-handler.h" - #define DEFAULT_RESOLUTION 0.1 using namespace sensor; +static gboolean provider_handler(GIOChannel *ch, GIOCondition condition, gpointer data) +{ + sensor_provider *p = (sensor_provider*) data; + unsigned int cond = (unsigned int)condition; + + if (cond & (G_IO_HUP)) { + p->restore(); + return false; + } + + ipc::message msg; + bool ret = p->read(msg); + if (!ret) + return false; + + p->handle(msg); + + return true; +} + sensor_provider::sensor_provider(const char *uri) -: m_channel(NULL) -, m_handler(NULL) -, m_connected(false) +: m_connected(false) +, m_start_cb(NULL) +, m_stop_cb(NULL) +, m_interval_changed_cb(NULL) +, m_attribute_str_cb(NULL) +, m_start_user_data(NULL) +, m_stop_user_data(NULL) +, m_interval_changed_user_data(NULL) +, m_attribute_str_user_data(NULL) +, g_src(NULL) { init(uri); + m_loop = g_main_loop_new(NULL, FALSE); } sensor_provider::~sensor_provider() { deinit(); + + if (m_loop) { + g_main_loop_quit(m_loop); + g_main_loop_unref(m_loop); + m_loop = NULL; + } } bool sensor_provider::init(const char *uri) { - m_handler = new(std::nothrow) channel_handler(this); - if (!m_handler) { - return false; - } - m_sensor.set_uri(uri); m_sensor.set_min_range(-FLT_MAX); m_sensor.set_max_range(FLT_MAX); @@ -68,9 +98,6 @@ bool sensor_provider::init(const char *uri) void sensor_provider::deinit(void) { disconnect(); - - delete m_handler; - m_handler = NULL; } const char *sensor_provider::get_uri(void) @@ -119,23 +146,50 @@ int sensor_provider::send_sensor_info(sensor_info *info) ipc::message msg((const char *)bytes, size); msg.set_type(CMD_PROVIDER_CONNECT); - m_channel->send_sync(msg); - + bool ret = send(msg); + if (!ret) + return OP_ERROR; return OP_SUCCESS; } int sensor_provider::connect(void) { - m_channel = new(std::nothrow) ipc::channel(); - retvm_if(!m_channel, -EIO, "Failed to allocate memory"); - m_channel->connect(m_handler, &m_loop, true); + m_socket = new(std::nothrow) ipc::socket(); + retvm_if(!m_socket, NULL, "Failed to allocate memory"); + + if (!m_socket->create(SENSOR_CHANNEL_PATH)) { + delete m_socket; + return 0; + } + + if (!m_socket->connect()) + return 0; + + GIOChannel *ch = NULL; + + ch = g_io_channel_unix_new(m_socket->get_fd()); + retvm_if(!ch, NULL, "Failed to create g_io_channel_unix_new"); + + g_src = g_io_create_watch(ch, (GIOCondition) (ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL)); + g_io_channel_unref(ch); + if (!g_src) { + _E("Failed to create g_io_create_watch"); + return OP_ERROR; + } + + g_source_set_callback(g_src, (GSourceFunc) provider_handler, this, NULL); + g_source_attach(g_src, g_main_loop_get_context(m_loop)); + g_source_unref(g_src); /* serialize and send sensor info */ send_sensor_info(get_sensor_info()); /* check error */ ipc::message reply; - m_channel->read_sync(reply); + + bool ret = read(reply); + if (!ret) + return OP_ERROR; retv_if(reply.header()->err < 0, reply.header()->err); m_connected.store(true); @@ -147,24 +201,29 @@ int sensor_provider::connect(void) bool sensor_provider::disconnect(void) { + AUTOLOCK(m_cmutex); retv_if(!is_connected(), false); - m_connected.store(false); - m_channel->disconnect(); - delete m_channel; - m_channel = NULL; + if (g_src && !g_source_is_destroyed(g_src)) { + g_source_destroy(g_src); + g_src = NULL; + } - _I("Disconnected[%s]", get_uri()); + m_connected.store(false); + delete m_socket; + m_socket = NULL; + _I("Disconnected[%s]", get_uri()); return true; } -void sensor_provider::restore(void) +bool sensor_provider::restore(void) { - ret_if(!is_connected()); - retm_if(!connect(), "Failed to restore provider"); + retv_if(!is_connected(), false); + retvm_if(connect(), false, "Failed to restore provider"); _D("Restored provider[%s]", get_uri()); + return true; } int sensor_provider::publish(const sensor_data_t &data) @@ -173,7 +232,9 @@ int sensor_provider::publish(const sensor_data_t &data) msg.set_type(CMD_PROVIDER_PUBLISH); msg.enclose((const void *)(&data), sizeof(data)); - m_channel->send_sync(msg); + bool ret = send(msg); + if (!ret) + return OP_ERROR; return OP_SUCCESS; } @@ -184,7 +245,7 @@ int sensor_provider::publish(const sensor_data_t data[], const int count) msg.set_type(CMD_PROVIDER_PUBLISH); msg.enclose((const void *)data, sizeof(sensor_data_t) * count); - m_channel->send_sync(msg); + send(msg); return OP_SUCCESS; } @@ -196,21 +257,129 @@ bool sensor_provider::is_connected(void) void sensor_provider::set_start_cb(sensord_provider_start_cb cb, void *user_data) { - m_handler->set_start_cb(cb, user_data); + m_start_cb = cb; + m_start_user_data = user_data; } void sensor_provider::set_stop_cb(sensord_provider_stop_cb cb, void *user_data) { - m_handler->set_stop_cb(cb, user_data); + m_stop_cb = cb; + m_stop_user_data = user_data; } void sensor_provider::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data) { - m_handler->set_interval_cb(cb, user_data); + m_interval_changed_cb = cb; + m_interval_changed_user_data = user_data; } void sensor_provider::set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data) { - m_handler->set_attribute_str_cb(cb, user_data); + m_attribute_str_cb = cb; + m_attribute_str_user_data = user_data; } +bool sensor_provider::read(ipc::message &msg) +{ + AUTOLOCK(m_cmutex); + if (!m_socket) { + _E("Socket is not connected"); + return false; + } + + ipc::message_header header; + ssize_t size = 0; + char buf[MAX_MSG_CAPACITY]; + + /* header */ + size = m_socket->recv(&header, sizeof(ipc::message_header), false); + if (size <= 0) + return false; + + // check error from header + if (header.err != 0) { + msg.header()->err = header.err; + return false; + } + + /* body */ + if (header.length >= MAX_MSG_CAPACITY) { + _E("header.length error %u", header.length); + return false; + } + + if (header.length > 0) { + size = m_socket->recv(&buf, header.length, false); + if (size <= 0) + return false; + } + + buf[header.length] = '\0'; + msg.enclose(reinterpret_cast(buf), header.length); + msg.set_type(header.type); + msg.header()->err = header.err; + + return true; +} + +void sensor_provider::handle(ipc::message &msg) +{ + switch (msg.type()) { + case CMD_PROVIDER_START: + if (m_start_cb) + m_start_cb(this, m_start_user_data); + break; + case CMD_PROVIDER_STOP: + if (m_stop_cb) + m_stop_cb(this, m_stop_user_data); + break; + case CMD_PROVIDER_ATTR_INT: + cmd_provider_attr_int_t buf; + msg.disclose((char *)&buf, sizeof(buf)); + + if (buf.attribute == SENSORD_ATTRIBUTE_INTERVAL && m_interval_changed_cb) + m_interval_changed_cb(this, buf.value, m_interval_changed_user_data); + break; + case CMD_PROVIDER_ATTR_STR: + cmd_provider_attr_str_t *attr; + + attr = (cmd_provider_attr_str_t *) new(std::nothrow) char[msg.size()]; + retm_if(!attr, "Failed to allocate memory"); + + msg.disclose((char *)attr, msg.size()); + + if (m_attribute_str_cb) + m_attribute_str_cb(this, attr->attribute, attr->value, attr->len, m_attribute_str_user_data); + + delete [] attr; + break; + } +} + +bool sensor_provider::send(ipc::message &msg) +{ + AUTOLOCK(m_cmutex); + if (!m_socket) { + _E("Socket is not connected"); + return false; + } + + retvm_if(msg.size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg.size()); + + ssize_t size = 0; + char *buf = msg.body(); + + /* header */ + size = m_socket->send(reinterpret_cast(msg.header()), + sizeof(ipc::message_header), true); + retvm_if(size <= 0, false, "Failed to send header"); + + /* if body size is zero, skip to send body message */ + retv_if(msg.size() == 0, true); + + /* body */ + size = m_socket->send(buf, msg.size(), true); + retvm_if(size <= 0, false, "Failed to send body"); + + return true; +} diff --git a/src/api/sensor-provider.h b/src/api/sensor-provider.h index 606a5e3..518e75b 100644 --- a/src/api/sensor-provider.h +++ b/src/api/sensor-provider.h @@ -20,12 +20,15 @@ #ifndef __SENSOR_PROVIDER_H__ #define __SENSOR_PROVIDER_H__ -#include -#include +#include +#include +#include #include #include #include #include +#include + #include #include @@ -34,14 +37,14 @@ namespace sensor { class sensor_provider { public: sensor_provider(const char *uri); - virtual ~sensor_provider(); + ~sensor_provider(); const char *get_uri(void); sensor_info *get_sensor_info(void); int connect(void); bool disconnect(void); - void restore(void); + bool restore(void); void set_start_cb(sensord_provider_start_cb cb, void *user_data); void set_stop_cb(sensord_provider_stop_cb cb, void *user_data); @@ -51,9 +54,11 @@ public: int publish(const sensor_data_t &data); int publish(const sensor_data_t data[], const int count); -private: - class channel_handler; + bool read(ipc::message &msg); + bool send(ipc::message &msg); + void handle(ipc::message &msg); +private: bool init(const char *uri); void deinit(void); @@ -64,10 +69,22 @@ private: sensor_info m_sensor; - ipc::channel *m_channel; - ipc::event_loop m_loop; - channel_handler *m_handler; + GMainLoop *m_loop; + GSource *g_src; + + ipc::socket *m_socket; std::atomic m_connected; + sensor::cmutex m_cmutex; + + sensord_provider_start_cb m_start_cb; + sensord_provider_stop_cb m_stop_cb; + sensord_provider_interval_changed_cb m_interval_changed_cb; + sensord_provider_attribute_str_cb m_attribute_str_cb; + + void *m_start_user_data; + void *m_stop_user_data; + void *m_interval_changed_user_data; + void *m_attribute_str_user_data; }; } -- 2.7.4