From 1b2ef3c89cd32df2515c27a8cf03709ae97262ed Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 24 May 2016 14:00:39 +0900 Subject: [PATCH 01/16] sensord: transpose acc/gyro axis w.r.t the display rotation Change-Id: I23f81740000c13d377038b15b1904da642b4060e Signed-off-by: kibak.yoon --- src/client/client.cpp | 2 + src/client/dbus_listener.cpp | 135 +++++++++++++++++++++++++++++++++++ src/client/dbus_listener.h | 46 ++++++++++++ src/client/sensor_event_listener.cpp | 41 +++++++++++ src/client/sensor_event_listener.h | 8 +++ 5 files changed, 232 insertions(+) create mode 100755 src/client/dbus_listener.cpp create mode 100644 src/client/dbus_listener.h diff --git a/src/client/client.cpp b/src/client/client.cpp index ae79346..b9b99c1 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -30,6 +30,7 @@ #include #include #include +#include "dbus_listener.h" using std::vector; @@ -636,6 +637,7 @@ API int sensord_connect(sensor_t sensor) } set_power_save_state_cb(); + dbus_listener::init(); return handle; } diff --git a/src/client/dbus_listener.cpp b/src/client/dbus_listener.cpp new file mode 100755 index 0000000..7f96ef1 --- /dev/null +++ b/src/client/dbus_listener.cpp @@ -0,0 +1,135 @@ +/* + * sensord + * + * Copyright (c) 2013 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 +#include "sensor_event_listener.h" +#include "dbus_listener.h" + +#define HANDLE_GERROR(Err) \ + do { \ + if ((Err)) { \ + _E("GError: %s", Err->message); \ + g_error_free(Err); \ + Err = NULL; \ + } \ + } while (0) + +#define ROTATION_DBUS_DEST "org.tizen.system.coord" +#define ROTATION_DBUS_OBJ_PATH "/Org/Tizen/System/Coord/Rotation" +#define ROTATION_DBUS_IFACE "org.tizen.system.coord.rotation" +#define ROTATION_DBUS_SIGNAL "Changed" +#define ROTATION_DBUS_METHOD "Degree" + +static void rotation_signal_cb(GDBusConnection *conn, const gchar *sender, + const gchar *obj_path, const gchar *iface, const gchar *signal_name, + GVariant *param, gpointer user_data) +{ + gint state; + g_variant_get(param, "(i)", &state); + sensor_event_listener::get_instance().set_display_rotation(state); +} + +static void rotation_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *conn = G_DBUS_CONNECTION(source_object); + GVariant *result = g_dbus_connection_call_finish(conn, res, &error); + HANDLE_GERROR(error); + ret_if(result == NULL); + + gint state; + g_variant_get(result, "(i)", &state); + g_variant_unref(result); + sensor_event_listener::get_instance().set_display_rotation(state); +} + +dbus_listener::dbus_listener() +: m_connection(NULL) +{ +#ifndef GLIB_VERSION_2_36 + g_type_init(); +#endif +} + +dbus_listener::~dbus_listener() +{ + disconnect(); +} + +void dbus_listener::init(void) +{ + static dbus_listener listener; + static bool done = false; + ret_if(done); + listener.connect(); + done = true; +} + +void dbus_listener::connect(void) +{ + GError *gerr = NULL; + + gchar *addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr); + HANDLE_GERROR(gerr); + retm_if(addr == NULL, "Getting address failed"); + + g_dbus_connection_new_for_address(addr, + (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), + NULL, NULL, on_connection_ready, this); + g_free(addr); +} + +void dbus_listener::on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *gerr = NULL; + dbus_listener *listener = static_cast(user_data); + + GDBusConnection *conn = g_dbus_connection_new_finish(res, &gerr); + HANDLE_GERROR(gerr); + + retm_if(conn == NULL, "Connection failed"); + _D("Dbus connection established: %s", g_dbus_connection_get_unique_name(conn)); + + listener->m_connection = conn; + listener->get_current_state(); + listener->subscribe(); +} + +void dbus_listener::disconnect(void) +{ + ret_if(!m_connection); + g_dbus_connection_close_sync(m_connection, NULL, NULL); + g_object_unref(m_connection); +} + +void dbus_listener::subscribe(void) +{ + /* Diplay rotation */ + g_dbus_connection_signal_subscribe(m_connection, + ROTATION_DBUS_DEST, ROTATION_DBUS_IFACE, ROTATION_DBUS_SIGNAL, ROTATION_DBUS_OBJ_PATH, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)rotation_signal_cb, NULL, NULL); +} + +void dbus_listener::get_current_state(void) +{ + /* Display rotation */ + g_dbus_connection_call(m_connection, + ROTATION_DBUS_DEST, ROTATION_DBUS_OBJ_PATH, ROTATION_DBUS_IFACE, ROTATION_DBUS_METHOD, + NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback)rotation_read_cb, NULL); +} diff --git a/src/client/dbus_listener.h b/src/client/dbus_listener.h new file mode 100644 index 0000000..3d4a804 --- /dev/null +++ b/src/client/dbus_listener.h @@ -0,0 +1,46 @@ +/* + * sensord + * + * Copyright (c) 2013 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 _DBUS_LISTENER_H_ +#define _DBUS_LISTENER_H_ + +#include +#include +#include + +class dbus_listener { +public: + static void init(void); + +private: + GDBusConnection *m_connection; + + dbus_listener(); + ~dbus_listener(); + + void connect(void); + void disconnect(void); + + void subscribe(void); + void get_current_state(void); + + static void on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data); +}; + +#endif /* _DBUS_LISTENER_H_ */ diff --git a/src/client/sensor_event_listener.cpp b/src/client/sensor_event_listener.cpp index 2dc8cd4..0215b29 100644 --- a/src/client/sensor_event_listener.cpp +++ b/src/client/sensor_event_listener.cpp @@ -45,6 +45,7 @@ sensor_event_listener::sensor_event_listener() , m_thread_state(THREAD_STATE_TERMINATE) , m_hup_observer(NULL) , m_client_info(sensor_client_info::get_instance()) +, m_display_rotation(AUTO_ROTATION_DEGREE_UNKNOWN) { } @@ -237,6 +238,36 @@ bool sensor_event_listener::is_valid_callback(client_callback_info *cb_info) return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id); } +void sensor_event_listener::align_sensor_axis(sensor_t sensor, sensor_data_t *data) +{ + sensor_type_t type = sensor_to_sensor_info(sensor)->get_type(); + + if (type != ACCELEROMETER_SENSOR && type != GYROSCOPE_SENSOR && type != GRAVITY_SENSOR) + return; + + float x, y; + + switch (m_display_rotation) { + case AUTO_ROTATION_DEGREE_90: /* Landscape Left */ + x = -data->values[1]; + y = data->values[0]; + break; + case AUTO_ROTATION_DEGREE_180: /* Portrait Bottom */ + x = -data->values[0]; + y = -data->values[1]; + break; + case AUTO_ROTATION_DEGREE_270: /* Landscape Right */ + x = data->values[1]; + y = -data->values[0]; + break; + default: + return; + } + + data->values[0] = x; + data->values[1] = y; +} + gboolean sensor_event_listener::callback_dispatcher(gpointer data) { client_callback_info *cb_info = (client_callback_info*) data; @@ -452,3 +483,13 @@ bool sensor_event_listener::start_event_listener(void) return true; } + +void sensor_event_listener::set_display_rotation(int rt) +{ + _D("New display rotation: %d", rt); + + if (rt < AUTO_ROTATION_DEGREE_0 || rt > AUTO_ROTATION_DEGREE_270) + return; + + m_display_rotation = rt; +} diff --git a/src/client/sensor_event_listener.h b/src/client/sensor_event_listener.h index 1c94475..5bb92ab 100644 --- a/src/client/sensor_event_listener.h +++ b/src/client/sensor_event_listener.h @@ -77,6 +77,8 @@ public: void clear(void); void set_hup_observer(hup_observer_t observer); + void set_display_rotation(int rt); + private: enum thread_state { THREAD_STATE_START, @@ -97,6 +99,9 @@ private: sensor_client_info &m_client_info; + /* WC1's rotation control */ + int m_display_rotation; + sensor_event_listener(); ~sensor_event_listener(); @@ -121,6 +126,9 @@ private: static gboolean callback_dispatcher(gpointer data); void set_thread_state(thread_state state); + + /* WC1's sensor axis alignment */ + void align_sensor_axis(sensor_t sensor, sensor_data_t *data); }; #endif /* _SENSOR_EVENT_LISTENER_H_ */ -- 2.7.4 From b3d0802bd19f3bb6a9c2c5047d247a7a91fe03bc Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 24 May 2016 16:56:21 +0900 Subject: [PATCH 02/16] sensord: change comment for syncing - comments are different between tizen 2.3 and tizen 3.0. so sync them. Change-Id: I011df5ef30ac5075f2eb36327364fc90bc85e4b1 Signed-off-by: kibak.yoon --- src/shared/csocket.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/shared/csocket.cpp b/src/shared/csocket.cpp index 00697f6..09a7d0e 100644 --- a/src/shared/csocket.cpp +++ b/src/shared/csocket.cpp @@ -250,10 +250,10 @@ ssize_t csocket::send_for_stream(const void *buffer, size_t size) const len, get_client_name()); /* - * If socket is not available to use it temporarily, - * EAGAIN(EWOULDBLOCK) is returned by ::send(). - * so in order to prevent that data are omitted, retry to send it - */ + * If socket is not available to use it temporarily, + * EAGAIN(EWOULDBLOCK) is returned by ::send(). + * so in order to prevent that data are omitted, sleep&retry to send it + */ if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { usleep(1000); continue; @@ -291,10 +291,10 @@ ssize_t csocket::recv_for_stream(void* buffer, size_t size) const len, get_client_name()); /* - * If socket is not available to use during for some time, - * EAGAIN(EWOULDBLOCK) is returned by ::recv(). - * so in order to prevent that data are omitted, retry to receive it - */ + * If socket is not available to use it temporarily, + * EAGAIN(EWOULDBLOCK) is returned by ::recv(). + * so in order to prevent that data are omitted, sleep&retry to receive it + */ if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { usleep(1000); continue; @@ -359,7 +359,7 @@ bool csocket::connect(const char *sock_path) addr_len = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family); - if (::connect(m_sock_fd, (sockaddr *) &m_addr, addr_len) < 0) { + if (::connect(m_sock_fd, (sockaddr *)&m_addr, addr_len) < 0) { _ERRNO(errno, _E, "Failed to connect sock_fd: %d for %s", m_sock_fd, get_client_name()); return false; -- 2.7.4 From c07705bdf7823d7f58c7887915ef5811aa5f5010 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 24 May 2016 18:40:53 +0900 Subject: [PATCH 03/16] sensord: support external sensor feature Change-Id: I3649a0b017c6b94c98cc5c71ac3c776002ea0f43 Signed-off-by: kibak.yoon --- src/client/command_channel.cpp | 6 + src/client/external_client.cpp | 256 ++++++++++++++++ src/client/external_data_channel.cpp | 266 ++++++++++++++++ src/client/external_data_channel.h | 46 +++ src/client/external_sensor_manager.cpp | 542 +++++++++++++++++++++++++++++++++ src/client/external_sensor_manager.h | 135 ++++++++ src/client/sensor_event_listener.cpp | 6 + src/server/command_queue.cpp | 55 ++++ src/server/command_queue.h | 50 +++ src/server/dbus_util.cpp | 174 +++++++++++ src/server/dbus_util.h | 44 +++ src/server/external_client_manager.cpp | 227 ++++++++++++++ src/server/external_client_manager.h | 55 ++++ src/server/external_sensor.cpp | 86 ++++++ src/server/external_sensor.h | 47 +++ src/server/external_sensor_record.cpp | 99 ++++++ src/server/external_sensor_record.h | 56 ++++ src/server/external_sensor_service.cpp | 152 +++++++++ src/server/external_sensor_service.h | 52 ++++ src/server/external_sensor_worker.cpp | 329 ++++++++++++++++++++ src/server/external_sensor_worker.h | 67 ++++ src/server/sensor_event_dispatcher.cpp | 1 + src/server/sensor_loader.cpp | 25 ++ src/server/sensor_loader.h | 1 + src/server/server.cpp | 84 ++++- src/server/server.h | 3 + src/shared/command_common.h | 55 ++++ src/shared/sensor_common.h | 5 + 28 files changed, 2911 insertions(+), 13 deletions(-) create mode 100644 src/client/external_client.cpp create mode 100644 src/client/external_data_channel.cpp create mode 100644 src/client/external_data_channel.h create mode 100644 src/client/external_sensor_manager.cpp create mode 100644 src/client/external_sensor_manager.h create mode 100644 src/server/command_queue.cpp create mode 100644 src/server/command_queue.h create mode 100755 src/server/dbus_util.cpp create mode 100644 src/server/dbus_util.h create mode 100644 src/server/external_client_manager.cpp create mode 100644 src/server/external_client_manager.h create mode 100644 src/server/external_sensor.cpp create mode 100644 src/server/external_sensor.h create mode 100644 src/server/external_sensor_record.cpp create mode 100644 src/server/external_sensor_record.h create mode 100644 src/server/external_sensor_service.cpp create mode 100644 src/server/external_sensor_service.h create mode 100644 src/server/external_sensor_worker.cpp create mode 100644 src/server/external_sensor_worker.h diff --git a/src/client/command_channel.cpp b/src/client/command_channel.cpp index 274552f..ff49a54 100644 --- a/src/client/command_channel.cpp +++ b/src/client/command_channel.cpp @@ -79,6 +79,7 @@ bool command_channel::command_handler(cpacket *packet, void **return_payload) bool command_channel::create_channel(void) { + const int cllient_type = CLIENT_TYPE_SENSOR_CLIENT; if (!m_command_socket.create(SOCK_STREAM)) return false; @@ -89,6 +90,11 @@ bool command_channel::create_channel(void) m_command_socket.set_connection_mode(); + if (m_command_socket.send(&cllient_type, sizeof(cllient_type)) <= 0) { + _E("Failed to send client type in client %s, command socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd()); + return false; + } + return true; } diff --git a/src/client/external_client.cpp b/src/client/external_client.cpp new file mode 100644 index 0000000..1a3e2da --- /dev/null +++ b/src/client/external_client.cpp @@ -0,0 +1,256 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include +#include +#include +#include + +using std::vector; +using std::string; + +static cmutex lock; + +static void clean_up(void); +static void restore_session(void); + +class initiator { +public: + initiator() + { + external_sensor_manager::get_instance().set_hup_observer(restore_session); + } +}; + +static initiator g_initiator; + +void clean_up(void) +{ + vector handles; + + external_sensor_manager::get_instance().get_all_handles(handles); + + auto it_handle = handles.begin(); + + while (it_handle != handles.end()) { + sensord_external_disconnect(*it_handle); + ++it_handle; + } +} + +void restore_session(void) +{ + AUTOLOCK(lock); + + _I("Trying to restore external source session for %s", get_client_name()); + + external_data_channel *data_channel; + int client_id; + + external_sensor_manager::get_instance().close_data_channel(); + external_sensor_manager::get_instance().set_client_id(CLIENT_ID_INVALID); + + vector handles; + + external_sensor_manager::get_instance().get_all_handles(handles); + + bool first_connection = true; + + auto it_handle = handles.begin(); + + while (it_handle != handles.end()) { + data_channel = new(std::nothrow) external_data_channel(); + retm_if(!data_channel, "Failed to allocate memory"); + + if (!data_channel->create_channel()) { + _E("%s failed to create data channel", get_client_name()); + delete data_channel; + goto FAILED; + } + + external_sensor_manager::get_instance().add_data_channel(*it_handle, data_channel); + + if (first_connection) { + first_connection = false; + if (!data_channel->cmd_get_id(client_id)) { + _E("Failed to get client id"); + goto FAILED; + } + + external_sensor_manager::get_instance().set_client_id(client_id); + external_sensor_manager::get_instance().start_command_listener(); + } + + data_channel->set_client_id(client_id); + + sensor_id_t dummy; + if (!data_channel->cmd_connect(external_sensor_manager::get_instance().get_key(*it_handle), dummy)) { + _E("Sending cmd_connect(%s) failed for %s", external_sensor_manager::get_instance().get_key(*it_handle).c_str(), get_client_name()); + goto FAILED; + } + + ++it_handle; + } + + _I("Succeeded to restore external source session for %s", get_client_name()); + + return; + +FAILED: + external_sensor_manager::get_instance().clear(); + _E("Failed to restore external source session for %s", get_client_name()); +} + +API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data) +{ + external_data_channel *channel = NULL; + int handle; + int client_id; + bool first_connection = false; + + retvm_if(!key, OP_ERROR, "client %s passes null key", get_client_name()); + + AUTOLOCK(lock); + + handle = external_sensor_manager::get_instance().create_handle(); + + // lazy loading after creating static variables + atexit(clean_up); + + if (handle == MAX_HANDLE) { + _E("Maximum number of handles reached, key %s in client %s", key, get_client_name()); + return OP_ERROR; + } + + channel = new(std::nothrow) external_data_channel(); + if (!channel) { + _E("Failed to allocated memory"); + external_sensor_manager::get_instance().delete_handle(handle); + return OP_ERROR; + } + + if (!channel->create_channel()) { + _E("%s failed to create data channel for %s", get_client_name(), key); + external_sensor_manager::get_instance().delete_handle(handle); + delete channel; + return OP_ERROR; + } + + external_sensor_manager::get_instance().add_data_channel(handle, channel); + + if (!external_sensor_manager::get_instance().has_client_id()) { + first_connection = true; + if (!channel->cmd_get_id(client_id)) { + _E("Sending cmd_get_id() failed for %s", key); + external_sensor_manager::get_instance().close_data_channel(handle); + external_sensor_manager::get_instance().delete_handle(handle); + return OP_ERROR; + } + + external_sensor_manager::get_instance().set_client_id(client_id); + _I("%s gets client_id [%d]", get_client_name(), client_id); + external_sensor_manager::get_instance().start_command_listener(); + _I("%s starts listening command with client_id [%d]", get_client_name(), client_id); + } + + client_id = external_sensor_manager::get_instance().get_client_id(); + channel->set_client_id(client_id); + + sensor_id_t sensor; + + if (!channel->cmd_connect(key, sensor)) { + _E("Failed to connect %s for %s", key, get_client_name()); + external_sensor_manager::get_instance().close_data_channel(handle); + external_sensor_manager::get_instance().delete_handle(handle); + + if (first_connection) { + external_sensor_manager::get_instance().set_client_id(CLIENT_ID_INVALID); + external_sensor_manager::get_instance().stop_command_listener(); + } + + return OP_ERROR; + } + + _I("%s[%d] connects with %s[%d]", get_client_name(), client_id, key, handle); + + external_sensor_manager::get_instance().set_handle(handle, sensor, string(key), (void *)cb, user_data); + + return handle; +} + +API bool sensord_external_disconnect(int handle) +{ + external_data_channel *channel; + + AUTOLOCK(lock); + + retvm_if(!external_sensor_manager::get_instance().is_valid(handle), false, "Handle %d is not valid for %s", + handle, get_client_name()); + + if (!external_sensor_manager::get_instance().get_data_channel(handle, &channel)) { + _E("client %s failed to get data channel", get_client_name()); + return false; + } + + _I("%s disconnects with %s[%d]", get_client_name(), external_sensor_manager::get_instance().get_key(handle).c_str(), handle); + + if (!external_sensor_manager::get_instance().delete_handle(handle)) + return false; + + if (!channel->cmd_disconnect()) { + _E("Sending cmd_disconnect() failed for %s", get_client_name()); + return false; + } + + external_sensor_manager::get_instance().close_data_channel(handle); + + if (!external_sensor_manager::get_instance().is_active()) { + _I("Stop listening command for client %s with client id [%d]", get_client_name(), external_sensor_manager::get_instance().get_client_id()); + external_sensor_manager::get_instance().set_client_id(CLIENT_ID_INVALID); + external_sensor_manager::get_instance().stop_command_listener(); + } + + return true; +} + +API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt) +{ + external_data_channel *channel; + + retvm_if(((data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), false, + "data_cnt(%d) is invalid for %s", data_cnt, get_client_name()); + + AUTOLOCK(lock); + + retvm_if(!external_sensor_manager::get_instance().is_valid(handle), false, "Handle %d is not valid for %s", + handle, get_client_name()); + + if (!external_sensor_manager::get_instance().get_data_channel(handle, &channel)) { + _E("client %s failed to get data channel", get_client_name()); + return false; + } + + if (!channel->cmd_post(timestamp, data, data_cnt)) { + _E("Failed to post data:%#x, data_cnt:%d", data, data_cnt); + return false; + } + + return true; +} diff --git a/src/client/external_data_channel.cpp b/src/client/external_data_channel.cpp new file mode 100644 index 0000000..70a7325 --- /dev/null +++ b/src/client/external_data_channel.cpp @@ -0,0 +1,266 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include + +using std::string; + +external_data_channel::external_data_channel() +: m_client_id(CLIENT_ID_INVALID) +, m_sensor_id(UNKNOWN_SENSOR) +{ +} + +external_data_channel::~external_data_channel() +{ + m_socket.close(); +} + +bool external_data_channel::command_handler(cpacket *packet, void **return_payload) +{ + packet_header header; + char *buffer = NULL; + + if (!m_socket.is_valid()) { + _E("Socket(%d) is not valid for client %s", m_socket.get_socket_fd(), get_client_name()); + return false; + } + + if (!packet->size()) { + _E("Packet is not valid for client %s", get_client_name()); + return false; + } + + if (m_socket.send(packet->packet(), packet->size()) <= 0) { + m_socket.close(); + _E("Failed to send command in client %s", get_client_name()); + return false; + } + + if (m_socket.recv(&header, sizeof(header)) <= 0) { + m_socket.close(); + _E("Failed to receive header for command packet in client %s", get_client_name()); + return false; + } + + buffer = new(std::nothrow) char[header.size]; + retvm_if(!buffer, false, "Failed to allocate memory"); + + if (m_socket.recv(buffer, header.size) <= 0) { + m_socket.close(); + _E("Failed to receive command packet in client %s", get_client_name()); + delete[] buffer; + return false; + } + + *return_payload = buffer; + + return true; +} + +bool external_data_channel::create_channel(void) +{ + const int client_type = CLIENT_TYPE_EXTERNAL_SOURCE; + + if (!m_socket.create(SOCK_STREAM)) { + _E("Failed to create external data channel for client %s", get_client_name()); + return false; + } + + if (!m_socket.connect(COMMAND_CHANNEL_PATH)) { + _E("Failed to connect external data channel for client %s, command socket fd[%d]", get_client_name(), m_socket.get_socket_fd()); + return false; + } + + m_socket.set_connection_mode(); + + if (m_socket.send(&client_type, sizeof(client_type)) <= 0) { + _E("Failed to send client type in client %s, command socket fd[%d]", get_client_name(), m_socket.get_socket_fd()); + return false; + } + + return true; +} + +void external_data_channel::set_client_id(int client_id) +{ + m_client_id = client_id; +} + +bool external_data_channel::cmd_get_id(int &client_id) +{ + cpacket *packet; + cmd_ext_get_id_t *cmd_ext_get_id; + cmd_ext_get_id_done_t *cmd_ext_get_id_done; + + packet = new(std::nothrow) cpacket(sizeof(cmd_ext_get_id_t)); + retvm_if(!packet, false, "Failed to allocate memory"); + + packet->set_cmd(CMD_EXT_GET_ID); + + cmd_ext_get_id = (cmd_ext_get_id_t *)packet->data(); + + get_proc_name(getpid(), cmd_ext_get_id->name); + + _I("%s send cmd_get_id()", get_client_name()); + + if (!command_handler(packet, (void **)&cmd_ext_get_id_done)) { + _E("Client %s failed to send/receive command", get_client_name()); + delete packet; + return false; + } + + if (cmd_ext_get_id_done->client_id < 0) { + _E("Client %s failed to get client_id[%d] from server", + get_client_name(), cmd_ext_get_id_done->client_id); + delete[] (char *)cmd_ext_get_id_done; + delete packet; + return false; + } + + client_id = cmd_ext_get_id_done->client_id; + + delete[] (char *)cmd_ext_get_id_done; + delete packet; + + return true; +} + +bool external_data_channel::cmd_connect(const string &key, sensor_id_t &sensor_id) +{ + cpacket *packet; + cmd_ext_connect_t *cmd_ext_connect; + cmd_ext_connect_done_t *cmd_ext_connect_done; + + int key_size = key.size(); + + if ((key_size == 0) || (key_size >= NAME_MAX)) { + _I("Key(%s) is not valid", key.c_str()); + return false; + } + + packet = new(std::nothrow) cpacket(sizeof(cmd_ext_connect_t)); + retvm_if(!packet, false, "Failed to allocate memory"); + + packet->set_cmd(CMD_EXT_CONNECT); + + cmd_ext_connect = (cmd_ext_connect_t *)packet->data(); + cmd_ext_connect->client_id = m_client_id; + strncpy(cmd_ext_connect->key, key.c_str(), NAME_MAX-1); + + _I("%s send cmd_get_connect(key = %s, client_id = %d)", get_client_name(), key.c_str(), m_client_id); + + if (!command_handler(packet, (void **)&cmd_ext_connect_done)) { + _E("Client %s failed to send/receive command", get_client_name()); + delete packet; + return false; + } + + if (cmd_ext_connect_done->sensor_id == UNKNOWN_SENSOR) { + _E("Client %s failed to connect to external sensor", get_client_name()); + delete[] (char *)cmd_ext_connect_done; + delete packet; + return false; + } + + m_sensor_id = sensor_id = cmd_ext_connect_done->sensor_id; + + delete[] (char *)cmd_ext_connect_done; + delete packet; + + return true; +} + +bool external_data_channel::cmd_disconnect(void) +{ + cpacket *packet; + cmd_ext_done_t *cmd_ext_done; + + packet = new(std::nothrow) cpacket(sizeof(cmd_ext_disconnect_t)); + retvm_if(!packet, false, "Failed to allocate memory"); + + packet->set_cmd(CMD_EXT_DISCONNECT); + + _I("%s send cmd_disconnect(client_id=%d)", get_client_name(), m_client_id); + + if (!command_handler(packet, (void **)&cmd_ext_done)) { + _E("Client %s failed to send/receive command with client_id [%d]", + get_client_name(), m_client_id); + delete packet; + return false; + } + + if (cmd_ext_done->value < 0) { + _E("Client %s got error[%d] from server with client_id [%d]", + get_client_name(), cmd_ext_done->value, m_client_id); + + delete[] (char *)cmd_ext_done; + delete packet; + return false; + } + + delete[] (char *)cmd_ext_done; + delete packet; + + m_socket.close(); + m_client_id = CLIENT_ID_INVALID; + return true; +} + +bool external_data_channel::cmd_post(unsigned long long timestamp, const float *data, int data_cnt) +{ + cpacket *packet; + cmd_ext_post_t *cmd_ext_post; + cmd_done_t *cmd_done; + + packet = new(std::nothrow) cpacket(sizeof(cmd_ext_post_t) + sizeof(float) * data_cnt); + retvm_if(!packet, false, "Failed to allocate memory"); + + packet->set_cmd(CMD_EXT_POST); + + cmd_ext_post = (cmd_ext_post_t*)packet->data(); + cmd_ext_post->timestamp = timestamp; + cmd_ext_post->data_cnt = data_cnt; + memcpy(cmd_ext_post->data, data, sizeof(float) * data_cnt); + + _I("%s send cmd_post(client_id=%d, data = %#x, data_cnt = %d)", + get_client_name(), m_client_id, data, data_cnt); + + if (!command_handler(packet, (void **)&cmd_done)) { + _E("%s failed to send/receive command with client_id [%d]", + get_client_name(), m_client_id); + delete packet; + return false; + } + + if (cmd_done->value < 0) { + _E("%s got error[%d] from server with client_id [%d]", + get_client_name(), cmd_done->value, m_client_id); + + delete[] (char *)cmd_done; + delete packet; + return false; + } + + delete[] (char *)cmd_done; + delete packet; + + return true; +} diff --git a/src/client/external_data_channel.h b/src/client/external_data_channel.h new file mode 100644 index 0000000..19a2a41 --- /dev/null +++ b/src/client/external_data_channel.h @@ -0,0 +1,46 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_DATA_CHANNEL_H_ +#define _EXTERNAL_DATA_CHANNEL_H_ + +#include +#include + +class cpacket; + +class external_data_channel { +public: + external_data_channel(); + ~external_data_channel(); + + bool create_channel(void); + void set_client_id(int client_id); + bool cmd_get_id(int &client_id); + bool cmd_connect(const std::string &key, sensor_id_t &sensor_id); + bool cmd_disconnect(void); + bool cmd_post(unsigned long long timestamp, const float *data, int data_cnt); +private: + csocket m_socket; + int m_client_id; + sensor_id_t m_sensor_id; + bool command_handler(cpacket *packet, void **return_payload); +}; + +#endif /* _EXTERNAL_DATA_CHANNEL_H_ */ diff --git a/src/client/external_sensor_manager.cpp b/src/client/external_sensor_manager.cpp new file mode 100644 index 0000000..e19b403 --- /dev/null +++ b/src/client/external_sensor_manager.cpp @@ -0,0 +1,542 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include +#include +#include +#include +#include + +using std::pair; +using std::vector; +using std::thread; +using std::string; + +external_sensor_manager::external_sensor_manager() +: m_client_id(CLIENT_ID_INVALID) +, m_poller(NULL) +, m_thread_state(THREAD_STATE_TERMINATE) +, m_hup_observer(NULL) +{ +} + +external_sensor_manager::~external_sensor_manager() +{ + stop_command_listener(); +} + +external_sensor_manager& external_sensor_manager::get_instance(void) +{ + static external_sensor_manager inst; + return inst; +} + +int external_sensor_manager::create_handle(void) +{ + sensor_ext_handle_info handle_info; + int handle = 0; + + AUTOLOCK(m_handle_info_lock); + + while (m_sensor_handle_infos.count(handle) > 0) + handle++; + + if (handle >= MAX_HANDLE) { + _E("Handles of client %s are full", get_client_name()); + return MAX_HANDLE_REACHED; + } + + handle_info.m_handle = handle; + handle_info.m_sensor = UNKNOWN_SENSOR; + handle_info.m_cb = NULL; + handle_info.m_user_data = NULL; + + m_sensor_handle_infos.insert(pair(handle, handle_info)); + + return handle; +} + +bool external_sensor_manager::delete_handle(int handle) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) { + _E("Handle[%d] is not found for client %s", handle, get_client_name()); + return false; + } + + m_sensor_handle_map.erase(it_handle->second.m_sensor); + m_sensor_handle_infos.erase(it_handle); + + return true; +} + +bool external_sensor_manager::set_handle(int handle, sensor_id_t sensor, const string& key, void* cb, void* user_data) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) { + _E("Handle[%d] is not found for client %s", handle, get_client_name()); + return false; + } + + it_handle->second.m_sensor = sensor; + it_handle->second.m_key = key; + it_handle->second.m_cb = cb; + it_handle->second.m_user_data = user_data; + + m_sensor_handle_map.insert(pair(sensor, handle)); + + return true; +} + +bool external_sensor_manager::get_sensor(int handle, sensor_id_t &sensor) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) { + _E("Handle[%d] is not found for client %s", handle, get_client_name()); + return false; + } + + sensor = it_handle->second.m_sensor; + + return true; +} + +int external_sensor_manager::get_handle(sensor_id_t sensor) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_map.find(sensor); + + if (it_handle == m_sensor_handle_map.end()) { + _E("Handle is not found for client %s with sensor: %d", get_client_name(), sensor); + return -1; + } + + return it_handle->second; +} + +bool external_sensor_manager::get_handle_info(int handle, const sensor_ext_handle_info*& handle_info) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) { + _E("Handle[%d] is not found for client %s", handle, get_client_name()); + return false; + } + + handle_info = &(it_handle->second); + return true; +} + +string external_sensor_manager::get_key(int handle) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) { + return string("INVALID_KEY"); + } + + return it_handle->second.m_key; +} + +bool external_sensor_manager::has_client_id(void) +{ + return (m_client_id != CLIENT_ID_INVALID); +} + +int external_sensor_manager::get_client_id(void) +{ + return m_client_id; +} + +void external_sensor_manager::set_client_id(int client_id) +{ + m_client_id = client_id; +} + +bool external_sensor_manager::add_data_channel(int handle, external_data_channel *channel) +{ + auto it_channel = m_data_channels.find(handle); + + if (it_channel != m_data_channels.end()) { + _E("%s alreay has data_channel for %s", get_client_name(), get_key(handle).c_str()); + return false; + } + + m_data_channels.insert(pair(handle, channel)); + return true; +} + +bool external_sensor_manager::get_data_channel(int handle, external_data_channel **channel) +{ + auto it_channel = m_data_channels.find(handle); + + if (it_channel == m_data_channels.end()) { + _E("%s doesn't have data_channel for %s", get_client_name(), get_key(handle).c_str()); + return false; + } + + *channel = it_channel->second; + + return true; +} + +bool external_sensor_manager::close_data_channel(void) +{ + auto it_channel = m_data_channels.begin(); + + if (it_channel != m_data_channels.end()) { + delete it_channel->second; + ++it_channel; + } + + m_data_channels.clear(); + + return true; +} + +bool external_sensor_manager::close_data_channel(int handle) +{ + auto it_channel = m_data_channels.find(handle); + + if (it_channel == m_data_channels.end()) { + _E("%s doesn't have data_channel for %s", get_client_name(), get_key(handle).c_str()); + return false; + } + + delete it_channel->second; + + m_data_channels.erase(it_channel); + + return true; +} + +bool external_sensor_manager::is_valid(int handle) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.find(handle); + + if (it_handle == m_sensor_handle_infos.end()) + return false; + + return true; +} + +bool external_sensor_manager::is_active(void) +{ + AUTOLOCK(m_handle_info_lock); + + return !m_sensor_handle_infos.empty(); +} + +void external_sensor_manager::get_all_handles(vector &handles) +{ + AUTOLOCK(m_handle_info_lock); + + auto it_handle = m_sensor_handle_infos.begin(); + + while (it_handle != m_sensor_handle_infos.end()) { + handles.push_back(it_handle->first); + ++it_handle; + } +} + +bool external_sensor_manager::create_command_channel(void) +{ + const int client_type = CLIENT_TYPE_EXTERNAL_SOURCE; + int client_id; + channel_ready_t channel_ready; + + if (!m_command_socket.create(SOCK_SEQPACKET)) + return false; + + if (!m_command_socket.connect(EVENT_CHANNEL_PATH)) { + _E("Failed to connect command channel for client %s, command socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd()); + return false; + } + + m_command_socket.set_connection_mode(); + + if (m_command_socket.send(&client_type, sizeof(client_type)) <= 0) { + _E("Failed to send client type in client %s, event socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd()); + return false; + } + + client_id = get_client_id(); + + if (m_command_socket.send(&client_id, sizeof(client_id)) <= 0) { + _E("Failed to send client id for client %s on command socket[%d]", get_client_name(), m_command_socket.get_socket_fd()); + return false; + } + + if (m_command_socket.recv(&channel_ready, sizeof(channel_ready)) <= 0) { + _E("%s failed to recv command channel ready packet on command socket[%d] with client id [%d]", + get_client_name(), m_command_socket.get_socket_fd(), client_id); + return false; + } + + if ((channel_ready.magic != CHANNEL_MAGIC_NUM) || (channel_ready.client_id != client_id)) { + _E("Command channel ready packet is wrong, magic = %#x, client id = %d", + channel_ready.magic, channel_ready.client_id); + return false; + } + + _I("Command channel is established for client %s on socket[%d] with client id : %d", + get_client_name(), m_command_socket.get_socket_fd(), client_id); + + return true; +} + +void external_sensor_manager::close_command_channel(void) +{ + m_command_socket.close(); +} + +bool external_sensor_manager::start_command_listener(void) +{ + if (!create_command_channel()) { + _E("Command channel is not established for %s", get_client_name()); + return false; + } + + m_command_socket.set_transfer_mode(); + + m_poller = new(std::nothrow) poller(m_command_socket.get_socket_fd()); + retvm_if(!m_poller, false, "Failed to allocate memory"); + + set_thread_state(THREAD_STATE_START); + + thread listener(&external_sensor_manager::listen_command, this); + listener.detach(); + + return true; +} + +void external_sensor_manager::stop_command_listener(void) +{ + const int THREAD_TERMINATING_TIMEOUT = 2; + + ulock u(m_thread_mutex); + + if (m_thread_state != THREAD_STATE_TERMINATE) { + m_thread_state = THREAD_STATE_STOP; + + _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state); + if (m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT)) + == std::cv_status::timeout) + _E("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT); + else + _D("Listener thread for %s is terminated", get_client_name()); + } +} + +void external_sensor_manager::set_thread_state(thread_state state) +{ + lock l(m_thread_mutex); + m_thread_state = state; +} + +bool external_sensor_manager::get_cb_info(sensor_id_t sensor, char* data, int data_cnt, command_cb_info &cb_info) +{ + int handle; + const sensor_ext_handle_info *handle_info; + + AUTOLOCK(m_handle_info_lock); + + handle = get_handle(sensor); + + if (handle < 0) + return false; + + get_handle_info(handle, handle_info); + + cb_info.handle = handle_info->m_handle; + cb_info.sensor = handle_info->m_sensor; + cb_info.cb = handle_info->m_cb; + cb_info.data = data; + cb_info.data_cnt = data_cnt; + cb_info.user_data = handle_info->m_user_data; + + return true; +} + +bool external_sensor_manager::sensor_command_poll(void* buffer, int buffer_len, struct epoll_event &event) +{ + ssize_t len; + + len = m_command_socket.recv(buffer, buffer_len); + + if (!len) { + if (!m_poller->poll(event)) + return false; + len = m_command_socket.recv(buffer, buffer_len); + + if (len <= 0) { + _I("%s failed to read after poll!", get_client_name()); + return false; + } + } else if (len < 0) { + _I("%s failed to recv command from command socket", get_client_name()); + return false; + } + + return true; +} + +void external_sensor_manager::post_callback_to_main_loop(command_cb_info* cb_info) +{ + g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL); +} + +void external_sensor_manager::handle_command(sensor_id_t sensor, char* data, int data_cnt) +{ + command_cb_info *cb_info = NULL; + + { /* scope for the lock */ + AUTOLOCK(m_handle_info_lock); + + cb_info = new(std::nothrow) command_cb_info; + if (!cb_info) { + _E("Failed to allocate memory"); + delete[] data; + } + + if (!get_cb_info(sensor, data, data_cnt, *cb_info)) { + delete[] data; + delete cb_info; + _E("Sensor %d is not connected, so command is discarded", sensor); + return; + } + } + + if (cb_info) + post_callback_to_main_loop(cb_info); +} + +void external_sensor_manager::listen_command(void) +{ + external_command_header_t command_header; + struct epoll_event event; + event.events = EPOLLIN | EPOLLPRI; + + do { + lock l(m_thread_mutex); + if (m_thread_state == THREAD_STATE_START) { + if (!sensor_command_poll(&command_header, sizeof(command_header), event)) { + _I("Failed to poll command header"); + break; + } + + char *command = new(std::nothrow) char[command_header.command_len]; + if (!command) { + _E("Failed to allocated memory"); + break; + } + + if (!sensor_command_poll(command, command_header.command_len, event)) { + _I("Failed to poll command data"); + delete []command; + break; + } + + handle_command(command_header.sensor_id, command, command_header.command_len); + } else { + break; + } + } while (true); + + if (m_poller != NULL) { + delete m_poller; + m_poller = NULL; + } + + close_command_channel(); + + { /* the scope for the lock */ + lock l(m_thread_mutex); + m_thread_state = THREAD_STATE_TERMINATE; + m_thread_cond.notify_one(); + } + + _I("Command listener thread is terminated."); + + if (has_client_id() && (event.events & EPOLLHUP)) { + if (m_hup_observer) + m_hup_observer(); + } +} + +bool external_sensor_manager::is_valid_callback(const command_cb_info *cb_info) +{ + sensor_id_t sensor; + + if (!external_sensor_manager::get_instance().get_sensor(cb_info->handle, sensor)) + return false; + + return (cb_info->sensor == sensor); +} + +gboolean external_sensor_manager::callback_dispatcher(gpointer data) +{ + const command_cb_info *cb_info = reinterpret_cast(data); + + if (external_sensor_manager::get_instance().is_valid_callback(cb_info)) { + reinterpret_cast(cb_info->cb)(cb_info->handle, cb_info->data, cb_info->data_cnt, cb_info->user_data); + } else { + _W("Discard invalid callback cb(%#x)(%d, %#x, %d, %#x)", + cb_info->cb, cb_info->handle, cb_info->data, cb_info->data_cnt, cb_info->user_data); + } + + delete[] cb_info->data; + delete cb_info; + +/* +* To be called only once, it returns false +*/ + return false; +} + +void external_sensor_manager::clear(void) +{ + close_command_channel(); + stop_command_listener(); + close_data_channel(); + m_sensor_handle_infos.clear(); + set_client_id(CLIENT_ID_INVALID); +} + +void external_sensor_manager::set_hup_observer(hup_observer_t observer) +{ + m_hup_observer = observer; +} diff --git a/src/client/external_sensor_manager.h b/src/client/external_sensor_manager.h new file mode 100644 index 0000000..9259c2c --- /dev/null +++ b/src/client/external_sensor_manager.h @@ -0,0 +1,135 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_SENSOR_MANAGER_H_ +#define _EXTERNAL_SENSOR_MANAGER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class external_data_channel; +class poller; + +class sensor_ext_handle_info { +public: + int m_handle; + sensor_id_t m_sensor; + std::string m_key; + void *m_cb; + void *m_user_data; +}; + +typedef struct { + int handle; + sensor_id_t sensor; + char *data; + int data_cnt; + void *cb; + void *user_data; +} command_cb_info; + +class external_sensor_manager { +public: + typedef void (*hup_observer_t)(void); + + static external_sensor_manager& get_instance(void); + int create_handle(void); + bool delete_handle(int handle); + + bool set_handle(int handle, sensor_id_t sensor, const std::string& key, void* cb, void* user_data); + + bool get_sensor(int handle, sensor_id_t &sensor_id); + int get_handle(sensor_id_t sensor); + bool get_handle_info(int handle, const sensor_ext_handle_info*& handle_info); + std::string get_key(int handle); + + bool has_client_id(void); + int get_client_id(void); + void set_client_id(int client_id); + + bool add_data_channel(int handle, external_data_channel *channel); + bool get_data_channel(int handle, external_data_channel **channel); + bool close_data_channel(void); + bool close_data_channel(int handle); + + bool is_valid(int handle); + bool is_active(void); + + void get_all_handles(std::vector &handles); + + bool start_command_listener(void); + void stop_command_listener(void); + void clear(void); + + void set_hup_observer(hup_observer_t observer); +private: + enum thread_state { + THREAD_STATE_START, + THREAD_STATE_STOP, + THREAD_STATE_TERMINATE, + }; + + typedef std::lock_guard lock; + typedef std::unique_lock ulock; + + external_sensor_manager(); + ~external_sensor_manager(); + + external_sensor_manager(const external_sensor_manager&) {}; + external_sensor_manager& operator=(const external_sensor_manager&); + + bool create_command_channel(void); + void close_command_channel(void); + void set_thread_state(thread_state state); + + bool sensor_command_poll(void* buffer, int buffer_len, struct epoll_event &event); + + bool get_cb_info(sensor_id_t sensor, char* data, int data_cnt, command_cb_info &cb_info); + void post_callback_to_main_loop(command_cb_info* cb_info); + void handle_command(sensor_id_t sensor, char* data, int data_cnt); + void listen_command(void); + + bool is_valid_callback(const command_cb_info *cb_info); + static gboolean callback_dispatcher(gpointer data); + + int m_client_id; + + csocket m_command_socket; + poller *m_poller; + + cmutex m_handle_info_lock; + + thread_state m_thread_state; + std::mutex m_thread_mutex; + std::condition_variable m_thread_cond; + + hup_observer_t m_hup_observer; + + std::unordered_map m_sensor_handle_infos; + std::unordered_map m_sensor_handle_map; + std::unordered_map m_data_channels; +}; +#endif /* _EXTERNAL_SENSOR_MANAGER_H_ */ diff --git a/src/client/sensor_event_listener.cpp b/src/client/sensor_event_listener.cpp index 0215b29..3182b78 100644 --- a/src/client/sensor_event_listener.cpp +++ b/src/client/sensor_event_listener.cpp @@ -380,6 +380,7 @@ void sensor_event_listener::listen_events(void) bool sensor_event_listener::create_event_channel(void) { + const int client_type = CLIENT_TYPE_SENSOR_CLIENT; int client_id; channel_ready_t event_channel_ready; @@ -396,6 +397,11 @@ bool sensor_event_listener::create_event_channel(void) return false; } + if (m_event_socket.send(&client_type, sizeof(client_type)) <= 0) { + _E("Failed to send client type in client %s, event socket fd[%d]", get_client_name(), m_event_socket.get_socket_fd()); + return false; + } + client_id = m_client_info.get_client_id(); if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) { diff --git a/src/server/command_queue.cpp b/src/server/command_queue.cpp new file mode 100644 index 0000000..0eadaab --- /dev/null +++ b/src/server/command_queue.cpp @@ -0,0 +1,55 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include + +command_queue& command_queue::get_instance(void) +{ + static command_queue inst; + return inst; +} + +void command_queue::push(std::shared_ptr &command) +{ + lock l(m_mutex); + + bool wake = m_queue.empty(); + + if (m_queue.size() >= QUEUE_FULL_SIZE) { + _E("Queue is full, drop it!"); + } else { + m_queue.push(command); + } + + if (wake) + m_cond_var.notify_one(); +} + +std::shared_ptr command_queue::pop(void) +{ + ulock u(m_mutex); + + while (m_queue.empty()) + m_cond_var.wait(u); + + std::shared_ptr command = m_queue.front(); + m_queue.pop(); + return command; +} diff --git a/src/server/command_queue.h b/src/server/command_queue.h new file mode 100644 index 0000000..d5ab195 --- /dev/null +++ b/src/server/command_queue.h @@ -0,0 +1,50 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _COMMAND_QUEUE_H_ +#define _COMMAND_QUEUE_H_ + +#include +#include +#include +#include +#include + +class command_queue { +private: + command_queue() {}; + ~command_queue() {}; + command_queue(const command_queue&) {}; + command_queue& operator=(const command_queue&); + + static const unsigned int QUEUE_FULL_SIZE = 1000; + + std::queue> m_queue; + std::mutex m_mutex; + std::condition_variable m_cond_var; + + typedef std::lock_guard lock; + typedef std::unique_lock ulock; +public: + static command_queue& get_instance(); + void push(std::shared_ptr &command); + std::shared_ptr pop(void); +}; + +#endif diff --git a/src/server/dbus_util.cpp b/src/server/dbus_util.cpp new file mode 100755 index 0000000..df1ade0 --- /dev/null +++ b/src/server/dbus_util.cpp @@ -0,0 +1,174 @@ +/* + * sensord + * + * Copyright (c) 2014 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 +#include +#include + +static int wrist_up_total_cnt; +static int wrist_up_lcdon_cnt; + +static GDBusNodeInfo *introspection_data = NULL; +static guint owner_id; + +static const gchar introspection_xml[] = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static void method_call_handler(GDBusConnection *conn, + const gchar *sender, const gchar *object_path, + const gchar *iface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data) +{ + int ret = DBUS_INIT; + + if (g_strcmp0(method_name, "check_privilege") == 0) { + _D("check_privilege called"); + ret = DBUS_SUCCESS; + } else if (g_strcmp0(method_name, "wristup_lcdon_cnt") == 0) { + _D("wristup_lcdon_cnt called, %d", wrist_up_lcdon_cnt); + ret = wrist_up_lcdon_cnt; + } else if (g_strcmp0(method_name, "wristup_total_cnt") == 0) { + _D("wristup_total_cnt called, %d", wrist_up_total_cnt); + ret = wrist_up_total_cnt; + } else { + _D("No matched method call"); + ret = DBUS_FAILED; + } + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", ret)); +} + +static const GDBusInterfaceVTable interface_vtable = +{ + method_call_handler, + NULL, + NULL +}; + +static void on_bus_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + + if (!connection) { + _E("connection is null"); + return; + } + + registration_id = g_dbus_connection_register_object(connection, + SENSORD_OBJECT_PATH, + introspection_data->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + + if (registration_id == 0) + _E("Failed to g_dbus_connection_register_object"); + + _I("Gdbus method call registrated"); +} + +static void on_name_acquired(GDBusConnection *conn, + const gchar *name, gpointer user_data) +{ +} + +static void on_name_lost(GDBusConnection *conn, + const gchar *name, gpointer user_data) +{ + _E("Dbus name is lost!"); +} + +int get_lcdon_count(void) +{ + return wrist_up_lcdon_cnt; +} + +void increase_lcdon_count(void) +{ + wrist_up_lcdon_cnt++; +} + +void reset_lcdon_count(void) +{ + wrist_up_lcdon_cnt = 0; +} + +int get_total_count(void) +{ + return wrist_up_total_cnt; +} + +void increase_total_count(void) +{ + wrist_up_total_cnt++; +} + +void reset_total_count(void) +{ + wrist_up_total_cnt = 0; +} + +void init_dbus(void) +{ + g_type_init(); + + introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); + if (introspection_data == NULL) { + _E("Failed to init g_dbus_node_info_new_for_xml"); + return; + } + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + SENSORD_BUS_NAME, + (GBusNameOwnerFlags) (G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT + | G_BUS_NAME_OWNER_FLAGS_REPLACE), + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + wrist_up_total_cnt = 0; + wrist_up_lcdon_cnt = 0; +} + +void fini_dbus(void) +{ + if (owner_id != 0) + g_bus_unown_name(owner_id); + + if (introspection_data) + g_dbus_node_info_unref(introspection_data); +} diff --git a/src/server/dbus_util.h b/src/server/dbus_util.h new file mode 100644 index 0000000..ce4ad54 --- /dev/null +++ b/src/server/dbus_util.h @@ -0,0 +1,44 @@ +/* + * sensord + * + * Copyright (c) 2014 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 _DBUS_UTIL_H_ +#define _DBUS_UTIL_H_ + +#define SENSORD_BUS_NAME "org.tizen.system.sensord" +#define SENSORD_OBJECT_PATH "/Org/Tizen/System/SensorD" +#define SENSORD_INTERFACE_NAME SENSORD_BUS_NAME + +enum dbus_ret { + DBUS_INIT = -1, + DBUS_FAILED = 0, + DBUS_SUCCESS = 1 +}; + +int get_lcdon_count(void); +void increase_lcdon_count(void); +void reset_lcdon_count(void); + +int get_total_count(void); +void increase_total_count(void); +void reset_total_count(void); + +void init_dbus(void); +void fini_dbus(void); + +#endif /* SENSORD_GDBUS_H_ */ diff --git a/src/server/external_client_manager.cpp b/src/server/external_client_manager.cpp new file mode 100644 index 0000000..a19d502 --- /dev/null +++ b/src/server/external_client_manager.cpp @@ -0,0 +1,227 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include + +using std::shared_ptr; +using std::make_shared; +using std::pair; +using std::string; + +external_client_manager::external_client_manager() +{ +} +external_client_manager::~external_client_manager() +{ +} + +external_client_manager& external_client_manager::get_instance(void) +{ + static external_client_manager instance; + return instance; +} + +int external_client_manager::create_client_record(void) +{ + AUTOLOCK(m_mutex); + + int client_id = 0; + + shared_ptr client_record = make_shared(); + + while (m_clients.count(client_id) > 0) + client_id++; + + if (client_id == MAX_HANDLE) { + _E("Sensor records of clients are full"); + return MAX_HANDLE_REACHED; + } + + client_record->set_client_id(client_id); + + m_clients.insert(pair>(client_id, client_record)); + + return client_id; +} + +bool external_client_manager::remove_client_record(int client_id) +{ + AUTOLOCK(m_mutex); + + if (!m_clients.erase(client_id)) { + _E("Client[%d] is not found", client_id); + return false; + } + + _I("Client record for client[%d] is removed from external client manager", client_id); + return true; +} + +bool external_client_manager::has_client_record(int client_id) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + return (it_record != m_clients.end()); +} + +void external_client_manager::set_client_info(int client_id, pid_t pid, const string &name) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _E("Client[%d] is not found", client_id); + return; + } + + it_record->second->set_client_info(pid, name); + + return; +} + +const char* external_client_manager::get_client_info(int client_id) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _D("Client[%d] is not found", client_id); + return NULL; + } + + return it_record->second->get_client_info(); +} + +bool external_client_manager::create_sensor_record(int client_id, sensor_id_t sensor) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _E("Client record[%d] is not registered", client_id); + return false; + } + + return it_record->second->add_usage(sensor); +} + +bool external_client_manager::remove_sensor_record(int client_id, sensor_id_t sensor) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _E("Client[%d] is not found", client_id); + return false; + } + + if (!it_record->second->remove_usage(sensor)) + return false; + + if (!it_record->second->has_usage()) + remove_client_record(client_id); + + return true; +} + +bool external_client_manager::has_sensor_record(int client_id, sensor_id_t sensor) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _D("Client[%d] is not found", client_id); + return false; + } + + return it_record->second->has_usage(sensor); +} + +bool external_client_manager::has_sensor_record(int client_id) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _D("Client[%d] is not found", client_id); + return false; + } + + return it_record->second->has_usage(); +} + +bool external_client_manager::get_listener_socket(sensor_id_t sensor, csocket &sock) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.begin(); + + while (it_record != m_clients.end()) { + if (it_record->second->has_usage(sensor)) { + it_record->second->get_command_socket(sock); + return true; + } + + ++it_record; + } + + return false; +} + +bool external_client_manager::get_command_socket(int client_id, csocket &socket) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _E("Client[%d] is not found", client_id); + return false; + } + + it_record->second->get_command_socket(socket); + + return true; +} + +bool external_client_manager::set_command_socket(int client_id, const csocket &socket) +{ + AUTOLOCK(m_mutex); + + auto it_record = m_clients.find(client_id); + + if (it_record == m_clients.end()) { + _E("Client[%d] is not found", client_id); + return false; + } + + it_record->second->set_command_socket(socket); + + return true; +} diff --git a/src/server/external_client_manager.h b/src/server/external_client_manager.h new file mode 100644 index 0000000..9934d8d --- /dev/null +++ b/src/server/external_client_manager.h @@ -0,0 +1,55 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_CLIENT_MANAGER_H_ +#define _EXTERNAL_CLIENT_MANAGER_H_ + +#include +#include +#include +#include + +class external_client_manager { +public: + static external_client_manager& get_instance(void); + int create_client_record(void); + bool remove_client_record(int client_id); + bool has_client_record(int client_id); + + void set_client_info(int client_id, pid_t pid, const std::string &name); + const char* get_client_info(int client_id); + + bool create_sensor_record(int client_id, sensor_id_t sensor); + bool remove_sensor_record(int client_id, sensor_id_t sensor); + bool has_sensor_record(int client_id, sensor_id_t sensor); + bool has_sensor_record(int client_id); + + bool get_listener_socket(sensor_id_t sensor, csocket &sock); + bool get_command_socket(int client_id, csocket &sock); + bool set_command_socket(int client_id, const csocket &sock); +private: + external_client_manager(); + ~external_client_manager(); + external_client_manager(const external_client_manager&) {}; + external_client_manager& operator=(const external_client_manager&); + + std::unordered_map> m_clients; + cmutex m_mutex; +}; +#endif /* _EXTERNAL_CLIENT_MANAGER_H_ */ diff --git a/src/server/external_sensor.cpp b/src/server/external_sensor.cpp new file mode 100644 index 0000000..9046739 --- /dev/null +++ b/src/server/external_sensor.cpp @@ -0,0 +1,86 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include +#include + +using std::string; +using std::shared_ptr; +using std::make_shared; + +external_sensor::external_sensor() +: m_source_connected(false) +{ +} + +external_sensor::~external_sensor() +{ + unregister_key(); +} + +bool external_sensor::register_key(const string &key) +{ + m_key = key; + return external_sensor_service::get_instance().register_sensor(this); +} + +bool external_sensor::unregister_key(void) +{ + return external_sensor_service::get_instance().unregister_sensor(this); +} + +string external_sensor::get_key(void) +{ + return m_key; +} + +bool external_sensor::set_source_connected(bool connected) +{ + AUTOLOCK(m_source_mutex); + + if (m_source_connected && connected) { + _E("Source is already connected"); + return false; + } + + m_source_connected = connected; + return true; +} + +bool external_sensor::get_source_connected(void) +{ + AUTOLOCK(m_source_mutex); + + return m_source_connected; +} + +int external_sensor::set_attribute(int32_t attribute, char *value, int value_size) +{ + shared_ptr external_command = make_shared(); + + external_command->header.sensor_id = get_id(); + external_command->header.command_len = value_size; + external_command->command.assign(value, value + value_size); + + command_queue::get_instance().push(external_command); + + return 0; +} diff --git a/src/server/external_sensor.h b/src/server/external_sensor.h new file mode 100644 index 0000000..c52b325 --- /dev/null +++ b/src/server/external_sensor.h @@ -0,0 +1,47 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_SENSOR_H_ +#define _EXTERNAL_SENSOR_H_ + +#include +#include +#include +#include + +class external_sensor : public sensor_base { +public: + external_sensor(); + virtual ~external_sensor(); + int send_data(const char* data, int data_cnt); + std::string get_key(void); + bool set_source_connected(bool connected); + bool get_source_connected(void); + virtual void on_receive(unsigned long long timestamp, const float* data, int data_cnt) = 0; + virtual int set_attribute(int32_t attribute, char *value, int value_size); +protected: + bool register_key(const std::string &key); +private: + bool unregister_key(void); + + std::string m_key; + bool m_source_connected; + cmutex m_source_mutex; +}; +#endif /* _EXTERNAL_SENSOR_H_ */ diff --git a/src/server/external_sensor_record.cpp b/src/server/external_sensor_record.cpp new file mode 100644 index 0000000..98d3c79 --- /dev/null +++ b/src/server/external_sensor_record.cpp @@ -0,0 +1,99 @@ +/* + * sensord + * + * Copyright (c) 2015 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 + +using std::string; + +external_sensor_record::external_sensor_record() +: m_client_id(0) +, m_pid(-1) +{ +} + +external_sensor_record::~external_sensor_record() +{ + close_command_socket(); +} + +bool external_sensor_record::add_usage(sensor_id_t sensor) +{ + if (!m_usages.insert(sensor).second) { + _E("Sensor[%#x] is already registered", sensor); + return false; + } + + return true; +} + +bool external_sensor_record::remove_usage(sensor_id_t sensor) +{ + if (!m_usages.erase(sensor)) { + _E("Sensor[%#x] is not found", sensor); + return false; + } + + return true; +} + +bool external_sensor_record::has_usage(void) +{ + return !m_usages.empty(); +} + +bool external_sensor_record::has_usage(sensor_id_t sensor) +{ + auto it_usage = m_usages.find(sensor); + + return (it_usage != m_usages.end()); +} + +void external_sensor_record::set_client_id(int client_id) +{ + m_client_id = client_id; +} + +void external_sensor_record::set_client_info(pid_t pid, const string &name) +{ + char client_info[NAME_MAX + 32]; + m_pid = pid; + + snprintf(client_info, sizeof(client_info), "%s[pid=%d, id=%d]", name.c_str(), m_pid, m_client_id); + m_client_info.assign(client_info); +} + +const char* external_sensor_record::get_client_info(void) +{ + return m_client_info.c_str(); +} + +void external_sensor_record::set_command_socket(const csocket &socket) +{ + m_command_socket = socket; +} + +void external_sensor_record::get_command_socket(csocket &socket) +{ + socket = m_command_socket; +} + +bool external_sensor_record::close_command_socket(void) +{ + return m_command_socket.close(); +} + diff --git a/src/server/external_sensor_record.h b/src/server/external_sensor_record.h new file mode 100644 index 0000000..9b85640 --- /dev/null +++ b/src/server/external_sensor_record.h @@ -0,0 +1,56 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_SENSOR_RECORD_H_ +#define _EXTERNAL_SENSOR_RECORD_H_ + +#include +#include +#include +#include + +class external_sensor_record { +public: + external_sensor_record(); + ~external_sensor_record(); + + void set_client_id(int client_id); + + void set_client_info(pid_t pid, const std::string &name); + const char* get_client_info(void); + + bool has_usage(void); + bool has_usage(sensor_id_t sensor); + + bool add_usage(sensor_id_t sensor); + bool remove_usage(sensor_id_t sensor); + + void set_command_socket(const csocket &socket); + void get_command_socket(csocket &socket); + bool close_command_socket(void); + +private: + int m_client_id; + pid_t m_pid; + std::string m_client_info; + csocket m_command_socket; + std::unordered_set m_usages; +}; + +#endif /* _EXTERNAL_SENSOR_RECORD_H_ */ diff --git a/src/server/external_sensor_service.cpp b/src/server/external_sensor_service.cpp new file mode 100644 index 0000000..c7d1e8e --- /dev/null +++ b/src/server/external_sensor_service.cpp @@ -0,0 +1,152 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include +#include +#include + +using std::thread; +using std::pair; +using std::string; +using std::shared_ptr; + +external_sensor_service::external_sensor_service() +{ +} + +external_sensor_service::~external_sensor_service() +{ +} + +external_sensor_service& external_sensor_service::get_instance(void) +{ + static external_sensor_service instance; + return instance; +} + +bool external_sensor_service::run(void) +{ + thread dispatcher(&external_sensor_service::dispatch_command, this); + dispatcher.detach(); + + return true; +} + +external_client_manager& external_sensor_service::get_client_manager(void) +{ + return external_client_manager::get_instance(); +} + +void external_sensor_service::accept_command_channel(csocket client_socket) +{ + thread th = thread([&, client_socket]() mutable { + int client_id; + channel_ready_t command_channel_ready; + external_client_manager& client_manager = get_client_manager(); + + client_socket.set_connection_mode(); + + if (client_socket.recv(&client_id, sizeof(client_id)) <= 0) { + _E("Failed to receive client id on socket fd[%d]", client_socket.get_socket_fd()); + return; + } + + client_socket.set_transfer_mode(); + + if (!client_manager.set_command_socket(client_id, client_socket)) { + _E("Failed to store event socket[%d] for %s", client_socket.get_socket_fd(), + client_manager.get_client_info(client_id)); + return; + } + + command_channel_ready.magic = CHANNEL_MAGIC_NUM; + command_channel_ready.client_id = client_id; + + _I("Command channel is accepted for %s on socket[%d]", + client_manager.get_client_info(client_id), client_socket.get_socket_fd()); + + if (client_socket.send(&command_channel_ready, sizeof(command_channel_ready)) <= 0) { + _E("Failed to send command channel_ready packet to %s on socket fd[%d]", + client_manager.get_client_info(client_id), client_socket.get_socket_fd()); + return; + } + }); + + th.detach(); +} + +void external_sensor_service::dispatch_command(void) +{ + while (true) { + shared_ptr command = command_queue::get_instance().pop(); + csocket client_sock; + sensor_id_t sensor_id = command->header.sensor_id; + bool ret; + + ret = external_client_manager::get_instance().get_listener_socket(sensor_id, client_sock); + + if (!ret) { + _E("Failed to get listener socket for sensor[%d]", sensor_id); + continue; + } + + if (client_sock.send(&(command->header), sizeof(command->header)) <= 0) { + _E("Failed to send command header to the client of sensor[%d]", sensor_id); + continue; + } + + if (client_sock.send(command->command.data(), command->header.command_len) <= 0) { + _E("Failed to send command header to the client of sensor[%d]", sensor_id); + continue; + } + } +} + +bool external_sensor_service::register_sensor(external_sensor *sensor) +{ + if (!m_external_sensors.insert(pair(sensor->get_key(), sensor)).second) { + _E("Failed to register sensor, key: %s", sensor->get_key().c_str()); + return false; + } + + return true; +} + +bool external_sensor_service::unregister_sensor(external_sensor *sensor) +{ + if (!m_external_sensors.erase(sensor->get_key())) { + _E("Failed to unregister sensor, key: %s", sensor->get_key().c_str()); + return false; + } + + return true; +} + +external_sensor* external_sensor_service::get_sensor(const string& key) +{ + auto it_sensor = m_external_sensors.find(key); + + if (it_sensor == m_external_sensors.end()) { + _E("Sensor(key:%s) is not found", key.c_str()); + return NULL; + } + + return it_sensor->second; +} diff --git a/src/server/external_sensor_service.h b/src/server/external_sensor_service.h new file mode 100644 index 0000000..28b1aa4 --- /dev/null +++ b/src/server/external_sensor_service.h @@ -0,0 +1,52 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_SENSOR_SERVICE_H_ +#define _EXTERNAL_SENSOR_SERVICE_H_ + +#include +#include +#include +#include + +class external_client_manager; + +class external_sensor_service { +public: + static external_sensor_service& get_instance(); + bool register_sensor(external_sensor *sensor); + bool unregister_sensor(external_sensor *sensor); + external_sensor* get_sensor(const std::string& key); + + void accept_command_channel(csocket client_socket); + bool run(void); +private: + external_sensor_service(); + ~external_sensor_service(); + external_sensor_service(const external_sensor_service&) {}; + external_sensor_service& operator=(const external_sensor_service&); + + static external_client_manager& get_client_manager(void); + + void dispatch_command(void); + + std::unordered_map m_external_sensors; +}; +#endif /* _EXTERNAL_SENSOR_SERVICE_H_ */ + diff --git a/src/server/external_sensor_worker.cpp b/src/server/external_sensor_worker.cpp new file mode 100644 index 0000000..9bc46fb --- /dev/null +++ b/src/server/external_sensor_worker.cpp @@ -0,0 +1,329 @@ +/* + * sensord + * + * Copyright (c) 2015 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 +#include +#include +#include +#include +#include + +using std::string; + +external_sensor_worker::cmd_handler_t external_sensor_worker::m_cmd_handlers[]; + +external_sensor_worker::external_sensor_worker(const csocket& socket) +: m_client_id(CLIENT_ID_INVALID) +, m_socket(socket) +, m_sensor(NULL) +, m_sensor_id(UNKNOWN_SENSOR) +{ + static bool init = false; + + if (!init) { + init_cmd_handlers(); + init = true; + } + + m_worker.set_context(this); + m_worker.set_working(working); + m_worker.set_stopped(stopped); +} + +external_sensor_worker::~external_sensor_worker() +{ + m_socket.close(); +} + +bool external_sensor_worker::start(void) +{ + return m_worker.start(); +} + +void external_sensor_worker::init_cmd_handlers(void) +{ + m_cmd_handlers[CMD_EXT_GET_ID] = &external_sensor_worker::cmd_get_id; + m_cmd_handlers[CMD_EXT_CONNECT] = &external_sensor_worker::cmd_connect; + m_cmd_handlers[CMD_EXT_DISCONNECT] = &external_sensor_worker::cmd_disconnect; + m_cmd_handlers[CMD_EXT_POST] = &external_sensor_worker::cmd_post; +} + +bool external_sensor_worker::working(void *ctx) +{ + bool ret; + external_sensor_worker *inst = (external_sensor_worker *)ctx; + + packet_header header; + char *payload; + + if (inst->m_socket.recv(&header, sizeof(header)) <= 0) { + string info; + inst->get_info(info); + _D("%s failed to receive header", info.c_str()); + return false; + } + + if (header.size > 0) { + payload = new(std::nothrow) char[header.size]; + retvm_if(!payload, false, "Failed to allocate memory"); + + if (inst->m_socket.recv(payload, header.size) <= 0) { + string info; + inst->get_info(info); + _D("%s failed to receive data of packet", info.c_str()); + delete[] payload; + return false; + } + } else { + payload = NULL; + } + + ret = inst->dispatch_command(header.cmd, payload); + + if (payload) + delete[] payload; + + return ret; +} + +bool external_sensor_worker::stopped(void *ctx) +{ + string info; + external_sensor_worker *inst = (external_sensor_worker *)ctx; + + inst->get_info(info); + _I("%s is stopped", info.c_str()); + + if (inst->m_client_id != CLIENT_ID_INVALID) { + _I("Client:%d leaves without disconnecting", inst->m_client_id); + if (get_client_manager().has_sensor_record(inst->m_client_id, inst->m_sensor_id)) { + _I("Removing sensor[%#x] record for client_id[%d]", inst->m_sensor_id, inst->m_client_id); + get_client_manager().remove_sensor_record(inst->m_client_id, inst->m_sensor_id); + + if (inst->m_sensor) + inst->m_sensor->set_source_connected(false); + } + } + + delete inst; + return true; +} + +bool external_sensor_worker::dispatch_command(int cmd, void* payload) +{ + int ret = false; + + if (!(cmd > 0 && cmd < CMD_EXT_CNT)) { + _E("Unknown command: %d", cmd); + } else { + cmd_handler_t cmd_handler; + cmd_handler = external_sensor_worker::m_cmd_handlers[cmd]; + if (cmd_handler) + ret = (this->*cmd_handler)(payload); + } + + return ret; +} + +bool external_sensor_worker::send_cmd_done(long value) +{ + cpacket* ret_packet; + cmd_ext_done_t *cmd_ext_done; + + ret_packet = new(std::nothrow) cpacket(sizeof(cmd_ext_done_t)); + retvm_if(!ret_packet, false, "Failed to allocate memory"); + + ret_packet->set_cmd(CMD_EXT_DONE); + + cmd_ext_done = (cmd_ext_done_t*)ret_packet->data(); + cmd_ext_done->value = value; + + if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) { + _E("Failed to send a cmd_done to client_id [%d] with value [%ld]", m_client_id, value); + delete ret_packet; + return false; + } + + delete ret_packet; + return true; +} + +bool external_sensor_worker::send_cmd_get_id_done(int client_id) +{ + cpacket* ret_packet; + cmd_ext_get_id_done_t *cmd_ext_get_id_done; + + ret_packet = new(std::nothrow) cpacket(sizeof(cmd_ext_get_id_done_t)); + retvm_if(!ret_packet, false, "Failed to allocate memory"); + + ret_packet->set_cmd(CMD_EXT_GET_ID); + + cmd_ext_get_id_done = (cmd_ext_get_id_done_t*)ret_packet->data(); + cmd_ext_get_id_done->client_id = client_id; + + if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) { + _E("Failed to send a cmd_get_id_done with client_id [%d]", client_id); + delete ret_packet; + return false; + } + + delete ret_packet; + return true; +} + +bool external_sensor_worker::send_cmd_connect_done(sensor_id_t sensor_id) +{ + cpacket* ret_packet; + cmd_ext_connect_done_t *cmd_ext_connect_done; + + ret_packet = new(std::nothrow) cpacket(sizeof(cmd_ext_connect_done_t)); + retvm_if(!ret_packet, false, "Failed to allocate memory"); + + ret_packet->set_cmd(CMD_EXT_CONNECT); + + cmd_ext_connect_done = (cmd_ext_connect_done_t*)ret_packet->data(); + cmd_ext_connect_done->sensor_id = sensor_id; + + if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) { + _E("Failed to send a cmd_connect done"); + delete ret_packet; + return false; + } + + delete ret_packet; + return true; +} + +bool external_sensor_worker::cmd_get_id(void *payload) +{ + cmd_ext_get_id_t *cmd = static_cast(payload); + int client_id; + struct ucred cr; + socklen_t opt_len = sizeof(cr); + + if (getsockopt(m_socket.get_socket_fd(), SOL_SOCKET, SO_PEERCRED, &cr, &opt_len)) { + _E("Failed to get socket option with SO_PEERCRED"); + return false; + } + + client_id = get_client_manager().create_client_record(); + + if (client_id != MAX_HANDLE_REACHED) { + get_client_manager().set_client_info(client_id, cr.pid, cmd->name); + _I("New client id [%d] created", client_id); + } + + if (!send_cmd_get_id_done(client_id)) + _E("Failed to send cmd_done to a client"); + + return true; +} + +bool external_sensor_worker::cmd_connect(void *payload) +{ + cmd_ext_connect_t *cmd = static_cast(payload); + m_client_id = cmd->client_id; + + external_sensor *sensor; + sensor = external_sensor_service::get_instance().get_sensor(string(cmd->key)); + if (!sensor) { + _E("No matched external sensor with key: %s", cmd->key); + goto out; + } + + if (!sensor->set_source_connected(true)) { + _E("External sensor(%s) is already connected", cmd->key); + goto out; + } + + m_sensor = sensor; + m_sensor_id = sensor->get_id(); + + if (!get_client_manager().create_sensor_record(m_client_id, m_sensor_id)) { + _E("Failed to create sensor record for client: %d, sensor_id: %d", m_client_id, m_sensor_id); + m_sensor_id = UNKNOWN_SENSOR; + goto out; + } + +out: + if (!send_cmd_connect_done(m_sensor_id)) + _E("Failed to send cmd_connect_done to a client : %d", m_client_id); + + return true; +} + +bool external_sensor_worker::cmd_disconnect(void *payload) +{ + long ret_value = OP_ERROR; + + if (!m_sensor) { + _E("External sensor is not connected"); + ret_value = OP_ERROR; + goto out; + } + + if (!get_client_manager().remove_sensor_record(m_client_id, m_sensor_id)) { + _E("Failed to remove sensor record for client [%d]", m_client_id); + ret_value = OP_ERROR; + goto out; + } + + m_sensor->set_source_connected(false); + + m_sensor = NULL; + m_client_id = CLIENT_ID_INVALID; + m_sensor_id = UNKNOWN_SENSOR; + ret_value = OP_SUCCESS; +out: + if (!send_cmd_done(ret_value)) + _E("Failed to send cmd_done to a client"); + + if (ret_value == OP_SUCCESS) + return false; + + return true; +} + +bool external_sensor_worker::cmd_post(void *payload) +{ + long ret_value = OP_SUCCESS; + cmd_ext_post_t *cmd = static_cast(payload); + + m_sensor->on_receive(cmd->timestamp, cmd->data, cmd->data_cnt); + + if (!send_cmd_done(ret_value)) + _E("Failed to send cmd_done to a client"); + + return true; +} + +external_client_manager& external_sensor_worker::get_client_manager(void) +{ + return external_client_manager::get_instance(); +} + +void external_sensor_worker::get_info(string &info) +{ + const char *client_info = NULL; + + if (m_client_id != CLIENT_ID_INVALID) + client_info = get_client_manager().get_client_info(m_client_id); + + info = string("Command worker for ") + (client_info ? string(client_info) : string("Unknown")); +} diff --git a/src/server/external_sensor_worker.h b/src/server/external_sensor_worker.h new file mode 100644 index 0000000..982dd09 --- /dev/null +++ b/src/server/external_sensor_worker.h @@ -0,0 +1,67 @@ +/* + * sensord + * + * Copyright (c) 2015 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 _EXTERNAL_SENSOR_WORKER_H_ +#define _EXTERNAL_SENSOR_WORKER_H_ + +#include +#include +#include +#include + +class external_client_manager; +class external_sensor; + +class external_sensor_worker { +private: + typedef bool (external_sensor_worker::*cmd_handler_t)(void *payload); + + int m_client_id; + csocket m_socket; + worker_thread m_worker; + external_sensor *m_sensor; + sensor_id_t m_sensor_id; + static cmd_handler_t m_cmd_handlers[CMD_EXT_CNT]; + + static void init_cmd_handlers(void); + static bool working(void *ctx); + static bool stopped(void *ctx); + + bool dispatch_command(int cmd, void *payload); + + bool send_cmd_done(long value); + bool send_cmd_get_id_done(int client_id); + bool send_cmd_connect_done(sensor_id_t sensor_id); + + bool cmd_get_id(void *payload); + bool cmd_connect(void *payload); + bool cmd_disconnect(void *payload); + bool cmd_post(void *payload); + + static external_client_manager& get_client_manager(void); + + void get_info(std::string &info); +public: + external_sensor_worker(const csocket& socket); + ~external_sensor_worker(); + + bool start(void); +}; + +#endif /* _EXTERNAL_SENSOR_WORKER_H_ */ diff --git a/src/server/sensor_event_dispatcher.cpp b/src/server/sensor_event_dispatcher.cpp index 03c4798..eeb4236 100644 --- a/src/server/sensor_event_dispatcher.cpp +++ b/src/server/sensor_event_dispatcher.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using std::thread; using std::vector; diff --git a/src/server/sensor_loader.cpp b/src/server/sensor_loader.cpp index d43ac62..5e0e0f9 100644 --- a/src/server/sensor_loader.cpp +++ b/src/server/sensor_loader.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -254,6 +255,30 @@ void sensor_loader::create_virtual_sensors(const char *name) } template +void sensor_loader::create_external_sensors(const char *name) +{ + int32_t index; + sensor_type_t type; + external_sensor *instance; + + instance = dynamic_cast(create_sensor<_sensor>()); + if (!instance) { + _E("Memory allocation failed[%s]", name); + return; + } + + std::shared_ptr sensor(instance); + type = sensor->get_type(); + index = (int32_t)(m_sensors.count(type)); + + sensor->set_id((int64_t)type << SENSOR_TYPE_SHIFT | index); + + m_sensors.insert(std::make_pair(type, sensor)); + + _I("created [%s] sensor", sensor->get_name()); +} + +template sensor_base* sensor_loader::create_sensor(void) { sensor_base *instance = NULL; diff --git a/src/server/sensor_loader.h b/src/server/sensor_loader.h index 3312c1d..c10c4bb 100644 --- a/src/server/sensor_loader.h +++ b/src/server/sensor_loader.h @@ -48,6 +48,7 @@ private: void create_sensors(void); template void create_physical_sensors(sensor_type_t type); template void create_virtual_sensors(const char *name); + template void create_external_sensors(const char *name); template sensor_base* create_sensor(void); void show_sensor_info(void); diff --git a/src/server/server.cpp b/src/server/server.cpp index e3c902b..684b265 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -25,11 +25,13 @@ #include #include #include +#include +#include #include #include #include -#define SYSTEMD_SOCKET_MAX 2 +#define SYSTEMD_SOCKET_MAX 2 using std::thread; @@ -75,8 +77,6 @@ int server::get_systemd_socket(const char *name) void server::accept_command_channel(void) { - command_worker *cmd_worker; - _I("Command channel acceptor is started"); while (m_running) { @@ -102,15 +102,8 @@ void server::accept_command_channel(void) /* TODO: if socket is closed, it should be erased */ client_command_sockets.push_back(client_command_socket); - cmd_worker = new(std::nothrow) command_worker(client_command_socket); - - if (!cmd_worker) { - _E("Failed to allocate memory"); - break; - } - - if (!cmd_worker->start()) - delete cmd_worker; + thread worker_dispatcher(&server::dispatch_worker, this, client_command_socket); + worker_dispatcher.detach(); } _I("Command channel acceptor is terminated"); @@ -143,12 +136,77 @@ void server::accept_event_channel(void) _D("New client(socket_fd : %d) connected", client_event_socket.get_socket_fd()); - sensor_event_dispatcher::get_instance().accept_event_connections(client_event_socket); + thread event_channel_creator(&server::dispatch_event_channel_creator, this, client_event_socket); + event_channel_creator.detach(); } _I("Event channel acceptor is terminated"); } +void server::dispatch_worker(csocket socket) +{ + int worker_type; + + if (socket.recv(&worker_type, sizeof(worker_type)) <= 0) { + _E("Failed to get worker type"); + socket.close(); + return; + } + + if (worker_type == CLIENT_TYPE_SENSOR_CLIENT) { + command_worker *worker; + worker = new(std::nothrow) command_worker(socket); + + if (!worker) { + _E("Failed to allocate memory"); + socket.close(); + return; + } + + if (!worker->start()) { + _E("Failed to start command worker"); + delete worker; + } + } else if (worker_type == CLIENT_TYPE_EXTERNAL_SOURCE) { + external_sensor_worker *worker; + worker = new(std::nothrow) external_sensor_worker(socket); + + if (!worker) { + _E("Failed to allocate memory"); + socket.close(); + return; + } + + if (!worker->start()) { + _E("Failed to start external worker"); + delete worker; + } + } else { + _E("Not supported worker type: %d", worker_type); + socket.close(); + } +} + +void server::dispatch_event_channel_creator(csocket socket) +{ + int client_type; + + if (socket.recv(&client_type, sizeof(client_type)) <= 0) { + _E("Failed to get client type"); + socket.close(); + return; + } + + if (client_type == CLIENT_TYPE_SENSOR_CLIENT) { + sensor_event_dispatcher::get_instance().accept_event_connections(socket); + } else if (client_type == CLIENT_TYPE_EXTERNAL_SOURCE) { + external_sensor_service::get_instance().accept_command_channel(socket); + } else { + _E("Not supported client type: %d", client_type); + socket.close(); + } +} + void server::poll_event(void) { _I("Event poller is started"); diff --git a/src/server/server.h b/src/server/server.h index e285cde..8f9daf7 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -58,6 +58,9 @@ private: void accept_command_channel(void); void accept_event_channel(void); + void dispatch_worker(csocket socket); + void dispatch_event_channel_creator(csocket socket); + void close_socket(void); /* TODO: move to socket class */ diff --git a/src/shared/command_common.h b/src/shared/command_common.h index 3346654..3973a92 100644 --- a/src/shared/command_common.h +++ b/src/shared/command_common.h @@ -22,6 +22,8 @@ #include #include +#include +#include #define COMMAND_CHANNEL_PATH "/tmp/sensord_command_socket\0" #define EVENT_CHANNEL_PATH "/tmp/sensord_event_socket\0" @@ -50,6 +52,16 @@ enum packet_type_t { CMD_CNT, }; +enum ext_packet_type_t { + CMD_EXT_DONE = -1, + CMD_EXT_NONE = 0, + CMD_EXT_GET_ID, + CMD_EXT_CONNECT, + CMD_EXT_DISCONNECT, + CMD_EXT_POST, + CMD_EXT_CNT, +}; + typedef struct { char name[NAME_MAX]; } cmd_get_id_t; @@ -127,6 +139,36 @@ typedef struct { typedef struct { } cmd_flush_t; +typedef struct { + char name[NAME_MAX]; +} cmd_ext_get_id_t; + +typedef struct { + int client_id; + char key[NAME_MAX]; +} cmd_ext_connect_t; + +typedef struct { +} cmd_ext_disconnect_t; + +typedef struct { + unsigned long long timestamp; + int data_cnt; + float data[0]; +} cmd_ext_post_t; + +typedef struct { + long value; +} cmd_ext_done_t; + +typedef struct { + int client_id; +} cmd_ext_get_id_done_t; + +typedef struct { + sensor_id_t sensor_id; +} cmd_ext_connect_done_t; + #define CHANNEL_MAGIC_NUM 0xCAFECAFE typedef struct { @@ -134,6 +176,19 @@ typedef struct { int client_id; } channel_ready_t; +typedef struct external_command_header_t { + sensor_id_t sensor_id; + int command_len; +} external_command_header_t; + +typedef struct external_command_t { + external_command_header_t header; + std::vector command; +} external_command_t; + typedef void *(*cmd_func_t)(void *data, void *cb_data); +#define COMMAND_LEN_MAX (10*1024) +#define POST_DATA_LEN_MAX (10*1024) + #endif /* _COMMAND_COMMON_H_ */ diff --git a/src/shared/sensor_common.h b/src/shared/sensor_common.h index d505918..a1c0541 100644 --- a/src/shared/sensor_common.h +++ b/src/shared/sensor_common.h @@ -116,6 +116,11 @@ enum sensor_permission_t { SENSOR_PERMISSION_BIO = (1 << 1) }; +enum client_type_t { + CLIENT_TYPE_SENSOR_CLIENT = 1, + CLIENT_TYPE_EXTERNAL_SOURCE, +}; + typedef struct sensor_event_t { unsigned int event_type; sensor_id_t sensor_id; -- 2.7.4 From 0a39e324be7d382a53c34254be458ed8bda4a520 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 11:40:59 +0900 Subject: [PATCH 04/16] sensord: update the duration of copyright in license Change-Id: I74c2b8d75f02ce89f5c8bb756923e997cc8c5a8d Signed-off-by: kibak.yoon --- LICENSE.APLv2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 index 91cbe82..23f43cc 100644 --- a/LICENSE.APLv2 +++ b/LICENSE.APLv2 @@ -1,4 +1,4 @@ -Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved. Apache License Version 2.0, January 2004 -- 2.7.4 From 52f700f18c9cfd0ed5370602c37473bda3a12baa Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 19 May 2016 16:11:49 +0900 Subject: [PATCH 05/16] sensord: terminate sensord if there is no sensor Change-Id: Ib4d2fe95691662fa8d750493b0c80067eaddd764 Signed-off-by: kibak.yoon --- src/server/main.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/server/main.cpp b/src/server/main.cpp index b136d69..d19c744 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -26,6 +26,8 @@ #define CAL_NODE_PATH "/sys/class/sensors/ssp_sensor/set_cal_data" #define SET_CAL 1 +#define TIMEOUT 10 + static void sig_term_handler(int signo, siginfo_t *info, void *data) { char proc_name[NAME_MAX]; @@ -73,6 +75,18 @@ static void set_cal_data(void) return; } +static gboolean terminate(gpointer data) +{ + std::vector sensors = sensor_loader::get_instance().get_sensors(ALL_SENSOR); + + if (sensors.size() == 0) { + _I("Terminating sensord.."); + server::get_instance().stop(); + } + + return FALSE; +} + int main(int argc, char *argv[]) { _I("Sensord started"); @@ -81,8 +95,9 @@ int main(int argc, char *argv[]) set_cal_data(); - /* TODO: loader has to be moved to server */ + /* TODO: loading sequence has to be moved to server */ sensor_loader::get_instance().load(); + g_timeout_add_seconds(TIMEOUT, terminate, NULL); server::get_instance().run(); server::get_instance().stop(); -- 2.7.4 From 02a0aef465e321e93a830243614625f9e8680952 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Mon, 23 May 2016 13:57:24 +0900 Subject: [PATCH 06/16] sensord: remove unused configs in spec file - unused sensor compile flags - unused build require package Change-Id: I26915b6fed772e7c29deec3fb595fefb4db0e9a6 Signed-off-by: kibak.yoon --- packaging/sensord.spec | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/packaging/sensord.spec b/packaging/sensord.spec index d4eb4ef..4457a4f 100644 --- a/packaging/sensord.spec +++ b/packaging/sensord.spec @@ -18,23 +18,11 @@ BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(libsystemd-daemon) -BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(cynara-creds-socket) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) Requires: libsensord = %{version}-%{release} -%define auto_rotation_state ON -%define orientation_state OFF -%define gravity_state OFF -%define linear_accel_state OFF -%define rv_state OFF -%define geomagnetic_rv_state OFF -%define gaming_rv_state OFF -%define tilt_state OFF -%define gyroscope_uncal_state OFF -%define build_test_suite ON - %ifarch %{ix86} x86_64 %define BUILD_ARCH EMULATOR %endif @@ -65,7 +53,6 @@ Group: System/Development %description -n sensor-hal-devel Sensord HAL interface -%if %{build_test_suite} == "ON" %package -n sensor-test Summary: Sensord library Group: System/Testing @@ -73,19 +60,12 @@ Group: System/Testing %description -n sensor-test Sensor functional testing -%endif - %prep %setup -q - MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} \ - -DORIENTATION=%{orientation_state} -DGRAVITY=%{gravity_state} \ - -DLINEAR_ACCEL=%{linear_accel_state} -DRV=%{rv_state} \ - -DGEOMAGNETIC_RV=%{geomagnetic_rv_state} -DGAMING_RV=%{gaming_rv_state} \ - -DGYROSCOPE_UNCAL=%{gyroscope_uncal_state} -DAUTO_ROTATION=%{auto_rotation_state} \ - -DTILT=%{tilt_state} -DTEST_SUITE=%{build_test_suite} -DARCH=%{BUILD_ARCH} + -DARCH=%{BUILD_ARCH} %build make %{?jobs:-j%jobs} @@ -153,7 +133,6 @@ ln -sf %{_libdir}/libsensor.so.%{version} %{_libdir}/libsensor.so.1 %{_includedir}/sensor/sensor_hal_types.h %license LICENSE.APLv2 -%if %{build_test_suite} == "ON" %files -n sensor-test %defattr(-,root,root,-) %{_bindir}/api-test @@ -162,4 +141,3 @@ ln -sf %{_libdir}/libsensor.so.%{version} %{_libdir}/libsensor.so.1 %{_bindir}/multi-process-performance-test %{_bindir}/fusion-data-collection %license LICENSE.APLv2 -%endif -- 2.7.4 From 41b38c5e369791882b0164beaa477ee700e25889 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 13:27:26 +0900 Subject: [PATCH 07/16] sensord: add power save vconf for syncing with tizen 2.3 - in public, there is no power save vconf key - this patch is only for maintainance Change-Id: I327fd0dfe96a849ef24b344a60aab971228340d5 Signed-off-by: kibak.yoon --- src/client/client.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index b9b99c1..e77b1b3 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -38,6 +38,10 @@ using std::vector; #define API __attribute__((visibility("default"))) #endif +#ifndef VCONFKEY_SETAPPL_PSMODE +#define VCONFKEY_SETAPPL_PSMODE "db/setting/psmode" +#endif + #define DEFAULT_INTERVAL POLL_10HZ_MS static cmutex lock; @@ -81,6 +85,7 @@ static void set_power_save_state_cb(void) g_power_save_state = get_power_save_state(); _D("power_save_state = [%d]", g_power_save_state); vconf_notify_key_changed(VCONFKEY_PM_STATE, power_save_state_cb, NULL); + vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, power_save_state_cb, NULL); } } @@ -94,6 +99,7 @@ static void unset_power_save_state_cb(void) if (g_power_save_state_cb_cnt == 0) { _D("Power save callback is unregistered"); vconf_ignore_key_changed(VCONFKEY_PM_STATE, power_save_state_cb); + vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, power_save_state_cb); } } @@ -113,14 +119,20 @@ void clean_up(void) static int get_power_save_state(void) { + int err; int state = 0; - int pm_state; + int pm_state, ps_state; - vconf_get_int(VCONFKEY_PM_STATE, &pm_state); + err = vconf_get_int(VCONFKEY_PM_STATE, &pm_state); - if (pm_state == VCONFKEY_PM_STATE_LCDOFF) + if (!err && pm_state == VCONFKEY_PM_STATE_LCDOFF) state |= SENSOR_OPTION_ON_IN_SCREEN_OFF; + err = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ps_state); + + if (!err && ps_state == SETTING_PSMODE_NORMAL) + state |= SENSOR_OPTION_ON_IN_POWERSAVE_MODE; + return state; } -- 2.7.4 From 7f38c1a44bce65ca524a05f6e15904beabc6cb1e Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 14:34:47 +0900 Subject: [PATCH 08/16] sensord: move deprecated event types to sensor_deprecated.h - clean up sensor_types.h Change-Id: I41225fcb478d00fd780aa46cda2ff94c18ede5c9 Signed-off-by: kibak.yoon --- src/shared/sensor_deprecated.h | 153 +++++++++++++++++++++++++++++++++++++ src/shared/sensor_types.h | 166 ----------------------------------------- 2 files changed, 153 insertions(+), 166 deletions(-) diff --git a/src/shared/sensor_deprecated.h b/src/shared/sensor_deprecated.h index a9481a5..41a4092 100644 --- a/src/shared/sensor_deprecated.h +++ b/src/shared/sensor_deprecated.h @@ -25,6 +25,79 @@ extern "C" { #endif +// Sensor Event Types +enum event_types_t { + ACCELEROMETER_RAW_DATA_EVENT = (ACCELEROMETER_SENSOR << 16) | 0x0001, + ACCELEROMETER_UNPROCESSED_DATA_EVENT = (ACCELEROMETER_SENSOR << 16) | 0x0002, + + GYROSCOPE_RAW_DATA_EVENT = (GYROSCOPE_SENSOR << 16) | 0x0001, + GYROSCOPE_UNPROCESSED_DATA_EVENT = (GYROSCOPE_SENSOR << 16) | 0x0002, + + GEOMAGNETIC_RAW_DATA_EVENT = (GEOMAGNETIC_SENSOR << 16) | 0x0001, + GEOMAGNETIC_UNPROCESSED_DATA_EVENT = (GEOMAGNETIC_SENSOR << 16) | 0x0002, + + PROXIMITY_CHANGE_STATE_EVENT = (PROXIMITY_SENSOR << 16) | 0x0001, + PROXIMITY_STATE_EVENT = (PROXIMITY_SENSOR << 16) | 0x0002, + PROXIMITY_DISTANCE_DATA_EVENT = (PROXIMITY_SENSOR << 16) | 0x0003, + + PRESSURE_RAW_DATA_EVENT = (PRESSURE_SENSOR << 16) | 0x0001, + + TEMPERATURE_RAW_DATA_EVENT = (TEMPERATURE_SENSOR << 16) | 0x0001, + + LIGHT_LUX_DATA_EVENT = (LIGHT_SENSOR << 16) | 0x0001, + LIGHT_LEVEL_DATA_EVENT = (LIGHT_SENSOR << 16) | 0x0002, + LIGHT_CHANGE_LEVEL_EVENT = (LIGHT_SENSOR << 16) | 0x0003, + + ROTATION_VECTOR_RAW_DATA_EVENT = (ROTATION_VECTOR_SENSOR << 16) | 0x0001, + + RV_RAW_RAW_DATA_EVENT = (RV_RAW_SENSOR << 16) | 0x0001, + + ULTRAVIOLET_RAW_DATA_EVENT = (ULTRAVIOLET_SENSOR << 16) | 0x0001, + + AUTO_ROTATION_CHANGE_STATE_EVENT = (AUTO_ROTATION_SENSOR << 16) | 0x0001, + + BIO_LED_RED_RAW_DATA_EVENT = (BIO_LED_RED_SENSOR << 16) | 0x0001, + + GAMING_RV_RAW_DATA_EVENT = (GYROSCOPE_RV_SENSOR << 16) | 0x0001, + + GEOMAGNETIC_RV_RAW_DATA_EVENT = (GEOMAGNETIC_RV_SENSOR << 16) | 0x0001, + + GRAVITY_RAW_DATA_EVENT = (GRAVITY_SENSOR << 16) | 0x0001, + + LINEAR_ACCEL_RAW_DATA_EVENT = (LINEAR_ACCEL_SENSOR << 16) | 0x0001, + + MOTION_ENGINE_EVENT_SNAP = (MOTION_SENSOR << 16) | 0x0001, + MOTION_ENGINE_EVENT_SHAKE = (MOTION_SENSOR << 16) | 0x0002, + MOTION_ENGINE_EVENT_DOUBLETAP = (MOTION_SENSOR << 16) | 0x0004, + MOTION_ENGINE_EVENT_PANNING = (MOTION_SENSOR << 16) | 0x0008, + MOTION_ENGINE_EVENT_TOP_TO_BOTTOM = (MOTION_SENSOR << 16) | 0x0010, + MOTION_ENGINE_EVENT_DIRECT_CALL = (MOTION_SENSOR << 16) | 0x0020, + MOTION_ENGINE_EVENT_TILT_TO_UNLOCK = (MOTION_SENSOR << 16) | 0x0040, + MOTION_ENGINE_EVENT_LOCK_EXECUTE_CAMERA = (MOTION_SENSOR << 16) | 0x0080, + MOTION_ENGINE_EVENT_SMART_ALERT = (MOTION_SENSOR << 16) | 0x0100, + MOTION_ENGINE_EVENT_TILT = (MOTION_SENSOR << 16) | 0x0200, + MOTION_ENGINE_EVENT_PANNING_BROWSE = (MOTION_SENSOR << 16) | 0x0400, + MOTION_ENGINE_EVENT_NO_MOVE = (MOTION_SENSOR << 16) | 0x0800, + MOTION_ENGINE_EVENT_SHAKE_ALWAYS_ON = (MOTION_SENSOR << 16) | 0x1000, + MOTION_ENGINE_EVENT_SMART_RELAY = (MOTION_SENSOR << 16) | 0x2000, + + ORIENTATION_RAW_DATA_EVENT = (ORIENTATION_SENSOR << 16) | 0x0001, + + TILT_RAW_DATA_EVENT = (TILT_SENSOR << 16) | 0x0001, + + GYROSCOPE_UNCAL_RAW_DATA_EVENT = (GYROSCOPE_UNCAL_SENSOR << 16) | 0x0001, + + FUSION_EVENT = (FUSION_SENSOR << 16) | 0x0001, + FUSION_GYROSCOPE_UNCAL_EVENT = (FUSION_SENSOR << 16) | 0x0002, + FUSION_CALIBRATION_NEEDED_EVENT = (FUSION_SENSOR << 16) | 0x0003, + FUSION_ORIENTATION_ENABLED = (FUSION_SENSOR << 16) | 0x0004, + FUSION_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0005, + FUSION_GAMING_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0006, + FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0007, + FUSION_TILT_ENABLED = (FUSION_SENSOR << 16) | 0x0008, + FUSION_GYROSCOPE_UNCAL_ENABLED = (FUSION_SENSOR << 16) | 0x0009, +}; + #define CALIBRATION_EVENT(sensor_type) (((sensor_type) << 16) | 0x2) #define ACCELEROMETER_EVENT_ROTATION_CHECK ((ACCELEROMETER_SENSOR << 16) | 0x0100) @@ -100,6 +173,86 @@ enum accelerometer_rotate_state { ROTATION_EVENT_270 = 4, }; +enum motion_snap_event { + MOTION_ENGIEN_SNAP_NONE = 0, + MOTION_ENGIEN_NEGATIVE_SNAP_X = 1, + MOTION_ENGIEN_POSITIVE_SNAP_X = 2, + MOTION_ENGIEN_NEGATIVE_SNAP_Y = 3, + MOTION_ENGIEN_POSITIVE_SNAP_Y = 4, + MOTION_ENGIEN_NEGATIVE_SNAP_Z = 5, + MOTION_ENGIEN_POSITIVE_SNAP_Z = 6, + MOTION_ENGIEN_SNAP_LEFT = MOTION_ENGIEN_NEGATIVE_SNAP_X, + MOTION_ENGIEN_SNAP_RIGHT = MOTION_ENGIEN_POSITIVE_SNAP_X, + MOTION_ENGINE_SNAP_NONE = 0, + MOTION_ENGINE_NEGATIVE_SNAP_X = 1, + MOTION_ENGINE_POSITIVE_SNAP_X = 2, + MOTION_ENGINE_NEGATIVE_SNAP_Y = 3, + MOTION_ENGINE_POSITIVE_SNAP_Y = 4, + MOTION_ENGINE_NEGATIVE_SNAP_Z = 5, + MOTION_ENGINE_POSITIVE_SNAP_Z = 6, + MOTION_ENGINE_SNAP_LEFT = MOTION_ENGINE_NEGATIVE_SNAP_X, + MOTION_ENGINE_SNAP_RIGHT = MOTION_ENGINE_POSITIVE_SNAP_X, +}; + +enum motion_shake_event { + MOTION_ENGIEN_SHAKE_NONE = 0, + MOTION_ENGIEN_SHAKE_DETECTION = 1, + MOTION_ENGIEN_SHAKE_CONTINUING = 2, + MOTION_ENGIEN_SHAKE_FINISH = 3, + MOTION_ENGINE_SHAKE_BREAK = 4, + MOTION_ENGINE_SHAKE_NONE = 0, + MOTION_ENGINE_SHAKE_DETECTION = 1, + MOTION_ENGINE_SHAKE_CONTINUING = 2, + MOTION_ENGINE_SHAKE_FINISH = 3, +}; + +enum motion_doubletap_event { + MOTION_ENGIEN_DOUBLTAP_NONE = 0, + MOTION_ENGIEN_DOUBLTAP_DETECTION = 1, + MOTION_ENGINE_DOUBLTAP_NONE = 0, + MOTION_ENGINE_DOUBLTAP_DETECTION = 1, +}; + +enum motion_top_to_bottom_event { + MOTION_ENGIEN_TOP_TO_BOTTOM_NONE = 0, + MOTION_ENGIEN_TOP_TO_BOTTOM_WAIT = 1, + MOTION_ENGIEN_TOP_TO_BOTTOM_DETECTION = 2, + MOTION_ENGINE_TOP_TO_BOTTOM_NONE = 0, + MOTION_ENGINE_TOP_TO_BOTTOM_WAIT = 1, + MOTION_ENGINE_TOP_TO_BOTTOM_DETECTION = 2, +}; + +enum motion_direct_call_event_t { + MOTION_ENGINE_DIRECT_CALL_NONE, + MOTION_ENGINE_DIRECT_CALL_DETECTION, +}; + +enum motion_smart_relay_event_t { + MOTION_ENGINE_SMART_RELAY_NONE, + MOTION_ENGINE_SMART_RELAY_DETECTION, +}; + +enum motion_tilt_to_unlock_event_t { + MOTION_ENGINE_TILT_TO_UNLOCK_NONE, + MOTION_ENGINE_TILT_TO_UNLOCK_DETECTION, +}; + +enum motion_lock_execute_camera_event_t { + MOTION_ENGINE_LOCK_EXECUTE_CAMERA_NONE, + MOTION_ENGINE_LOCK_EXECUTE_CAMERA_L_DETECTION, + MOTION_ENGINE_LOCK_EXECUTE_CAMERA_R_DETECTION, +}; + +enum motion_smart_alert_t { + MOTION_ENGINE_SMART_ALERT_NONE, + MOTION_ENGINE_SMART_ALERT_DETECTION, +}; + +enum motion_no_move_t { + MOTION_ENGINE_NO_MOVE_NONE, + MOTION_ENGINE_NO_MOVE_DETECTION, +}; + #ifdef __cplusplus } #endif diff --git a/src/shared/sensor_types.h b/src/shared/sensor_types.h index 6667684..cb8e65e 100644 --- a/src/shared/sensor_types.h +++ b/src/shared/sensor_types.h @@ -91,79 +91,6 @@ extern "C" DECLARE_SENSOR_ENUM(sensor_type_t, SENSOR_TYPE) -// Sensor Event Types -enum event_types_t { - ACCELEROMETER_RAW_DATA_EVENT = (ACCELEROMETER_SENSOR << 16) | 0x0001, - ACCELEROMETER_UNPROCESSED_DATA_EVENT = (ACCELEROMETER_SENSOR << 16) | 0x0002, - - GYROSCOPE_RAW_DATA_EVENT = (GYROSCOPE_SENSOR << 16) | 0x0001, - GYROSCOPE_UNPROCESSED_DATA_EVENT = (GYROSCOPE_SENSOR << 16) | 0x0002, - - GEOMAGNETIC_RAW_DATA_EVENT = (GEOMAGNETIC_SENSOR << 16) | 0x0001, - GEOMAGNETIC_UNPROCESSED_DATA_EVENT = (GEOMAGNETIC_SENSOR << 16) | 0x0002, - - PROXIMITY_CHANGE_STATE_EVENT = (PROXIMITY_SENSOR << 16) | 0x0001, - PROXIMITY_STATE_EVENT = (PROXIMITY_SENSOR << 16) | 0x0002, - PROXIMITY_DISTANCE_DATA_EVENT = (PROXIMITY_SENSOR << 16) | 0x0003, - - PRESSURE_RAW_DATA_EVENT = (PRESSURE_SENSOR << 16) | 0x0001, - - TEMPERATURE_RAW_DATA_EVENT = (TEMPERATURE_SENSOR << 16) | 0x0001, - - LIGHT_LUX_DATA_EVENT = (LIGHT_SENSOR << 16) | 0x0001, - LIGHT_LEVEL_DATA_EVENT = (LIGHT_SENSOR << 16) | 0x0002, - LIGHT_CHANGE_LEVEL_EVENT = (LIGHT_SENSOR << 16) | 0x0003, - - ROTATION_VECTOR_RAW_DATA_EVENT = (ROTATION_VECTOR_SENSOR << 16) | 0x0001, - - RV_RAW_RAW_DATA_EVENT = (RV_RAW_SENSOR << 16) | 0x0001, - - ULTRAVIOLET_RAW_DATA_EVENT = (ULTRAVIOLET_SENSOR << 16) | 0x0001, - - AUTO_ROTATION_CHANGE_STATE_EVENT = (AUTO_ROTATION_SENSOR << 16) | 0x0001, - - BIO_LED_RED_RAW_DATA_EVENT = (BIO_LED_RED_SENSOR << 16) | 0x0001, - - GAMING_RV_RAW_DATA_EVENT = (GYROSCOPE_RV_SENSOR << 16) | 0x0001, - - GEOMAGNETIC_RV_RAW_DATA_EVENT = (GEOMAGNETIC_RV_SENSOR << 16) | 0x0001, - - GRAVITY_RAW_DATA_EVENT = (GRAVITY_SENSOR << 16) | 0x0001, - - LINEAR_ACCEL_RAW_DATA_EVENT = (LINEAR_ACCEL_SENSOR << 16) | 0x0001, - - MOTION_ENGINE_EVENT_SNAP = (MOTION_SENSOR << 16) | 0x0001, - MOTION_ENGINE_EVENT_SHAKE = (MOTION_SENSOR << 16) | 0x0002, - MOTION_ENGINE_EVENT_DOUBLETAP = (MOTION_SENSOR << 16) | 0x0004, - MOTION_ENGINE_EVENT_PANNING = (MOTION_SENSOR << 16) | 0x0008, - MOTION_ENGINE_EVENT_TOP_TO_BOTTOM = (MOTION_SENSOR << 16) | 0x0010, - MOTION_ENGINE_EVENT_DIRECT_CALL = (MOTION_SENSOR << 16) | 0x0020, - MOTION_ENGINE_EVENT_TILT_TO_UNLOCK = (MOTION_SENSOR << 16) | 0x0040, - MOTION_ENGINE_EVENT_LOCK_EXECUTE_CAMERA = (MOTION_SENSOR << 16) | 0x0080, - MOTION_ENGINE_EVENT_SMART_ALERT = (MOTION_SENSOR << 16) | 0x0100, - MOTION_ENGINE_EVENT_TILT = (MOTION_SENSOR << 16) | 0x0200, - MOTION_ENGINE_EVENT_PANNING_BROWSE = (MOTION_SENSOR << 16) | 0x0400, - MOTION_ENGINE_EVENT_NO_MOVE = (MOTION_SENSOR << 16) | 0x0800, - MOTION_ENGINE_EVENT_SHAKE_ALWAYS_ON = (MOTION_SENSOR << 16) | 0x1000, - MOTION_ENGINE_EVENT_SMART_RELAY = (MOTION_SENSOR << 16) | 0x2000, - - ORIENTATION_RAW_DATA_EVENT = (ORIENTATION_SENSOR << 16) | 0x0001, - - TILT_RAW_DATA_EVENT = (TILT_SENSOR << 16) | 0x0001, - - GYROSCOPE_UNCAL_RAW_DATA_EVENT = (GYROSCOPE_UNCAL_SENSOR << 16) | 0x0001, - - FUSION_EVENT = (FUSION_SENSOR << 16) | 0x0001, - FUSION_GYROSCOPE_UNCAL_EVENT = (FUSION_SENSOR << 16) | 0x0002, - FUSION_CALIBRATION_NEEDED_EVENT = (FUSION_SENSOR << 16) | 0x0003, - FUSION_ORIENTATION_ENABLED = (FUSION_SENSOR << 16) | 0x0004, - FUSION_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0005, - FUSION_GAMING_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0006, - FUSION_GEOMAGNETIC_ROTATION_VECTOR_ENABLED = (FUSION_SENSOR << 16) | 0x0007, - FUSION_TILT_ENABLED = (FUSION_SENSOR << 16) | 0x0008, - FUSION_GYROSCOPE_UNCAL_ENABLED = (FUSION_SENSOR << 16) | 0x0009, -}; - enum proxi_change_state { PROXIMITY_STATE_NEAR = 0, PROXIMITY_STATE_FAR = 1, @@ -177,99 +104,6 @@ enum auto_rotation_state { AUTO_ROTATION_DEGREE_270, }; -enum motion_snap_event { - MOTION_ENGIEN_SNAP_NONE = 0, - MOTION_ENGIEN_NEGATIVE_SNAP_X = 1, - MOTION_ENGIEN_POSITIVE_SNAP_X = 2, - MOTION_ENGIEN_NEGATIVE_SNAP_Y = 3, - MOTION_ENGIEN_POSITIVE_SNAP_Y = 4, - MOTION_ENGIEN_NEGATIVE_SNAP_Z = 5, - MOTION_ENGIEN_POSITIVE_SNAP_Z = 6, - MOTION_ENGIEN_SNAP_LEFT = MOTION_ENGIEN_NEGATIVE_SNAP_X, - MOTION_ENGIEN_SNAP_RIGHT = MOTION_ENGIEN_POSITIVE_SNAP_X, - MOTION_ENGINE_SNAP_NONE = 0, - MOTION_ENGINE_NEGATIVE_SNAP_X = 1, - MOTION_ENGINE_POSITIVE_SNAP_X = 2, - MOTION_ENGINE_NEGATIVE_SNAP_Y = 3, - MOTION_ENGINE_POSITIVE_SNAP_Y = 4, - MOTION_ENGINE_NEGATIVE_SNAP_Z = 5, - MOTION_ENGINE_POSITIVE_SNAP_Z = 6, - MOTION_ENGINE_SNAP_LEFT = MOTION_ENGINE_NEGATIVE_SNAP_X, - MOTION_ENGINE_SNAP_RIGHT = MOTION_ENGINE_POSITIVE_SNAP_X, -}; - -enum motion_shake_event { - MOTION_ENGIEN_SHAKE_NONE = 0, - MOTION_ENGIEN_SHAKE_DETECTION = 1, - MOTION_ENGIEN_SHAKE_CONTINUING = 2, - MOTION_ENGIEN_SHAKE_FINISH = 3, - MOTION_ENGINE_SHAKE_BREAK = 4, - MOTION_ENGINE_SHAKE_NONE = 0, - MOTION_ENGINE_SHAKE_DETECTION = 1, - MOTION_ENGINE_SHAKE_CONTINUING = 2, - MOTION_ENGINE_SHAKE_FINISH = 3, -}; - -enum motion_doubletap_event { - MOTION_ENGIEN_DOUBLTAP_NONE = 0, - MOTION_ENGIEN_DOUBLTAP_DETECTION = 1, - MOTION_ENGINE_DOUBLTAP_NONE = 0, - MOTION_ENGINE_DOUBLTAP_DETECTION = 1, -}; - -enum motion_top_to_bottom_event { - MOTION_ENGIEN_TOP_TO_BOTTOM_NONE = 0, - MOTION_ENGIEN_TOP_TO_BOTTOM_WAIT = 1, - MOTION_ENGIEN_TOP_TO_BOTTOM_DETECTION = 2, - MOTION_ENGINE_TOP_TO_BOTTOM_NONE = 0, - MOTION_ENGINE_TOP_TO_BOTTOM_WAIT = 1, - MOTION_ENGINE_TOP_TO_BOTTOM_DETECTION = 2, -}; - -enum motion_direct_call_event_t { - MOTION_ENGINE_DIRECT_CALL_NONE, - MOTION_ENGINE_DIRECT_CALL_DETECTION, -}; - -enum motion_smart_relay_event_t { - MOTION_ENGINE_SMART_RELAY_NONE, - MOTION_ENGINE_SMART_RELAY_DETECTION, -}; - -enum motion_tilt_to_unlock_event_t { - MOTION_ENGINE_TILT_TO_UNLOCK_NONE, - MOTION_ENGINE_TILT_TO_UNLOCK_DETECTION, -}; - -enum motion_lock_execute_camera_event_t { - MOTION_ENGINE_LOCK_EXECUTE_CAMERA_NONE, - MOTION_ENGINE_LOCK_EXECUTE_CAMERA_L_DETECTION, - MOTION_ENGINE_LOCK_EXECUTE_CAMERA_R_DETECTION, -}; - -enum motion_smart_alert_t { - MOTION_ENGINE_SMART_ALERT_NONE, - MOTION_ENGINE_SMART_ALERT_DETECTION, -}; - -enum motion_no_move_t { - MOTION_ENGINE_NO_MOVE_NONE, - MOTION_ENGINE_NO_MOVE_DETECTION, -}; - -enum motion_property_id { - MOTION_PROPERTY_UNKNOWN = 0, - MOTION_PROPERTY_CHECK_ACCEL_SENSOR, - MOTION_PROPERTY_CHECK_GYRO_SENSOR, - MOTION_PROPERTY_CHECK_GEO_SENSOR, - MOTION_PROPERTY_CHECK_PRIXI_SENSOR, - MOTION_PROPERTY_CHECK_LIGHT_SENSOR, - MOTION_PROPERTY_CHECK_BARO_SENSOR, - MOTION_PROPERTY_LCD_TOUCH_ON, - MOTION_PROPERTY_LCD_TOUCH_OFF, - MOTION_PROPERTY_CHECK_GYRO_CAL_STATUS, -}; - #ifdef __cplusplus } #endif -- 2.7.4 From cc8a4379634ead1ec90824249f7079e3bfedadaf Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 14:44:02 +0900 Subject: [PATCH 09/16] sensord: fix build warning because of using g_type_init() - g_type_init() should be called under glib version 2.36 Change-Id: I5291cd4ea92168ddba0a961c0f24631cc2265dfb Signed-off-by: kibak.yoon --- src/server/dbus_util.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/dbus_util.cpp b/src/server/dbus_util.cpp index df1ade0..c29b61d 100755 --- a/src/server/dbus_util.cpp +++ b/src/server/dbus_util.cpp @@ -143,7 +143,9 @@ void reset_total_count(void) void init_dbus(void) { +#ifndef GLIB_VERSION_2_36 g_type_init(); +#endif introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); if (introspection_data == NULL) { -- 2.7.4 From e93b462a0a9e10411876ef5f4a12e50dea3c7aaf Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 17:53:40 +0900 Subject: [PATCH 10/16] sensord: initialize dbus when sensord is launched Change-Id: Ie8563a7892cdb70ef01d29b329daa85f1ea47281 Signed-off-by: kibak.yoon --- src/server/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/server/main.cpp b/src/server/main.cpp index d19c744..e3e9f73 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -93,6 +94,8 @@ int main(int argc, char *argv[]) signal_init(); + init_dbus(); + set_cal_data(); /* TODO: loading sequence has to be moved to server */ @@ -102,7 +105,8 @@ int main(int argc, char *argv[]) server::get_instance().run(); server::get_instance().stop(); - _I("Sensord terminated"); + fini_dbus(); + _I("Sensord terminated"); return 0; } -- 2.7.4 From 45fe7451b4c008fb012e860ab2b07eca1cd59ae9 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 17:56:46 +0900 Subject: [PATCH 11/16] sensord: add null check when sensor event is pushed to event queue if event or data is null, it is unnecessary to push event Change-Id: If7e28e3531f59dd30d5d9f0d14e46662c340ca45 Signed-off-by: kibak.yoon --- src/server/sensor_base.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/sensor_base.cpp b/src/server/sensor_base.cpp index b06b2f3..dd78a2a 100644 --- a/src/server/sensor_base.cpp +++ b/src/server/sensor_base.cpp @@ -297,6 +297,9 @@ void sensor_base::set_permission(int permission) bool sensor_base::push(sensor_event_t *event) { + if (!event || !(event->data)) + return false; + set_cache(event->data); AUTOLOCK(m_client_mutex); -- 2.7.4 From 4ec6c0b129c1068c956ecbd680d189508a8137cb Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 17:58:02 +0900 Subject: [PATCH 12/16] sensord: change error log macro from ERR to _E for code unity Change-Id: I2498ce26cbd92a39ef72e5ca2832e6035dec0072 Signed-off-by: kibak.yoon --- src/server/server.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/server.cpp b/src/server/server.cpp index 684b265..9b649ad 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -234,18 +234,18 @@ bool server::listen_command_channel(void) INFO("Failed to get systemd socket, create it by myself!"); if (!m_command_channel_accept_socket.create(SOCK_STREAM)) { - ERR("Failed to create command channel"); + _E("Failed to create command channel"); return false; } if (!m_command_channel_accept_socket.bind(COMMAND_CHANNEL_PATH)) { - ERR("Failed to bind command channel"); + _E("Failed to bind command channel"); m_command_channel_accept_socket.close(); return false; } if (!m_command_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) { - ERR("Failed to listen command channel"); + _E("Failed to listen command channel"); return false; } @@ -268,18 +268,18 @@ bool server::listen_event_channel(void) INFO("Failed to get systemd socket, create it by myself!"); if (!m_event_channel_accept_socket.create(SOCK_SEQPACKET)) { - ERR("Failed to create event channel"); + _E("Failed to create event channel"); return false; } if (!m_event_channel_accept_socket.bind(EVENT_CHANNEL_PATH)) { - ERR("Failed to bind event channel"); + _E("Failed to bind event channel"); m_event_channel_accept_socket.close(); return false; } if (!m_event_channel_accept_socket.listen(MAX_PENDING_CONNECTION)) { - ERR("Failed to listen event channel"); + _E("Failed to listen event channel"); m_event_channel_accept_socket.close(); return false; } -- 2.7.4 From 7863c4a857f056b2eb489593e97c97d9d13a9795 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 18:23:22 +0900 Subject: [PATCH 13/16] sensord: remove EVENT_TYPE_SHIFT macro in sensor_log.h - they are duplicated macro, so remove them. Change-Id: I1a635c7b49657229da2edf539a3f183033d4de64 Signed-off-by: kibak.yoon --- src/client/client_common.cpp | 5 +++-- src/shared/sensor_log.h | 3 --- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/client/client_common.cpp b/src/client/client_common.cpp index ce0eab2..a91dbb0 100644 --- a/src/client/client_common.cpp +++ b/src/client/client_common.cpp @@ -17,6 +17,7 @@ * */ #include +#include #include #include #include @@ -40,7 +41,7 @@ const char* get_sensor_name(sensor_id_t id) const char* get_event_name(unsigned int event_type) { - sensor_type_t type = (sensor_type_t) (event_type >> EVENT_TYPE_SHIFT); + sensor_type_t type = (sensor_type_t) (event_type >> SENSOR_EVENT_SHIFT); std::string name(util_sensor_type_t::get_string(type)); return name.append("_EVENT").c_str(); @@ -48,7 +49,7 @@ const char* get_event_name(unsigned int event_type) unsigned int get_calibration_event_type(unsigned int event_type) { - sensor_type_t type = (sensor_type_t)(event_type >> EVENT_TYPE_SHIFT); + sensor_type_t type = (sensor_type_t)(event_type >> SENSOR_EVENT_SHIFT); switch (type) { case GEOMAGNETIC_SENSOR: diff --git a/src/shared/sensor_log.h b/src/shared/sensor_log.h index d478e07..22d1d7d 100644 --- a/src/shared/sensor_log.h +++ b/src/shared/sensor_log.h @@ -23,9 +23,6 @@ #include #include -#define EVENT_TYPE_SHIFT 16 -#define SENSOR_TYPE_SHIFT 32 - #define MICROSECONDS(tv) ((tv.tv_sec * 1000000ll) + tv.tv_usec) #ifdef LOG_TAG -- 2.7.4 From 1ced21e7b94e30b57b93803b19debfa38ca35fcb Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 23:12:05 +0900 Subject: [PATCH 14/16] sensord: change the log level from _E to _I - this state is not error Change-Id: I9f294f14e6071f7cab8f40eaf8d296fd836a57a9 Signed-off-by: kibak.yoon --- src/sensor/accel/accel_sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sensor/accel/accel_sensor.cpp b/src/sensor/accel/accel_sensor.cpp index 3470850..892ecb0 100644 --- a/src/sensor/accel/accel_sensor.cpp +++ b/src/sensor/accel/accel_sensor.cpp @@ -23,7 +23,7 @@ accel_sensor::accel_sensor() { - _E("accel_sensor is created : %#x", this); + _I("accel_sensor is created : %#x", this); } accel_sensor::~accel_sensor() -- 2.7.4 From fd9c129f5af7769c37082c2628bf5016b041c430 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 23:12:55 +0900 Subject: [PATCH 15/16] sensord: remove unused APIs - there is no module which uses these APIs - sf_check_rotation is used in xwalk.... Change-Id: I3c462da847015f54f3aa1d573a7380342f941205 Signed-off-by: kibak.yoon --- src/client/client_deprecated.cpp | 10 ---------- src/client/sensor_internal_deprecated.h | 28 ++-------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/client/client_deprecated.cpp b/src/client/client_deprecated.cpp index 38cf33f..e721bed 100644 --- a/src/client/client_deprecated.cpp +++ b/src/client/client_deprecated.cpp @@ -82,13 +82,3 @@ API int sf_is_sensor_event_available(sensor_type_t sensor_type, unsigned int eve { return OP_ERROR; } - -API int sf_get_data_properties(unsigned int data_id, sensor_data_properties_t *return_data_properties) -{ - return OP_ERROR; -} - -API int sf_get_properties(sensor_type_t sensor_type, sensor_properties_t *return_properties) -{ - return OP_ERROR; -} diff --git a/src/client/sensor_internal_deprecated.h b/src/client/sensor_internal_deprecated.h index d74cab8..a2b5b30 100644 --- a/src/client/sensor_internal_deprecated.h +++ b/src/client/sensor_internal_deprecated.h @@ -38,8 +38,6 @@ extern "C" { #endif -#define MAX_KEY_LEN 30 - typedef struct { condition_op_t cond_op; float cond_value1; @@ -59,30 +57,6 @@ typedef struct { int z; } sensor_panning_data_t; -typedef struct { - int sensor_unit_idx; - float sensor_min_range; - float sensor_max_range; - float sensor_resolution; - char sensor_name[MAX_KEY_LEN]; - char sensor_vendor[MAX_KEY_LEN]; -} sensor_properties_t; - -typedef struct { - int sensor_unit_idx; - float sensor_min_range; - float sensor_max_range; - float sensor_resolution; -} sensor_data_properties_t; - -DEPRECATED int sf_is_sensor_event_available(sensor_type_t sensor_type, unsigned int event_type); - -DEPRECATED int sf_get_data_properties(unsigned int data_id, sensor_data_properties_t *return_data_properties); - -DEPRECATED int sf_get_properties(sensor_type_t sensor_type, sensor_properties_t *return_properties); - -DEPRECATED int sf_check_rotation(unsigned long *rotation); - /** * @fn int sf_connect(sensor_type_t sensor) * @brief This API connects a sensor type to respective sensor. The application calls with the type of the sensor (ex. ACCELEROMETER_SENSOR) and on basis of that server takes decision of which plug-in to be connected. Once sensor connected application can proceed for data processing. This API returns a positive handle which should be used by application to communicate on sensor type. @@ -177,6 +151,8 @@ DEPRECATED int sf_change_sensor_option(int handle, int option); */ DEPRECATED int sf_send_sensorhub_data(int handle, const char* data, int data_len); +DEPRECATED int sf_check_rotation(unsigned long *rotation); + #ifdef __cplusplus } #endif -- 2.7.4 From df00850a3de2f89fbfd61d12ab61295d8e2ff0d1 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 25 May 2016 23:20:03 +0900 Subject: [PATCH 16/16] sensord: clean up permission_checker for syncing with tizen_2.3 - in tizen 2.3, there is another security module, security_server. - clean up permission_checker for converting it easily Change-Id: I4489849fbb4e8178058e1b1d403dde99c402b0bd Signed-off-by: kibak.yoon --- src/server/permission_checker.cpp | 34 ++++++++++++++++------------------ src/server/permission_checker.h | 12 +++++++----- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/server/permission_checker.cpp b/src/server/permission_checker.cpp index 72fef47..3da9ac6 100644 --- a/src/server/permission_checker.cpp +++ b/src/server/permission_checker.cpp @@ -21,15 +21,17 @@ #include #include #include +#include #include #include #include +#include #define CACHE_SIZE 16 static cynara *cynara_env = NULL; -static bool check_privilege_by_sockfd(int sock_fd, const char *priv) +static bool check_privilege_by_sockfd(int sock_fd, const char *priv, const char *access) { retvm_if(cynara_env == NULL, false, "Cynara not initialized"); @@ -60,15 +62,16 @@ static bool check_privilege_by_sockfd(int sock_fd, const char *priv) return (ret == CYNARA_API_ACCESS_ALLOWED); } -permission_checker::permission_checker(void) +permission_checker::permission_checker() : m_permission_set(0) { init(); + init_cynara(); } -permission_checker::~permission_checker(void) +permission_checker::~permission_checker() { - deinit(); + deinit_cynara(); } permission_checker& permission_checker::get_instance(void) @@ -79,10 +82,7 @@ permission_checker& permission_checker::get_instance(void) void permission_checker::init(void) { - AUTOLOCK(m_mutex); - - m_permission_infos.push_back(std::make_shared (SENSOR_PERMISSION_STANDARD, false, "")); - m_permission_infos.push_back(std::make_shared (SENSOR_PERMISSION_BIO, true, "http://tizen.org/privilege/healthinfo")); + m_permission_infos.push_back(std::make_shared(SENSOR_PERMISSION_BIO, "http://tizen.org/privilege/healthinfo", "")); std::vector sensors; sensors = sensor_loader::get_instance().get_sensors(ALL_SENSOR); @@ -91,12 +91,12 @@ void permission_checker::init(void) m_permission_set |= sensors[i]->get_permission(); _I("Permission Set = %d", m_permission_set); - - init_cynara(); } void permission_checker::init_cynara(void) { + AUTOLOCK(m_mutex); + cynara_configuration *conf; int err = cynara_configuration_create(&conf); @@ -121,7 +121,7 @@ void permission_checker::init_cynara(void) _I("Cynara initialized"); } -void permission_checker::deinit(void) +void permission_checker::deinit_cynara(void) { AUTOLOCK(m_mutex); @@ -135,16 +135,14 @@ int permission_checker::get_permission(int sock_fd) { AUTOLOCK(m_mutex); - int permission = SENSOR_PERMISSION_NONE; + int permission = SENSOR_PERMISSION_STANDARD; for (unsigned int i = 0; i < m_permission_infos.size(); ++i) { - if (!m_permission_infos[i]->need_to_check) { + if (!(m_permission_set & m_permission_infos[i]->permission)) + continue; + + if (check_privilege_by_sockfd(sock_fd, m_permission_infos[i]->privilege.c_str(), m_permission_infos[i]->access.c_str())) permission |= m_permission_infos[i]->permission; - } else if (m_permission_set & m_permission_infos[i]->permission) { - if (check_privilege_by_sockfd(sock_fd, m_permission_infos[i]->privilege.c_str())) { - permission |= m_permission_infos[i]->permission; - } - } } return permission; diff --git a/src/server/permission_checker.h b/src/server/permission_checker.h index d47524d..d42ba09 100644 --- a/src/server/permission_checker.h +++ b/src/server/permission_checker.h @@ -34,33 +34,35 @@ public: private: class permission_info { public: - permission_info(int _permission, bool _need_to_check, std::string _priv) + permission_info(int _permission, std::string _priv, std::string _access) : permission(_permission) - , need_to_check(_need_to_check) , privilege(_priv) + , access(_access) { } int permission; - bool need_to_check; std::string privilege; + std::string access; }; typedef std::vector> permission_info_vector; permission_checker(); - ~permission_checker(); permission_checker(permission_checker const&) {}; permission_checker& operator=(permission_checker const&); + ~permission_checker(); + void init(void); - void deinit(void); private: permission_info_vector m_permission_infos; int m_permission_set; cmutex m_mutex; +private: void init_cynara(void); + void deinit_cynara(void); }; #endif /* _PERMISSION_CHECKER_H_ */ -- 2.7.4