+++ /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-manager-channel-handler.h"
-
-#include <sensor-log-private.h>
-#include <command-types.h>
-#include "sensor-manager.h"
-
-using namespace sensor;
-
-sensor_manager::channel_handler::channel_handler(sensor_manager *manager)
-: m_manager(manager)
-{
-}
-
-void sensor_manager::channel_handler::connected(ipc::channel *ch)
-{
-}
-
-void sensor_manager::channel_handler::disconnected(ipc::channel *ch)
-{
- /* If channel->disconnect() is not explicitly called, it will be restored */
- m_manager->restore();
-}
-
-void sensor_manager::channel_handler::read(ipc::channel *ch, ipc::message &msg)
-{
- switch (msg.header()->type) {
- case CMD_MANAGER_SENSOR_ADDED:
- on_sensor_added(ch, msg);
- break;
- case CMD_MANAGER_SENSOR_REMOVED:
- on_sensor_removed(ch, msg);
- break;
- }
-}
-
-void sensor_manager::channel_handler::read_complete(ipc::channel *ch)
-{
-}
-
-void sensor_manager::channel_handler::error_caught(ipc::channel *ch, int error)
-{
-}
-
-void sensor_manager::channel_handler::on_sensor_added(ipc::channel *ch, ipc::message &msg)
-{
- ret_if(msg.header()->err < OP_SUCCESS);
-
- sensor_info info;
- info.clear();
- info.deserialize(msg.body(), msg.size());
-
- m_manager->add_sensor(info);
-
- auto it = m_sensor_added_callbacks.begin();
- while (it != m_sensor_added_callbacks.end()) {
- it->first(info.get_uri().c_str(), it->second);
- ++it;
- }
-}
-
-void sensor_manager::channel_handler::on_sensor_removed(ipc::channel *ch, ipc::message &msg)
-{
- ret_if(msg.header()->err < 0);
- char uri[NAME_MAX] = {0, };
-
- msg.disclose(uri, NAME_MAX);
- m_manager->remove_sensor(uri);
-
- auto it = m_sensor_removed_callbacks.begin();
- while (it != m_sensor_removed_callbacks.end()) {
- it->first(uri, it->second);
- ++it;
- }
-}
-
-void sensor_manager::channel_handler::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
-{
- m_sensor_added_callbacks.emplace(cb, user_data);
-}
-
-void sensor_manager::channel_handler::remove_sensor_added_cb(sensord_added_cb cb)
-{
- m_sensor_added_callbacks.erase(cb);
-}
-
-void sensor_manager::channel_handler::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
-{
- m_sensor_removed_callbacks.emplace(cb, user_data);
-}
-
-void sensor_manager::channel_handler::remove_sensor_removed_cb(sensord_removed_cb cb)
-{
- m_sensor_removed_callbacks.erase(cb);
-}
+++ /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_MANAGER_CHANNEL_HANDLER__
-#define __SENSOR_MANAGER_CHANNEL_HANDLER__
-
-#include <sensor-internal.h>
-#include <sensor-manager.h>
-#include <channel-handler.h>
-#include <map>
-
-namespace sensor {
-
-class sensor_manager::channel_handler : public ipc::channel_handler
-{
-public:
- channel_handler(sensor_manager *manager);
-
- 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 on_sensor_added(ipc::channel *ch, ipc::message &msg);
- void on_sensor_removed(ipc::channel *ch, ipc::message &msg);
-
- void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
- void remove_sensor_added_cb(sensord_added_cb cb);
-
- void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
- void remove_sensor_removed_cb(sensord_removed_cb cb);
-
- void set_handler(int num, ipc::channel_handler* handler) {}
- void disconnect(void) {}
-
-private:
- typedef std::map<sensord_added_cb, void *> sensor_added_cb_list_t;
- typedef std::map<sensord_removed_cb, void *> sensor_removed_cb_list_t;
-
- sensor_manager *m_manager;
- sensor_added_cb_list_t m_sensor_added_callbacks;
- sensor_removed_cb_list_t m_sensor_removed_callbacks;
-};
-
-}
-
-#endif /* __SENSOR_MANAGER_CHANNEL_HANDLER__ */
#include <sensor-utils.h>
#include <command-types.h>
#include <message.h>
-#include <channel.h>
-
-#include "sensor-manager-channel-handler.h"
using namespace sensor;
+static gboolean manager_handler(GIOChannel *ch, GIOCondition condition, gpointer data)
+{
+ sensor_manager *manager = (sensor_manager*) data;
+ unsigned int cond = (unsigned int)condition;
+
+ if (cond & (G_IO_HUP)) {
+ manager->restore();
+ return false;
+ }
+
+ ipc::message msg;
+ bool ret = manager->read(msg);
+ if (!ret)
+ return false;
+
+ manager->handle(msg);
+
+ return true;
+}
+
sensor_manager::sensor_manager()
-: m_cmd_channel(NULL)
-, m_mon_channel(NULL)
+: m_cmd_socket(NULL)
+, m_mon_socket(NULL)
+, g_src(NULL)
, m_connected(false)
-, m_handler(NULL)
{
- init();
+ m_loop = g_main_loop_new(NULL, false);
}
sensor_manager::~sensor_manager()
{
- deinit();
+ disconnect();
+
+ if (m_loop) {
+ g_main_loop_quit(m_loop);
+ g_main_loop_unref(m_loop);
+ m_loop = NULL;
+ }
}
int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
void sensor_manager::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
{
- m_handler->add_sensor_added_cb(cb, user_data);
+ m_sensor_added_callbacks.emplace(cb, user_data);
}
void sensor_manager::remove_sensor_added_cb(sensord_added_cb cb)
{
- m_handler->remove_sensor_added_cb(cb);
+ m_sensor_added_callbacks.erase(cb);
}
void sensor_manager::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
{
- m_handler->add_sensor_removed_cb(cb, user_data);
+ m_sensor_removed_callbacks.emplace(cb, user_data);
}
void sensor_manager::remove_sensor_removed_cb(sensord_removed_cb cb)
{
- m_handler->remove_sensor_removed_cb(cb);
+ m_sensor_removed_callbacks.erase(cb);
}
-bool sensor_manager::init(void)
+bool sensor_manager::connect_channel(void)
{
- m_handler = new(std::nothrow) channel_handler(this);
- if (!m_handler) {
- return false;
- }
+ ipc::message msg;
+ GIOChannel *ch = NULL;
+ bool ret = false;
- return true;
-}
+ m_cmd_socket = new(std::nothrow) ipc::socket();
+ retvm_if(!m_cmd_socket, false, "Failed to allocate memory");
-void sensor_manager::deinit(void)
-{
- disconnect();
+ if (!m_cmd_socket->create(SENSOR_CHANNEL_PATH))
+ goto fail;
- delete m_handler;
- m_handler = NULL;
-}
+ if (!m_cmd_socket->connect())
+ goto fail;
-bool sensor_manager::connect_channel(void)
-{
- ipc::message msg;
+ m_mon_socket = new(std::nothrow) ipc::socket();
+ if (!m_mon_socket) {
+ _E("Failed to allocate memory");
+ goto fail;
+ }
- m_cmd_channel = new(std::nothrow) ipc::channel();
- retvm_if(!m_cmd_channel, false, "Failed to allocate memory");
- m_cmd_channel->connect(NULL, NULL, true);
+ if (!m_mon_socket->create(SENSOR_CHANNEL_PATH))
+ goto fail;
- m_mon_channel = new(std::nothrow) ipc::channel();
- retvm_if(!m_mon_channel, false, "Failed to allocate memory");
- m_mon_channel->connect(m_handler, &m_loop, true);
+ if (!m_mon_socket->connect())
+ goto fail;
+
+ ch = g_io_channel_unix_new(m_mon_socket->get_fd());
+ retvm_if(!ch, false, "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");
+ goto fail;
+ }
+
+ g_source_set_callback(g_src, (GSourceFunc) manager_handler, this, NULL);
+ g_source_attach(g_src, g_main_loop_get_context(m_loop));
+ g_source_unref(g_src);
msg.set_type(CMD_MANAGER_CONNECT);
- m_mon_channel->send_sync(msg);
+ ret = send(m_mon_socket, msg);
+ if (!ret)
+ goto fail;
m_connected.store(true);
_D("Connected");
return true;
+
+fail:
+ delete m_mon_socket;
+ m_mon_socket = NULL;
+
+ delete m_cmd_socket;
+ m_cmd_socket = NULL;
+
+ return false;
}
bool sensor_manager::connect(void)
ret_if(!is_connected());
m_connected.store(false);
- m_mon_channel->disconnect();
- delete m_mon_channel;
- m_mon_channel = NULL;
+ if (g_src && !g_source_is_destroyed(g_src)) {
+ g_source_destroy(g_src);
+ g_src = NULL;
+ }
+
+ delete m_mon_socket;
+ m_mon_socket = NULL;
- m_cmd_channel->disconnect();
- delete m_cmd_channel;
- m_cmd_channel = NULL;
+ delete m_cmd_socket;
+ m_cmd_socket = NULL;
_D("Disconnected");
}
{
ret_if(!is_connected());
- m_cmd_channel->disconnect();
- delete m_cmd_channel;
- m_cmd_channel = NULL;
+ if (g_src && !g_source_is_destroyed(g_src)) {
+ g_source_destroy(g_src);
+ g_src = NULL;
+ }
+
+ delete m_mon_socket;
+ m_mon_socket = NULL;
+
+ delete m_cmd_socket;
+ m_cmd_socket = NULL;
m_connected.store(false);
retm_if(!connect_channel(), "Failed to restore manager");
msg.set_type(CMD_MANAGER_SENSOR_LIST);
- ret = m_cmd_channel->send_sync(msg);
+ ret = send(m_cmd_socket, msg);
retvm_if(!ret, false, "Failed to send message");
- ret = m_cmd_channel->read_sync(reply);
+ ret = read(m_cmd_socket, reply);
retvm_if(!ret, false, "Failed to receive message");
reply.disclose(buf, MAX_BUF_SIZE);
memcpy(buf.sensor, uri.c_str(), uri.size());
msg.enclose((const char *)&buf, sizeof(buf));
- ret = m_cmd_channel->send_sync(msg);
+ ret = send(m_cmd_socket, msg);
retvm_if(!ret, false, "Failed to send message");
- ret = m_cmd_channel->read_sync(reply);
+ ret = read(m_cmd_socket, reply);
retvm_if(!ret, false, "Failed to receive message");
if (reply.header()->err == OP_SUCCESS)
return infos;
}
+bool sensor_manager::read(ipc::message &msg)
+{
+ return read(m_mon_socket, msg);
+}
+
+bool sensor_manager::read(ipc::socket *m_socket, 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;
+}
+
+bool sensor_manager::send(ipc::socket *m_socket, 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;
+}
+
+void sensor_manager::handle(ipc::message &msg)
+{
+ switch (msg.header()->type) {
+ case CMD_MANAGER_SENSOR_ADDED:
+ on_sensor_added(msg);
+ break;
+ case CMD_MANAGER_SENSOR_REMOVED:
+ on_sensor_removed(msg);
+ break;
+ }
+}
+
+void sensor_manager::on_sensor_added(ipc::message &msg)
+{
+ ret_if(msg.header()->err < OP_SUCCESS);
+
+ sensor_info info;
+ info.clear();
+ info.deserialize(msg.body(), msg.size());
+
+ add_sensor(info);
+
+ auto it = m_sensor_added_callbacks.begin();
+ while (it != m_sensor_added_callbacks.end()) {
+ it->first(info.get_uri().c_str(), it->second);
+ ++it;
+ }
+}
+
+void sensor_manager::on_sensor_removed(ipc::message &msg)
+{
+ ret_if(msg.header()->err < 0);
+ char uri[NAME_MAX] = {0, };
+
+ msg.disclose(uri, NAME_MAX);
+ remove_sensor(uri);
+
+ auto it = m_sensor_removed_callbacks.begin();
+ while (it != m_sensor_removed_callbacks.end()) {
+ it->first(uri, it->second);
+ ++it;
+ }
+}
\ No newline at end of file