+++ /dev/null
-/*
- * 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 <command-types.h>
-#include <sensor-log-private.h>
-#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;
-}
+++ /dev/null
-/*
- * 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 <channel-handler.h>
-#include <sensor-internal.h>
-#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__ */
#include "sensor-provider.h"
+#include <glib.h>
#include <message.h>
-#include <channel.h>
+#include <socket.h>
#include <sensor-log-private.h>
#include <sensor-types-private.h>
#include <sensor-utils.h>
#include <command-types.h>
+#include <lock.h>
+
#include <cfloat>
#include <cmath>
-#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);
void sensor_provider::deinit(void)
{
disconnect();
-
- delete m_handler;
- m_handler = NULL;
}
const char *sensor_provider::get_uri(void)
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);
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)
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;
}
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;
}
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<const void *>(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<void *>(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;
+}