Copy libsensor to API 44/277244/4
authorTaeminYeom <taemin.yeom@samsung.com>
Mon, 4 Jul 2022 05:49:07 +0000 (14:49 +0900)
committerTaeminYeom <taemin.yeom@samsung.com>
Wed, 6 Jul 2022 06:03:23 +0000 (15:03 +0900)
Change-Id: Ib82941e2ba6cbb6b7d360a095a1f390797d08e9a
Signed-off-by: TaeminYeom <taemin.yeom@samsung.com>
74 files changed:
CMakeLists.txt
include/sensor_info.h [deleted file]
include/sensor_info_list.h [new file with mode: 0644]
include/sensor_internal.h [new file with mode: 0644]
include/sensor_log.h
include/sensor_types.h [new file with mode: 0644]
packaging/capi-system-sensor.spec
src/api/CMakeLists.txt [new file with mode: 0644]
src/api/capi-system-sensor.pc.in [new file with mode: 0644]
src/api/fusion_util.c [new file with mode: 0644]
src/api/geomagnetic_field.c [new file with mode: 0644]
src/api/sensor-internal.cpp [new file with mode: 0644]
src/api/sensor.cpp [new file with mode: 0644]
src/api/sensor_internal.cpp [new file with mode: 0644]
src/api/sensor_listener.cpp [new file with mode: 0644]
src/api/sensor_listener.h [new file with mode: 0644]
src/api/sensor_manager.cpp [new file with mode: 0644]
src/api/sensor_manager.h [new file with mode: 0644]
src/api/sensor_manager_channel_handler.cpp [new file with mode: 0644]
src/api/sensor_manager_channel_handler.h [new file with mode: 0644]
src/api/sensor_provider.cpp [new file with mode: 0644]
src/api/sensor_provider_channel_handler.cpp [new file with mode: 0644]
src/api/sensor_provider_channel_handler.h [new file with mode: 0644]
src/api/sensor_provider_internal.cpp [new file with mode: 0644]
src/api/sensor_provider_internal.h [new file with mode: 0644]
src/api/sensor_reader.cpp [new file with mode: 0644]
src/api/sensor_reader.h [new file with mode: 0644]
src/api/sensor_recorder/sensor_recorder.cpp [new file with mode: 0644]
src/api/sensor_recorder/sensor_recorder_dummy.cpp [new file with mode: 0644]
src/fusion_util.c [deleted file]
src/geomagnetic_field.c [deleted file]
src/sensor-internal.cpp [deleted file]
src/sensor.cpp [deleted file]
src/sensor_provider.cpp [deleted file]
src/sensor_recorder.cpp [deleted file]
src/sensor_recorder_dummy.cpp [deleted file]
src/shared/CMakeLists.txt [new file with mode: 0644]
src/shared/accept_event_handler.cpp [new file with mode: 0644]
src/shared/accept_event_handler.h [new file with mode: 0644]
src/shared/cbase_lock.cpp [new file with mode: 0644]
src/shared/cbase_lock.h [new file with mode: 0644]
src/shared/channel.cpp [new file with mode: 0644]
src/shared/channel.h [new file with mode: 0644]
src/shared/channel_event_handler.cpp [new file with mode: 0644]
src/shared/channel_event_handler.h [new file with mode: 0644]
src/shared/channel_handler.h [new file with mode: 0644]
src/shared/cmutex.cpp [new file with mode: 0644]
src/shared/cmutex.h [new file with mode: 0644]
src/shared/command_types.h [new file with mode: 0644]
src/shared/event_handler.h [new file with mode: 0644]
src/shared/event_loop.cpp [new file with mode: 0644]
src/shared/event_loop.h [new file with mode: 0644]
src/shared/ipc_client.cpp [new file with mode: 0644]
src/shared/ipc_client.h [new file with mode: 0644]
src/shared/ipc_server.cpp [new file with mode: 0644]
src/shared/ipc_server.h [new file with mode: 0644]
src/shared/macro.h [new file with mode: 0644]
src/shared/message.cpp [new file with mode: 0644]
src/shared/message.h [new file with mode: 0644]
src/shared/sensor_info.cpp [new file with mode: 0644]
src/shared/sensor_info.h [new file with mode: 0644]
src/shared/sensor_types_private.h [new file with mode: 0644]
src/shared/sensor_utils.cpp [new file with mode: 0644]
src/shared/sensor_utils.h [new file with mode: 0644]
src/shared/seqpacket_socket.cpp [new file with mode: 0644]
src/shared/seqpacket_socket.h [new file with mode: 0644]
src/shared/socket.cpp [new file with mode: 0644]
src/shared/socket.h [new file with mode: 0644]
src/shared/stream_socket.cpp [new file with mode: 0644]
src/shared/stream_socket.h [new file with mode: 0644]
tests/main.c
tests/spec_test.c
tests/stress_test.c
tools/sensor-tool.c

index 12faffe893e14cf4119b5454e3a8df227e1f5ce4..c4964fb1689d85fcf0be81ad468b7bb6bf78267e 100644 (file)
@@ -1,62 +1,29 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(capi-system-sensor)
+PROJECT(capi-system-sensor-main)
 INCLUDE(GNUInstallDirs)
 
-SET(DEPENDENTS "dlog sensor hal-api-sensor capi-base-common")
-
-IF("${SENSOR_RECORDER}" STREQUAL "on")
-       SET(DEPENDENTS "${DEPENDENTS} context-sensor-recorder-client")
-ENDIF()
-
 SET(VERSION ${FULLVER})
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 
-SET(PC_NAME ${PROJECT_NAME})
-SET(PC_DESCRIPTION "Sensor C-API library")
-SET(PC_INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/sensor")
-SET(PC_DEPENDENTS "${DEPENDENTS}")
-SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
-SET(PC_LDFLAGS "-l${PROJECT_NAME}")
-
 INCLUDE_DIRECTORIES(include ${CMAKE_CURRENT_SOURCE_DIR})
 
 # Build options
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED ${DEPENDENTS})
-
 FOREACH(flag ${${PROJECT_NAME}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -Werror -g -fdump-rtl-expand")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -g -fdump-rtl-expand")
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fPIC -std=c++0x")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
 
 # Internal Logging Option
 #ADD_DEFINITIONS("-DTIZEN_DEBUG")
 
-# Compile Source files
-SET(SOURCES src/sensor.cpp
-                       src/sensor_provider.cpp
-                       src/sensor-internal.cpp
-                       src/geomagnetic_field.c
-                       src/fusion_util.c)
-
-IF("${SENSOR_RECORDER}" STREQUAL "on")
-       SET(SOURCES ${SOURCES} src/sensor_recorder.cpp)
-ELSE()
-       SET(SOURCES ${SOURCES} src/sensor_recorder_dummy.cpp)
-ENDIF()
-
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES})
-
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${FULLVER} SOVERSION ${MAJORVER} CLEAN_DIRECT_OUTPUT 1)
-CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-INSTALL(FILES include/sensor.h include/sensor-internal.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor)
-INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
+ADD_SUBDIRECTORY(src/shared)
+ADD_SUBDIRECTORY(src/api)
 ADD_SUBDIRECTORY(tests)
 ADD_SUBDIRECTORY(tools)
+
+INSTALL(FILES include/sensor.h include/sensor-internal.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor)
diff --git a/include/sensor_info.h b/include/sensor_info.h
deleted file mode 100644 (file)
index ee13601..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#define SENSOR_NUM (sizeof(sensor_infos) / sizeof(sensor_infos[0]))
-
-struct sensor_info {
-       sensor_type_e type;
-       const char* name;
-       const char* alias;
-       int value_num;
-};
-
-static const struct sensor_info sensor_infos[] = {
-       {SENSOR_ALL,                         "All",                                      "ALL",                0},
-       {SENSOR_ACCELEROMETER,               "Accelerometer",                            "ACCEL",              3},
-       {SENSOR_GRAVITY,                     "Gravity sensor",                           "GRAVITY",            3},
-       {SENSOR_LINEAR_ACCELERATION,         "Linear acceleration sensor",               "LINEAR_ACCEL",       3},
-       {SENSOR_MAGNETIC,                    "Magnetic sensor",                          "MAGNET",             3},
-       {SENSOR_ROTATION_VECTOR,             "Rotation vector sensor",                   "ROTATION",           4},
-       {SENSOR_ORIENTATION,                 "Orientation sensor",                       "ORIENTATION",        3},
-       {SENSOR_GYROSCOPE,                   "Gyroscope",                                "GYRO",               3},
-       {SENSOR_LIGHT,                       "Light sensor",                             "LIGHT",              1},
-       {SENSOR_PROXIMITY,                   "Proximity sensor",                         "PROXIMITY",          1},
-       {SENSOR_PRESSURE,                    "Pressure sensor",                          "PRESSURE",           1},
-       {SENSOR_ULTRAVIOLET,                 "Ultraviolet sensor",                       "UV",                 1},
-       {SENSOR_TEMPERATURE,                 "Temperature sensor",                       "TEMP",               1},
-       {SENSOR_HUMIDITY,                    "Humidity sensor",                          "HUMIDITY",           1},
-       {SENSOR_HRM,                         "Heart-rate monitor",                       "HRM",                1},
-       {SENSOR_HRM_LED_GREEN,               "Green LED sensor of HRM",                  "GREEN_HRM",          1},
-       {SENSOR_HRM_LED_IR,                  "Infra-Red LED sensor of HRM",              "IR_HRM",             1},
-       {SENSOR_HRM_LED_RED,                 "Red LED sensor of HRM",                    "RED_HRM",            1},
-       {SENSOR_GYROSCOPE_UNCALIBRATED,      "Uncalibrated Gyroscope sensor",            "UNCAL_GYRO",         6},
-       {SENSOR_GEOMAGNETIC_UNCALIBRATED,    "Uncalibrated Geomagnetic sensor",          "UNCAL_MAGNET",       6},
-       {SENSOR_GYROSCOPE_ROTATION_VECTOR,   "Gyroscope-based rotation vector sensor",   "GYRO_ROTATION",      4},
-       {SENSOR_GEOMAGNETIC_ROTATION_VECTOR, "Geomagnetic-based rotation vector sensor", "MAGNET_ROTATION",    4},
-       {SENSOR_GYROSCOPE_ORIENTATION,       "Gyroscope-based orientation sensor",       "GYRO_ORIENTATION",   3},
-       {SENSOR_GEOMAGNETIC_ORIENTATION,     "Geomagnetic-based orientation sensor",     "MAGNET_ORIENTATION", 3},
-       {SENSOR_SIGNIFICANT_MOTION,          "Significant motion sensor",                "MOTION",             1},
-       {SENSOR_HRM_BATCH,                   "Heart-rate monitor batch sensor",          "HRM_BATCH",          1},
-       {SENSOR_HRM_LED_GREEN_BATCH,         "Green LED of HRM batch sensor",            "GREEN_HRM_BATCH",    1},
-       {SENSOR_HUMAN_PEDOMETER,             "Pedometer",                                "PEDOMETER",          3},
-       {SENSOR_HUMAN_SLEEP_MONITOR,         "Sleep monitor",                            "SLEEP_MONITOR",      1},
-       {SENSOR_HUMAN_SLEEP_DETECTOR,        "Sleep detector",                           "SLEEP_DETECTOR",     1},
-};
diff --git a/include/sensor_info_list.h b/include/sensor_info_list.h
new file mode 100644 (file)
index 0000000..99d6cd3
--- /dev/null
@@ -0,0 +1,41 @@
+#define SENSOR_NUM (sizeof(sensor_info_lists) / sizeof(sensor_info_lists[0]))
+
+struct sensor_info_list {
+       sensor_type_e type;
+       const char* name;
+       const char* alias;
+       int value_num;
+};
+
+static const struct sensor_info_list sensor_info_lists[] = {
+       {SENSOR_ALL,                         "All",                                      "ALL",                0},
+       {SENSOR_ACCELEROMETER,               "Accelerometer",                            "ACCEL",              3},
+       {SENSOR_GRAVITY,                     "Gravity sensor",                           "GRAVITY",            3},
+       {SENSOR_LINEAR_ACCELERATION,         "Linear acceleration sensor",               "LINEAR_ACCEL",       3},
+       {SENSOR_MAGNETIC,                    "Magnetic sensor",                          "MAGNET",             3},
+       {SENSOR_ROTATION_VECTOR,             "Rotation vector sensor",                   "ROTATION",           4},
+       {SENSOR_ORIENTATION,                 "Orientation sensor",                       "ORIENTATION",        3},
+       {SENSOR_GYROSCOPE,                   "Gyroscope",                                "GYRO",               3},
+       {SENSOR_LIGHT,                       "Light sensor",                             "LIGHT",              1},
+       {SENSOR_PROXIMITY,                   "Proximity sensor",                         "PROXIMITY",          1},
+       {SENSOR_PRESSURE,                    "Pressure sensor",                          "PRESSURE",           1},
+       {SENSOR_ULTRAVIOLET,                 "Ultraviolet sensor",                       "UV",                 1},
+       {SENSOR_TEMPERATURE,                 "Temperature sensor",                       "TEMP",               1},
+       {SENSOR_HUMIDITY,                    "Humidity sensor",                          "HUMIDITY",           1},
+       {SENSOR_HRM,                         "Heart-rate monitor",                       "HRM",                1},
+       {SENSOR_HRM_LED_GREEN,               "Green LED sensor of HRM",                  "GREEN_HRM",          1},
+       {SENSOR_HRM_LED_IR,                  "Infra-Red LED sensor of HRM",              "IR_HRM",             1},
+       {SENSOR_HRM_LED_RED,                 "Red LED sensor of HRM",                    "RED_HRM",            1},
+       {SENSOR_GYROSCOPE_UNCALIBRATED,      "Uncalibrated Gyroscope sensor",            "UNCAL_GYRO",         6},
+       {SENSOR_GEOMAGNETIC_UNCALIBRATED,    "Uncalibrated Geomagnetic sensor",          "UNCAL_MAGNET",       6},
+       {SENSOR_GYROSCOPE_ROTATION_VECTOR,   "Gyroscope-based rotation vector sensor",   "GYRO_ROTATION",      4},
+       {SENSOR_GEOMAGNETIC_ROTATION_VECTOR, "Geomagnetic-based rotation vector sensor", "MAGNET_ROTATION",    4},
+       {SENSOR_GYROSCOPE_ORIENTATION,       "Gyroscope-based orientation sensor",       "GYRO_ORIENTATION",   3},
+       {SENSOR_GEOMAGNETIC_ORIENTATION,     "Geomagnetic-based orientation sensor",     "MAGNET_ORIENTATION", 3},
+       {SENSOR_SIGNIFICANT_MOTION,          "Significant motion sensor",                "MOTION",             1},
+       {SENSOR_HRM_BATCH,                   "Heart-rate monitor batch sensor",          "HRM_BATCH",          1},
+       {SENSOR_HRM_LED_GREEN_BATCH,         "Green LED of HRM batch sensor",            "GREEN_HRM_BATCH",    1},
+       {SENSOR_HUMAN_PEDOMETER,             "Pedometer",                                "PEDOMETER",          3},
+       {SENSOR_HUMAN_SLEEP_MONITOR,         "Sleep monitor",                            "SLEEP_MONITOR",      1},
+       {SENSOR_HUMAN_SLEEP_DETECTOR,        "Sleep detector",                           "SLEEP_DETECTOR",     1},
+};
diff --git a/include/sensor_internal.h b/include/sensor_internal.h
new file mode 100644 (file)
index 0000000..477c8d7
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * 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 __SENSORD_INTERNAL_H__
+#define __SENSORD_INTERNAL_H__
+
+#ifndef API
+#define API __attribute__((visibility("default")))
+#endif
+
+#include <stdbool.h>
+#include <sys/types.h>
+#include <limits.h>
+
+/*header for common sensor type*/
+#include <sensor_types.h>
+
+#define SENSOR_BATCH_LATENCY_DEFAULT UINT_MAX
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef void (*sensor_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data);
+typedef void (*sensor_events_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t events[], int events_count, void *user_data);
+typedef void (*sensorhub_cb_t)(sensor_t sensor, unsigned int event_type, sensorhub_data_t *data, void *user_data);
+typedef void (*sensor_accuracy_changed_cb_t) (sensor_t sensor, unsigned long long timestamp, int accuracy, void *user_data);
+typedef void (*sensor_attribute_int_changed_cb_t)(sensor_t sensor, int attribute, int value, void *user_data);
+typedef void (*sensor_attribute_str_changed_cb_t)(sensor_t sensor, int attribute, const char *value, int len, void *user_data);
+
+/**
+ * @brief Get the list of available sensors of a certain type,  use ALL_SENSOR to get all the sensors.
+ *
+ * @param[in] type the type of sensors requested.
+ * @param[out] list the list of sensors matching the asked type,  the caller should explicitly free this list.
+ * @param[out] sensor count the count of sensors contained in the list.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count);
+
+/**
+ * @brief Get the default sensor for a given type.
+ *
+ * @param[in] type the type of a sensor requested.
+ * @return the default sensor matching the asked type on success, otherwise NULL.
+ */
+sensor_t sensord_get_sensor(sensor_type_t type);
+
+/**
+ * @brief Get the list of available sensors of a certain type,  use ALL_SENSOR to get all the sensors.
+ *
+ * @param[in] type the type of sensors requested.
+ * @param[out] list the list of sensors matching the asked type,  the caller should explicitly free this list.
+ * @param[out] sensor count the count of sensors contained in the list.
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EPERM Operation not permitted
+ * @retval -EACCES Permission denied
+ * @retval -ENODATA NO sensor available
+ */
+int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *sensor_count);
+
+/**
+ * @brief Get the default sensor for a given type.
+ *
+ * @param[in] type the type of a sensor requested.
+ * @param[out] a sensor matching the asked type.
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EPERM Operation not permitted
+ * @retval -EACCES Permission denied
+ */
+int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor);
+
+/**
+ * @brief Get the type of this sensor.
+ *
+ * @param[in] sensor a sensor to get type.
+ * @param[out] type the type of this sensor.
+ * @return return true on success, otherwise false.
+ */
+bool sensord_get_type(sensor_t sensor, sensor_type_t *type);
+
+/**
+ * @brief Get the URI string of this sensor.
+ *
+ * @param[in] sensor a sensor to get uri.
+ * @return the name string of this sensor on success, otherwise NULL.
+ */
+const char* sensord_get_uri(sensor_t sensor);
+
+/**
+ * @brief Get the name string of this sensor.
+ *
+ * @param[in] sensor a sensor to get name.
+ * @return the name string of this sensor on success, otherwise NULL.
+ */
+const char* sensord_get_name(sensor_t sensor);
+
+/**
+ * @brief Get the vendor string of this sensor.
+ *
+ * @param[in] sensor a sensor to get vendor.
+ * @return the vendor string of this sensor on success, otherwise NULL.
+ */
+const char* sensord_get_vendor(sensor_t sensor);
+
+/**
+ * @brief Get the privilege of this sensor.
+ *
+ * @param[in] sensor a sensor to get privilege.
+ * @param[out] privilege the privilege of this sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege);
+
+/**
+ * @brief Get the minimum range of this sensor in the sensor's unit.
+ *
+ * @param[in] sensor a sensor to get minimum range.
+ * @param[out] min_range the minimum range of this sensor in the sensor's unit.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_min_range(sensor_t sensor, float *min_range);
+
+/**
+ * @brief Get the maximum range of this sensor in the sensor's unit.
+ *
+ * @param[in] sensor a sensor to get maximum range.
+ * @param[out] max_range the maximum range of this sensor in the sensor's unit.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_max_range(sensor_t sensor, float *max_range);
+
+/**
+ * @brief Get the resolution of this sensor in the sensor's unit.
+ *
+ * @param[in] sensor a sensor to get resolution.
+ * @param[out] resolution the resolution of this sensor in the sensor's unit.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_resolution(sensor_t sensor, float *resolution);
+
+/**
+ * @brief Get the minimum interval allowed between two events in microsecond or zero if this sensor only returns a value when the data it's measuring changes.
+ *
+ * @param[in] sensor a sensor to get minimum interval.
+ * @param[out] min_interval the minimum interval of this sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_min_interval(sensor_t sensor, int *min_interval);
+
+/**
+ * @brief Get the number of events reserved for this sensor in the batch mode FIFO.
+ *
+ * @param[in] sensor a sensor to get the number of fifo count
+ * @param[out] fifo_count the number of events reserved for this sensor in the batch mode FIFO
+ * @return true on success, otherwise false
+ */
+bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count);
+
+/**
+ * @brief Get the maximum number of events of this sensor that could be batched. If this value is zero it indicates that batch mode is not supported for this sensor.
+ *
+ * @param[in] sensor a sensor to the maximum number of events that could be batched.
+ * @param[out] max_batch_count the maximum number of events of this sensor that could be batched.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count);
+
+/**
+ * @brief Get the supported event types of this sensor.
+ *
+ * @param[in] sensor a sensor to get the supported event types.
+ * @param[out] event_types the array containing supported event types of this sensor, the caller should explicitly free this array.
+ * @param[out] count the count of the supported event types of this sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count);
+
+/**
+ * @brief Check a given event type is supporeted by this sensor.
+ *
+ * @param[in] sensor a sensor to check a given event type is supporeted.
+ * @param[out] event_type an event type to be checked whether supported or not.
+ * @param[out] supported whether a given event is supported or not in this sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported);
+
+/**
+ * @brief Check a wakeup supported or not by this sensor.
+ *
+ * @param[in] sensor a sensor to check a given event type is supporeted.
+ * @return true on success, otherwise false.
+ */
+bool sensord_is_wakeup_supported(sensor_t sensor);
+
+/**
+ * @brief Connect a given sensor and get a handle of a given sensor.
+ *
+ * @param[in] sensor a sensor to connect
+ * @return a handle of a given sensor on success, otherwise negative value
+ */
+int sensord_connect(sensor_t sensor);
+
+/**
+ * @brief Disconnect a given sensor.
+ *
+ * @param[in] handle a handle to disconnect.
+ * @return true on success, otherwise false.
+ */
+bool sensord_disconnect(int handle);
+
+/**
+ * @brief Register a callback with a connected sensor for a given event_type. This callback will be called when a given event occurs in a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type  to register
+ * @param[in] interval The desired interval between two consecutive events in microseconds. This is only a hint to the system so events may be received faster or slower than the specified interval.
+ *                                  It can be one of SENSOR_INTERVAL_NORMAL,  SENSOR_INTERVAL_FASTEST or the interval in microseconds.
+ * @param[in] max_batch_latency An event in the batch can be delayed by at most max_batch_latency microseconds. If this is set to zero, batch mode is disabled.
+ * @param[in] cb a callback which is called when a given event occurs
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_event(int handle, unsigned int event_type, unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data);
+
+/**
+ * @brief Register a callback with a connected sensor for a given event_type. This callback will be called when a given event occurs in a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type  to register
+ * @param[in] max_batch_latency An event in the batch can be delayed by at most max_batch_latency microseconds. If this is set to zero, batch mode is disabled.
+ * @param[in] cb a callback which is called when a given event occurs
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_events(int handle, unsigned int event_type, unsigned int max_batch_latency, sensor_events_cb_t cb, void *user_data);
+
+/**
+ * @brief Register a callback with a connected context sensor for a given event_type. This callback will be called when a given event occurs in a connected context sensor.
+ *
+ * @param[in] handle a handle represensting a connected context sensor.
+ * @param[in] event_type an event type to register
+ * @param[in] interval The desired interval between two consecutive events in microseconds. This is only a hint to the system so events may be received faster or slower than the specified interval.
+ *                                   It can be one of SENSOR_INTERVAL_NORMAL,  SENSOR_INTERVAL_FASTEST or the interval in microseconds.
+ * @param[in] max_batch_latency An event in the batch can be delayed by at most max_batch_latency microseconds. If this is set to zero, batch mode is disabled.
+ * @param[in] cb a callback which is called when a given event occurs
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_hub_event(int handle, unsigned int event_type, unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data);
+
+/**
+ * @brief Unregister a event with a connected sensor.  After unregistering, that event will not be sent.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type to unregister.
+ * @return true on success, otherwise false.
+ */
+bool sensord_unregister_event(int handle, unsigned int event_type);
+
+/**
+ * @brief Unregister a event with a connected sensor.  After unregistering, that event will not be sent.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type to unregister.
+ * @return true on success, otherwise false.
+ */
+bool sensord_unregister_events(int handle, unsigned int event_type);
+
+/**
+ * @brief Register a callback with a connected sensor. This callback will be called when the accuracy of a sensor has changed.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] cb a callback which is called when he accuracy of a sensor has changed.
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data);
+
+/**
+ * @brief Unregister a callback with a connected sensor.  After unregistering,  sensor_accuray_change_cb will not be called.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_unregister_accuracy_cb(int handle);
+
+/**
+ * @brief Register a callback with a connected sensor. This callback will be called when attributes of a sensor has changed.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] cb a callback which is called when he attributes of a sensor has changed.
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_attribute_int_changed_cb(int handle, sensor_attribute_int_changed_cb_t cb, void *user_data);
+
+/**
+ * @brief Unregister a callback with a connected sensor. After unregistering, sensor_attribute_int_changed_cb will not be called.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_unregister_attribute_int_changed_cb(int handle);
+
+/**
+ * @brief Register a callback with a connected sensor. This callback will be called when attributes of a sensor has changed.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] cb a callback which is called when he attributes of a sensor has changed.
+ * @param[in] user_data the callback is called with user_data
+ * @return true on success, otherwise false.
+ */
+bool sensord_register_attribute_str_changed_cb(int handle, sensor_attribute_str_changed_cb_t cb, void *user_data);
+
+/**
+ * @brief Unregister a callback with a connected sensor. After unregistering, sensor_attribute_str_changed_cb will not be called.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_unregister_attribute_str_changed_cb(int handle);
+
+/**
+ * @brief Start listening events with a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] option either one of SENSOR_OPTION_DEFAULT and  SENSOR_OPTION_ALWAYS_ON.
+ *                                with SENSOR_OPTION_DEFAULT, it stops to listening events when LCD is off or in power save mode.
+ *                                with SENSOR_OPTION_ALWAYS_ON, it continues to listening events even when LCD is off or in power save mode.
+ * @return true on success, otherwise false.
+ */
+bool sensord_start(int handle, int option);
+
+/**
+ * @brief Stop listening events with a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_stop(int handle);
+
+/**
+ * @brief Change the interval of a specifed event type in a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type to change interval.
+ * @param[in] interval The desired interval between two consecutive events in microseconds. This is only a hint to the system so events may be received faster or slower than the specified interval.
+ *                                   It can be one of SENSOR_INTERVAL_NORMAL,  SENSOR_INTERVAL_FASTEST or the interval in microseconds.
+ * @return true on success, otherwise false.
+ */
+bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval);
+
+/**
+ * @brief Change the max batch latency of a specifed event type in a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] event_type an event type to change max batch latency
+ * @param[in] max_batch_latency an event in the batch can be delayed by at most max_batch_latency microseconds. If this is set to zero, batch mode is disabled.
+ * @return true on success, otherwise false.
+ */
+bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency);
+
+/**
+ * @brief Change the option of a connected sensor.
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] option either one of SENSOR_OPTION_DEFAULT and  SENSOR_OPTION_ALWAYS_ON.
+ *                                with SENSOR_OPTION_DEFAULT, it stops to listening events when LCD is off or in power save mode.
+ *                                with SENSOR_OPTION_ALWAYS_ON, it continues to listening events even when LCD is off or in power save mode.
+ * @return true on success, otherwise false.
+ */
+bool sensord_set_option(int handle, int option);
+
+/*
+ * @brief Set the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to change
+ * @param[in] value an attribute value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_set_attribute_int(int handle, int attribute, int value);
+
+/*
+ * @brief Get the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to get value
+ * @param[out] value an attribute value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_get_attribute_int(int handle, int attribute, int* value);
+
+/**
+ * @brief Set the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to change
+ * @param[in] value an attribute value
+ * @param[in] value_len the length of value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_set_attribute_str(int handle, int attribute, const char *value, int len);
+
+/**
+ * @brief Get the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to get value
+ * @param[out] value an attribute value, the caller should explicitly free this value
+ * @param[out] len the length of value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_get_attribute_str(int handle, int attribute, char **value, int *len);
+
+/**
+ * @brief Send data to sensorhub
+ *
+ * @param[in] handle a handle represensting a connected context sensor.
+ * @param[in] data it holds data to send to sensorhub
+ * @param[in] data_len the length of data
+ * @return true on success, otherwise false.
+ */
+bool sensord_send_sensorhub_data(int handle, const char *data, int data_len);
+bool sensord_send_command(int handle, const char *command, int command_len);
+
+/**
+ * @brief get sensor data from a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected context sensor.
+ * @param[in] data_id it specifies data to get
+ * @param[out] sensor_data data from connected sensor
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data);
+
+/**
+ * @brief get sensor data from a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected context sensor.
+ * @param[in] data_id it specifies data to get
+ * @param[out] sensor_data the data list from connected sensor, the caller should explicitly free this list.
+ * @param[out] count the count of data contained in the list.
+ * @return true on success, otherwise false.
+ */
+bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count);
+
+/**
+ * @brief flush sensor data from a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected context sensor.
+ * @return true on success, otherwise false.
+ */
+bool sensord_flush(int handle);
+
+bool sensord_set_passive_mode(int handle, bool passive);
+
+
+/* Sensor Internal API using URI */
+int sensord_get_default_sensor_by_uri(const char *uri, sensor_t *sensor);
+int sensord_get_sensors_by_uri(const char *uri, sensor_t **list, int *sensor_count);
+
+typedef void (*sensord_added_cb)(const char *uri, void *user_data);
+int sensord_add_sensor_added_cb(sensord_added_cb callback, void *user_data);
+int sensord_remove_sensor_added_cb(sensord_added_cb callback);
+
+typedef void (*sensord_removed_cb)(const char *uri, void *user_data);
+int sensord_add_sensor_removed_cb(sensord_removed_cb callback, void *user_data);
+int sensord_remove_sensor_removed_cb(sensord_removed_cb callback);
+
+/* Sensor provider */
+typedef void *sensord_provider_h;
+int sensord_create_provider(const char *uri, sensord_provider_h *provider);
+int sensord_destroy_provider(sensord_provider_h provider);
+int sensord_add_provider(sensord_provider_h provider);
+int sensord_remove_provider(sensord_provider_h provider);
+
+int sensord_provider_set_name(sensord_provider_h provider, const char *name);
+int sensord_provider_set_vendor(sensord_provider_h provider, const char *vendor);
+int sensord_provider_set_range(sensord_provider_h provider, float min_range, float max_range);
+int sensord_provider_set_resolution(sensord_provider_h provider, float resolution);
+
+typedef void (*sensord_provider_start_cb)(sensord_provider_h provider, void *user_data);
+int sensord_provider_set_start_cb(sensord_provider_h provider, sensord_provider_start_cb callback, void *user_data);
+
+typedef void (*sensord_provider_stop_cb)(sensord_provider_h provider, void *user_data);
+int sensord_provider_set_stop_cb(sensord_provider_h provider, sensord_provider_stop_cb callback, void *user_data);
+
+typedef void (*sensord_provider_interval_changed_cb)(sensord_provider_h provider, unsigned int interval_ms, void *user_data);
+int sensord_provider_set_interval_changed_cb(sensord_provider_h provider, sensord_provider_interval_changed_cb callback, void *user_data);
+
+typedef void (*sensord_provider_attribute_str_cb)(sensord_provider_h provider, int attribute, const char *value, int count, void *user_data);
+int sensord_provider_set_attribute_str_cb(sensord_provider_h provider, sensord_provider_attribute_str_cb callback, void *user_data);
+
+int sensord_provider_publish(sensord_provider_h provider, sensor_data_t data);
+int sensord_provider_publish_events(sensord_provider_h provider, sensor_data_t events[], int count);
+
+/* Deprecated */
+typedef void (*sensor_external_command_cb_t)(int handle, const char* data, int data_cnt, void *user_data);
+int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data);
+bool sensord_external_disconnect(int handle);
+bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt);
+
+/**
+  * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENSORD_INTERNAL_H__ */
index e70b435ffc3b3dbd2108510844c1b5e1176907a6..3904e13e692f34b257b26172c471dcb1d7f448f2 100644 (file)
@@ -22,11 +22,58 @@ extern "C"
 {
 #endif
 
-#include <dlog.h>
+#include <dlog/dlog.h>
+#include <sys/types.h>
 
-#undef LOG_TAG
+#ifdef LOG_TAG
+       #undef LOG_TAG
+#endif
 #define LOG_TAG        "TIZEN_SYSTEM_SENSOR"
 
+/* Logging and Error Handling */
+#define _I SLOGI
+#define _D SLOGD
+#define _W SLOGW
+#define _E SLOGE
+#define _SI SECURE_SLOGI
+#define _SD SECURE_SLOGD
+#define _SW SECURE_SLOGW
+#define _SE SECURE_SLOGE
+
+#define _ERRNO(errno, tag, fmt, arg...) \
+       do { \
+               char buf[1024]; \
+               char *error = strerror_r(errno, buf, 1024); \
+               if (!error) { \
+                       _E("Failed to strerror_r()"); \
+                       break; \
+               } \
+               tag(fmt" (%s[%d])", ##arg, error, errno); \
+       } while (0)
+
+#define warn_if(expr, fmt, arg...) \
+       do { if (expr) { _E(fmt, ##arg); } } while (0)
+
+#define ret_if(expr) \
+       do { if (expr) { return; } } while (0)
+
+#define retv_if(expr, val) \
+       do { if (expr) { return (val); } } while (0)
+
+#define retm_if(expr, fmt, arg...) \
+       do { if (expr) { _E(fmt, ##arg); return; } } while (0)
+
+#define retvm_if(expr, val, fmt, arg...) \
+       do { if (expr) { _E(fmt, ##arg); return (val); } } while (0)
+
+#define LOG_DUMP(fp, fmt, arg...) \
+       do { if (fp) fprintf(fp, fmt, ##arg); else _E(fmt, ##arg); } while (0)
+
+#define log_oom() ({ \
+       _E("Out of memory"); \
+       -ENOMEM;})
+
+
 #define _MSG_SENSOR_ERROR_IO_ERROR "Io Error"
 #define _MSG_SENSOR_ERROR_INVALID_PARAMETER "Invalid Parameter"
 #define _MSG_SENSOR_ERROR_OUT_OF_MEMORY "Out of Memory"
@@ -36,13 +83,8 @@ extern "C"
 
 #define _E_MSG(err) SLOGE(_MSG_##err "(0x%08x)", (err))
 
-#define _E(fmt, args...) LOGE(fmt, ##args)
-#define _W(fmt, args...) LOGW(fmt, ##args)
-#define _I(fmt, args...) LOGI(fmt, ##args)
-#define _D(fmt, args...) LOGD(fmt, ##args)
-
 #ifdef __cplusplus
 }
 #endif
 
-#endif /*_SENSOR_LOG_H_*/
+#endif /* _SENSOR_LOG_H_ */
diff --git a/include/sensor_types.h b/include/sensor_types.h
new file mode 100644 (file)
index 0000000..a2028d3
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_TYPES_H__
+#define __SENSOR_TYPES_H__
+
+/* TODO: It is for compatibility with capi-system-sensor */
+#define __SENSOR_COMMON_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <hal/hal-sensor-types.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef OP_SUCCESS
+#define OP_SUCCESS 0
+#endif
+#ifndef OP_ERROR
+#define OP_ERROR   -1
+#endif
+#ifndef OP_DEFAULT
+#define OP_DEFAULT 1
+#endif
+#ifndef OP_CONTINUE
+#define OP_CONTINUE 2
+#endif
+#ifndef NAME_MAX
+#define NAME_MAX 256
+#endif
+
+#define SENSOR_TYPE_SHIFT 32
+#define SENSOR_EVENT_SHIFT 16
+#define SENSOR_INDEX_MASK 0xFFFFFFFF
+
+#define CONVERT_ID_TYPE(id) ((id) >> SENSOR_TYPE_SHIFT)
+#define CONVERT_TYPE_EVENT(type) ((type) << SENSOR_EVENT_SHIFT | 0x1)
+
+#define MICROSECONDS(tv)        ((tv.tv_sec * 1000000ll) + tv.tv_usec)
+
+#define SENSOR_UNKNOWN_TYPE "http://tizen.org/sensor/unknown"
+#define SENSOR_UNKNOWN_NAME "Unknown"
+
+typedef int64_t sensor_id_t;
+typedef void *sensor_t;
+
+typedef enum sensor_type_t {
+       UNKNOWN_SENSOR = -2,
+       ALL_SENSOR = -1,
+       ACCELEROMETER_SENSOR = 0,
+       GRAVITY_SENSOR,
+       LINEAR_ACCEL_SENSOR,
+       GEOMAGNETIC_SENSOR,
+       ROTATION_VECTOR_SENSOR,
+       ORIENTATION_SENSOR,
+       GYROSCOPE_SENSOR,
+       LIGHT_SENSOR,
+       PROXIMITY_SENSOR,
+       PRESSURE_SENSOR,
+       ULTRAVIOLET_SENSOR,
+       TEMPERATURE_SENSOR,
+       HUMIDITY_SENSOR,
+       HRM_SENSOR,
+       BIO_HRM_SENSOR = HRM_SENSOR,
+       HRM_LED_GREEN_SENSOR,
+       BIO_LED_GREEN_SENSOR = HRM_LED_GREEN_SENSOR,
+       HRM_LED_IR_SENSOR,
+       BIO_LED_IR_SENSOR = HRM_LED_IR_SENSOR,
+       HRM_LED_RED_SENSOR,
+       BIO_LED_RED_SENSOR = HRM_LED_RED_SENSOR,
+       GYROSCOPE_UNCAL_SENSOR,
+       GEOMAGNETIC_UNCAL_SENSOR,
+       GYROSCOPE_RV_SENSOR,
+       GEOMAGNETIC_RV_SENSOR,
+
+       GYROSCOPE_ORIENTATION_SENSOR = 100,
+       GEOMAGNETIC_ORIENTATION_SENSOR = 105,
+
+       SIGNIFICANT_MOTION_SENSOR = 0x100, //256
+
+       HRM_BATCH_SENSOR = 0x200, //512
+       HRM_LED_GREEN_BATCH_SENSOR,
+
+       HUMAN_PEDOMETER_SENSOR = 0x300, //768
+       HUMAN_SLEEP_MONITOR_SENSOR,
+       HUMAN_SLEEP_DETECTOR_SENSOR,
+       SLEEP_DETECTOR_SENSOR = HUMAN_SLEEP_DETECTOR_SENSOR,
+       HUMAN_STRESS_MONITOR_SENSOR,
+       STRESS_MONITOR_SENSOR = HUMAN_STRESS_MONITOR_SENSOR,
+
+       LIDAR_SENSOR = 1000,
+
+       EXERCISE_WALKING_SENSOR = 0x400, //1024
+       EXERCISE_RUNNING_SENSOR,
+       EXERCISE_HIKING_SENSOR,
+       EXERCISE_CYCLING_SENSOR,
+       EXERCISE_ELLIPTICAL_SENSOR,
+       EXERCISE_INDOOR_CYCLING_SENSOR,
+       EXERCISE_ROWING_SENSOR,
+       EXERCISE_STEPPER_SENSOR,
+
+       DATA_JOURNAL_SENSOR = 0x500,
+       // 0x500~0x600 Reserved (1280 ~ 1536)
+
+       EXTERNAL_EXERCISE_SENSOR = 0x800, //2048
+       EXERCISE_SENSOR = EXTERNAL_EXERCISE_SENSOR,
+
+       FUSION_SENSOR = 0x900, //2304
+       AUTO_ROTATION_SENSOR,
+       AUTO_BRIGHTNESS_SENSOR,
+       MYOTEST_SENSOR,
+
+       GESTURE_MOVEMENT_SENSOR = 0x1200, //4608
+       GESTURE_WRIST_UP_SENSOR,
+       GESTURE_WRIST_DOWN_SENSOR,
+       GESTURE_MOVEMENT_STATE_SENSOR,
+       GESTURE_PICK_UP_SENSOR,
+       GESTURE_FACE_DOWN_SENSOR,
+
+       ACTIVITY_TRACKER_SENSOR = 0x1A00, //6656
+       ACTIVITY_LEVEL_MONITOR_SENSOR,
+       GPS_BATCH_SENSOR,
+       PPG_BATCH_SENSOR,
+       GPS_TIMESYNC_SENSOR,
+
+       HRM_CTRL_SENSOR = 0x1A80, //6784
+       REG_CTRL_SENSOR,
+       GPS_CTRL_SENSOR,
+
+       WEAR_STATUS_SENSOR = 0x2000, //8192
+       WEAR_ON_MONITOR_SENSOR,
+       NO_MOVE_DETECTOR_SENSOR,
+       RESTING_HR_SENSOR,
+       STEP_LEVEL_MONITOR_SENSOR,
+       EXERCISE_STANDALONE_SENSOR,
+       EXERCISE_COACH_SENSOR = EXERCISE_STANDALONE_SENSOR,
+       EXERCISE_HR_SENSOR,
+       WORKOUT_SENSOR,
+       AUTOSESSION_EXERCISE_SENSOR = WORKOUT_SENSOR,
+       CYCLE_MONITOR_SENSOR,
+       STAIR_TRACKER_SENSOR,
+       PRESSURE_INDICATOR_SENSOR,
+       PRESSURE_ALERT_SENSOR,
+       HR_CALORIE_SENSOR,
+       SWIMMING_TRACKER_SENSOR,
+       STRESS_TRACKER_SENSOR,
+       FAKE_MOTION_SENSOR,
+       GEOFENCE_SENSOR,
+       SWIMMING_OUTDOOR_SENSOR,
+       AUTO_SWIMMING_SENSOR,
+       INACTIVITY_DETECTOR_SENSOR,
+       HRM_BP_SENSOR,
+       ECG_SENSOR,
+       FALL_DETECTION_SENSOR,
+
+       CONTEXT_SENSOR = 0x7000, //28,672
+       MOTION_SENSOR,
+       PIR_SENSOR,
+       PIR_LONG_SENSOR,
+       DUST_SENSOR,
+       THERMOMETER_SENSOR,
+       PEDOMETER_SENSOR,
+       FLAT_SENSOR,
+       HRM_RAW_SENSOR,
+       BIO_SENSOR = HRM_RAW_SENSOR,
+       TILT_SENSOR,
+       RV_RAW_SENSOR,
+       GSR_SENSOR,
+       SIMSENSE_SENSOR,
+       PPG_SENSOR,
+
+       CUSTOM_SENSOR = 0X9000, //36,864
+} sensor_type_t;
+
+typedef struct sensor_info2_t {
+       uint32_t id;
+       sensor_type_t type;
+       const char *uri;
+       const char *vendor;
+       float min_range;
+       float max_range;
+       float resolution;
+       int min_interval;
+       int max_interval;
+       int max_batch_count;
+       bool wakeup_supported;
+       const char *privilege;
+       void *reserved[8];
+} sensor_info2_t;
+
+typedef enum sensor_privilege_t {
+       SENSOR_PRIVILEGE_PUBLIC = 0,
+} sensor_privilege_t;
+
+typedef struct sensor_event_t {
+       unsigned int event_type;
+       sensor_id_t sensor_id;
+       unsigned int data_length;
+       sensor_data_t *data;
+} sensor_event_t;
+
+/*
+ *     To prevent naming confliction as using same enums as sensor CAPI use
+ */
+#ifndef __SENSOR_H__
+enum sensor_option_t {
+       SENSOR_OPTION_DEFAULT = 0,
+       SENSOR_OPTION_ON_IN_SCREEN_OFF = 1,
+       SENSOR_OPTION_ON_IN_POWERSAVE_MODE = 2,
+       SENSOR_OPTION_ALWAYS_ON = SENSOR_OPTION_ON_IN_SCREEN_OFF | SENSOR_OPTION_ON_IN_POWERSAVE_MODE,
+       SENSOR_OPTION_END
+};
+
+typedef enum sensor_option_t sensor_option_e;
+#endif
+
+enum sensord_attribute_e {
+       SENSORD_ATTRIBUTE_AXIS_ORIENTATION = 1,
+       SENSORD_ATTRIBUTE_PAUSE_POLICY,
+       SENSORD_ATTRIBUTE_INTERVAL = 0x10,
+       SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY,
+       SENSORD_ATTRIBUTE_PASSIVE_MODE,
+       SENSORD_ATTRIBUTE_FLUSH,
+       // 0x50~0x80 Reserved
+};
+
+enum sensord_axis_e {
+       SENSORD_AXIS_DEVICE_ORIENTED = 1,
+       SENSORD_AXIS_DISPLAY_ORIENTED,
+};
+
+enum sensord_pause_e {
+       SENSORD_PAUSE_NONE = 0,
+       SENSORD_PAUSE_ON_DISPLAY_OFF = 1,
+       SENSORD_PAUSE_ON_POWERSAVE_MODE = 2,
+       SENSORD_PAUSE_ALL = 3,
+       SENSORD_PAUSE_END,
+};
+
+enum poll_interval_t {
+       POLL_100HZ_MS   = 10,
+       POLL_50HZ_MS    = 20,
+       POLL_25HZ_MS    = 40,
+       POLL_20HZ_MS    = 50,
+       POLL_10HZ_MS    = 100,
+       POLL_5HZ_MS             = 200,
+       POLL_1HZ_MS             = 1000,
+       POLL_MAX_HZ_MS  = 255000,
+};
+
+#define DEFAULT_INTERVAL POLL_10HZ_MS
+
+enum sensor_interval_t {
+       SENSOR_INTERVAL_FASTEST = POLL_100HZ_MS,
+       SENSOR_INTERVAL_NORMAL = POLL_5HZ_MS,
+};
+
+enum proxi_change_state {
+       PROXIMITY_STATE_NEAR = 0,
+       PROXIMITY_STATE_FAR = 1,
+};
+
+enum auto_rotation_state {
+       AUTO_ROTATION_DEGREE_UNKNOWN = 0,
+       AUTO_ROTATION_DEGREE_0,
+       AUTO_ROTATION_DEGREE_90,
+       AUTO_ROTATION_DEGREE_180,
+       AUTO_ROTATION_DEGREE_270,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENSOR_TYPES_H__ */
index 7a737c7b978f8622c2b3a1b75fdf6db9d450472b..dd07e4020f6decd64bc61a03edf80ba23b41275b 100644 (file)
@@ -14,7 +14,9 @@ Source0:    %{name}-%{version}.tar.gz
 
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(sensor)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(libsystemd)
+BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(hal-api-sensor)
 %if "%{?SENSOR_RECORDER}" == "on"
@@ -99,6 +101,7 @@ find . -name '*.gcno' -exec cp --parents '{}' "$gcno_obj_dir" ';'
 %files
 %manifest packaging/capi-system-sensor.manifest
 %{_libdir}/libcapi-system-sensor.so.*
+%{_libdir}/libsensor-shared.so
 %license LICENSE.APLv2
 
 %files devel
diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2e70720
--- /dev/null
@@ -0,0 +1,58 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(capi-system-sensor)
+INCLUDE(GNUInstallDirs)
+
+SET(DEPENDENTS "dlog hal-api-sensor capi-base-common")
+
+IF("${SENSOR_RECORDER}" STREQUAL "on")
+       SET(DEPENDENTS "${DEPENDENTS} context-sensor-recorder-client")
+ENDIF()
+
+SET(VERSION ${FULLVER})
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(PC_NAME ${PROJECT_NAME})
+SET(PC_DESCRIPTION "Sensor C-API library")
+SET(PC_INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/sensor")
+SET(PC_DEPENDENTS "${DEPENDENTS}")
+SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
+SET(PC_LDFLAGS "-l${PROJECT_NAME}")
+
+INCLUDE_DIRECTORIES(
+       ${CMAKE_SOURCE_DIR}/src/shared
+       ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# Build options
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED ${DEPENDENTS})
+
+FOREACH(flag ${${PROJECT_NAME}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -g -fdump-rtl-expand")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fPIC -std=c++0x")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+
+# Internal Logging Option
+#ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+# Compile Source files
+FILE(GLOB SOURCES *.c *.cpp)
+
+IF("${SENSOR_RECORDER}" STREQUAL "on")
+       SET(SOURCES ${SOURCES} sensor_recorder/sensor_recorder.cpp)
+ELSE()
+       SET(SOURCES ${SOURCES} sensor_recorder/sensor_recorder_dummy.cpp)
+ENDIF()
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS} "sensor-shared")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${FULLVER} SOVERSION ${MAJORVER} CLEAN_DIRECT_OUTPUT 1)
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
diff --git a/src/api/capi-system-sensor.pc.in b/src/api/capi-system-sensor.pc.in
new file mode 100644 (file)
index 0000000..c7ebed2
--- /dev/null
@@ -0,0 +1,14 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@PREFIX@/bin
+libdir=@PC_LIBDIR@
+includedir=@PC_INCLUDEDIR@
+
+Name: @PC_NAME@
+Description: @PC_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_DEPENDENTS@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
diff --git a/src/api/fusion_util.c b/src/api/fusion_util.c
new file mode 100644 (file)
index 0000000..b370cc8
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <math.h>
+#include <stdlib.h>
+
+float clamp(float v)
+{
+       return (v < 0) ? 0.0 : v;
+}
+
+int getAngleChange(float *R, float *prevR, float *angleChange)
+{
+       if (R == NULL || prevR == NULL || angleChange == NULL)
+               return -1;
+
+       float rd1, rd4, rd6, rd7, rd8;
+       float ri0, ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
+       float pri0, pri1, pri2, pri3, pri4, pri5, pri6, pri7, pri8;
+
+       ri0 = R[0];
+       ri1 = R[1];
+       ri2 = R[2];
+       ri3 = R[3];
+       ri4 = R[4];
+       ri5 = R[5];
+       ri6 = R[6];
+       ri7 = R[7];
+       ri8 = R[8];
+
+       pri0 = prevR[0];
+       pri1 = prevR[1];
+       pri2 = prevR[2];
+       pri3 = prevR[3];
+       pri4 = prevR[4];
+       pri5 = prevR[5];
+       pri6 = prevR[6];
+       pri7 = prevR[7];
+       pri8 = prevR[8];
+
+       rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7;
+       rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7;
+       rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6;
+       rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7;
+       rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8;
+
+       angleChange[0] = atan2(rd1, rd4);
+       angleChange[1] = asin(-rd7);
+       angleChange[2] = atan2(-rd6, rd8);
+
+       return 0;
+}
+int quatToMatrix(float *quat, float *R)
+{
+       if (quat == NULL || R == NULL)
+               return -1;
+
+       float q0 = quat[0];
+       float q1 = quat[1];
+       float q2 = quat[2];
+       float q3 = quat[3];
+
+       float sq_q1 = 2 * q1 * q1;
+       float sq_q2 = 2 * q2 * q2;
+       float sq_q3 = 2 * q3 * q3;
+       float q1_q2 = 2 * q1 * q2;
+       float q3_q0 = 2 * q3 * q0;
+       float q1_q3 = 2 * q1 * q3;
+       float q2_q0 = 2 * q2 * q0;
+       float q2_q3 = 2 * q2 * q3;
+       float q1_q0 = 2 * q1 * q0;
+
+       R[0] = 1 - sq_q2 - sq_q3;
+       R[1] = q1_q2 - q3_q0;
+       R[2] = q1_q3 + q2_q0;
+       R[3] = q1_q2 + q3_q0;
+       R[4] = 1 - sq_q1 - sq_q3;
+       R[5] = q2_q3 - q1_q0;
+       R[6] = q1_q3 - q2_q0;
+       R[7] = q2_q3 + q1_q0;
+       R[8] = 1 - sq_q1 - sq_q2;
+
+       return 0;
+}
+
+int matrixToQuat(float *mat, float *q)
+{
+       if (q == NULL || mat == NULL)
+               return -1;
+
+       const float Hx = mat[0];
+       const float My = mat[4];
+       const float Az = mat[8];
+       q[0] = sqrtf(clamp(Hx - My - Az + 1) * 0.25f);
+       q[1] = sqrtf(clamp(-Hx + My - Az + 1) * 0.25f);
+       q[2] = sqrtf(clamp(-Hx - My + Az + 1) * 0.25f);
+       q[3] = sqrtf(clamp(Hx + My + Az + 1) * 0.25f);
+       q[0] = copysignf(q[0], mat[7] - mat[5]);
+       q[1] = copysignf(q[1], mat[2] - mat[6]);
+       q[2] = copysignf(q[2], mat[3] - mat[1]);
+
+       return 0;
+}
+
+int getRotationMatrix(float *accel, float *geo, float *R, float *I)
+{
+       if (accel == NULL || geo == NULL || R == NULL || I == NULL)
+               return -1;
+
+       float Ax = accel[0];
+       float Ay = accel[1];
+       float Az = accel[2];
+       float Ex = geo[0];
+       float Ey = geo[1];
+       float Ez = geo[2];
+       float Hx = Ey*Az - Ez*Ay;
+       float Hy = Ez*Ax - Ex*Az;
+       float Hz = Ex*Ay - Ey*Ax;
+       float normH =  (float)sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
+       if (normH < 0.1f)
+               return -1;
+
+       float invH = 1.0f / normH;
+       Hx *= invH;
+       Hy *= invH;
+       Hz *= invH;
+       float invA = 1.0f / (float)sqrt(Ax*Ax + Ay*Ay + Az*Az);
+       Ax *= invA;
+       Ay *= invA;
+       Az *= invA;
+       float Mx = Ay*Hz - Az*Hy;
+       float My = Az*Hx - Ax*Hz;
+       float Mz = Ax*Hy - Ay*Hx;
+
+       R[0] = Hx;  R[1] = Hy;  R[2] = Hz;
+       R[3] = Mx;  R[4] = My;  R[5] = Mz;
+       R[6] = Ax;  R[7] = Ay;  R[8] = Az;
+
+       float invE = 1.0 / (float)sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
+       float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
+       float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
+
+       I[0] = 1;     I[1] = 0;     I[2] = 0;
+       I[3] = 0;     I[4] = c;     I[5] = s;
+       I[6] = 0;     I[7] = -s;    I[8] = c;
+
+       return 0;
+}
+
+
+int remapCoordinateSystem(float *inR, int X, int Y, float *outR)
+{
+       if (inR == NULL || outR == NULL)
+               return -1;
+
+       if ((X & 0x7C) != 0 || (Y & 0x7C) != 0)
+               return -1;   /* invalid parameter */
+       if (((X & 0x3) == 0) || ((Y & 0x3) == 0))
+               return -1;   /* no axis specified */
+       if ((X & 0x3) == (Y & 0x3))
+               return -1;   /* same axis specified */
+
+       int Z = X ^ Y;
+       int x = (X & 0x3)-1;
+       int y = (Y & 0x3)-1;
+       int z = (Z & 0x3)-1;
+
+       int axis_y = (z+1)%3;
+       int axis_z = (z+2)%3;
+       if (((x^axis_y)|(y^axis_z)) != 0)
+               Z ^= 0x80;
+
+       char sx = (X >= 0x80) ? 1 : 0;
+       char sy = (Y >= 0x80) ? 1 : 0;
+       char sz = (Z >= 0x80) ? 1 : 0;
+
+       int i = 0 , j = 0;
+       for (j = 0 ; j < 3 ; j++) {
+               int offset = j * 3;
+               for (i = 0 ; i < 3 ; i++) {
+                       if (x == i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
+                       if (y == i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
+                       if (z == i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
+               }
+       }
+       return 0;
+}
+
diff --git a/src/api/geomagnetic_field.c b/src/api/geomagnetic_field.c
new file mode 100644 (file)
index 0000000..771fbb5
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * This file is part of WMM source code.
+ * The original code is the WMM Source from National Oceanic And Atmospheric.
+ *
+ * See the license below for more details.
+ *
+ * The WMM source code is in the public domain and not licensed or under
+ * copyright. The information and software may be used freely by the public.
+ * As required by 17 U.S.C. 403, third parties producing copyrighted works
+ * consisting predominantly of the material produced by U.S.
+ * government agencies must provide notice with such work  identifying the U.S.
+ * Government material incorporated and stating that such material is not
+ * subject to copyright protection.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+const float c[13][13] = {
+       {0.0, -29496.6, -3594.9, 3350.2, 3992.6, -1818.3, 1051.0, 2158.4, 1226.7, 512.8, -360.9, 1033.3, -1452.4, },
+       {4944.4, -1586.3, 5241.4, -7122.5, 4476.4, 3631.5, 1296.8, -2663.8, 543.0, 1197.6, -1532.7, -699.6, -179.4, },
+       {-4689.9, -498.9, 1445.0, 2385.6, 652.3, 1539.3, 1135.8, -136.1, -813.2, 369.4, 189.6, -859.0, 238.5, },
+       {-490.5, 487.8, -424.2, 501.2, -746.9, -664.0, -1408.7, 927.7, -231.9, -431.5, -181.8, 557.5, 649.2, },
+       {1584.9, -826.5, 343.7, -228.6, 66.1, -361.6, -124.4, 171.7, -516.0, 174.8, -23.4, -119.8, -292.1, },
+       {453.4, 1451.7, -556.3, 0.0, 70.8, -5.5, 30.7, 64.2, 170.6, -417.8, 184.8, 79.2, 300.6, },
+       {-393.2, 659.0, 612.7, -361.8, 7.2, 36.9, -52.3, 4.1, 74.8, -12.2, -12.4, -75.3, -20.8, },
+       {-2053.7, -611.1, 133.1, 307.5, 43.2, -67.1, -2.1, 3.2, -35.3, 63.3, 44.1, 19.8, 58.5, },
+       {737.3, -1121.6, 492.9, -465.2, 247.7, 48.1, -27.1, 1.1, -2.3, -22.0, 25.4, 41.0, -23.4, },
+       {-2611.8, 1249.5, 1062.2, -405.9, -249.3, 139.2, 15.8, -15.8, 4.3, -6.2, -2.7, 0.9, -10.2, },
+       {681.2, -21.1, 776.8, 514.2, -532.2, -41.3, -78.2, -16.4, -5.3, -4.9, -1.7, 1.9, 1.9, },
+       {93.3, 695.4, -196.8, -431.1, 142.6, -37.6, -124.0, -29.6, -18.5, -5.2, -1.0, 2.2, -2.2, },
+       {-807.3, 238.5, 1363.4, -1217.3, 167.0, 125.0, 0.0, 5.9, 7.7, -8.5, -0.6, 0.5, 0.0, }
+};
+
+const float cd[13][13] = {
+       {0.0, 11.6, -18.1, 1.0, -7.9, -7.9, -2.9, 2.7, -5.0, 0.0, 0.0, 0.0, 0.0, },
+       {-25.9, 16.5, -7.6, -12.6, 12.7, 6.1, -3.8, -3.5, 6.7, -12.7, 0.0, 0.0, 0.0, },
+       {-39.0, -10.2, 1.6, -5.6, -34.0, -13.8, -1.5, -17.4, -33.6, 0.0, -21.1, 0.0, 79.5, },
+       {22.4, -7.6, -2.1, -6.1, 9.6, -4.7, 19.9, 26.6, 8.3, 24.9, 33.1, 32.8, 64.9, },
+       {6.1, 10.6, 8.2, -0.6, -1.6, 2.0, -9.3, 4.9, -5.3, -22.6, 0.0, 0.0, -48.7, },
+       {4.1, 13.8, 5.6, 8.9, -0.4, 0.7, -0.7, 1.9, 4.4, -10.1, -7.4, 0.0, 0.0, },
+       {-3.8, -31.4, -4.0, -3.3, 1.2, 0.6, 1.1, -1.7, 2.1, 1.7, -8.3, 0.0, 0.0, },
+       {24.8, 8.7, -2.0, -1.2, -4.9, -0.7, 0.2, 0.4, -1.5, -0.8, 0.0, 0.0, 0.0, },
+       {-6.7, 11.2, 16.6, 10.7, 1.5, -0.7, 1.0, 0.2, 0.1, -1.0, -0.8, 0.0, 0.0, },
+       {0.0, -21.7, 0.0, -5.6, 3.4, 0.0, -1.5, 0.8, 0.1, -0.1, -0.5, 0.0, 0.0, },
+       {24.3, -21.1, 0.0, -11.7, -7.4, 0.0, -2.0, -1.6, 0.0, -0.1, -0.1, -0.3, 0.0, },
+       {0.0, 40.9, 0.0, 24.0, 0.0, 9.4, 0.0, -2.3, -0.9, 0.0, -0.1, 0.0, -0.3, },
+       {0.0, 0.0, 0.0, 0.0, 0.0, 20.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, }
+};
+
+float g_declination = 0;
+float g_inclination = 0;
+
+static void E0000(int IENTRY, int maxdeg, float alt, float glat, float glon, float time, float *dec, float *dip, float *ti, float *gv);
+
+int getDeclination(float *decl)
+{
+       if (decl == NULL)
+               return -1;
+
+       *decl = g_declination;
+
+       return 0;
+}
+
+int getInclination(float *incl)
+{
+       if (incl == NULL)
+               return -1;
+
+       *incl = g_inclination;
+
+       return 0;
+}
+
+int setCoordinate(float latitude, float longitude, float altitude, float *declination, float *inclination, int option)
+{
+       float dec, dip, ti, gv;
+       float h;
+       float rTd = 0.017453292;
+
+       E0000(0, 12, 0.0, 0.0, 0.0, 0.0, NULL, NULL, NULL, NULL);
+       E0000(1, 0, altitude, latitude, longitude, 2, &dec, &dip, &ti, &gv);
+
+       h = ti*(cos((dip*rTd)));
+
+       /* deal with geographic and magnetic poles */
+
+       if (h < 100.0) {    /* at magnetic poles */
+               dec = 0;
+       }
+
+       if (option == 1) {
+               if (declination != NULL)
+                       *declination = dec;
+               if (inclination != NULL)
+                       *inclination = dip;
+       } else if (option == 0) {
+               g_declination = dec;
+               g_inclination = dip;
+       }
+
+       return 0;
+}
+/*************************************************************************/
+
+static void E0000(int IENTRY, int maxdeg, float alt, float glat, float glon, float time, float *dec, float *dip, float *ti, float *gv)
+{
+       static int maxord, n, m, j, D1, D2, D3, D4;
+       static float tc[13][13], dp[13][13], snorm[169],
+                       sp[13], cp[13], fn[13], fm[13], pp[13], k[13][13], pi, dtr, a, b, re,
+                       a2, b2, c2, a4, b4, c4, flnmj, otime, oalt,
+                       olat, olon, dt, rlon, rlat, srlon, srlat, crlon, crlat, srlat2,
+                       crlat2, q, q1, q2, ct, st, r2, r, d, ca, sa, aor, ar, br, bt, bp, bpp,
+                       par, temp1, temp2, parp, bx, by, bz, bh;
+       static float *p = snorm;
+
+       switch (IENTRY) {case 0: goto GEOMAG; case 1: goto GEOMG1; }
+
+GEOMAG:
+       maxord = 12;
+       sp[0] = 0.0;
+       cp[0] = *p = pp[0] = 1.0;
+       dp[0][0] = 0.0;
+       a = 6378.137;
+       b = 6356.7523142;
+       re = 6371.2;
+       a2 = a*a;
+       b2 = b*b;
+       c2 = a2-b2;
+       a4 = a2*a2;
+       b4 = b2*b2;
+       c4 = a4 - b4;
+
+       *snorm = 1.0;
+       fm[0] = 0.0;
+       for (n = 1; n <= maxord; n++) {
+               *(snorm+n) = *(snorm+n-1)*(float)(2*n-1)/(float)n;
+               j = 2;
+               for (m = 0, D1 = 1, D2 = (n-m+D1)/D1; D2 > 0; D2--, m += D1) {
+                       k[m][n] = (float)(((n-1)*(n-1))-(m*m))/(float)((2*n-1)*(2*n-3));
+                       if (m > 0) {
+                               flnmj = (float)((n-m+1)*j)/(float)(n+m);
+                               *(snorm+n+m*13) = *(snorm+n+(m-1)*13)*sqrt(flnmj);
+                               j = 1;
+                       }
+               }
+               fn[n] = (float)(n+1);
+               fm[n] = (float)n;
+       }
+       k[1][1] = 0.0;
+
+       otime = oalt = olat = olon = -1000.0;
+
+       return;
+
+       /*************************************************************************/
+
+GEOMG1:
+
+       dt = time;
+       pi = 3.14159265359;
+       dtr = pi/180.0;
+       rlon = glon*dtr;
+       rlat = glat*dtr;
+       srlon = sin(rlon);
+       srlat = sin(rlat);
+       crlon = cos(rlon);
+       crlat = cos(rlat);
+       srlat2 = srlat*srlat;
+       crlat2 = crlat*crlat;
+       sp[1] = srlon;
+       cp[1] = crlon;
+
+       if (alt != oalt || glat != olat) {
+               q = sqrt(a2-c2*srlat2);
+               q1 = alt*q;
+               q2 = ((q1+a2)/(q1+b2))*((q1+a2)/(q1+b2));
+               ct = srlat/sqrt(q2*crlat2+srlat2);
+               st = sqrt(1.0-(ct*ct));
+               r2 = (alt*alt)+2.0*q1+(a4-c4*srlat2)/(q*q);
+               r = sqrt(r2);
+               d = sqrt(a2*crlat2+b2*srlat2);
+               ca = (alt+d)/r;
+               sa = c2*crlat*srlat/(r*d);
+       }
+       if (glon != olon) {
+               for (m = 2; m <= maxord; m++) {
+                       sp[m] = sp[1]*cp[m-1]+cp[1]*sp[m-1];
+                       cp[m] = cp[1]*cp[m-1]-sp[1]*sp[m-1];
+               }
+       }
+       aor = re/r;
+       ar = aor*aor;
+       br = bt = bp = bpp = 0.0;
+       for (n = 1; n <= maxord; n++) {
+               ar = ar*aor;
+               for (m = 0, D3 = 1, D4 = (n+m+D3)/D3; D4 > 0; D4--, m += D3) {
+                       if (alt != oalt || glat != olat) {
+                               if (n == m && m != 0) {
+                                       *(p+n+m*13) = st**(p+n-1+(m-1)*13);
+                                       dp[m][n] = st*dp[m-1][n-1]+ct**(p+n-1+(m-1)*13);
+                                       goto S50;
+                               }
+                               if (n == 1 && m == 0) {
+                                       *(p+n+m*13) = ct**(p+n-1+m*13);
+                                       dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13);
+                                       goto S50;
+                               }
+                               if (n > 1 && n != m) {
+                                       if (m > n-2) *(p+n-2+m*13) = 0.0;
+                                       if (m > n-2) dp[m][n-2] = 0.0;
+                                       *(p+n+m*13) = ct**(p+n-1+m*13)-k[m][n]**(p+n-2+m*13);
+                                       dp[m][n] = ct*dp[m][n-1] - st**(p+n-1+m*13)-k[m][n]*dp[m][n-2];
+                               }
+                       }
+S50:
+                       if (time != otime) {
+                               tc[m][n] = c[m][n]+dt*cd[m][n];
+                               if (m != 0) tc[n][m-1] = c[n][m-1]+dt*cd[n][m-1];
+                       }
+
+                       par = ar**(p+n+m*13);
+                       if (m == 0) {
+                               temp1 = tc[m][n]*cp[m];
+                               temp2 = tc[m][n]*sp[m];
+                       } else {
+                               temp1 = tc[m][n]*cp[m]+tc[n][m-1]*sp[m];
+                               temp2 = tc[m][n]*sp[m]-tc[n][m-1]*cp[m];
+                       }
+                       bt = bt-ar*temp1*dp[m][n];
+                       bp += (fm[m]*temp2*par);
+                       br += (fn[n]*temp1*par);
+
+                       if (st == 0.0 && m == 1) {
+                               if (n == 1) pp[n] = pp[n-1];
+                               else pp[n] = ct*pp[n-1]-k[m][n]*pp[n-2];
+                               parp = ar*pp[n];
+                               bpp += (fm[m]*temp2*parp);
+                       }
+               }
+       }
+       if (st == 0.0) bp = bpp;
+       else bp /= st;
+
+       bx = -bt*ca-br*sa;
+       by = bp;
+       bz = bt*sa-br*ca;
+       bh = sqrt((bx*bx)+(by*by));
+       *ti = sqrt((bh*bh)+(bz*bz));
+       *dec = atan2(by, bx)/dtr;
+       *dip = atan2(bz, bh)/dtr;
+       *gv = -999.0;
+       if (fabs(glat) >= 55.) {
+               if (glat > 0.0 && glon >= 0.0) *gv = *dec-glon;
+               if (glat > 0.0 && glon < 0.0) *gv = *dec+fabs(glon);
+               if (glat < 0.0 && glon >= 0.0) *gv = *dec+glon;
+               if (glat < 0.0 && glon < 0.0) *gv = *dec-fabs(glon);
+               if (*gv > +180.0) *gv -= 360.0;
+               if (*gv < -180.0) *gv += 360.0;
+       }
+       otime = time;
+       oalt = alt;
+       olat = glat;
+       olon = glon;
+       return;
+}
+
diff --git a/src/api/sensor-internal.cpp b/src/api/sensor-internal.cpp
new file mode 100644 (file)
index 0000000..514b95f
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor-internal.h>
+
+#include <errno.h>
+#include <sensor.h>
+#include <sensor_internal.h>
+
+int sensor_util_set_attribute_int(sensor_type_e type, sensor_attribute_e attr, int value)
+{
+       sensor_t sensor;
+       int ret = 0;
+       int handle = 0;
+       ret = sensord_get_default_sensor((sensor_type_t) type, &sensor);
+       if (ret < 0) {
+               return ret;
+       }
+
+       handle = sensord_connect(sensor);
+       if (handle < 0) {
+               return handle;
+       }
+
+       ret = sensord_set_attribute_int(handle, attr, value);
+       if (ret < 0) {
+               return ret;
+       }
+
+       ret = sensord_disconnect(handle);
+       if (ret < 0) {
+               return ret;
+       }
+
+       return 0;
+}
+
+int sensor_util_get_attribute_int(sensor_type_e type, sensor_attribute_e attr, int *value)
+{
+       if (!value)
+               return -EINVAL;
+
+       sensor_t sensor;
+       int ret = 0;
+       int handle = 0;
+       ret = sensord_get_default_sensor((sensor_type_t) type, &sensor);
+       if (ret < 0) {
+               return ret;
+       }
+
+       handle = sensord_connect(sensor);
+       if (handle < 0) {
+               return handle;
+       }
+
+       ret = sensord_get_attribute_int(handle, attr, value);
+       if (ret < 0) {
+               return ret;
+       }
+
+       ret = sensord_disconnect(handle);
+       if (ret < 0) {
+               return ret;
+       }
+
+       return 0;
+}
diff --git a/src/api/sensor.cpp b/src/api/sensor.cpp
new file mode 100644 (file)
index 0000000..287af04
--- /dev/null
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <limits.h>
+
+#include <sensor_internal.h>
+#include <sensor.h>
+#include <sensor_private.h>
+#include <libgen.h>
+#include <memory>
+#include "include/sensor_log.h"
+
+#define RETURN_VAL_IF(expr, err) \
+       do { \
+               if (expr) { \
+                       _E_MSG(err); \
+                       return (err); \
+               } \
+       } while (0)
+
+#define RETURN_ERROR(err) \
+       do { \
+               _E_MSG(err); \
+               return (err); \
+       } while (0)
+
+#define SENSOR_SHIFT_TYPE 16
+#define SENSOR_UNDEFINED_ID -1
+
+#define SENSOR_LISTENER_MAGIC 0xCAFECAFE
+
+#define CONVERT_AXIS_ENUM(X) ((X) < 3 ? (X) + 0x81 : (X) - 2)
+
+#define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11)
+
+#define WARN_DEPRECATED_SENSOR(X) \
+       do { \
+               if ((X) == SENSOR_LAST || (X) == SENSOR_CUSTOM || (X) == SENSOR_HUMAN_STRESS_MONITOR) { \
+                       _W("DEPRECATION WARNING: This sensor type is deprecated and will be removed from next release."); \
+               } \
+       } while (0)
+
+static int sensor_connect(sensor_h sensor, sensor_listener_h listener)
+{
+       int id = SENSOR_UNDEFINED_ID;
+       int event_type;
+       sensor_type_t type;
+       bool support = false;
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _D("called sensor_connect : listener[%p], sensor[%p]", listener, sensor);
+
+       sensord_get_type(sensor, &type);
+       event_type = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       if (!sensord_is_supported_event_type(sensor, event_type, &support))
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!support)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+
+       id = sensord_connect(sensor);
+
+       if (id < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_connect: id[%d]", id);
+
+       listener->id = id;
+       listener->type = type;
+
+       return id;
+}
+
+static void sensor_callback(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data)
+{
+       sensor_event_s *event;
+       sensor_listener_h listener;
+       listener = (sensor_listener_h)user_data;
+
+       if (!sensor || !listener->callback)
+               return;
+
+       event = (sensor_event_s *)data;
+
+       ((sensor_event_cb) listener->callback)(sensor, event, listener->user_data);
+       return;
+}
+
+static void sensor_events_callback(sensor_t sensor, unsigned int event_type, sensor_data_t datas[], int events_count, void *user_data)
+{
+       sensor_event_s *events;
+       sensor_listener_h listener;
+       listener = (sensor_listener_h)user_data;
+
+       if (!sensor || !listener->callback)
+               return;
+
+       events = (sensor_event_s *)datas;
+
+       ((sensor_events_cb) listener->callback)(sensor, events, events_count, listener->user_data);
+       return;
+}
+
+static inline int sensor_listener_unset_event_cb_impl(sensor_listener_h listener, bool is_events_callback)
+{
+       int id;
+       int type;
+       unsigned int event_id;
+
+       _D("called sensor_listener_unset_event_cb_impl : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       type = (int)listener->type;
+       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       int ret = false;
+       if (is_events_callback) {
+               ret = sensord_unregister_events(id, event_id);
+       } else {
+               ret = sensord_unregister_event(id, event_id);
+       }
+
+       if (!ret)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       listener->callback = NULL;
+       listener->user_data = NULL;
+
+       _D("success sensor_unregister_event");
+
+       return SENSOR_ERROR_NONE;
+}
+
+static inline int sensor_listener_set_event_cb_impl(sensor_listener_h listener,
+               unsigned int interval, void* callback, bool is_events_callback, void *user_data)
+{
+       int id;
+       unsigned int event_id;
+       unsigned int batch_latency;
+
+       if (!listener || !callback)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _D("called sensor_listener_set_event_cb_impl : listener[%p], interval[%u], callback[%p], user_data[%p], id[%d]",
+                       listener, interval, callback, user_data, listener->id);
+
+       id = listener->id;
+       event_id = (listener->type) << SENSOR_SHIFT_TYPE | 0x1;
+       batch_latency = listener->batch_latency;
+
+       listener->callback = (void *)callback;
+       listener->user_data = user_data;
+
+       int ret = false;
+       if (is_events_callback) {
+               ret = sensord_register_events(id, event_id, batch_latency, sensor_events_callback, listener);
+       } else {
+               ret = sensord_register_event(id, event_id, interval, batch_latency, sensor_callback, listener);
+       }
+
+       if (!ret) {
+               listener->callback = NULL;
+               listener->user_data = NULL;
+               return SENSOR_ERROR_OPERATION_FAILED;
+       }
+
+       _D("success sensor_listener_set_event");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_is_supported(sensor_type_e type, bool *supported)
+{
+       int result;
+       sensor_t sensor;
+
+       WARN_DEPRECATED_SENSOR(type);
+
+       if (type < SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!supported)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _D("called sensor_is_supported : type[%d]", type);
+
+        result = sensord_get_default_sensor((sensor_type_t)type, &sensor);
+
+       if (result == -EPERM)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *supported = false;
+
+       /*
+        * because is_supported() API is N/P API,
+        * it must not returns PERMISSION_DENIED error.
+        * -EACCES means that there is at least one sensor.
+        */
+       if (sensor || (result == -EACCES))
+               *supported = true;
+
+       _D("success sensor(%d) is supported[%d]", type, *supported);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_is_supported_by_uri(const char *uri, bool *supported)
+{
+       int result;
+       sensor_t sensor;
+
+       if (!supported)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       result = sensord_get_default_sensor_by_uri(uri, &sensor);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result == -EPERM || result == -EIO)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       if (result == -ENODATA)
+               *supported = false;
+       else
+               *supported = true;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_default_sensor(sensor_type_e type, sensor_h *sensor)
+{
+       int result;
+       sensor_t _sensor;
+       sensor_privilege_t privilege;
+
+       WARN_DEPRECATED_SENSOR(type);
+
+       _D("called sensor_get_default_sensor : type[%d], sensor[%p]", type, sensor);
+
+       if (type < SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensor)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       result = sensord_get_default_sensor((sensor_type_t)type, &_sensor);
+       if (result == -EACCES)
+               return SENSOR_ERROR_PERMISSION_DENIED;
+       else if (result == -EPERM)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       if (!_sensor)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+
+       sensord_get_privilege(_sensor, &privilege);
+       if (privilege != SENSOR_PRIVILEGE_PUBLIC)
+               return SENSOR_ERROR_PERMISSION_DENIED;
+
+       *sensor = _sensor;
+
+       _D("success sensor_get_default_sensor sensor[%p]", _sensor);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_default_sensor_by_uri(const char *uri, sensor_h *sensor)
+{
+       int result;
+
+       result = sensord_get_default_sensor_by_uri(uri, sensor);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result == -EACCES)
+               return SENSOR_ERROR_PERMISSION_DENIED;
+       else if (result == -ENODATA)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_sensor_list(sensor_type_e type, sensor_h **list, int *sensor_count)
+{
+       int result;
+       sensor_h *_list;
+       int count;
+
+       WARN_DEPRECATED_SENSOR(type);
+
+       _D("called sensor_get_list : type[%d]", type);
+
+       if (type < SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensor_count || !list)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       result = sensord_get_sensors((sensor_type_t)type, &_list, &count);
+
+       if (result == -EACCES)
+               return SENSOR_ERROR_PERMISSION_DENIED;
+       else if (result == -EPERM)
+               return SENSOR_ERROR_OPERATION_FAILED;
+       else if (result == -ENODATA)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+
+       int i, j;
+       int count_public = 0;
+
+       for (i = 0; i < count; ++i) {
+               sensor_privilege_t privilege;
+
+               sensord_get_privilege(_list[i], &privilege);
+               if (privilege != SENSOR_PRIVILEGE_PUBLIC)
+                       continue;
+
+               count_public++;
+       }
+
+       if (count_public == 0) {
+               free(_list);
+               return SENSOR_ERROR_PERMISSION_DENIED;
+       }
+
+       *list = (sensor_h *) malloc((sizeof(int *)) * count_public);
+
+       if (!*list) {
+               free(_list);
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (i = 0, j = 0; i < count; ++i) {
+               sensor_privilege_t privilege;
+
+               sensord_get_privilege(_list[i], &privilege);
+               if (privilege != SENSOR_PRIVILEGE_PUBLIC)
+                       continue;
+
+               *(*list + j) = _list[i];
+               j++;
+       }
+
+       free(_list);
+
+       *sensor_count = count_public;
+
+       _D("success sensor_get_list");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_sensor_list_by_uri(const char *uri, sensor_h **list, int *sensor_count)
+{
+       int result;
+       result = sensord_get_sensors_by_uri(uri, list, sensor_count);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result == -EACCES)
+               return SENSOR_ERROR_PERMISSION_DENIED;
+       else if (result == -ENODATA)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_is_wake_up(sensor_h sensor, bool *wakeup)
+{
+       _D("called sensor_get_type");
+
+       if (!sensor || !wakeup)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *wakeup = sensord_is_wakeup_supported(sensor);
+
+       _D("success sensor_is_wake_up : [%d]", *wakeup);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_create_listener(sensor_h sensor, sensor_listener_h *listener)
+{
+       struct sensor_listener_s *_listener;
+       int error;
+
+       _D("called sensor_create_listener : listener[%p]", listener);
+
+       if (!sensor || !listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _listener = new(std::nothrow) struct sensor_listener_s;
+
+       if (!_listener)
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+
+       error = sensor_connect(sensor, _listener);
+
+       if (error < 0) {
+               delete (struct sensor_listener_s *)_listener;
+               return SENSOR_ERROR_OPERATION_FAILED;
+       }
+
+       _listener->sensor = sensor;
+       _listener->pause = SENSOR_PAUSE_ALL;
+       _listener->batch_latency = SENSOR_BATCH_LATENCY_DEFAULT;
+       _listener->magic = SENSOR_LISTENER_MAGIC;
+
+       *listener = (sensor_listener_h) _listener;
+
+       _D("success sensor_create_listener");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_destroy_listener(sensor_listener_h listener)
+{
+       _D("called sensor_destroy : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       sensord_disconnect(listener->id);
+       listener->magic = 0;
+
+       delete (sensor_listener_s *)listener;
+
+       _D("success sensor_destroy");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_start(sensor_listener_h listener)
+{
+       int id;
+       unsigned int pause = SENSOR_PAUSE_ALL;
+
+       _D("called sensor_listener_start : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       pause = listener->pause;
+
+       if (!sensord_start(id, 0))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       if (sensord_set_attribute_int(id, SENSOR_ATTRIBUTE_PAUSE_POLICY, pause) < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_listener_start : id[%d]", id);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_stop(sensor_listener_h listener)
+{
+       int id;
+
+       _D("called sensor_listener_stop : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+
+       if (!sensord_stop(id))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_listener_stop");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_set_event_cb(sensor_listener_h listener,
+               unsigned int interval, sensor_event_cb callback, void *user_data)
+{
+       _W("DEPRECATION WARNING: sensor_listener_set_event_cb() is deprecated and will be removed from next release. Use sensor_listener_set_events_cb() instead.");
+       _D("called sensor_listener_set_event_cb : listener[%p]", listener);
+       return sensor_listener_set_event_cb_impl(listener, interval, (void*) callback, false, user_data);
+}
+
+int sensor_listener_unset_event_cb(sensor_listener_h listener)
+{
+       _W("DEPRECATION WARNING: sensor_listener_unset_event_cb() is deprecated and will be removed from next release. Use sensor_listener_unset_events_cb() instead.");
+       _D("called sensor_listener_unset_event_cb : listener[%p]", listener);
+       return sensor_listener_unset_event_cb_impl(listener, false);
+}
+
+int sensor_listener_set_events_cb(sensor_listener_h listener, sensor_events_cb callback, void *user_data)
+{
+       _D("called sensor_listener_set_events_cb : listener[%p]", listener);
+       return sensor_listener_set_event_cb_impl(listener, 0, (void*) callback, true, user_data);
+}
+
+int sensor_listener_unset_events_cb(sensor_listener_h listener)
+{
+       _D("called sensor_listener_unset_events_cb : listener[%p]", listener);
+       return sensor_listener_unset_event_cb_impl(listener, true);
+}
+
+static void accuracy_changed_callback(sensor_t sensor,
+               unsigned long long timestamp, int accuracy, void *data)
+{
+       sensor_listener_h listener = (sensor_listener_h)data;
+
+       if (!sensor || !listener->accu_callback)
+               return;
+
+       ((sensor_accuracy_changed_cb)listener->accu_callback)
+                       (sensor, timestamp, (sensor_data_accuracy_e)accuracy, listener->accu_user_data);
+
+       return;
+}
+
+int sensor_listener_set_accuracy_cb(sensor_listener_h listener,
+               sensor_accuracy_changed_cb callback, void *data)
+{
+       int id;
+
+       _D("called sensor_register_accuracy_cb : listener[%p], callback[%p], user_data[%p] cb[%p]",
+                       listener, callback, data, accuracy_changed_callback);
+
+       if (!listener || !callback)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       listener->accu_callback = (void *)callback;
+       listener->accu_user_data = data;
+
+       if (!sensord_register_accuracy_cb(id, accuracy_changed_callback, listener)) {
+               listener->accu_callback = NULL;
+               listener->accu_user_data = NULL;
+
+               return SENSOR_ERROR_OPERATION_FAILED;
+       }
+
+       _D("success sensor_register_accuracy_cb");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_unset_accuracy_cb(sensor_listener_h listener)
+{
+       int id;
+
+       _D("called sensor_unregister_accuracy_cb : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+
+       if (!sensord_unregister_accuracy_cb(id))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       listener->accu_callback = NULL;
+       listener->accu_user_data = NULL;
+
+       _D("success sensor_unregister_accuracy_cb");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_set_interval(sensor_listener_h listener, unsigned int interval)
+{
+       int id;
+       int type;
+       unsigned int event_id;
+
+       _D("called sensor_set_interval : listener[%p], interval[%u]", listener, interval);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       type = (int)listener->type;
+       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       if (!sensord_change_event_interval(id, event_id, interval))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_set_interval");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_set_max_batch_latency(sensor_listener_h listener, unsigned int max_batch_latency)
+{
+       int id;
+       int type;
+       int max_batch_count;
+       unsigned int event_id;
+
+       _D("called sensor_set_max_batch_latency : listener[%p], max_batch_latency[%u]", listener, max_batch_latency);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_max_batch_count(listener->sensor, &max_batch_count))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       if (max_batch_count == 0)
+               return SENSOR_ERROR_NOT_SUPPORTED;
+
+       id = listener->id;
+       type = (int)listener->type;
+       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       if (!sensord_change_event_max_batch_latency(id, event_id, max_batch_latency))
+               return SENSOR_ERROR_NOT_SUPPORTED;
+
+       listener->batch_latency = max_batch_latency;
+
+       _D("success sensor_set_max_batch_latency");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_set_attribute_int(sensor_listener_h listener, sensor_attribute_e attribute, int value)
+{
+       int id;
+       int error;
+
+       _D("called sensor_set_attribute_int : listener[%p], attribute[%d], value[%d]", listener, attribute, value);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+
+       error = sensord_set_attribute_int(id, (int)attribute, (int)value);
+
+       if (error == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (error != SENSOR_ERROR_NONE)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       if (attribute == SENSOR_ATTRIBUTE_PAUSE_POLICY)
+               listener->pause = value;
+
+       _D("success sensor_set_attribute_int");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_set_option(sensor_listener_h listener, sensor_option_e option)
+{
+       int id;
+
+       _D("called sensor_set_option : listener[%p], option[%d]", listener, option);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+
+       if (sensord_set_attribute_int(id, SENSOR_ATTRIBUTE_PAUSE_POLICY, CONVERT_OPTION_PAUSE_POLICY(option)) < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       listener->pause = CONVERT_OPTION_PAUSE_POLICY(option);
+
+       _D("success sensor_set_option");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_read_data(sensor_listener_h listener, sensor_event_s *event)
+{
+       int id;
+       int type;
+       sensor_data_t data;
+       unsigned int data_id;
+
+       _W("DEPRECATION WARNING: sensor_listener_read_data() is deprecated and will be removed from next release. Use sensor_listener_read_data_list() instead.");
+       _D("called sensor_read_data : listener[%p]", listener);
+
+       if (!listener || !event)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       type = (int)listener->type;
+       data_id = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       if (!sensord_get_data(id, data_id, &data))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       event->accuracy = data.accuracy;
+       event->timestamp = data.timestamp;
+       event->value_count = data.value_count;
+
+       for (int i = 0; i < data.value_count; ++i)
+               event->values[i] = data.values[i];
+
+       _D("success sensor_read_data");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_read_data_list(sensor_listener_h listener, sensor_event_s **events, int *count)
+{
+       int id;
+       int type;
+       sensor_data_t* data_list = NULL;
+       int data_list_count = 0;
+       unsigned int data_id;
+
+       _D("called sensor_get_data_list : listener[%p]", listener);
+
+       if (!listener || !events || !count)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+       type = (int)listener->type;
+       data_id = type << SENSOR_SHIFT_TYPE | 0x1;
+
+       if (!sensord_get_data_list(id, data_id, &data_list, &data_list_count))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *events = (sensor_event_s *)data_list;
+       *count = data_list_count;
+
+       _D("success sensor_get_data_list");
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_listener_flush(sensor_listener_h listener)
+{
+       int id;
+
+       _D("called sensor_flush : listener[%p]", listener);
+
+       if (!listener)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (listener->magic != SENSOR_LISTENER_MAGIC)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       id = listener->id;
+
+       if (!sensord_flush(id))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_flush");
+
+       return SENSOR_ERROR_NONE;;
+}
+
+int sensor_get_uri(sensor_h sensor, char **uri)
+{
+       const char *ret_url;
+
+       if (!sensor || !uri)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if ((ret_url = sensord_get_uri(sensor)) == NULL)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *uri = strdup(ret_url);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_name(sensor_h sensor, char** name)
+{
+       _D("called sensor_get_name");
+
+       const char *ret_name;
+
+       if (!sensor || !name)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if ((ret_name = sensord_get_name(sensor)) == NULL)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *name = strdup(ret_name);
+
+       _D("success sensor_get_vendor : [%s]", *name);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_vendor(sensor_h sensor, char** vendor)
+{
+       _D("called sensor_get_vendor");
+
+       const char *ret_vendor;
+
+       if (!sensor || !vendor)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if  ((ret_vendor = sensord_get_vendor(sensor)) == NULL)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *vendor = strdup(ret_vendor);
+
+       _D("success sensor_vendor : [%s]", *vendor);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_type(sensor_h sensor, sensor_type_e *type)
+{
+       sensor_type_t _type;
+       //_D("called sensor_get_type");
+
+       if (!sensor || !type)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_type(sensor, &_type))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       *type = (sensor_type_e) _type;
+
+       //_D("success sensor_get_type : [%d]", *type);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_min_range(sensor_h sensor, float *min_range)
+{
+       _D("called sensor_get_min_range");
+
+       if (!sensor || !min_range)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_min_range(sensor, min_range))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_min_range : [%f]", *min_range);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_max_range(sensor_h sensor, float *max_range)
+{
+       _D("called sensor_get_max_range");
+
+       if (!sensor || !max_range)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_max_range(sensor, max_range))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_max_range : [%f]", *max_range);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_resolution(sensor_h sensor, float *resolution)
+{
+       _D("called sensor_get_resolution");
+
+       if (!sensor || !resolution)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_resolution(sensor, resolution))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_resolution : [%f]", *resolution);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_min_interval(sensor_h sensor, int *min_interval)
+{
+       _D("called sensor_get_min_interval");
+
+       if (!sensor || !min_interval)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_min_interval(sensor, min_interval))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_min_interval : [%d]", *min_interval);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_fifo_count(sensor_h sensor, int *fifo_count)
+{
+       _D("called sensor_get_fifo_count");
+
+       if (!sensor || !fifo_count)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_fifo_count(sensor, fifo_count))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_fifo_count : [%d]", *fifo_count);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_get_max_batch_count(sensor_h sensor, int *max_batch_count)
+{
+       _D("called sensor_get_max_batch_count");
+
+       if (!sensor || !max_batch_count)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       if (!sensord_get_max_batch_count(sensor, max_batch_count))
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       _D("success sensor_get_max_batch_count : [%d]", *max_batch_count);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_add_sensor_added_cb(sensor_added_cb callback, void *user_data)
+{
+       int result;
+       result = sensord_add_sensor_added_cb(callback, user_data);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_remove_sensor_added_cb(sensor_added_cb callback)
+{
+       int result;
+       result = sensord_remove_sensor_added_cb(callback);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_add_sensor_removed_cb(sensor_removed_cb callback, void *user_data)
+{
+       int result;
+       result = sensord_add_sensor_removed_cb(callback, user_data);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_remove_sensor_removed_cb(sensor_removed_cb callback)
+{
+       int result;
+       result = sensord_remove_sensor_removed_cb(callback);
+       if (result == -EINVAL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       else if (result < 0)
+               return SENSOR_ERROR_OPERATION_FAILED;
+
+       return SENSOR_ERROR_NONE;
+}
+
+/*
+ *     FUNCTIONS : SENSOR_UTIL_*
+ */
+
+int sensor_util_get_declination(float latitude, float longitude, float altitude, float *declination)
+{
+       if (!declination)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       setCoordinate(latitude, longitude, altitude, declination, NULL, 1);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_angle_change(float R[], float prevR[], float angleChange[])
+{
+       if (getAngleChange(R, prevR, angleChange) < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_orientation(float R[], float values[])
+{
+       if (!R || !values)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       values[0] = (float) atan2(R[1], R[4]);
+       values[1] = (float) asin(-R[7]);
+       values[2] = (float) atan2(-R[6], R[8]);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_inclination(float I[], float* inclination)
+{
+       if (!I || !inclination)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *inclination = atan2(I[5], I[4]);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_remap_coordinate_system(float inR[], sensor_util_axis_e x, sensor_util_axis_e y, float outR[])
+{
+       if (remapCoordinateSystem(inR, CONVERT_AXIS_ENUM(x), CONVERT_AXIS_ENUM(y), outR) < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_rotation_matrix_from_vector(float Vx, float Vy, float Vz, float R[])
+{
+       float RV[4] = {0, Vx, Vy, Vz};
+
+       RV[0] = 1 - Vx * Vx - Vy * Vy - Vz * Vz;
+       RV[0] = (Vx > 0) ? (float) (sqrt(Vx)) : 0;
+
+       if (quatToMatrix(RV, R) < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_rotation_matrix(float Gx, float Gy, float Gz, float Mx, float My, float Mz, float R[], float I[])
+{
+       float G[3] = {Gx, Gy, Gz};
+       float M[3] = {Mx, My, Mz};
+
+       if (getRotationMatrix(G, M, R, I) < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_util_get_altitude(float pressure, float sea_level_pressure, float temperature, float* altitude)
+{
+       if (pressure <= 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (sea_level_pressure <= 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!altitude)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *altitude = (temperature + 273.15f) / 0.0065f * (1.0f - pow(pressure/sea_level_pressure, 1.0f/5.255f));
+
+       return SENSOR_ERROR_NONE;
+}
diff --git a/src/api/sensor_internal.cpp b/src/api/sensor_internal.cpp
new file mode 100644 (file)
index 0000000..2c9b833
--- /dev/null
@@ -0,0 +1,1197 @@
+/*
+ * 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 <sensor_internal.h>
+#include <sensor_types.h>
+#include <sensor_types_private.h>
+#include <sensor_utils.h>
+
+#include <channel_handler.h>
+#include <sensor_manager.h>
+#include <sensor_listener.h>
+#include <sensor_provider_internal.h>
+#include <sensor_log.h>
+#include <unordered_map>
+#include <regex>
+#include <thread>
+#include <cmutex.h>
+#include <command_types.h>
+
+#include "sensor_reader.h"
+
+#define CONVERT_OPTION_TO_PAUSE_POLICY(option) ((option) ^ 0b11)
+#define MAX_LISTENER 100
+#define MAX_PROVIDER 20
+
+using namespace sensor;
+
+typedef struct {
+       int listener_id;
+       sensor_info *sensor;
+       void* cb;
+       char* data;
+       size_t data_size;
+       void *user_data;
+} callback_info_s;
+
+typedef GSourceFunc callback_dispatcher_t;
+
+static sensor::sensor_manager manager;
+static std::unordered_map<int, sensor::sensor_listener *> listeners;
+static cmutex lock;
+static uint providerCnt = 0;
+
+static gboolean sensor_events_callback_dispatcher(gpointer data)
+{
+       int event_type = 0;
+       callback_info_s *info = (callback_info_s *)data;
+
+       AUTOLOCK(lock);
+
+       if (info->sensor)
+               event_type = CONVERT_TYPE_EVENT(info->sensor->get_type());
+
+       if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
+               size_t element_size =  sizeof(sensor_data_t);
+               size_t count = info->data_size / element_size;
+               ((sensor_events_cb_t)info->cb)(info->sensor, event_type, (sensor_data_t*)info->data, count, info->user_data);
+       }
+
+       delete [] info->data;
+       delete info;
+       return FALSE;
+}
+
+static gboolean sensor_event_callback_dispatcher(gpointer data)
+{
+       int event_type = 0;
+       callback_info_s *info = (callback_info_s *)data;
+
+       AUTOLOCK(lock);
+
+       if (info->sensor)
+               event_type = CONVERT_TYPE_EVENT(info->sensor->get_type());
+
+       if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
+               ((sensor_cb_t)info->cb)(info->sensor, event_type, (sensor_data_t*)info->data, info->user_data);
+       }
+
+       delete [] info->data;
+       delete info;
+       return FALSE;
+}
+
+static gboolean sensor_accuracy_changed_callback_dispatcher(gpointer data)
+{
+       callback_info_s *info = (callback_info_s *)data;
+
+       AUTOLOCK(lock);
+
+       if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
+               sensor_data_t * sensor_data = (sensor_data_t *)info->data;
+               ((sensor_accuracy_changed_cb_t)info->cb)(info->sensor, sensor_data->timestamp, sensor_data->accuracy, info->user_data);
+       }
+
+       delete [] info->data;
+       delete info;
+       return FALSE;
+}
+
+static gboolean sensor_attribute_int_changed_callback_dispatcher(gpointer data)
+{
+       callback_info_s *info = (callback_info_s *)data;
+
+       AUTOLOCK(lock);
+
+       if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
+               cmd_listener_attr_int_t *d = (cmd_listener_attr_int_t *)info->data;
+               ((sensor_attribute_int_changed_cb_t)info->cb)(info->sensor, d->attribute, d->value, info->user_data);
+       }
+
+       delete [] info->data;
+       delete info;
+       return FALSE;
+}
+
+static gboolean sensor_attribute_str_changed_callback_dispatcher(gpointer data)
+{
+       callback_info_s *info = (callback_info_s *)data;
+
+       AUTOLOCK(lock);
+
+       if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
+               cmd_listener_attr_str_t *d = (cmd_listener_attr_str_t *)info->data;
+               ((sensor_attribute_str_changed_cb_t)info->cb)(info->sensor, d->attribute, d->value, d->len, info->user_data);
+       }
+
+       delete [] info->data;
+       delete info;
+       return FALSE;
+}
+
+class sensor_listener_channel_handler : public ipc::channel_handler
+{
+public:
+       sensor_listener_channel_handler(int id, sensor_t sensor, void* cb, void *user_data, callback_dispatcher_t dispatcher)
+       : m_listener_id(id)
+       , m_sensor(reinterpret_cast<sensor_info *>(sensor))
+       , m_cb(cb)
+       , m_user_data(user_data)
+       , m_dispatcher(dispatcher)
+       {}
+
+       void connected(ipc::channel *ch) {}
+       void disconnected(ipc::channel *ch) {}
+       void read(ipc::channel *ch, ipc::message &msg)
+       {
+               callback_info_s *info;
+               auto size = msg.size();
+               char *data = new(std::nothrow) char[size];
+               if (data == NULL)
+                       return;
+               memcpy(data, msg.body(), size);
+
+               info = new(std::nothrow) callback_info_s();
+               info->listener_id = m_listener_id;
+               info->cb = m_cb;
+               info->sensor = m_sensor;
+               info->data = data;
+               info->data_size = size;
+               info->user_data = m_user_data;
+
+               g_idle_add(m_dispatcher, info);
+       }
+
+       void read_complete(ipc::channel *ch) {}
+       void error_caught(ipc::channel *ch, int error) {}
+       void set_handler(int num, ipc::channel_handler* handler) {}
+       void disconnect(void) {}
+
+private:
+       int m_listener_id;
+       sensor_info *m_sensor;
+       void* m_cb;
+       void *m_user_data;
+       callback_dispatcher_t m_dispatcher;
+};
+
+/*
+ * TO-DO-LIST:
+ * 1. power save option / lcd vconf : move to server
+ * 2. thread-safe : ipc_client
+ */
+
+API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
+{
+       return sensord_get_sensors_by_uri(utils::get_uri(type), list, count);
+}
+
+API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
+{
+       return sensord_get_default_sensor_by_uri(utils::get_uri(type), sensor);
+}
+
+API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
+{
+       retvm_if(!type, false, "Invalid type");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *type = static_cast<sensor_info *>(sensor)->get_type();
+
+       return true;
+}
+
+API const char* sensord_get_uri(sensor_t sensor)
+{
+       retvm_if(!manager.connect(), NULL, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), NULL,
+                       "Invalid sensor[%p]", sensor);
+
+       return static_cast<sensor_info *>(sensor)->get_uri().c_str();
+}
+
+API const char* sensord_get_name(sensor_t sensor)
+{
+       retvm_if(!manager.connect(), NULL, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), NULL,
+                       "Invalid sensor[%p]", sensor);
+
+       return static_cast<sensor_info *>(sensor)->get_model().c_str();
+}
+
+API const char* sensord_get_vendor(sensor_t sensor)
+{
+       retvm_if(!manager.connect(), NULL, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), NULL,
+                       "Invalid sensor[%p]", sensor);
+
+       return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
+}
+
+API bool sensord_get_min_range(sensor_t sensor, float *min_range)
+{
+       retvm_if(!min_range, false, "Invalid paramter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
+
+       return true;
+}
+
+API bool sensord_get_max_range(sensor_t sensor, float *max_range)
+{
+       retvm_if(!max_range, false, "Invalid parameter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
+
+       return true;
+}
+
+API bool sensord_get_resolution(sensor_t sensor, float *resolution)
+{
+       retvm_if(!resolution, false, "Invalid parameter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
+
+       return true;
+}
+
+API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
+{
+       retvm_if(!min_interval, false, "Invalid parameter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
+
+       return true;
+}
+
+API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
+{
+       retvm_if(!fifo_count, false, "Invalid parameter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *fifo_count = 0;
+
+       return true;
+}
+
+API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
+{
+       retvm_if(!max_batch_count, false, "Invalid parameter");
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
+
+       return true;
+}
+
+API bool sensord_is_wakeup_supported(sensor_t sensor)
+{
+       retvm_if(!manager.connect(), false, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), false,
+                       "Invalid sensor[%p]", sensor);
+
+       return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
+}
+
+API int sensord_connect(sensor_t sensor)
+{
+       AUTOLOCK(lock);
+
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+       retvm_if(!manager.is_supported(sensor), -EINVAL,
+                       "Invalid sensor[%p]", sensor);
+       retvm_if(listeners.size() > MAX_LISTENER, -EPERM, "Exceeded the maximum listener");
+
+       sensor::sensor_listener *listener;
+       static sensor_reader reader;
+
+       listener = new(std::nothrow) sensor::sensor_listener(sensor, reader.get_event_loop());
+       retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
+
+       listeners[listener->get_id()] = listener;
+
+       _D("Connect[%d]", listener->get_id());
+
+       return listener->get_id();
+}
+
+API bool sensord_disconnect(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+       retvm_if(!listener, false, "Invalid handle[%d]", handle);
+
+       _D("Disconnect[%d]", listener->get_id());
+
+       delete listener;
+       listeners.erase(handle);
+
+       if (listeners.empty())
+               manager.disconnect();
+
+       return true;
+}
+
+static inline bool sensord_register_event_impl(int handle, unsigned int event_type,
+               unsigned int interval, unsigned int max_batch_latency, void* cb, bool is_events_callback, void *user_data)
+{
+       sensor::sensor_listener *listener;
+       int prev_interval;
+       int prev_max_batch_latency;
+       sensor_listener_channel_handler *handler;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       prev_interval = listener->get_interval();
+       prev_max_batch_latency = listener->get_max_batch_latency();
+
+       if (listener->set_interval(interval) < 0) {
+               _E("Failed to set interval");
+               return false;
+       }
+
+       if (listener->set_max_batch_latency(max_batch_latency) < 0) {
+               listener->set_interval(prev_interval);
+               _E("Failed to set max_batch_latency");
+               return false;
+       }
+
+       if (is_events_callback) {
+               handler = new(std::nothrow)sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_events_callback_dispatcher);
+       } else {
+               handler = new(std::nothrow)sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_event_callback_dispatcher);
+       }
+
+       if (!handler) {
+               listener->set_max_batch_latency(prev_max_batch_latency);
+               listener->set_interval(prev_interval);
+               _E("Failed to allocate memory");
+               return false;
+       }
+
+       listener->set_event_handler(handler);
+
+       _D("Register event[%d]", listener->get_id());
+
+       return true;
+}
+
+API bool sensord_register_event(int handle, unsigned int event_type,
+               unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
+{
+       return sensord_register_event_impl(handle, event_type, interval, max_batch_latency, (void*)cb, false, user_data);
+}
+
+static inline bool sensord_unregister_event_imple(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       listener->unset_event_handler();
+
+       _D("Unregister event[%d]", listener->get_id());
+
+       return true;
+}
+
+API bool sensord_unregister_event(int handle, unsigned int event_type)
+{
+       return sensord_unregister_event_imple(handle);
+}
+
+API bool sensord_register_events(int handle, unsigned int event_type, unsigned int max_batch_latency, sensor_events_cb_t cb, void *user_data)
+{
+       return sensord_register_event_impl(handle, event_type, 0, max_batch_latency, (void*)cb, true, user_data);
+}
+
+API bool sensord_unregister_events(int handle, unsigned int event_type)
+{
+       return sensord_unregister_event_imple(handle);
+}
+
+API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
+{
+       sensor::sensor_listener *listener;
+       sensor_listener_channel_handler *handler;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_accuracy_changed_callback_dispatcher);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       listener->set_accuracy_handler(handler);
+
+       return true;
+}
+
+API bool sensord_unregister_accuracy_cb(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       listener->unset_accuracy_handler();
+
+       return true;
+}
+
+API bool sensord_register_attribute_int_changed_cb(int handle, sensor_attribute_int_changed_cb_t cb, void *user_data)
+{
+       sensor::sensor_listener *listener;
+       sensor_listener_channel_handler *handler;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_attribute_int_changed_callback_dispatcher);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       listener->set_attribute_int_changed_handler(handler);
+
+       return true;
+}
+
+API bool sensord_unregister_attribute_int_changed_cb(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       listener->unset_attribute_int_changed_handler();
+
+       return true;
+}
+
+API bool sensord_register_attribute_str_changed_cb(int handle, sensor_attribute_str_changed_cb_t cb, void *user_data)
+{
+       sensor::sensor_listener *listener;
+       sensor_listener_channel_handler *handler;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_attribute_str_changed_callback_dispatcher);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       listener->set_attribute_str_changed_handler(handler);
+
+       return true;
+}
+
+API bool sensord_unregister_attribute_str_changed_cb(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       listener->unset_attribute_str_changed_handler();
+
+       return true;
+}
+
+API bool sensord_start(int handle, int option)
+{
+       sensor::sensor_listener *listener;
+       int prev_pause;
+       int pause;
+       int interval, batch_latency;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       pause = CONVERT_OPTION_TO_PAUSE_POLICY(option);
+       prev_pause = listener->get_pause_policy();
+
+       if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
+               _E("Failed to set pause policy[%d]", pause);
+               return false;
+       }
+
+       if (listener->start() < 0) {
+               listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
+               _E("Failed to start listener");
+               return false;
+       }
+
+       interval = listener->get_interval();
+       if (interval > 0)
+               listener->set_interval(interval);
+
+       batch_latency = listener->get_max_batch_latency();
+       if (batch_latency != SENSOR_BATCH_LATENCY_DEFAULT)
+               listener->set_max_batch_latency(batch_latency);
+
+       _D("Start[%d] with the interval[%d] batch_latency[%d]",
+               listener->get_id(), interval, batch_latency);
+
+       return true;
+}
+
+API bool sensord_stop(int handle)
+{
+       int ret;
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       ret = listener->stop();
+
+       if (ret == -EAGAIN || ret == OP_SUCCESS)
+               return true;
+
+       _D("Stop[%d]", listener->get_id());
+
+       return false;
+}
+
+API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->set_interval(interval) < 0) {
+               _E("Failed to set interval to listener");
+               return false;
+       }
+
+       _D("Set interval[%d, %d]", listener->get_id(), interval);
+
+       return true;
+}
+
+API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->set_max_batch_latency(max_batch_latency) < 0) {
+               _E("Failed to set max_batch_latency to listener");
+               return false;
+       }
+
+       _D("Set max batch latency[%d, %u]", listener->get_id(), max_batch_latency);
+
+       return true;
+}
+
+API bool sensord_set_option(int handle, int option)
+{
+       sensor::sensor_listener *listener;
+       int pause;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       pause = CONVERT_OPTION_TO_PAUSE_POLICY(option);
+
+       if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
+               _E("Failed to set option[%d(%d)] to listener", option, pause);
+               return false;
+       }
+
+       _D("Set pause option[%d, %d]", listener->get_id(), pause);
+
+       return true;
+}
+
+API int sensord_set_attribute_int(int handle, int attribute, int value)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->set_attribute(attribute, value) < 0) {
+               _E("Failed to set attribute[%d, %d]", attribute, value);
+               return -EIO;
+       }
+
+       _D("Set attribute[%d, %d, %d]", listener->get_id(), attribute, value);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_get_attribute_int(int handle, int attribute, int* value)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_attribute(attribute, value) < 0) {
+               _E("Failed to get attribute[%d]", attribute);
+               return -EIO;
+       }
+
+       _D("Get attribute[%d, %d, %d]", listener->get_id(), attribute, *value);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->set_attribute(attribute, value, len) < 0) {
+               _E("Failed to set attribute[%d, %s]", attribute, value);
+               return -EIO;
+       }
+       _D("Set attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, len);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_get_attribute_str(int handle, int attribute, char **value, int* len)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_attribute(attribute, value, len) < 0) {
+               _E("Failed to get attribute[%d]", attribute);
+               return -EIO;
+       }
+       _D("Get attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, *len);
+
+       return OP_SUCCESS;
+}
+
+API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_sensor_data(sensor_data) < 0) {
+               _E("Failed to get sensor data from listener");
+               return false;
+       }
+
+       return true;
+}
+
+API bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_sensor_data_list(sensor_data, count) < 0) {
+               _E("Failed to get sensor data from listener");
+               return false;
+       }
+
+       return true;
+}
+
+API bool sensord_flush(int handle)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->flush() < 0) {
+               _E("Failed to flush sensor");
+               return false;
+       }
+
+       return true;
+}
+
+API bool sensord_set_passive_mode(int handle, bool passive)
+{
+       sensor::sensor_listener *listener;
+
+       AUTOLOCK(lock);
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->set_passive_mode(passive) < 0) {
+               _E("Failed to set passive mode");
+               return false;
+       }
+
+       return true;
+}
+
+/* Sensor Internal API using URI */
+API int sensord_get_default_sensor_by_uri(const char *uri, sensor_t *sensor)
+{
+       retvm_if(!sensor, -EINVAL, "Invalid parameter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       return manager.get_sensor(uri, sensor);
+}
+
+API int sensord_get_sensors_by_uri(const char *uri, sensor_t **list, int *count)
+{
+       retvm_if((!list || !count), -EINVAL, "Invalid parameter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       return manager.get_sensors(uri, list, count);
+}
+
+API int sensord_add_sensor_added_cb(sensord_added_cb callback, void *user_data)
+{
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       manager.add_sensor_added_cb(callback, user_data);
+       return OP_SUCCESS;
+}
+
+API int sensord_remove_sensor_added_cb(sensord_added_cb callback)
+{
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       manager.remove_sensor_added_cb(callback);
+       return OP_SUCCESS;
+}
+
+API int sensord_add_sensor_removed_cb(sensord_removed_cb callback, void *user_data)
+{
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       manager.add_sensor_removed_cb(callback, user_data);
+       return OP_SUCCESS;
+}
+
+API int sensord_remove_sensor_removed_cb(sensord_removed_cb callback)
+{
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       manager.remove_sensor_removed_cb(callback);
+       return OP_SUCCESS;
+}
+
+/* Sensor provider */
+API int sensord_create_provider(const char *uri, sensord_provider_h *provider)
+{
+       retvm_if(providerCnt >= MAX_PROVIDER, -EPERM, "Exceeded the maximum provider");
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       std::string str_uri(uri);
+       retvm_if(str_uri.find(PREDEFINED_TYPE_URI) != std::string::npos,
+                       -EINVAL, "Invalid URI format[%s]", uri);
+
+       static std::regex uri_regex(SENSOR_URI_REGEX, std::regex::optimize);
+       retvm_if(!std::regex_match(uri, uri_regex),
+                       -EINVAL, "Invalid URI format[%s]", uri);
+
+       sensor_provider *p;
+
+       p = new(std::nothrow) sensor_provider(uri);
+       retvm_if(!p, -ENOMEM, "Failed to allocate memory");
+
+       *provider = static_cast<sensord_provider_h>(p);
+       providerCnt++;
+       return OP_SUCCESS;
+}
+
+API int sensord_destroy_provider(sensord_provider_h provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       delete static_cast<sensor::sensor_provider *>(provider);
+       providerCnt--;
+       return OP_SUCCESS;
+}
+
+API int sensord_add_provider(sensord_provider_h provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       int ret;
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       ret = p->connect();
+       retv_if(ret < 0, ret);
+
+       ret = manager.add_sensor(p);
+       if (ret < 0) {
+               p->disconnect();
+               return ret;
+       }
+
+       return OP_SUCCESS;
+}
+
+API int sensord_remove_provider(sensord_provider_h provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+       int ret;
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       if (!p->disconnect())
+               return OP_ERROR;
+
+       ret = manager.remove_sensor(p);
+       if (ret < 0) {
+               p->connect();
+               return OP_ERROR;
+       }
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_name(sensord_provider_h provider, const char *name)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       sensor_info *info = p->get_sensor_info();
+       info->set_model(name);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_vendor(sensord_provider_h provider, const char *vendor)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       sensor_info *info = p->get_sensor_info();
+       info->set_vendor(vendor);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_range(sensord_provider_h provider, float min_range, float max_range)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       sensor_info *info = p->get_sensor_info();
+       info->set_min_range(min_range);
+       info->set_max_range(max_range);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_resolution(sensord_provider_h provider, float resolution)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       sensor_info *info = p->get_sensor_info();
+       info->set_resolution(resolution);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_start_cb(sensord_provider_h provider, sensord_provider_start_cb callback, void *user_data)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       p->set_start_cb(callback, user_data);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_stop_cb(sensord_provider_h provider, sensord_provider_stop_cb callback, void *user_data)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       p->set_stop_cb(callback, user_data);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_interval_changed_cb(sensord_provider_h provider, sensord_provider_interval_changed_cb callback, void *user_data)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       p->set_interval_cb(callback, user_data);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_set_attribute_str_cb(sensord_provider_h provider, sensord_provider_attribute_str_cb callback, void *user_data)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+       retvm_if(!callback, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       p->set_attribute_str_cb(callback, user_data);
+
+       return OP_SUCCESS;
+}
+
+API int sensord_provider_publish(sensord_provider_h provider, sensor_data_t data)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       /* TODO: synchronous call is enough? */
+       return p->publish(data);
+}
+
+API int sensord_provider_publish_events(sensord_provider_h provider, sensor_data_t events[], int count)
+{
+       retvm_if(!provider, -EINVAL, "Invalid paramter");
+
+       sensor_provider *p = static_cast<sensor_provider *>(provider);
+
+       return p->publish(events, count);
+};
+
+/* deperecated */
+API sensor_t sensord_get_sensor(sensor_type_t type)
+{
+       sensor_t sensor;
+
+       if (sensord_get_default_sensor(type, &sensor) < 0)
+               return NULL;
+
+       return sensor;
+}
+
+/* deprecated */
+API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
+{
+       return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
+}
+
+/* deprecated */
+API bool sensord_register_hub_event(int handle, unsigned int event_type,
+               unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
+{
+       return false;
+}
+
+/* deprecated */
+API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
+{
+       /*
+        * 1. check parameter
+        * 2. if there is no sensor, return false
+        * 3. memory allocation
+        */
+       return true;
+}
+
+/* deprecated(BUT it is used in C-API....) */
+API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
+{
+       if (!manager.is_supported(sensor))
+               *supported = false;
+       else
+               *supported = true;
+
+       return true;
+}
+
+/* deprecated */
+API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
+{
+       return (sensord_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
+}
+
+/* deprecated */
+API bool sensord_send_command(int handle, const char *command, int command_len)
+{
+       return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
+}
+
+/* deprecated */
+API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
+{
+       *privilege = SENSOR_PRIVILEGE_PUBLIC;
+
+       return true;
+}
+
+/* deprecated */
+API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
+{
+       /*
+        * 1. check parameter
+        * 2. create handle in this client
+        * 3. first connection(client)
+        * 4. cmd_connect for external sensor with key
+        */
+       retvm_if(!key, -EINVAL, "Invalid key");
+       return 0;
+}
+
+/* deprecated */
+API bool sensord_external_disconnect(int handle)
+{
+       /*
+        * 1. check parameter
+        * 2. create handle in this client
+        * 3. first connection(client)
+        * 4. cmd_connect for external sensor with key
+        * 5. disconnect this handle
+        * 6. if there is no active sensor, remove client id and stop listener
+        */
+       return true;
+}
+
+/* deprecated */
+API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
+{
+       /*
+        * 1. check parameter
+        * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false
+        * 2. cmd_post
+        */
+
+       return true;
+}
+
diff --git a/src/api/sensor_listener.cpp b/src/api/sensor_listener.cpp
new file mode 100644 (file)
index 0000000..7c3ab4b
--- /dev/null
@@ -0,0 +1,723 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_listener.h"
+
+#include <channel_handler.h>
+#include <sensor_log.h>
+#include <sensor_types.h>
+#include <command_types.h>
+#include <ipc_client.h>
+
+using namespace sensor;
+
+class listener_handler : public ipc::channel_handler
+{
+public:
+       listener_handler(sensor_listener *listener)
+       : m_listener(listener)
+       {
+               evt_handler[0] = evt_handler[1] = evt_handler[2] = evt_handler[3] = NULL;
+       }
+
+       void connected(ipc::channel *ch) {}
+       void disconnected(ipc::channel *ch)
+       {
+               /* If channel->disconnect() is not explicitly called,
+                * listener will be restored */
+               if (m_listener)
+                       m_listener->restore();
+       }
+
+       void disconnect(void)
+       {
+               m_listener = NULL;
+       }
+
+       void read(ipc::channel *ch, ipc::message &msg)
+       {
+               ipc::channel_handler *handler = NULL;
+               switch (msg.header()->type) {
+               case CMD_LISTENER_EVENT:
+                       handler = evt_handler[0];
+                       if (handler)
+                               handler->read(ch, msg);
+                       break;
+               case CMD_LISTENER_ACC_EVENT:
+                       handler = evt_handler[1];
+                       if (handler)
+                               handler->read(ch, msg);
+                       break;
+               case CMD_LISTENER_SET_ATTR_INT:
+                       handler = evt_handler[2];
+                       if (handler)
+                               handler->read(ch, msg);
+                       break;
+               case CMD_LISTENER_SET_ATTR_STR:
+                       handler = evt_handler[3];
+                       if (handler)
+                               handler->read(ch, msg);
+                       break;
+               case CMD_LISTENER_CONNECTED:
+                       // Do nothing
+                       break;
+               default:
+                       _W("Invalid command message");
+               }
+       }
+
+       void set_handler(int num, ipc::channel_handler* handler) {
+               evt_handler[num] = handler;
+       }
+
+       void read_complete(ipc::channel *ch) {}
+       void error_caught(ipc::channel *ch, int error) {}
+
+private:
+       ipc::channel_handler *evt_handler[4];
+       sensor_listener *m_listener;
+};
+
+sensor_listener::sensor_listener(sensor_t sensor)
+: m_id(0)
+, m_sensor(reinterpret_cast<sensor_info *>(sensor))
+, m_client(NULL)
+, m_cmd_channel(NULL)
+, m_evt_channel(NULL)
+, m_handler(NULL)
+, m_evt_handler(NULL)
+, m_acc_handler(NULL)
+, m_attr_int_changed_handler(NULL)
+, m_attr_str_changed_handler(NULL)
+, m_connected(false)
+, m_started(false)
+{
+       init();
+}
+
+sensor_listener::sensor_listener(sensor_t sensor, ipc::event_loop *loop)
+: m_id(0)
+, m_sensor(reinterpret_cast<sensor_info *>(sensor))
+, m_client(NULL)
+, m_cmd_channel(NULL)
+, m_evt_channel(NULL)
+, m_handler(NULL)
+, m_evt_handler(NULL)
+, m_acc_handler(NULL)
+, m_attr_int_changed_handler(NULL)
+, m_attr_str_changed_handler(NULL)
+, m_loop(loop)
+, m_connected(false)
+, m_started(false)
+{
+       init();
+}
+
+sensor_listener::~sensor_listener()
+{
+       deinit();
+}
+
+bool sensor_listener::init(void)
+{
+       m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
+       retvm_if(!m_client, false, "Failed to allocate memory");
+
+       m_handler = new(std::nothrow) listener_handler(this);
+       if (!m_handler) {
+               _E("Failed to allocate memory");
+               delete m_client;
+               return false;
+       }
+
+       if (!connect()) {
+               delete m_handler;
+               delete m_client;
+               m_handler = NULL;
+               m_client = NULL;
+               return false;
+       }
+
+       return true;
+}
+
+void sensor_listener::deinit(void)
+{
+       AUTOLOCK(lock);
+       _D("Deinitializing..");
+       stop();
+       disconnect();
+
+       unset_event_handler();
+       unset_accuracy_handler();
+       unset_attribute_int_changed_handler();
+       unset_attribute_str_changed_handler();
+
+       m_handler->disconnect();
+       m_loop->add_channel_handler_release_list(m_handler);
+       m_handler = NULL;
+
+       delete m_client;
+       m_client = NULL;
+
+       m_attributes_int.clear();
+       m_attributes_str.clear();
+       _D("Deinitialized..");
+}
+
+int sensor_listener::get_id(void)
+{
+       return m_id;
+}
+
+sensor_t sensor_listener::get_sensor(void)
+{
+       return static_cast<sensor_t>(m_sensor);
+}
+
+void sensor_listener::restore(void)
+{
+       if (lock.try_lock())
+               return;
+
+       m_cmd_channel->disconnect();
+       delete m_cmd_channel;
+       m_cmd_channel = NULL;
+
+       retm_if(!connect(), "Failed to restore listener");
+
+       _D("Restoring sensor listener");
+
+       /* Restore attributes/status */
+       if (m_started.load())
+               start();
+
+       auto interval = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
+       if (interval != m_attributes_int.end())
+               set_interval(m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]);
+
+       auto latency = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       if (latency != m_attributes_int.end())
+               set_max_batch_latency(m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]);
+
+       auto power = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
+       if (power != m_attributes_int.end())
+               set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY]);
+
+       _D("Restored listener[%d]", get_id());
+       lock.unlock();
+}
+
+bool sensor_listener::connect(void)
+{
+       m_cmd_channel = m_client->connect(NULL);
+       retvm_if(!m_cmd_channel, false, "Failed to connect to server");
+
+       m_evt_channel = m_client->connect(m_handler, m_loop, false);
+       retvm_if(!m_evt_channel, false, "Failed to connect to server");
+
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_connect_t buf = {0, };
+
+       memcpy(buf.sensor, m_sensor->get_uri().c_str(), m_sensor->get_uri().size());
+       msg.set_type(CMD_LISTENER_CONNECT);
+       msg.enclose((const char *)&buf, sizeof(buf));
+       m_evt_channel->send_sync(msg);
+
+       m_evt_channel->read_sync(reply);
+       reply.disclose((char *)&buf, sizeof(buf));
+
+       m_id = buf.listener_id;
+       m_connected.store(true);
+
+       m_evt_channel->bind();
+
+       _I("Connected listener[%d] with sensor[%s]", get_id(), m_sensor->get_uri().c_str());
+
+       return true;
+}
+
+void sensor_listener::disconnect(void)
+{
+       ret_if(!is_connected());
+       m_connected.store(false);
+
+       _D("Disconnecting..");
+
+       m_loop->add_channel_release_queue(m_evt_channel);
+       m_evt_channel = NULL;
+
+       m_cmd_channel->disconnect();
+       delete m_cmd_channel;
+       m_cmd_channel = NULL;
+
+       _I("Disconnected[%d]", get_id());
+}
+
+bool sensor_listener::is_connected(void)
+{
+       return m_connected.load();
+}
+
+ipc::channel_handler *sensor_listener::get_event_handler(void)
+{
+       return m_evt_handler;
+}
+
+void sensor_listener::set_event_handler(ipc::channel_handler *handler)
+{
+       m_handler->set_handler(0, handler);
+       if (m_evt_handler)
+               m_loop->add_channel_handler_release_list(m_evt_handler);
+       m_evt_handler = handler;
+}
+
+void sensor_listener::unset_event_handler(void)
+{
+       if (m_evt_handler) {
+               m_handler->set_handler(0, NULL);
+               m_loop->add_channel_handler_release_list(m_evt_handler);
+               m_evt_handler = NULL;
+       }
+}
+
+ipc::channel_handler *sensor_listener::get_accuracy_handler(void)
+{
+       return m_acc_handler;
+}
+
+void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler)
+{
+       m_handler->set_handler(1, handler);
+       if (m_acc_handler)
+               m_loop->add_channel_handler_release_list(m_acc_handler);
+       m_acc_handler = handler;
+}
+
+void sensor_listener::unset_accuracy_handler(void)
+{
+       if (m_acc_handler) {
+               m_handler->set_handler(1, NULL);
+               m_loop->add_channel_handler_release_list(m_acc_handler);
+               m_acc_handler = NULL;
+       }
+}
+
+ipc::channel_handler *sensor_listener::get_attribute_int_changed_handler(void)
+{
+       return m_attr_int_changed_handler;
+}
+
+void sensor_listener::set_attribute_int_changed_handler(ipc::channel_handler *handler)
+{
+       m_handler->set_handler(2, handler);
+       if (m_attr_int_changed_handler)
+               m_loop->add_channel_handler_release_list(m_attr_int_changed_handler);
+       m_attr_int_changed_handler = handler;
+}
+
+void sensor_listener::unset_attribute_int_changed_handler(void)
+{
+       if (m_attr_int_changed_handler) {
+               m_handler->set_handler(2, NULL);
+               m_loop->add_channel_handler_release_list(m_attr_int_changed_handler);
+               m_attr_int_changed_handler = NULL;
+       }
+}
+
+ipc::channel_handler *sensor_listener::get_attribute_str_changed_handler(void)
+{
+       return m_attr_str_changed_handler;
+}
+
+void sensor_listener::set_attribute_str_changed_handler(ipc::channel_handler *handler)
+{
+       m_handler->set_handler(3, handler);
+       if (m_attr_str_changed_handler)
+               m_loop->add_channel_handler_release_list(m_attr_str_changed_handler);
+       m_attr_str_changed_handler = handler;
+}
+
+void sensor_listener::unset_attribute_str_changed_handler(void)
+{
+       if (m_attr_str_changed_handler) {
+               m_handler->set_handler(3, NULL);
+               m_loop->add_channel_handler_release_list(m_attr_str_changed_handler);
+               m_attr_str_changed_handler = NULL;
+       }
+}
+
+int sensor_listener::start(void)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_start_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EINVAL, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_START);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0) {
+               _E("Failed to start listener[%d], sensor[%s]", get_id(), m_sensor->get_uri().c_str());
+               return reply.header()->err;
+       }
+
+       m_started.store(true);
+
+       _I("Listener[%d] started", get_id());
+
+       return OP_SUCCESS;
+}
+
+int sensor_listener::stop(void)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_stop_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EINVAL, "Failed to connect to server");
+       retvm_if(!m_started.load(), -EAGAIN, "Already stopped");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_STOP);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0) {
+               _E("Failed to stop listener[%d]", get_id());
+               return reply.header()->err;
+       }
+
+       m_started.store(false);
+
+       _I("Listener[%d] stopped", get_id());
+
+       return OP_SUCCESS;
+}
+
+int sensor_listener::get_interval(void)
+{
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
+       retv_if(it == m_attributes_int.end(), -1);
+
+       return m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL];
+}
+
+int sensor_listener::get_max_batch_latency(void)
+{
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       retv_if(it == m_attributes_int.end(), -1);
+
+       return m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
+}
+
+int sensor_listener::get_pause_policy(void)
+{
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
+       retv_if(it == m_attributes_int.end(), -1);
+
+       return m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY];
+}
+
+int sensor_listener::get_passive_mode(void)
+{
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
+       retv_if(it == m_attributes_int.end(), -1);
+
+       return m_attributes_int[SENSORD_ATTRIBUTE_PASSIVE_MODE];
+}
+
+int sensor_listener::set_interval(unsigned int interval)
+{
+       int _interval;
+
+       /* TODO: move this logic to server */
+       if (interval == 0)
+               _interval = DEFAULT_INTERVAL;
+       else if (interval < (unsigned int)m_sensor->get_min_interval())
+               _interval = m_sensor->get_min_interval();
+       else
+               _interval = interval;
+
+       _I("Listener[%d] set interval[%u]", get_id(), _interval);
+
+       /* If it is not started, store the value only */
+       if (!m_started.load()) {
+               m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL] = _interval;
+               return OP_SUCCESS;
+       }
+
+       return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval);
+}
+
+int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency)
+{
+       _I("Listener[%d] set max batch latency[%u]", get_id(), max_batch_latency);
+
+       /* If it is not started, store the value only */
+       if (!m_started.load()) {
+               m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency;
+               return OP_SUCCESS;
+       }
+
+       return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency);
+}
+
+int sensor_listener::set_passive_mode(bool passive)
+{
+       _I("Listener[%d] set passive mode[%d]", get_id(), passive);
+
+       return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive);
+}
+
+int sensor_listener::flush(void)
+{
+       _I("Listener[%d] flushes", get_id());
+
+       return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1);
+}
+
+int sensor_listener::set_attribute(int attribute, int value)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_int_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       buf.attribute = attribute;
+       buf.value = value;
+       msg.set_type(CMD_LISTENER_SET_ATTR_INT);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0)
+               return reply.header()->err;
+
+       if (attribute != SENSORD_ATTRIBUTE_FLUSH) {
+               update_attribute(attribute, value);
+       }
+
+       return OP_SUCCESS;
+}
+
+int sensor_listener::get_attribute(int attribute, int* value)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_int_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       buf.attribute = attribute;
+       msg.set_type(CMD_LISTENER_GET_ATTR_INT);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0) {
+               return reply.header()->err;
+       }
+
+       if (reply.header()->length && reply.body()) {
+               *value = ((cmd_listener_attr_int_t *)reply.body())->value;
+               return OP_SUCCESS;
+       }
+
+       return OP_ERROR;
+}
+
+void sensor_listener::update_attribute(int attribute, int value)
+{
+       AUTOLOCK(lock);
+       m_attributes_int[attribute] = value;
+       _I("Update_attribute(int) listener[%d] attribute[%d] value[%d] attributes size[%d]", get_id(), attribute, value, m_attributes_int.size());
+}
+
+int sensor_listener::set_attribute(int attribute, const char *value, int len)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_str_t *buf;
+       size_t size;
+
+       retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
+
+       size = sizeof(cmd_listener_attr_str_t) + len;
+
+       buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
+       retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
+
+       msg.set_type(CMD_LISTENER_SET_ATTR_STR);
+       buf->listener_id = m_id;
+       buf->attribute = attribute;
+
+       memcpy(buf->value, value, len);
+       buf->len = len;
+
+       msg.enclose((char *)buf, size);
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       /* Message memory is released automatically after sending message,
+          so it doesn't need to free memory */
+
+       delete [] buf;
+
+       if (reply.header()->err < 0)
+               return reply.header()->err;
+
+       update_attribute(attribute, value, len);
+
+       return OP_SUCCESS;
+}
+
+int sensor_listener::get_attribute(int attribute, char **value, int* len)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_str_t buf = {0, };
+
+       buf.listener_id = m_id;
+       buf.attribute = attribute;
+
+       msg.set_type(CMD_LISTENER_GET_ATTR_STR);
+       msg.enclose((char *)&buf, sizeof(buf));
+       m_cmd_channel->send_sync(msg);
+
+       m_cmd_channel->read_sync(reply);
+       if (reply.header()->err < 0) {
+               return reply.header()->err;
+       }
+
+       if (reply.header()->length && reply.body()) {
+               cmd_listener_attr_str_t * recv_buf = (cmd_listener_attr_str_t *)reply.body();
+               char* p = (char *)recv_buf->value;
+               *len = recv_buf->len;
+               *value = (char *) malloc(*len);
+               std::copy(p, p + recv_buf->len, *value);
+               return OP_SUCCESS;
+       }
+
+       return OP_ERROR;
+}
+
+void sensor_listener::update_attribute(int attribute, const char *value, int len)
+{
+       AUTOLOCK(lock);
+       m_attributes_str[attribute].clear();
+       m_attributes_str[attribute].insert(m_attributes_str[attribute].begin(), value, value + len);
+       _I("Update_attribute(str) listener[%d] attribute[%d] value[%s] attributes size[%zu]", get_id(), attribute, value, m_attributes_int.size());
+}
+
+int sensor_listener::get_sensor_data(sensor_data_t *data)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_get_data_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_GET_DATA);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0) {
+               return OP_ERROR;
+       }
+
+       reply.disclose((char *)&buf, sizeof(buf));
+       int size = sizeof(sensor_data_t);
+
+       if (buf.len > size || buf.len <= 0) {
+               data->accuracy = -1;
+               data->value_count = 0;
+               return OP_ERROR;
+       }
+
+       memcpy(data, &buf.data, buf.len);
+
+       _D("Listener[%d] read sensor data", get_id());
+
+       return OP_SUCCESS;
+}
+
+int sensor_listener::get_sensor_data_list(sensor_data_t **data, int *count)
+{
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_get_data_list_t buf = {0, };
+
+       retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_GET_DATA_LIST);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_cmd_channel->send_sync(msg);
+       m_cmd_channel->read_sync(reply);
+
+       if (reply.header()->err < 0) {
+               return reply.header()->err;
+       }
+
+       size_t size = reply.size();
+       cmd_listener_get_data_list_t* reply_buf = (cmd_listener_get_data_list_t *) new(std::nothrow) char[size];
+
+       retvm_if(!reply_buf, -ENOMEM, "Failed to allocate memory");
+
+       reply.disclose((char *)reply_buf, size);
+
+       if (reply_buf->len <= 0) {
+               delete [] reply_buf;
+               return OP_ERROR;
+       }
+
+       *count = reply_buf->data_count;
+       *data = (sensor_data_t*) malloc(reply_buf->len);
+
+       if (!(*data)) {
+               _E("Memory allocation failed");
+               delete [] reply_buf;
+               return -ENOMEM;
+       }
+
+       memcpy(*data, reply_buf->data, reply_buf->len);
+
+       _D("Listener[%d] read sensor data list", get_id());
+       delete [] reply_buf;
+       return OP_SUCCESS;
+}
diff --git a/src/api/sensor_listener.h b/src/api/sensor_listener.h
new file mode 100644 (file)
index 0000000..aed8b11
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_LISTENER_H__
+#define __SENSOR_LISTENER_H__
+
+#include <ipc_client.h>
+#include <channel.h>
+#include <channel_handler.h>
+#include <event_loop.h>
+#include <sensor_info.h>
+#include <sensor_types.h>
+#include <cmutex.h>
+#include <map>
+#include <atomic>
+#include <vector>
+
+namespace sensor {
+
+class sensor_listener {
+public:
+       sensor_listener(sensor_t sensor);
+       sensor_listener(sensor_t sensor, ipc::event_loop *loop);
+       virtual ~sensor_listener();
+
+       int get_id(void);
+       sensor_t get_sensor(void);
+
+       ipc::channel_handler *get_event_handler(void);
+       ipc::channel_handler *get_accuracy_handler(void);
+       ipc::channel_handler *get_attribute_int_changed_handler(void);
+       ipc::channel_handler *get_attribute_str_changed_handler(void);
+
+       /* TODO: modify the listener so that it can register multiple handlers(1:n) */
+       void set_event_handler(ipc::channel_handler *handler);
+       void set_accuracy_handler(ipc::channel_handler *handler);
+       void set_attribute_int_changed_handler(ipc::channel_handler *handler);
+       void set_attribute_str_changed_handler(ipc::channel_handler *handler);
+
+       void unset_event_handler(void);
+       void unset_accuracy_handler(void);
+       void unset_attribute_int_changed_handler(void);
+       void unset_attribute_str_changed_handler(void);
+
+       int start(void);
+       int stop(void);
+
+       int get_interval(void);
+       int get_max_batch_latency(void);
+       int get_pause_policy(void);
+       int get_passive_mode(void);
+
+       int set_interval(unsigned int interval);
+       int set_max_batch_latency(unsigned int max_batch_latency);
+       int set_passive_mode(bool passive);
+       int set_attribute(int attribute, int value);
+       int get_attribute(int attribute, int* value);
+       void update_attribute(int attribute, int value);
+       int set_attribute(int attribute, const char *value, int len);
+       int get_attribute(int attribute, char **value, int *len);
+       void update_attribute(int attribute, const char *value, int len);
+       int get_sensor_data(sensor_data_t *data);
+       int get_sensor_data_list(sensor_data_t **data, int *count);
+       int flush(void);
+
+       void restore(void);
+
+private:
+       bool init(void);
+       void deinit(void);
+
+       bool connect(void);
+       void disconnect(void);
+       bool is_connected(void);
+
+       int m_id;
+       sensor_info *m_sensor;
+
+       ipc::ipc_client *m_client;
+       ipc::channel *m_cmd_channel;
+       ipc::channel *m_evt_channel;
+       ipc::channel_handler *m_handler;
+       ipc::channel_handler *m_evt_handler;
+       ipc::channel_handler *m_acc_handler;
+       ipc::channel_handler *m_attr_int_changed_handler;
+       ipc::channel_handler *m_attr_str_changed_handler;
+
+       ipc::event_loop *m_loop { nullptr };
+       std::atomic<bool> m_connected;
+       std::atomic<bool> m_started;
+       std::map<int, int> m_attributes_int;
+       std::map<int, std::vector<char>> m_attributes_str;
+
+       cmutex lock;
+};
+
+}
+
+#endif /* __SENSOR_LISTENER_H__ */
diff --git a/src/api/sensor_manager.cpp b/src/api/sensor_manager.cpp
new file mode 100644 (file)
index 0000000..cec6260
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_manager.h"
+
+#include <sensor_log.h>
+#include <sensor_info.h>
+#include <sensor_utils.h>
+#include <command_types.h>
+#include <ipc_client.h>
+#include <message.h>
+#include <channel.h>
+
+#include "sensor_manager_channel_handler.h"
+
+using namespace sensor;
+
+sensor_manager::sensor_manager()
+: m_client(NULL)
+, m_cmd_channel(NULL)
+, m_mon_channel(NULL)
+, m_connected(false)
+, m_handler(NULL)
+{
+       init();
+}
+
+sensor_manager::~sensor_manager()
+{
+       deinit();
+}
+
+int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
+{
+       if (!is_supported(uri)) {
+               *sensor = NULL;
+               _D("Not supported URI [%s]\n", uri);
+               return -ENODATA;
+       }
+
+       sensor_info *info = get_info(uri);
+       retvm_if(!info, -EACCES, "There is no accessible sensor for uri[%s]", uri);
+
+       *sensor = (sensor_t)info;
+       return OP_SUCCESS;
+}
+
+int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
+{
+       retv_if(!is_supported(uri), -ENODATA);
+
+       std::vector<sensor_info *> infos;
+       int size;
+
+       infos = get_infos(uri);
+       size = infos.size();
+       retvm_if(size == 0, -EACCES, "There is no accessible sensors for uri[%s]", uri);
+
+       *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
+       retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
+
+       for (int i = 0; i < size; ++i)
+               *(*list + i) = infos[i];
+
+       *count = size;
+       return OP_SUCCESS;
+}
+
+bool sensor_manager::is_supported(sensor_t sensor)
+{
+       retvm_if(!sensor, false, "Invalid sensor");
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if (&*it == sensor)
+                       return true;
+       }
+
+       return false;
+}
+
+bool sensor_manager::is_supported(const char *uri)
+{
+       if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
+               return true;
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if ((*it).get_uri() == uri)
+                       return true;
+
+               std::size_t found = (*it).get_uri().find_last_of("/");
+               if (found == std::string::npos)
+                       continue;
+
+               if ((*it).get_uri().substr(0, found) == uri)
+                       return true;
+       }
+
+       return false;
+}
+
+int sensor_manager::add_sensor(sensor_info &info)
+{
+       retv_if(is_supported(info.get_uri().c_str()), OP_ERROR);
+
+       m_sensors.push_back(info);
+
+       _I("Added sensor[%s]", info.get_uri().c_str());
+
+       return OP_SUCCESS;
+}
+
+int sensor_manager::add_sensor(sensor_provider *provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid parameter");
+       return add_sensor(*(provider->get_sensor_info()));
+}
+
+int sensor_manager::remove_sensor(const char *uri)
+{
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if ((*it).get_uri() == uri) {
+                       m_sensors.erase(it);
+                       _I("Removed sensor[%s]", uri);
+
+                       return OP_SUCCESS;
+               }
+       }
+
+       return OP_ERROR;
+}
+
+int sensor_manager::remove_sensor(sensor_provider *provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid parameter");
+       return remove_sensor(provider->get_uri());
+}
+
+void sensor_manager::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
+{
+       m_handler->add_sensor_added_cb(cb, user_data);
+}
+
+void sensor_manager::remove_sensor_added_cb(sensord_added_cb cb)
+{
+       m_handler->remove_sensor_added_cb(cb);
+}
+
+void sensor_manager::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
+{
+       m_handler->add_sensor_removed_cb(cb, user_data);
+}
+
+void sensor_manager::remove_sensor_removed_cb(sensord_removed_cb cb)
+{
+       m_handler->remove_sensor_removed_cb(cb);
+}
+
+bool sensor_manager::init(void)
+{
+       m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
+       retvm_if(!m_client, false, "Failed to allocate memory");
+
+       m_handler = new(std::nothrow) channel_handler(this);
+       if (!m_handler) {
+               delete m_client;
+               m_client = NULL;
+               return false;
+       }
+
+       return true;
+}
+
+void sensor_manager::deinit(void)
+{
+       disconnect();
+
+       delete m_handler;
+       m_handler = NULL;
+
+       delete m_client;
+       m_client = NULL;
+}
+
+bool sensor_manager::connect_channel(void)
+{
+       ipc::message msg;
+
+       m_cmd_channel = m_client->connect(NULL);
+       retvm_if(!m_cmd_channel, false, "Failed to connect to server");
+
+       m_mon_channel = m_client->connect(m_handler, &m_loop);
+       retvm_if(!m_mon_channel, false, "Failed to connect to server");
+
+       msg.set_type(CMD_MANAGER_CONNECT);
+       m_mon_channel->send_sync(msg);
+
+       m_connected.store(true);
+
+       _D("Connected");
+       return true;
+}
+
+bool sensor_manager::connect(void)
+{
+       retv_if(is_connected(), true);
+       retv_if(!connect_channel(), false);
+
+       return get_sensors_internal();
+}
+
+void sensor_manager::disconnect(void)
+{
+       ret_if(!is_connected());
+       m_connected.store(false);
+
+       m_mon_channel->disconnect();
+       delete m_mon_channel;
+       m_mon_channel = NULL;
+
+       m_cmd_channel->disconnect();
+       delete m_cmd_channel;
+       m_cmd_channel = NULL;
+
+       _D("Disconnected");
+}
+
+bool sensor_manager::is_connected(void)
+{
+       return m_connected.load();
+}
+
+void sensor_manager::restore(void)
+{
+       ret_if(!is_connected());
+
+       m_cmd_channel->disconnect();
+       delete m_cmd_channel;
+       m_cmd_channel = NULL;
+
+       m_connected.store(false);
+       retm_if(!connect_channel(), "Failed to restore manager");
+
+       _D("Restored manager");
+}
+
+void sensor_manager::decode_sensors(const char *buf, std::list<sensor_info> &infos)
+{
+       int count = 0;
+       sensor_info info;
+       const int32_t *size;
+       const char *data;
+       cmd_manager_sensor_list_t *raw;
+
+       raw = (cmd_manager_sensor_list_t *)buf;
+       count = raw->sensor_cnt;
+       size = (const int32_t *)raw->data;
+       data = (const char *)raw->data + sizeof(int32_t);
+
+       for (int i = 0; i < count; ++i) {
+               info.clear();
+               info.deserialize(data, size[0]);
+               infos.push_back(info);
+
+               size = (const int32_t *)((const char *)data + size[0]);
+               data = (const char *)size + sizeof(int32_t);
+       }
+
+       _D("Sensor count : %d", count);
+}
+
+bool sensor_manager::get_sensors_internal(void)
+{
+       retvm_if(!is_connected(), false, "Failed to get sensors");
+
+       bool ret;
+       ipc::message msg;
+       ipc::message reply;
+       char buf[MAX_BUF_SIZE];
+
+       msg.set_type(CMD_MANAGER_SENSOR_LIST);
+
+       ret = m_cmd_channel->send_sync(msg);
+       retvm_if(!ret, false, "Failed to send message");
+
+       ret = m_cmd_channel->read_sync(reply);
+       retvm_if(!ret, false, "Failed to receive message");
+
+       reply.disclose(buf, MAX_BUF_SIZE);
+
+       if (!m_sensors.empty())
+               m_sensors.clear();
+
+       decode_sensors(buf, m_sensors);
+
+       return true;
+}
+
+bool sensor_manager::has_privilege(std::string &uri)
+{
+       retvm_if(!is_connected(), false, "Failed to get sensors");
+
+       bool ret;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_has_privilege_t buf = {0, };
+
+       msg.set_type(CMD_HAS_PRIVILEGE);
+       memcpy(buf.sensor, uri.c_str(), uri.size());
+       msg.enclose((const char *)&buf, sizeof(buf));
+
+       ret = m_cmd_channel->send_sync(msg);
+       retvm_if(!ret, false, "Failed to send message");
+
+       ret = m_cmd_channel->read_sync(reply);
+       retvm_if(!ret, false, "Failed to receive message");
+
+       if (reply.header()->err == OP_SUCCESS)
+               return true;
+
+       _W("This client doesn't have the privilege for sensor[%s]", uri.c_str());
+
+       return false;
+}
+
+sensor_info *sensor_manager::get_info(const char *uri)
+{
+       if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
+               return &m_sensors.front();
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if ((*it).get_uri() != uri)
+                       continue;
+
+               if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
+                       return &*it;
+
+               return NULL;
+       }
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               std::size_t found = (*it).get_uri().find_last_of("/");
+               if (found == std::string::npos)
+                       continue;
+               if ((*it).get_uri().substr(0, found) != uri)
+                       continue;
+
+               if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
+                       return &*it;
+       }
+
+       return NULL;
+}
+
+std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
+{
+       std::vector<sensor_info *> infos;
+       bool all = false;
+
+       if (strncmp(uri, utils::get_uri(ALL_SENSOR), strlen(utils::get_uri(ALL_SENSOR))) == 0)
+               all = true;
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if ((*it).get_uri() != uri)
+                       continue;
+
+               if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
+                       infos.push_back(&*it);
+
+               return infos;
+       }
+
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               std::size_t found = (*it).get_uri().find_last_of("/");
+               if (!all && found == std::string::npos)
+                       continue;
+               if (!all && (*it).get_uri().substr(0, found) != uri)
+                       continue;
+
+               if ((*it).get_privilege().empty() || has_privilege((*it).get_uri()))
+                       infos.push_back(&*it);
+       }
+
+       return infos;
+}
+
diff --git a/src/api/sensor_manager.h b/src/api/sensor_manager.h
new file mode 100644 (file)
index 0000000..a825f3e
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_MANAGER_H__
+#define __SENSOR_MANAGER_H__
+
+#include <channel.h>
+#include <sensor_info.h>
+#include <ipc_client.h>
+#include <event_loop.h>
+#include <list>
+#include <atomic>
+
+#include "sensor_internal.h"
+#include "sensor_provider_internal.h"
+
+namespace sensor {
+
+class sensor_manager {
+public:
+       sensor_manager();
+       virtual ~sensor_manager();
+
+       bool connect(void);
+       void disconnect(void);
+       void restore(void);
+
+       int get_sensor(const char *uri, sensor_t *sensor);
+       int get_sensors(const char *uri, sensor_t **list, int *count);
+
+       bool is_supported(sensor_t sensor);
+       bool is_supported(const char *uri);
+
+       /* sensor provider */
+       int add_sensor(sensor_info &info);
+       int add_sensor(sensor_provider *provider);
+       int remove_sensor(const char *uri);
+       int remove_sensor(sensor_provider *provider);
+
+       void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
+       void remove_sensor_added_cb(sensord_added_cb cb);
+
+       void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
+       void remove_sensor_removed_cb(sensord_removed_cb cb);
+
+private:
+       class channel_handler;
+
+       bool init(void);
+       void deinit(void);
+
+       bool connect_channel(void);
+       bool is_connected(void);
+
+       void decode_sensors(const char *buf, std::list<sensor_info> &infos);
+       bool get_sensors_internal(void);
+
+       bool has_privilege(std::string &uri);
+       sensor_info *get_info(const char *uri);
+       std::vector<sensor_info *> get_infos(const char *uri);
+
+       ipc::ipc_client *m_client;
+       ipc::channel *m_cmd_channel;     /* get sensor information */
+       ipc::channel *m_mon_channel;     /* monitor sensors dinamically added/removed */
+       ipc::event_loop m_loop;
+       std::atomic<bool> m_connected;
+       channel_handler *m_handler;
+
+       std::list<sensor_info> m_sensors;
+};
+
+}
+
+#endif /* __SENSOR_MANAGER_H__ */
diff --git a/src/api/sensor_manager_channel_handler.cpp b/src/api/sensor_manager_channel_handler.cpp
new file mode 100644 (file)
index 0000000..3feed82
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_manager_channel_handler.h"
+
+#include <sensor_log.h>
+#include <command_types.h>
+#include "sensor_manager.h"
+
+using namespace sensor;
+
+sensor_manager::channel_handler::channel_handler(sensor_manager *manager)
+: m_manager(manager)
+{
+}
+
+void sensor_manager::channel_handler::connected(ipc::channel *ch)
+{
+}
+
+void sensor_manager::channel_handler::disconnected(ipc::channel *ch)
+{
+       /* If channel->disconnect() is not explicitly called, it will be restored */
+       m_manager->restore();
+}
+
+void sensor_manager::channel_handler::read(ipc::channel *ch, ipc::message &msg)
+{
+       switch (msg.header()->type) {
+       case CMD_MANAGER_SENSOR_ADDED:
+               on_sensor_added(ch, msg);
+               break;
+       case CMD_MANAGER_SENSOR_REMOVED:
+               on_sensor_removed(ch, msg);
+               break;
+       }
+}
+
+void sensor_manager::channel_handler::read_complete(ipc::channel *ch)
+{
+}
+
+void sensor_manager::channel_handler::error_caught(ipc::channel *ch, int error)
+{
+}
+
+void sensor_manager::channel_handler::on_sensor_added(ipc::channel *ch, ipc::message &msg)
+{
+       ret_if(msg.header()->err < OP_SUCCESS);
+
+       sensor_info info;
+       info.clear();
+       info.deserialize(msg.body(), msg.size());
+
+       m_manager->add_sensor(info);
+
+       auto it = m_sensor_added_callbacks.begin();
+       while (it != m_sensor_added_callbacks.end()) {
+               it->first(info.get_uri().c_str(), it->second);
+               ++it;
+       }
+}
+
+void sensor_manager::channel_handler::on_sensor_removed(ipc::channel *ch, ipc::message &msg)
+{
+       ret_if(msg.header()->err < 0);
+       char uri[NAME_MAX] = {0, };
+
+       msg.disclose(uri, NAME_MAX);
+       m_manager->remove_sensor(uri);
+
+       auto it = m_sensor_removed_callbacks.begin();
+       while (it != m_sensor_removed_callbacks.end()) {
+               it->first(uri, it->second);
+               ++it;
+       }
+}
+
+void sensor_manager::channel_handler::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
+{
+       m_sensor_added_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager::channel_handler::remove_sensor_added_cb(sensord_added_cb cb)
+{
+       m_sensor_added_callbacks.erase(cb);
+}
+
+void sensor_manager::channel_handler::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
+{
+       m_sensor_removed_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager::channel_handler::remove_sensor_removed_cb(sensord_removed_cb cb)
+{
+       m_sensor_removed_callbacks.erase(cb);
+}
diff --git a/src/api/sensor_manager_channel_handler.h b/src/api/sensor_manager_channel_handler.h
new file mode 100644 (file)
index 0000000..99f76ed
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_MANAGER_CHANNEL_HANDLER__
+#define __SENSOR_MANAGER_CHANNEL_HANDLER__
+
+#include <sensor_internal.h>
+#include <sensor_manager.h>
+#include <channel_handler.h>
+#include <map>
+
+namespace sensor {
+
+class sensor_manager::channel_handler : public ipc::channel_handler
+{
+public:
+       channel_handler(sensor_manager *manager);
+
+       void connected(ipc::channel *ch);
+       void disconnected(ipc::channel *ch);
+       void read(ipc::channel *ch, ipc::message &msg);
+       void read_complete(ipc::channel *ch);
+       void error_caught(ipc::channel *ch, int error);
+
+       void on_sensor_added(ipc::channel *ch, ipc::message &msg);
+       void on_sensor_removed(ipc::channel *ch, ipc::message &msg);
+
+       void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
+       void remove_sensor_added_cb(sensord_added_cb cb);
+
+       void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
+       void remove_sensor_removed_cb(sensord_removed_cb cb);
+
+       void set_handler(int num, ipc::channel_handler* handler) {}
+       void disconnect(void) {}
+
+private:
+       typedef std::map<sensord_added_cb, void *> sensor_added_cb_list_t;
+       typedef std::map<sensord_removed_cb, void *> sensor_removed_cb_list_t;
+
+       sensor_manager *m_manager;
+       sensor_added_cb_list_t m_sensor_added_callbacks;
+       sensor_removed_cb_list_t m_sensor_removed_callbacks;
+};
+
+}
+
+#endif /* __SENSOR_MANAGER_CHANNEL_HANDLER__ */
diff --git a/src/api/sensor_provider.cpp b/src/api/sensor_provider.cpp
new file mode 100644 (file)
index 0000000..1f0dc26
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensor.h>
+#include <sensor_private.h>
+#include <sensor_internal.h>
+#include <new>
+#include <map>
+
+#include "include/sensor_log.h"
+
+#define RETV_IF(expr, val) \
+       do { if (expr) { return (val); } } while (0)
+
+typedef struct _sensor_provider_s {
+       sensord_provider_h sensor;
+       sensor_provider_start_cb start_cb;
+       sensor_provider_stop_cb  stop_cb;
+       sensor_provider_interval_changed_cb interval_cb;
+       void *start_user_data;
+       void *stop_user_data;
+       void *interval_user_data;
+} sensor_provider_handle;
+
+int sensor_create_provider(const char *uri, sensor_provider_h *provider)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       *provider = new(std::nothrow) sensor_provider_handle();
+       RETV_IF(!*provider, SENSOR_ERROR_OUT_OF_MEMORY);
+
+       (*provider)->sensor = NULL;
+       (*provider)->stop_cb = NULL;
+       (*provider)->interval_cb = NULL;
+       (*provider)->start_cb = NULL;
+       (*provider)->start_user_data = NULL;
+       (*provider)->stop_user_data = NULL;
+       (*provider)->interval_user_data = NULL;
+
+       return sensord_create_provider(uri, &(*provider)->sensor);
+}
+
+int sensor_add_provider(sensor_provider_h provider)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       int result;
+       result = sensord_add_provider(provider->sensor);
+       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(result == -EACCES, SENSOR_ERROR_PERMISSION_DENIED);
+       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_remove_provider(sensor_provider_h provider)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       int result;
+       result = sensord_remove_provider(provider->sensor);
+       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_destroy_provider(sensor_provider_h provider)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       int result;
+       result = sensord_destroy_provider(provider->sensor);
+
+       if (result == SENSOR_ERROR_NONE)
+               delete provider;
+
+       return result;
+}
+
+int sensor_provider_set_name(sensor_provider_h provider, const char *name)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       return sensord_provider_set_name(provider->sensor, name);
+}
+
+int sensor_provider_set_vendor(sensor_provider_h provider, const char *vendor)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       return sensord_provider_set_vendor(provider->sensor, vendor);
+}
+
+int sensor_provider_set_range(sensor_provider_h provider, float min_range, float max_range)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       return sensord_provider_set_range(provider->sensor, min_range, max_range);
+}
+
+int sensor_provider_set_resolution(sensor_provider_h provider, float resolution)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       return sensord_provider_set_resolution(provider->sensor, resolution);
+}
+
+static void sensor_start_callback(sensord_provider_h provider, void *user_data)
+{
+       sensor_provider_h p = (sensor_provider_h)user_data;
+       if (p->start_cb)
+               p->start_cb(p, p->start_user_data);
+}
+
+int sensor_provider_set_start_cb(sensor_provider_h provider,
+               sensor_provider_start_cb callback, void *user_data)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
+
+       provider->start_cb = callback;
+       provider->start_user_data = user_data;
+
+       return sensord_provider_set_start_cb(provider->sensor, sensor_start_callback, provider);
+}
+
+static void sensor_stop_callback(sensord_provider_h provider, void *user_data)
+{
+       sensor_provider_h p = (sensor_provider_h)user_data;
+       if (p->stop_cb)
+               p->stop_cb(p, p->stop_user_data);
+}
+
+int sensor_provider_set_stop_cb(sensor_provider_h provider,
+               sensor_provider_stop_cb callback, void *user_data)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
+
+       provider->stop_cb = callback;
+       provider->stop_user_data = user_data;
+
+       return sensord_provider_set_stop_cb(provider->sensor, sensor_stop_callback, provider);
+}
+
+static void sensor_interval_changed_callback(sensord_provider_h provider,
+               unsigned int interval_ms, void *user_data)
+{
+       sensor_provider_h p = (sensor_provider_h)user_data;
+       if (p->interval_cb)
+               p->interval_cb(p, interval_ms, p->interval_user_data);
+}
+
+int sensor_provider_set_interval_changed_cb(sensor_provider_h provider,
+               sensor_provider_interval_changed_cb callback, void *user_data)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
+
+       provider->interval_cb = callback;
+       provider->interval_user_data = user_data;
+
+       return sensord_provider_set_interval_changed_cb(provider->sensor,
+                       sensor_interval_changed_callback, provider);
+}
+
+int sensor_provider_publish(sensor_provider_h provider, sensor_event_s event)
+{
+       _W("DEPRECATION WARNING: sensor_provider_publish() is deprecated and will be removed from next release. Use sensor_provider_publish_events() instead.");
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       int result;
+       sensor_data_t* data = (sensor_data_t *)&event;
+
+       result = sensord_provider_publish(provider->sensor, *data);
+
+       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_provider_publish_events(sensor_provider_h provider, sensor_event_s events[], int count)
+{
+       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
+
+       int result;
+       result = sensord_provider_publish_events(provider->sensor, (sensor_data_t*) events, count);
+
+       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
+       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
+
+       return SENSOR_ERROR_NONE;
+}
\ No newline at end of file
diff --git a/src/api/sensor_provider_channel_handler.cpp b/src/api/sensor_provider_channel_handler.cpp
new file mode 100644 (file)
index 0000000..b39573b
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_provider_channel_handler.h"
+
+#include <command_types.h>
+#include <sensor_log.h>
+#include "sensor_provider_internal.h"
+
+using namespace sensor;
+
+sensor_provider::channel_handler::channel_handler(sensor_provider *provider)
+: m_provider(provider)
+, m_start_cb(NULL)
+, m_stop_cb(NULL)
+, m_interval_changed_cb(NULL)
+, m_attribute_str_cb(NULL)
+, m_start_user_data(NULL)
+, m_stop_user_data(NULL)
+, m_interval_changed_user_data(NULL)
+, m_attribute_str_user_data(NULL)
+{
+}
+
+void sensor_provider::channel_handler::connected(ipc::channel *ch)
+{
+       _I("Connected");
+}
+
+void sensor_provider::channel_handler::disconnected(ipc::channel *ch)
+{
+       /* TODO */
+       /* m_provider->restore(); */
+}
+
+void sensor_provider::channel_handler::read(ipc::channel *ch, ipc::message &msg)
+{
+       switch (msg.type()) {
+       case CMD_PROVIDER_START:
+               if (m_start_cb)
+                       m_start_cb(m_provider, m_start_user_data);
+               break;
+       case CMD_PROVIDER_STOP:
+               if (m_stop_cb)
+                       m_stop_cb(m_provider, m_stop_user_data);
+               break;
+       case CMD_PROVIDER_ATTR_INT:
+               cmd_provider_attr_int_t buf;
+               msg.disclose((char *)&buf, sizeof(buf));
+
+               if (buf.attribute == SENSORD_ATTRIBUTE_INTERVAL && m_interval_changed_cb)
+                       m_interval_changed_cb(m_provider, buf.value, m_interval_changed_user_data);
+               break;
+       case CMD_PROVIDER_ATTR_STR:
+               cmd_provider_attr_str_t *attr;
+
+               attr = (cmd_provider_attr_str_t *) new(std::nothrow) char[msg.size()];
+               retm_if(!attr, "Failed to allocate memory");
+
+               msg.disclose((char *)attr, msg.size());
+
+               if (m_attribute_str_cb)
+                       m_attribute_str_cb(m_provider, attr->attribute, attr->value, attr->len, m_attribute_str_user_data);
+
+               delete [] attr;
+               break;
+       }
+}
+
+void sensor_provider::channel_handler::read_complete(ipc::channel *ch)
+{
+}
+
+void sensor_provider::channel_handler::error_caught(ipc::channel *ch, int error)
+{
+}
+
+void sensor_provider::channel_handler::set_start_cb(sensord_provider_start_cb cb, void *user_data)
+{
+       m_start_cb = cb;
+       m_start_user_data = user_data;
+}
+
+void sensor_provider::channel_handler::set_stop_cb(sensord_provider_stop_cb cb, void *user_data)
+{
+       m_stop_cb = cb;
+       m_stop_user_data = user_data;
+}
+
+void sensor_provider::channel_handler::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data)
+{
+       m_interval_changed_cb = cb;
+       m_interval_changed_user_data = user_data;
+}
+
+void sensor_provider::channel_handler::set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data)
+{
+       m_attribute_str_cb = cb;
+       m_attribute_str_user_data = user_data;
+}
diff --git a/src/api/sensor_provider_channel_handler.h b/src/api/sensor_provider_channel_handler.h
new file mode 100644 (file)
index 0000000..aa33006
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_PROVIDER_CHANNEL_HANDLER__
+#define __SENSOR_PROVIDER_CHANNEL_HANDLER__
+
+#include <channel_handler.h>
+#include <sensor_internal.h>
+#include "sensor_provider_internal.h"
+
+namespace sensor {
+
+class sensor_provider::channel_handler : public ipc::channel_handler
+{
+public:
+       channel_handler(sensor_provider *provider);
+
+       void connected(ipc::channel *ch);
+       void disconnected(ipc::channel *ch);
+       void read(ipc::channel *ch, ipc::message &msg);
+
+       void read_complete(ipc::channel *ch);
+       void error_caught(ipc::channel *ch, int error);
+
+       void set_start_cb(sensord_provider_start_cb cb, void *user_data);
+       void set_stop_cb(sensord_provider_stop_cb cb, void *user_data);
+       void set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data);
+       void set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data);
+       void set_handler(int num, ipc::channel_handler* handler) {}
+       void disconnect(void) {}
+private:
+       sensor_provider *m_provider;
+
+       sensord_provider_start_cb m_start_cb;
+       sensord_provider_stop_cb m_stop_cb;
+       sensord_provider_interval_changed_cb m_interval_changed_cb;
+       sensord_provider_attribute_str_cb m_attribute_str_cb;
+
+       void *m_start_user_data;
+       void *m_stop_user_data;
+       void *m_interval_changed_user_data;
+       void *m_attribute_str_user_data;
+};
+
+}
+
+#endif /* __SENSOR_PROVIDER_CHANNEL_HANDLER__ */
diff --git a/src/api/sensor_provider_internal.cpp b/src/api/sensor_provider_internal.cpp
new file mode 100644 (file)
index 0000000..30762c4
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_provider_internal.h"
+
+#include <message.h>
+#include <channel.h>
+#include <sensor_log.h>
+#include <sensor_types.h>
+#include <sensor_utils.h>
+#include <ipc_client.h>
+#include <command_types.h>
+#include <cfloat>
+#include <cmath>
+
+#include "sensor_provider_channel_handler.h"
+
+#define DEFAULT_RESOLUTION 0.1
+
+using namespace sensor;
+
+sensor_provider::sensor_provider(const char *uri)
+: m_client(NULL)
+, m_channel(NULL)
+, m_handler(NULL)
+, m_connected(false)
+{
+       init(uri);
+}
+
+sensor_provider::~sensor_provider()
+{
+       deinit();
+}
+
+bool sensor_provider::init(const char *uri)
+{
+       m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
+       retvm_if(!m_client, false, "Failed to allocate memory");
+
+       m_handler = new(std::nothrow) channel_handler(this);
+       if (!m_handler) {
+               delete m_client;
+               return false;
+       }
+
+       m_sensor.set_uri(uri);
+       m_sensor.set_min_range(-FLT_MAX);
+       m_sensor.set_max_range(FLT_MAX);
+       m_sensor.set_resolution(DEFAULT_RESOLUTION);
+       /* TODO: temporary walkaround */
+       const char *priv = sensor::utils::get_privilege(uri);
+       m_sensor.set_privilege(priv);
+
+       return true;
+}
+
+void sensor_provider::deinit(void)
+{
+       disconnect();
+
+       delete m_handler;
+       m_handler = NULL;
+
+       delete m_client;
+       m_client = NULL;
+}
+
+const char *sensor_provider::get_uri(void)
+{
+       return m_sensor.get_uri().c_str();
+}
+
+sensor_info *sensor_provider::get_sensor_info(void)
+{
+       return &m_sensor;
+}
+
+int sensor_provider::serialize(sensor_info *info, char **bytes)
+{
+       int size;
+       raw_data_t *raw = new(std::nothrow) raw_data_t;
+       retvm_if(!raw, -ENOMEM, "Failed to allocated memory");
+
+       info->serialize(*raw);
+
+       *bytes = (char *) malloc(raw->size());
+
+       if (!(*bytes)) {
+               delete(raw);
+               _E("Failed to allocate memory");
+               return -ENOMEM;
+       }
+
+       std::copy(raw->begin(), raw->end(), *bytes);
+
+       size = raw->size();
+       delete raw;
+
+       return size;
+}
+
+int sensor_provider::send_sensor_info(sensor_info *info)
+{
+       char *bytes;
+       int size;
+
+       size = serialize(info, &bytes);
+       if (size < 0)
+               return OP_ERROR;
+
+       ipc::message msg((const char *)bytes, size);
+       msg.set_type(CMD_PROVIDER_CONNECT);
+
+       m_channel->send_sync(msg);
+
+       return OP_SUCCESS;
+}
+
+int sensor_provider::connect(void)
+{
+       m_channel = m_client->connect(m_handler, &m_loop);
+       retvm_if(!m_channel, -EIO, "Failed to connect to server");
+
+       /* serialize and send sensor info */
+       send_sensor_info(get_sensor_info());
+
+       /* check error */
+       ipc::message reply;
+       m_channel->read_sync(reply);
+       retv_if(reply.header()->err < 0, reply.header()->err);
+
+       m_connected.store(true);
+
+       _I("Provider URI[%s]", get_uri());
+
+       return OP_SUCCESS;
+}
+
+bool sensor_provider::disconnect(void)
+{
+       retv_if(!is_connected(), false);
+       m_connected.store(false);
+
+       m_channel->disconnect();
+       delete m_channel;
+       m_channel = NULL;
+
+       _I("Disconnected[%s]", get_uri());
+
+       return true;
+}
+
+void sensor_provider::restore(void)
+{
+       ret_if(!is_connected());
+       retm_if(!connect(), "Failed to restore provider");
+
+       _D("Restored provider[%s]", get_uri());
+}
+
+int sensor_provider::publish(const sensor_data_t &data)
+{
+       ipc::message msg;
+       msg.set_type(CMD_PROVIDER_PUBLISH);
+       msg.enclose((const void *)(&data), sizeof(data));
+
+       m_channel->send_sync(msg);
+
+       return OP_SUCCESS;
+}
+
+int sensor_provider::publish(const sensor_data_t data[], const int count)
+{
+       ipc::message msg;
+       msg.set_type(CMD_PROVIDER_PUBLISH);
+       msg.enclose((const void *)data, sizeof(sensor_data_t) * count);
+
+       m_channel->send_sync(msg);
+
+       return OP_SUCCESS;
+}
+
+bool sensor_provider::is_connected(void)
+{
+       return m_connected.load();
+}
+
+void sensor_provider::set_start_cb(sensord_provider_start_cb cb, void *user_data)
+{
+       m_handler->set_start_cb(cb, user_data);
+}
+
+void sensor_provider::set_stop_cb(sensord_provider_stop_cb cb, void *user_data)
+{
+       m_handler->set_stop_cb(cb, user_data);
+}
+
+void sensor_provider::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data)
+{
+       m_handler->set_interval_cb(cb, user_data);
+}
+
+void sensor_provider::set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data)
+{
+       m_handler->set_attribute_str_cb(cb, user_data);
+}
+
diff --git a/src/api/sensor_provider_internal.h b/src/api/sensor_provider_internal.h
new file mode 100644 (file)
index 0000000..e694b0e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_PROVIDER_INTERNAL_H__
+#define __SENSOR_PROVIDER_INTERNAL_H__
+
+#include <ipc_client.h>
+#include <channel.h>
+#include <channel_handler.h>
+#include <event_loop.h>
+#include <sensor_internal.h>
+#include <sensor_info.h>
+#include <sensor_types.h>
+#include <map>
+#include <atomic>
+
+namespace sensor {
+
+class sensor_provider {
+public:
+       sensor_provider(const char *uri);
+       virtual ~sensor_provider();
+
+       const char *get_uri(void);
+       sensor_info *get_sensor_info(void);
+
+       int connect(void);
+       bool disconnect(void);
+       void restore(void);
+
+       void set_start_cb(sensord_provider_start_cb cb, void *user_data);
+       void set_stop_cb(sensord_provider_stop_cb cb, void *user_data);
+       void set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data);
+       void set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data);
+
+       int publish(const sensor_data_t &data);
+       int publish(const sensor_data_t data[], const int count);
+
+private:
+       class channel_handler;
+
+       bool init(const char *uri);
+       void deinit(void);
+
+       bool is_connected(void);
+
+       int serialize(sensor_info *info, char **bytes);
+       int send_sensor_info(sensor_info *info);
+
+       sensor_info m_sensor;
+
+       ipc::ipc_client *m_client;
+       ipc::channel *m_channel;
+       ipc::event_loop m_loop;
+       channel_handler *m_handler;
+       std::atomic<bool> m_connected;
+};
+
+}
+
+#endif /* __SENSOR_PROVIDER_INTERNAL_H__ */
diff --git a/src/api/sensor_reader.cpp b/src/api/sensor_reader.cpp
new file mode 100644 (file)
index 0000000..bc3a7a1
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_reader.h"
+
+#include <sensor_log.h>
+#include <sensor_types.h>
+#include <chrono>
+
+using namespace sensor;
+
+sensor_reader::sensor_reader()
+: m_reader(NULL)
+, m_loop(NULL)
+, m_event_loop(NULL)
+, m_mutex()
+, m_cond()
+, m_running(false)
+{
+       m_event_loop = new(std::nothrow) ipc::event_loop();
+       m_reader = new(std::nothrow) std::thread(&sensor::sensor_reader::read_event, this);
+       m_reader->detach();
+
+       if (!m_running)
+               wait_for_preparation();
+
+       _I("Created");
+}
+
+sensor_reader::~sensor_reader()
+{
+       _I("Destroying..");
+       retm_if(!m_reader, "Invalid reader");
+
+       m_running = false;
+
+       m_event_loop->stop();
+
+       delete m_reader;
+       m_reader = NULL;
+
+       delete m_event_loop;
+       m_event_loop = NULL;
+
+       _I("Destroyed");
+}
+
+ipc::event_loop *sensor_reader::get_event_loop(void)
+{
+       retvm_if(!m_event_loop, NULL, "Invalid context");
+
+       return m_event_loop;
+}
+
+void sensor_reader::wait_for_preparation(void)
+{
+       std::unique_lock<std::mutex> lock(m_mutex);
+       m_cond.wait_for(lock, std::chrono::seconds(1));
+}
+
+void sensor_reader::read_event(void)
+{
+       _I("RUN");
+       m_loop = g_main_loop_new(g_main_context_new(), false);
+       m_event_loop->set_mainloop(m_loop);
+
+       m_cond.notify_one();
+       m_running = true;
+
+       if (!m_event_loop->run())
+               _E("Failed to run event loop");
+}
diff --git a/src/api/sensor_reader.h b/src/api/sensor_reader.h
new file mode 100644 (file)
index 0000000..010eb42
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_READER_H__
+#define __SENSOR_READER_H__
+
+#include <glib.h>
+#include <event_loop.h>
+
+#include <thread>
+#include <atomic>
+#include <condition_variable>
+
+namespace sensor {
+
+class sensor_reader {
+public:
+       sensor_reader();
+       ~sensor_reader();
+
+       ipc::event_loop *get_event_loop(void);
+
+private:
+       void wait_for_preparation(void);
+       void read_event(void);
+
+       std::thread *m_reader;
+       GMainLoop *m_loop;
+       ipc::event_loop *m_event_loop;
+       std::mutex m_mutex;
+       std::condition_variable m_cond;
+       std::atomic<bool> m_running;
+};
+
+}
+
+#endif /* __SENSOR_READER_H__ */
diff --git a/src/api/sensor_recorder/sensor_recorder.cpp b/src/api/sensor_recorder/sensor_recorder.cpp
new file mode 100644 (file)
index 0000000..3139bc1
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <stdlib.h>
+#include <sensor.h>
+#include <sensor_log.h>
+#include <sensor_recorder_internal.h>
+#include <map>
+#include <string>
+
+static std::map<sensor_type_e, std::string> sensor_keys = {
+       {SENSOR_HRM,                              CTX_SENSOR_RECORDER_HEART_RATE},
+       {SENSOR_HUMAN_PEDOMETER,                  CTX_SENSOR_RECORDER_PEDOMETER},
+       {SENSOR_HUMAN_SLEEP_MONITOR,              CTX_SENSOR_RECORDER_SLEEP_MONITOR},
+       {SENSOR_PRESSURE,                         CTX_SENSOR_RECORDER_PRESSURE},
+};
+
+static std::map<sensor_recorder_option_e, std::string> option_keys = {
+       {SENSOR_RECORDER_OPTION_RETENTION_PERIOD, CTX_SENSOR_RECORDER_KEY_RETENTION},
+       {SENSOR_RECORDER_OPTION_INTERVAL,         CTX_SENSOR_RECORDER_KEY_INTERVAL}
+};
+
+static std::map<sensor_recorder_query_e, std::string> query_keys = {
+       {SENSOR_RECORDER_QUERY_START_TIME,        CTX_SENSOR_RECORDER_KEY_START_TIME},
+       {SENSOR_RECORDER_QUERY_END_TIME,          CTX_SENSOR_RECORDER_KEY_END_TIME},
+       {SENSOR_RECORDER_QUERY_ANCHOR_TIME,       CTX_SENSOR_RECORDER_KEY_ANCHOR},
+       {SENSOR_RECORDER_QUERY_TIME_INTERVAL,     CTX_SENSOR_RECORDER_KEY_INTERVAL},
+};
+
+static std::map<sensor_recorder_data_e, std::string> data_keys = {
+       {SENSOR_RECORDER_DATA_STEPS,              CTX_SENSOR_RECORDER_KEY_STEPS},
+       {SENSOR_RECORDER_DATA_WALK_STEPS,         CTX_SENSOR_RECORDER_KEY_WALK_STEPS},
+       {SENSOR_RECORDER_DATA_RUN_STEPS,          CTX_SENSOR_RECORDER_KEY_RUN_STEPS},
+       {SENSOR_RECORDER_DATA_DISTANCE,           CTX_SENSOR_RECORDER_KEY_DISTANCE},
+       {SENSOR_RECORDER_DATA_CALORIE,            CTX_SENSOR_RECORDER_KEY_CALORIES},
+       {SENSOR_RECORDER_DATA_HEART_RATE,         CTX_SENSOR_RECORDER_KEY_HEART_RATE},
+       {SENSOR_RECORDER_DATA_SLEEP_STATE,        CTX_SENSOR_RECORDER_KEY_SLEEP_STATE},
+       {SENSOR_RECORDER_DATA_PRESSURE,           CTX_SENSOR_RECORDER_KEY_PRESSURE},
+       {SENSOR_RECORDER_DATA_MAX_PRESSURE,       CTX_SENSOR_RECORDER_KEY_MAX_PRESSURE},
+       {SENSOR_RECORDER_DATA_MIN_PRESSURE,       CTX_SENSOR_RECORDER_KEY_MIN_PRESSURE},
+       {SENSOR_RECORDER_DATA_AVERAGE_PRESSURE,   CTX_SENSOR_RECORDER_KEY_AVG_PRESSURE}
+};
+
+static sensor_error_e convert_error(int error)
+{
+       switch (error) {
+       case SENSOR_ERROR_NONE:
+       case SENSOR_ERROR_IO_ERROR:
+       case SENSOR_ERROR_INVALID_PARAMETER:
+       case SENSOR_ERROR_NOT_SUPPORTED:
+       case SENSOR_ERROR_PERMISSION_DENIED:
+       case SENSOR_ERROR_OUT_OF_MEMORY:
+       case SENSOR_ERROR_NO_DATA:
+               return (sensor_error_e)error;
+       case CTX_SENSOR_RECORDER_ERROR_STARTED:
+               return SENSOR_ERROR_NOT_AVAILABLE;
+       default:
+               break;
+       }
+       return SENSOR_ERROR_OPERATION_FAILED;
+}
+
+int sensor_recorder_is_supported(sensor_type_e type, bool *supported)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!supported)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       ret = ctx_sensor_rec_is_supported(sensor_keys[type].c_str(), supported);
+
+       if (ret == SENSOR_ERROR_NONE || ret == SENSOR_ERROR_NOT_SUPPORTED)
+               return SENSOR_ERROR_NONE;
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_start(sensor_type_e type, sensor_recorder_option_h option)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       ret = ctx_sensor_rec_start(sensor_keys[type].c_str(),
+                       reinterpret_cast<ctx_sensor_rec_option_h>(option));
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_stop(sensor_type_e type)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       ret = ctx_sensor_rec_stop(sensor_keys[type].c_str());
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_create_option(sensor_recorder_option_h *option)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_create_option(reinterpret_cast<ctx_sensor_rec_option_h *>(option));
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_destroy_option(sensor_recorder_option_h option)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_destroy_option(reinterpret_cast<ctx_sensor_rec_option_h>(option));
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_option_set_int(sensor_recorder_option_h option, sensor_recorder_option_e attribute, int value)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_option_set_int(
+                       reinterpret_cast<ctx_sensor_rec_option_h>(option), option_keys[attribute].c_str(), value);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_create_query(sensor_recorder_query_h *query)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_create_query(reinterpret_cast<ctx_sensor_rec_query_h *>(query));
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_destroy_query(sensor_recorder_query_h query)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_destroy_query(
+                       reinterpret_cast<ctx_sensor_rec_query_h>(query));
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_query_set_int(sensor_recorder_query_h query, sensor_recorder_query_e attribute, int value)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_query_set_int(
+                       reinterpret_cast<ctx_sensor_rec_query_h>(query), query_keys[attribute].c_str(), value);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_query_set_time(sensor_recorder_query_h query, sensor_recorder_query_e attribute, time_t t)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_query_set_time(
+                       reinterpret_cast<ctx_sensor_rec_query_h>(query), query_keys[attribute].c_str(), t);
+
+       return convert_error(ret);
+}
+
+struct _sensor_rec_info {
+       sensor_type_e type;
+       sensor_recorder_data_cb cb;
+       void *user_data;
+};
+
+static bool sensor_rec_data_callback(const char* subject, ctx_sensor_rec_data_h data,
+               int remains, ctx_sensor_rec_error_e error, void *user_data)
+{
+       _sensor_rec_info *info = (_sensor_rec_info *)user_data;
+
+       bool ret = info->cb(info->type, data, remains, convert_error(error), info->user_data);
+
+       if (remains == 0 || ret == false)
+               delete info;
+
+       return ret;
+}
+
+int sensor_recorder_read(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       if (sensor_keys.find(type) == sensor_keys.end())
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!query || !cb)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _sensor_rec_info *info = new(std::nothrow) _sensor_rec_info;
+       if (!info)
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+
+       info->type = type;
+       info->cb = cb;
+       info->user_data = user_data;
+
+       ret = ctx_sensor_rec_read(sensor_keys[type].c_str(),
+                       reinterpret_cast<ctx_sensor_rec_query_h>(query), sensor_rec_data_callback, info);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_read_sync(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       if (sensor_keys.find(type) == sensor_keys.end())
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!query || !cb)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       _sensor_rec_info *info = new(std::nothrow) _sensor_rec_info;
+       if (!info)
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+
+       info->type = type;
+       info->cb = cb;
+       info->user_data = user_data;
+
+       ret = ctx_sensor_rec_read_sync(sensor_keys[type].c_str(),
+                       reinterpret_cast<ctx_sensor_rec_query_h>(query), sensor_rec_data_callback, info);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_data_get_time(sensor_recorder_data_h data, time_t *start_time, time_t *end_time)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_data_get_time(
+                       reinterpret_cast<ctx_sensor_rec_data_h>(data), start_time, end_time);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_data_get_int(sensor_recorder_data_h data, sensor_recorder_data_e key, int *value)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_data_get_int(
+                       reinterpret_cast<ctx_sensor_rec_data_h>(data), data_keys[key].c_str(), value);
+
+       return convert_error(ret);
+}
+
+int sensor_recorder_data_get_double(sensor_recorder_data_h data, sensor_recorder_data_e key, double *value)
+{
+       int ret = SENSOR_ERROR_NONE;
+
+       ret = ctx_sensor_rec_data_get_double(
+                       reinterpret_cast<ctx_sensor_rec_data_h>(data), data_keys[key].c_str(), value);
+
+       return convert_error(ret);
+}
diff --git a/src/api/sensor_recorder/sensor_recorder_dummy.cpp b/src/api/sensor_recorder/sensor_recorder_dummy.cpp
new file mode 100644 (file)
index 0000000..669afae
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <stdlib.h>
+#include <sensor.h>
+#include <sensor_log.h>
+
+int sensor_recorder_is_supported(sensor_type_e type, bool *supported)
+{
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!supported)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *supported = false;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_start(sensor_type_e type, sensor_recorder_option_h option)
+{
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NOT_SUPPORTED;
+}
+
+int sensor_recorder_stop(sensor_type_e type)
+{
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NOT_SUPPORTED;
+}
+
+int sensor_recorder_create_option(sensor_recorder_option_h *option)
+{
+       if (!option)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *option = (sensor_recorder_option_h)malloc(sizeof(sensor_recorder_option_h));
+       if (!*option)
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_destroy_option(sensor_recorder_option_h option)
+{
+       if (!option)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_option_set_int(sensor_recorder_option_h option, sensor_recorder_option_e attribute, int value)
+{
+       if (!option)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (attribute < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_create_query(sensor_recorder_query_h *query)
+{
+       if (!query)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       *query = (sensor_recorder_query_h)malloc(sizeof(sensor_recorder_query_h));
+       if (!*query)
+               return SENSOR_ERROR_OUT_OF_MEMORY;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_destroy_query(sensor_recorder_query_h query)
+{
+       if (!query)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_query_set_int(sensor_recorder_query_h query, sensor_recorder_query_e attribute, int value)
+{
+       if (!query)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (attribute < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_query_set_time(sensor_recorder_query_h query, sensor_recorder_query_e attribute, time_t t)
+{
+       if (!query)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (attribute < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (t < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_read(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
+{
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!query || !cb)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_read_sync(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
+{
+       if (type <= SENSOR_ALL)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (!query || !cb)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_data_get_time(sensor_recorder_data_h data, time_t *start_time, time_t *end_time)
+{
+       if (!data || !start_time || !end_time)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_data_get_int(sensor_recorder_data_h data, sensor_recorder_data_e key, int *value)
+{
+       if (!data || !value)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (key < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
+
+int sensor_recorder_data_get_double(sensor_recorder_data_h data, sensor_recorder_data_e key, double *value)
+{
+       if (!data || !value)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+       if (key < 0)
+               return SENSOR_ERROR_INVALID_PARAMETER;
+
+       return SENSOR_ERROR_NONE;
+}
diff --git a/src/fusion_util.c b/src/fusion_util.c
deleted file mode 100644 (file)
index b370cc8..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <math.h>
-#include <stdlib.h>
-
-float clamp(float v)
-{
-       return (v < 0) ? 0.0 : v;
-}
-
-int getAngleChange(float *R, float *prevR, float *angleChange)
-{
-       if (R == NULL || prevR == NULL || angleChange == NULL)
-               return -1;
-
-       float rd1, rd4, rd6, rd7, rd8;
-       float ri0, ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
-       float pri0, pri1, pri2, pri3, pri4, pri5, pri6, pri7, pri8;
-
-       ri0 = R[0];
-       ri1 = R[1];
-       ri2 = R[2];
-       ri3 = R[3];
-       ri4 = R[4];
-       ri5 = R[5];
-       ri6 = R[6];
-       ri7 = R[7];
-       ri8 = R[8];
-
-       pri0 = prevR[0];
-       pri1 = prevR[1];
-       pri2 = prevR[2];
-       pri3 = prevR[3];
-       pri4 = prevR[4];
-       pri5 = prevR[5];
-       pri6 = prevR[6];
-       pri7 = prevR[7];
-       pri8 = prevR[8];
-
-       rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7;
-       rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7;
-       rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6;
-       rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7;
-       rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8;
-
-       angleChange[0] = atan2(rd1, rd4);
-       angleChange[1] = asin(-rd7);
-       angleChange[2] = atan2(-rd6, rd8);
-
-       return 0;
-}
-int quatToMatrix(float *quat, float *R)
-{
-       if (quat == NULL || R == NULL)
-               return -1;
-
-       float q0 = quat[0];
-       float q1 = quat[1];
-       float q2 = quat[2];
-       float q3 = quat[3];
-
-       float sq_q1 = 2 * q1 * q1;
-       float sq_q2 = 2 * q2 * q2;
-       float sq_q3 = 2 * q3 * q3;
-       float q1_q2 = 2 * q1 * q2;
-       float q3_q0 = 2 * q3 * q0;
-       float q1_q3 = 2 * q1 * q3;
-       float q2_q0 = 2 * q2 * q0;
-       float q2_q3 = 2 * q2 * q3;
-       float q1_q0 = 2 * q1 * q0;
-
-       R[0] = 1 - sq_q2 - sq_q3;
-       R[1] = q1_q2 - q3_q0;
-       R[2] = q1_q3 + q2_q0;
-       R[3] = q1_q2 + q3_q0;
-       R[4] = 1 - sq_q1 - sq_q3;
-       R[5] = q2_q3 - q1_q0;
-       R[6] = q1_q3 - q2_q0;
-       R[7] = q2_q3 + q1_q0;
-       R[8] = 1 - sq_q1 - sq_q2;
-
-       return 0;
-}
-
-int matrixToQuat(float *mat, float *q)
-{
-       if (q == NULL || mat == NULL)
-               return -1;
-
-       const float Hx = mat[0];
-       const float My = mat[4];
-       const float Az = mat[8];
-       q[0] = sqrtf(clamp(Hx - My - Az + 1) * 0.25f);
-       q[1] = sqrtf(clamp(-Hx + My - Az + 1) * 0.25f);
-       q[2] = sqrtf(clamp(-Hx - My + Az + 1) * 0.25f);
-       q[3] = sqrtf(clamp(Hx + My + Az + 1) * 0.25f);
-       q[0] = copysignf(q[0], mat[7] - mat[5]);
-       q[1] = copysignf(q[1], mat[2] - mat[6]);
-       q[2] = copysignf(q[2], mat[3] - mat[1]);
-
-       return 0;
-}
-
-int getRotationMatrix(float *accel, float *geo, float *R, float *I)
-{
-       if (accel == NULL || geo == NULL || R == NULL || I == NULL)
-               return -1;
-
-       float Ax = accel[0];
-       float Ay = accel[1];
-       float Az = accel[2];
-       float Ex = geo[0];
-       float Ey = geo[1];
-       float Ez = geo[2];
-       float Hx = Ey*Az - Ez*Ay;
-       float Hy = Ez*Ax - Ex*Az;
-       float Hz = Ex*Ay - Ey*Ax;
-       float normH =  (float)sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
-       if (normH < 0.1f)
-               return -1;
-
-       float invH = 1.0f / normH;
-       Hx *= invH;
-       Hy *= invH;
-       Hz *= invH;
-       float invA = 1.0f / (float)sqrt(Ax*Ax + Ay*Ay + Az*Az);
-       Ax *= invA;
-       Ay *= invA;
-       Az *= invA;
-       float Mx = Ay*Hz - Az*Hy;
-       float My = Az*Hx - Ax*Hz;
-       float Mz = Ax*Hy - Ay*Hx;
-
-       R[0] = Hx;  R[1] = Hy;  R[2] = Hz;
-       R[3] = Mx;  R[4] = My;  R[5] = Mz;
-       R[6] = Ax;  R[7] = Ay;  R[8] = Az;
-
-       float invE = 1.0 / (float)sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
-       float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
-       float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
-
-       I[0] = 1;     I[1] = 0;     I[2] = 0;
-       I[3] = 0;     I[4] = c;     I[5] = s;
-       I[6] = 0;     I[7] = -s;    I[8] = c;
-
-       return 0;
-}
-
-
-int remapCoordinateSystem(float *inR, int X, int Y, float *outR)
-{
-       if (inR == NULL || outR == NULL)
-               return -1;
-
-       if ((X & 0x7C) != 0 || (Y & 0x7C) != 0)
-               return -1;   /* invalid parameter */
-       if (((X & 0x3) == 0) || ((Y & 0x3) == 0))
-               return -1;   /* no axis specified */
-       if ((X & 0x3) == (Y & 0x3))
-               return -1;   /* same axis specified */
-
-       int Z = X ^ Y;
-       int x = (X & 0x3)-1;
-       int y = (Y & 0x3)-1;
-       int z = (Z & 0x3)-1;
-
-       int axis_y = (z+1)%3;
-       int axis_z = (z+2)%3;
-       if (((x^axis_y)|(y^axis_z)) != 0)
-               Z ^= 0x80;
-
-       char sx = (X >= 0x80) ? 1 : 0;
-       char sy = (Y >= 0x80) ? 1 : 0;
-       char sz = (Z >= 0x80) ? 1 : 0;
-
-       int i = 0 , j = 0;
-       for (j = 0 ; j < 3 ; j++) {
-               int offset = j * 3;
-               for (i = 0 ; i < 3 ; i++) {
-                       if (x == i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
-                       if (y == i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
-                       if (z == i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
-               }
-       }
-       return 0;
-}
-
diff --git a/src/geomagnetic_field.c b/src/geomagnetic_field.c
deleted file mode 100644 (file)
index 771fbb5..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * This file is part of WMM source code.
- * The original code is the WMM Source from National Oceanic And Atmospheric.
- *
- * See the license below for more details.
- *
- * The WMM source code is in the public domain and not licensed or under
- * copyright. The information and software may be used freely by the public.
- * As required by 17 U.S.C. 403, third parties producing copyrighted works
- * consisting predominantly of the material produced by U.S.
- * government agencies must provide notice with such work  identifying the U.S.
- * Government material incorporated and stating that such material is not
- * subject to copyright protection.
- */
-
-#include <math.h>
-#include <stdlib.h>
-
-const float c[13][13] = {
-       {0.0, -29496.6, -3594.9, 3350.2, 3992.6, -1818.3, 1051.0, 2158.4, 1226.7, 512.8, -360.9, 1033.3, -1452.4, },
-       {4944.4, -1586.3, 5241.4, -7122.5, 4476.4, 3631.5, 1296.8, -2663.8, 543.0, 1197.6, -1532.7, -699.6, -179.4, },
-       {-4689.9, -498.9, 1445.0, 2385.6, 652.3, 1539.3, 1135.8, -136.1, -813.2, 369.4, 189.6, -859.0, 238.5, },
-       {-490.5, 487.8, -424.2, 501.2, -746.9, -664.0, -1408.7, 927.7, -231.9, -431.5, -181.8, 557.5, 649.2, },
-       {1584.9, -826.5, 343.7, -228.6, 66.1, -361.6, -124.4, 171.7, -516.0, 174.8, -23.4, -119.8, -292.1, },
-       {453.4, 1451.7, -556.3, 0.0, 70.8, -5.5, 30.7, 64.2, 170.6, -417.8, 184.8, 79.2, 300.6, },
-       {-393.2, 659.0, 612.7, -361.8, 7.2, 36.9, -52.3, 4.1, 74.8, -12.2, -12.4, -75.3, -20.8, },
-       {-2053.7, -611.1, 133.1, 307.5, 43.2, -67.1, -2.1, 3.2, -35.3, 63.3, 44.1, 19.8, 58.5, },
-       {737.3, -1121.6, 492.9, -465.2, 247.7, 48.1, -27.1, 1.1, -2.3, -22.0, 25.4, 41.0, -23.4, },
-       {-2611.8, 1249.5, 1062.2, -405.9, -249.3, 139.2, 15.8, -15.8, 4.3, -6.2, -2.7, 0.9, -10.2, },
-       {681.2, -21.1, 776.8, 514.2, -532.2, -41.3, -78.2, -16.4, -5.3, -4.9, -1.7, 1.9, 1.9, },
-       {93.3, 695.4, -196.8, -431.1, 142.6, -37.6, -124.0, -29.6, -18.5, -5.2, -1.0, 2.2, -2.2, },
-       {-807.3, 238.5, 1363.4, -1217.3, 167.0, 125.0, 0.0, 5.9, 7.7, -8.5, -0.6, 0.5, 0.0, }
-};
-
-const float cd[13][13] = {
-       {0.0, 11.6, -18.1, 1.0, -7.9, -7.9, -2.9, 2.7, -5.0, 0.0, 0.0, 0.0, 0.0, },
-       {-25.9, 16.5, -7.6, -12.6, 12.7, 6.1, -3.8, -3.5, 6.7, -12.7, 0.0, 0.0, 0.0, },
-       {-39.0, -10.2, 1.6, -5.6, -34.0, -13.8, -1.5, -17.4, -33.6, 0.0, -21.1, 0.0, 79.5, },
-       {22.4, -7.6, -2.1, -6.1, 9.6, -4.7, 19.9, 26.6, 8.3, 24.9, 33.1, 32.8, 64.9, },
-       {6.1, 10.6, 8.2, -0.6, -1.6, 2.0, -9.3, 4.9, -5.3, -22.6, 0.0, 0.0, -48.7, },
-       {4.1, 13.8, 5.6, 8.9, -0.4, 0.7, -0.7, 1.9, 4.4, -10.1, -7.4, 0.0, 0.0, },
-       {-3.8, -31.4, -4.0, -3.3, 1.2, 0.6, 1.1, -1.7, 2.1, 1.7, -8.3, 0.0, 0.0, },
-       {24.8, 8.7, -2.0, -1.2, -4.9, -0.7, 0.2, 0.4, -1.5, -0.8, 0.0, 0.0, 0.0, },
-       {-6.7, 11.2, 16.6, 10.7, 1.5, -0.7, 1.0, 0.2, 0.1, -1.0, -0.8, 0.0, 0.0, },
-       {0.0, -21.7, 0.0, -5.6, 3.4, 0.0, -1.5, 0.8, 0.1, -0.1, -0.5, 0.0, 0.0, },
-       {24.3, -21.1, 0.0, -11.7, -7.4, 0.0, -2.0, -1.6, 0.0, -0.1, -0.1, -0.3, 0.0, },
-       {0.0, 40.9, 0.0, 24.0, 0.0, 9.4, 0.0, -2.3, -0.9, 0.0, -0.1, 0.0, -0.3, },
-       {0.0, 0.0, 0.0, 0.0, 0.0, 20.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, }
-};
-
-float g_declination = 0;
-float g_inclination = 0;
-
-static void E0000(int IENTRY, int maxdeg, float alt, float glat, float glon, float time, float *dec, float *dip, float *ti, float *gv);
-
-int getDeclination(float *decl)
-{
-       if (decl == NULL)
-               return -1;
-
-       *decl = g_declination;
-
-       return 0;
-}
-
-int getInclination(float *incl)
-{
-       if (incl == NULL)
-               return -1;
-
-       *incl = g_inclination;
-
-       return 0;
-}
-
-int setCoordinate(float latitude, float longitude, float altitude, float *declination, float *inclination, int option)
-{
-       float dec, dip, ti, gv;
-       float h;
-       float rTd = 0.017453292;
-
-       E0000(0, 12, 0.0, 0.0, 0.0, 0.0, NULL, NULL, NULL, NULL);
-       E0000(1, 0, altitude, latitude, longitude, 2, &dec, &dip, &ti, &gv);
-
-       h = ti*(cos((dip*rTd)));
-
-       /* deal with geographic and magnetic poles */
-
-       if (h < 100.0) {    /* at magnetic poles */
-               dec = 0;
-       }
-
-       if (option == 1) {
-               if (declination != NULL)
-                       *declination = dec;
-               if (inclination != NULL)
-                       *inclination = dip;
-       } else if (option == 0) {
-               g_declination = dec;
-               g_inclination = dip;
-       }
-
-       return 0;
-}
-/*************************************************************************/
-
-static void E0000(int IENTRY, int maxdeg, float alt, float glat, float glon, float time, float *dec, float *dip, float *ti, float *gv)
-{
-       static int maxord, n, m, j, D1, D2, D3, D4;
-       static float tc[13][13], dp[13][13], snorm[169],
-                       sp[13], cp[13], fn[13], fm[13], pp[13], k[13][13], pi, dtr, a, b, re,
-                       a2, b2, c2, a4, b4, c4, flnmj, otime, oalt,
-                       olat, olon, dt, rlon, rlat, srlon, srlat, crlon, crlat, srlat2,
-                       crlat2, q, q1, q2, ct, st, r2, r, d, ca, sa, aor, ar, br, bt, bp, bpp,
-                       par, temp1, temp2, parp, bx, by, bz, bh;
-       static float *p = snorm;
-
-       switch (IENTRY) {case 0: goto GEOMAG; case 1: goto GEOMG1; }
-
-GEOMAG:
-       maxord = 12;
-       sp[0] = 0.0;
-       cp[0] = *p = pp[0] = 1.0;
-       dp[0][0] = 0.0;
-       a = 6378.137;
-       b = 6356.7523142;
-       re = 6371.2;
-       a2 = a*a;
-       b2 = b*b;
-       c2 = a2-b2;
-       a4 = a2*a2;
-       b4 = b2*b2;
-       c4 = a4 - b4;
-
-       *snorm = 1.0;
-       fm[0] = 0.0;
-       for (n = 1; n <= maxord; n++) {
-               *(snorm+n) = *(snorm+n-1)*(float)(2*n-1)/(float)n;
-               j = 2;
-               for (m = 0, D1 = 1, D2 = (n-m+D1)/D1; D2 > 0; D2--, m += D1) {
-                       k[m][n] = (float)(((n-1)*(n-1))-(m*m))/(float)((2*n-1)*(2*n-3));
-                       if (m > 0) {
-                               flnmj = (float)((n-m+1)*j)/(float)(n+m);
-                               *(snorm+n+m*13) = *(snorm+n+(m-1)*13)*sqrt(flnmj);
-                               j = 1;
-                       }
-               }
-               fn[n] = (float)(n+1);
-               fm[n] = (float)n;
-       }
-       k[1][1] = 0.0;
-
-       otime = oalt = olat = olon = -1000.0;
-
-       return;
-
-       /*************************************************************************/
-
-GEOMG1:
-
-       dt = time;
-       pi = 3.14159265359;
-       dtr = pi/180.0;
-       rlon = glon*dtr;
-       rlat = glat*dtr;
-       srlon = sin(rlon);
-       srlat = sin(rlat);
-       crlon = cos(rlon);
-       crlat = cos(rlat);
-       srlat2 = srlat*srlat;
-       crlat2 = crlat*crlat;
-       sp[1] = srlon;
-       cp[1] = crlon;
-
-       if (alt != oalt || glat != olat) {
-               q = sqrt(a2-c2*srlat2);
-               q1 = alt*q;
-               q2 = ((q1+a2)/(q1+b2))*((q1+a2)/(q1+b2));
-               ct = srlat/sqrt(q2*crlat2+srlat2);
-               st = sqrt(1.0-(ct*ct));
-               r2 = (alt*alt)+2.0*q1+(a4-c4*srlat2)/(q*q);
-               r = sqrt(r2);
-               d = sqrt(a2*crlat2+b2*srlat2);
-               ca = (alt+d)/r;
-               sa = c2*crlat*srlat/(r*d);
-       }
-       if (glon != olon) {
-               for (m = 2; m <= maxord; m++) {
-                       sp[m] = sp[1]*cp[m-1]+cp[1]*sp[m-1];
-                       cp[m] = cp[1]*cp[m-1]-sp[1]*sp[m-1];
-               }
-       }
-       aor = re/r;
-       ar = aor*aor;
-       br = bt = bp = bpp = 0.0;
-       for (n = 1; n <= maxord; n++) {
-               ar = ar*aor;
-               for (m = 0, D3 = 1, D4 = (n+m+D3)/D3; D4 > 0; D4--, m += D3) {
-                       if (alt != oalt || glat != olat) {
-                               if (n == m && m != 0) {
-                                       *(p+n+m*13) = st**(p+n-1+(m-1)*13);
-                                       dp[m][n] = st*dp[m-1][n-1]+ct**(p+n-1+(m-1)*13);
-                                       goto S50;
-                               }
-                               if (n == 1 && m == 0) {
-                                       *(p+n+m*13) = ct**(p+n-1+m*13);
-                                       dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13);
-                                       goto S50;
-                               }
-                               if (n > 1 && n != m) {
-                                       if (m > n-2) *(p+n-2+m*13) = 0.0;
-                                       if (m > n-2) dp[m][n-2] = 0.0;
-                                       *(p+n+m*13) = ct**(p+n-1+m*13)-k[m][n]**(p+n-2+m*13);
-                                       dp[m][n] = ct*dp[m][n-1] - st**(p+n-1+m*13)-k[m][n]*dp[m][n-2];
-                               }
-                       }
-S50:
-                       if (time != otime) {
-                               tc[m][n] = c[m][n]+dt*cd[m][n];
-                               if (m != 0) tc[n][m-1] = c[n][m-1]+dt*cd[n][m-1];
-                       }
-
-                       par = ar**(p+n+m*13);
-                       if (m == 0) {
-                               temp1 = tc[m][n]*cp[m];
-                               temp2 = tc[m][n]*sp[m];
-                       } else {
-                               temp1 = tc[m][n]*cp[m]+tc[n][m-1]*sp[m];
-                               temp2 = tc[m][n]*sp[m]-tc[n][m-1]*cp[m];
-                       }
-                       bt = bt-ar*temp1*dp[m][n];
-                       bp += (fm[m]*temp2*par);
-                       br += (fn[n]*temp1*par);
-
-                       if (st == 0.0 && m == 1) {
-                               if (n == 1) pp[n] = pp[n-1];
-                               else pp[n] = ct*pp[n-1]-k[m][n]*pp[n-2];
-                               parp = ar*pp[n];
-                               bpp += (fm[m]*temp2*parp);
-                       }
-               }
-       }
-       if (st == 0.0) bp = bpp;
-       else bp /= st;
-
-       bx = -bt*ca-br*sa;
-       by = bp;
-       bz = bt*sa-br*ca;
-       bh = sqrt((bx*bx)+(by*by));
-       *ti = sqrt((bh*bh)+(bz*bz));
-       *dec = atan2(by, bx)/dtr;
-       *dip = atan2(bz, bh)/dtr;
-       *gv = -999.0;
-       if (fabs(glat) >= 55.) {
-               if (glat > 0.0 && glon >= 0.0) *gv = *dec-glon;
-               if (glat > 0.0 && glon < 0.0) *gv = *dec+fabs(glon);
-               if (glat < 0.0 && glon >= 0.0) *gv = *dec+glon;
-               if (glat < 0.0 && glon < 0.0) *gv = *dec-fabs(glon);
-               if (*gv > +180.0) *gv -= 360.0;
-               if (*gv < -180.0) *gv += 360.0;
-       }
-       otime = time;
-       oalt = alt;
-       olat = glat;
-       olon = glon;
-       return;
-}
-
diff --git a/src/sensor-internal.cpp b/src/sensor-internal.cpp
deleted file mode 100644 (file)
index 514b95f..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sensor-internal.h>
-
-#include <errno.h>
-#include <sensor.h>
-#include <sensor_internal.h>
-
-int sensor_util_set_attribute_int(sensor_type_e type, sensor_attribute_e attr, int value)
-{
-       sensor_t sensor;
-       int ret = 0;
-       int handle = 0;
-       ret = sensord_get_default_sensor((sensor_type_t) type, &sensor);
-       if (ret < 0) {
-               return ret;
-       }
-
-       handle = sensord_connect(sensor);
-       if (handle < 0) {
-               return handle;
-       }
-
-       ret = sensord_set_attribute_int(handle, attr, value);
-       if (ret < 0) {
-               return ret;
-       }
-
-       ret = sensord_disconnect(handle);
-       if (ret < 0) {
-               return ret;
-       }
-
-       return 0;
-}
-
-int sensor_util_get_attribute_int(sensor_type_e type, sensor_attribute_e attr, int *value)
-{
-       if (!value)
-               return -EINVAL;
-
-       sensor_t sensor;
-       int ret = 0;
-       int handle = 0;
-       ret = sensord_get_default_sensor((sensor_type_t) type, &sensor);
-       if (ret < 0) {
-               return ret;
-       }
-
-       handle = sensord_connect(sensor);
-       if (handle < 0) {
-               return handle;
-       }
-
-       ret = sensord_get_attribute_int(handle, attr, value);
-       if (ret < 0) {
-               return ret;
-       }
-
-       ret = sensord_disconnect(handle);
-       if (ret < 0) {
-               return ret;
-       }
-
-       return 0;
-}
diff --git a/src/sensor.cpp b/src/sensor.cpp
deleted file mode 100644 (file)
index 287af04..0000000
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <limits.h>
-
-#include <sensor_internal.h>
-#include <sensor.h>
-#include <sensor_private.h>
-#include <libgen.h>
-#include <memory>
-#include "include/sensor_log.h"
-
-#define RETURN_VAL_IF(expr, err) \
-       do { \
-               if (expr) { \
-                       _E_MSG(err); \
-                       return (err); \
-               } \
-       } while (0)
-
-#define RETURN_ERROR(err) \
-       do { \
-               _E_MSG(err); \
-               return (err); \
-       } while (0)
-
-#define SENSOR_SHIFT_TYPE 16
-#define SENSOR_UNDEFINED_ID -1
-
-#define SENSOR_LISTENER_MAGIC 0xCAFECAFE
-
-#define CONVERT_AXIS_ENUM(X) ((X) < 3 ? (X) + 0x81 : (X) - 2)
-
-#define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11)
-
-#define WARN_DEPRECATED_SENSOR(X) \
-       do { \
-               if ((X) == SENSOR_LAST || (X) == SENSOR_CUSTOM || (X) == SENSOR_HUMAN_STRESS_MONITOR) { \
-                       _W("DEPRECATION WARNING: This sensor type is deprecated and will be removed from next release."); \
-               } \
-       } while (0)
-
-static int sensor_connect(sensor_h sensor, sensor_listener_h listener)
-{
-       int id = SENSOR_UNDEFINED_ID;
-       int event_type;
-       sensor_type_t type;
-       bool support = false;
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _D("called sensor_connect : listener[%p], sensor[%p]", listener, sensor);
-
-       sensord_get_type(sensor, &type);
-       event_type = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       if (!sensord_is_supported_event_type(sensor, event_type, &support))
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!support)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-
-       id = sensord_connect(sensor);
-
-       if (id < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_connect: id[%d]", id);
-
-       listener->id = id;
-       listener->type = type;
-
-       return id;
-}
-
-static void sensor_callback(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data)
-{
-       sensor_event_s *event;
-       sensor_listener_h listener;
-       listener = (sensor_listener_h)user_data;
-
-       if (!sensor || !listener->callback)
-               return;
-
-       event = (sensor_event_s *)data;
-
-       ((sensor_event_cb) listener->callback)(sensor, event, listener->user_data);
-       return;
-}
-
-static void sensor_events_callback(sensor_t sensor, unsigned int event_type, sensor_data_t datas[], int events_count, void *user_data)
-{
-       sensor_event_s *events;
-       sensor_listener_h listener;
-       listener = (sensor_listener_h)user_data;
-
-       if (!sensor || !listener->callback)
-               return;
-
-       events = (sensor_event_s *)datas;
-
-       ((sensor_events_cb) listener->callback)(sensor, events, events_count, listener->user_data);
-       return;
-}
-
-static inline int sensor_listener_unset_event_cb_impl(sensor_listener_h listener, bool is_events_callback)
-{
-       int id;
-       int type;
-       unsigned int event_id;
-
-       _D("called sensor_listener_unset_event_cb_impl : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       type = (int)listener->type;
-       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       int ret = false;
-       if (is_events_callback) {
-               ret = sensord_unregister_events(id, event_id);
-       } else {
-               ret = sensord_unregister_event(id, event_id);
-       }
-
-       if (!ret)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       listener->callback = NULL;
-       listener->user_data = NULL;
-
-       _D("success sensor_unregister_event");
-
-       return SENSOR_ERROR_NONE;
-}
-
-static inline int sensor_listener_set_event_cb_impl(sensor_listener_h listener,
-               unsigned int interval, void* callback, bool is_events_callback, void *user_data)
-{
-       int id;
-       unsigned int event_id;
-       unsigned int batch_latency;
-
-       if (!listener || !callback)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _D("called sensor_listener_set_event_cb_impl : listener[%p], interval[%u], callback[%p], user_data[%p], id[%d]",
-                       listener, interval, callback, user_data, listener->id);
-
-       id = listener->id;
-       event_id = (listener->type) << SENSOR_SHIFT_TYPE | 0x1;
-       batch_latency = listener->batch_latency;
-
-       listener->callback = (void *)callback;
-       listener->user_data = user_data;
-
-       int ret = false;
-       if (is_events_callback) {
-               ret = sensord_register_events(id, event_id, batch_latency, sensor_events_callback, listener);
-       } else {
-               ret = sensord_register_event(id, event_id, interval, batch_latency, sensor_callback, listener);
-       }
-
-       if (!ret) {
-               listener->callback = NULL;
-               listener->user_data = NULL;
-               return SENSOR_ERROR_OPERATION_FAILED;
-       }
-
-       _D("success sensor_listener_set_event");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_is_supported(sensor_type_e type, bool *supported)
-{
-       int result;
-       sensor_t sensor;
-
-       WARN_DEPRECATED_SENSOR(type);
-
-       if (type < SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!supported)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _D("called sensor_is_supported : type[%d]", type);
-
-        result = sensord_get_default_sensor((sensor_type_t)type, &sensor);
-
-       if (result == -EPERM)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *supported = false;
-
-       /*
-        * because is_supported() API is N/P API,
-        * it must not returns PERMISSION_DENIED error.
-        * -EACCES means that there is at least one sensor.
-        */
-       if (sensor || (result == -EACCES))
-               *supported = true;
-
-       _D("success sensor(%d) is supported[%d]", type, *supported);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_is_supported_by_uri(const char *uri, bool *supported)
-{
-       int result;
-       sensor_t sensor;
-
-       if (!supported)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       result = sensord_get_default_sensor_by_uri(uri, &sensor);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result == -EPERM || result == -EIO)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       if (result == -ENODATA)
-               *supported = false;
-       else
-               *supported = true;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_default_sensor(sensor_type_e type, sensor_h *sensor)
-{
-       int result;
-       sensor_t _sensor;
-       sensor_privilege_t privilege;
-
-       WARN_DEPRECATED_SENSOR(type);
-
-       _D("called sensor_get_default_sensor : type[%d], sensor[%p]", type, sensor);
-
-       if (type < SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensor)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       result = sensord_get_default_sensor((sensor_type_t)type, &_sensor);
-       if (result == -EACCES)
-               return SENSOR_ERROR_PERMISSION_DENIED;
-       else if (result == -EPERM)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       if (!_sensor)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-
-       sensord_get_privilege(_sensor, &privilege);
-       if (privilege != SENSOR_PRIVILEGE_PUBLIC)
-               return SENSOR_ERROR_PERMISSION_DENIED;
-
-       *sensor = _sensor;
-
-       _D("success sensor_get_default_sensor sensor[%p]", _sensor);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_default_sensor_by_uri(const char *uri, sensor_h *sensor)
-{
-       int result;
-
-       result = sensord_get_default_sensor_by_uri(uri, sensor);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result == -EACCES)
-               return SENSOR_ERROR_PERMISSION_DENIED;
-       else if (result == -ENODATA)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_sensor_list(sensor_type_e type, sensor_h **list, int *sensor_count)
-{
-       int result;
-       sensor_h *_list;
-       int count;
-
-       WARN_DEPRECATED_SENSOR(type);
-
-       _D("called sensor_get_list : type[%d]", type);
-
-       if (type < SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensor_count || !list)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       result = sensord_get_sensors((sensor_type_t)type, &_list, &count);
-
-       if (result == -EACCES)
-               return SENSOR_ERROR_PERMISSION_DENIED;
-       else if (result == -EPERM)
-               return SENSOR_ERROR_OPERATION_FAILED;
-       else if (result == -ENODATA)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-
-       int i, j;
-       int count_public = 0;
-
-       for (i = 0; i < count; ++i) {
-               sensor_privilege_t privilege;
-
-               sensord_get_privilege(_list[i], &privilege);
-               if (privilege != SENSOR_PRIVILEGE_PUBLIC)
-                       continue;
-
-               count_public++;
-       }
-
-       if (count_public == 0) {
-               free(_list);
-               return SENSOR_ERROR_PERMISSION_DENIED;
-       }
-
-       *list = (sensor_h *) malloc((sizeof(int *)) * count_public);
-
-       if (!*list) {
-               free(_list);
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-       }
-
-       for (i = 0, j = 0; i < count; ++i) {
-               sensor_privilege_t privilege;
-
-               sensord_get_privilege(_list[i], &privilege);
-               if (privilege != SENSOR_PRIVILEGE_PUBLIC)
-                       continue;
-
-               *(*list + j) = _list[i];
-               j++;
-       }
-
-       free(_list);
-
-       *sensor_count = count_public;
-
-       _D("success sensor_get_list");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_sensor_list_by_uri(const char *uri, sensor_h **list, int *sensor_count)
-{
-       int result;
-       result = sensord_get_sensors_by_uri(uri, list, sensor_count);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result == -EACCES)
-               return SENSOR_ERROR_PERMISSION_DENIED;
-       else if (result == -ENODATA)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_is_wake_up(sensor_h sensor, bool *wakeup)
-{
-       _D("called sensor_get_type");
-
-       if (!sensor || !wakeup)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *wakeup = sensord_is_wakeup_supported(sensor);
-
-       _D("success sensor_is_wake_up : [%d]", *wakeup);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_create_listener(sensor_h sensor, sensor_listener_h *listener)
-{
-       struct sensor_listener_s *_listener;
-       int error;
-
-       _D("called sensor_create_listener : listener[%p]", listener);
-
-       if (!sensor || !listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _listener = new(std::nothrow) struct sensor_listener_s;
-
-       if (!_listener)
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-
-       error = sensor_connect(sensor, _listener);
-
-       if (error < 0) {
-               delete (struct sensor_listener_s *)_listener;
-               return SENSOR_ERROR_OPERATION_FAILED;
-       }
-
-       _listener->sensor = sensor;
-       _listener->pause = SENSOR_PAUSE_ALL;
-       _listener->batch_latency = SENSOR_BATCH_LATENCY_DEFAULT;
-       _listener->magic = SENSOR_LISTENER_MAGIC;
-
-       *listener = (sensor_listener_h) _listener;
-
-       _D("success sensor_create_listener");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_destroy_listener(sensor_listener_h listener)
-{
-       _D("called sensor_destroy : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       sensord_disconnect(listener->id);
-       listener->magic = 0;
-
-       delete (sensor_listener_s *)listener;
-
-       _D("success sensor_destroy");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_start(sensor_listener_h listener)
-{
-       int id;
-       unsigned int pause = SENSOR_PAUSE_ALL;
-
-       _D("called sensor_listener_start : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       pause = listener->pause;
-
-       if (!sensord_start(id, 0))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       if (sensord_set_attribute_int(id, SENSOR_ATTRIBUTE_PAUSE_POLICY, pause) < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_listener_start : id[%d]", id);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_stop(sensor_listener_h listener)
-{
-       int id;
-
-       _D("called sensor_listener_stop : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-
-       if (!sensord_stop(id))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_listener_stop");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_set_event_cb(sensor_listener_h listener,
-               unsigned int interval, sensor_event_cb callback, void *user_data)
-{
-       _W("DEPRECATION WARNING: sensor_listener_set_event_cb() is deprecated and will be removed from next release. Use sensor_listener_set_events_cb() instead.");
-       _D("called sensor_listener_set_event_cb : listener[%p]", listener);
-       return sensor_listener_set_event_cb_impl(listener, interval, (void*) callback, false, user_data);
-}
-
-int sensor_listener_unset_event_cb(sensor_listener_h listener)
-{
-       _W("DEPRECATION WARNING: sensor_listener_unset_event_cb() is deprecated and will be removed from next release. Use sensor_listener_unset_events_cb() instead.");
-       _D("called sensor_listener_unset_event_cb : listener[%p]", listener);
-       return sensor_listener_unset_event_cb_impl(listener, false);
-}
-
-int sensor_listener_set_events_cb(sensor_listener_h listener, sensor_events_cb callback, void *user_data)
-{
-       _D("called sensor_listener_set_events_cb : listener[%p]", listener);
-       return sensor_listener_set_event_cb_impl(listener, 0, (void*) callback, true, user_data);
-}
-
-int sensor_listener_unset_events_cb(sensor_listener_h listener)
-{
-       _D("called sensor_listener_unset_events_cb : listener[%p]", listener);
-       return sensor_listener_unset_event_cb_impl(listener, true);
-}
-
-static void accuracy_changed_callback(sensor_t sensor,
-               unsigned long long timestamp, int accuracy, void *data)
-{
-       sensor_listener_h listener = (sensor_listener_h)data;
-
-       if (!sensor || !listener->accu_callback)
-               return;
-
-       ((sensor_accuracy_changed_cb)listener->accu_callback)
-                       (sensor, timestamp, (sensor_data_accuracy_e)accuracy, listener->accu_user_data);
-
-       return;
-}
-
-int sensor_listener_set_accuracy_cb(sensor_listener_h listener,
-               sensor_accuracy_changed_cb callback, void *data)
-{
-       int id;
-
-       _D("called sensor_register_accuracy_cb : listener[%p], callback[%p], user_data[%p] cb[%p]",
-                       listener, callback, data, accuracy_changed_callback);
-
-       if (!listener || !callback)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       listener->accu_callback = (void *)callback;
-       listener->accu_user_data = data;
-
-       if (!sensord_register_accuracy_cb(id, accuracy_changed_callback, listener)) {
-               listener->accu_callback = NULL;
-               listener->accu_user_data = NULL;
-
-               return SENSOR_ERROR_OPERATION_FAILED;
-       }
-
-       _D("success sensor_register_accuracy_cb");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_unset_accuracy_cb(sensor_listener_h listener)
-{
-       int id;
-
-       _D("called sensor_unregister_accuracy_cb : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-
-       if (!sensord_unregister_accuracy_cb(id))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       listener->accu_callback = NULL;
-       listener->accu_user_data = NULL;
-
-       _D("success sensor_unregister_accuracy_cb");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_set_interval(sensor_listener_h listener, unsigned int interval)
-{
-       int id;
-       int type;
-       unsigned int event_id;
-
-       _D("called sensor_set_interval : listener[%p], interval[%u]", listener, interval);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       type = (int)listener->type;
-       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       if (!sensord_change_event_interval(id, event_id, interval))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_set_interval");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_set_max_batch_latency(sensor_listener_h listener, unsigned int max_batch_latency)
-{
-       int id;
-       int type;
-       int max_batch_count;
-       unsigned int event_id;
-
-       _D("called sensor_set_max_batch_latency : listener[%p], max_batch_latency[%u]", listener, max_batch_latency);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_max_batch_count(listener->sensor, &max_batch_count))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       if (max_batch_count == 0)
-               return SENSOR_ERROR_NOT_SUPPORTED;
-
-       id = listener->id;
-       type = (int)listener->type;
-       event_id = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       if (!sensord_change_event_max_batch_latency(id, event_id, max_batch_latency))
-               return SENSOR_ERROR_NOT_SUPPORTED;
-
-       listener->batch_latency = max_batch_latency;
-
-       _D("success sensor_set_max_batch_latency");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_set_attribute_int(sensor_listener_h listener, sensor_attribute_e attribute, int value)
-{
-       int id;
-       int error;
-
-       _D("called sensor_set_attribute_int : listener[%p], attribute[%d], value[%d]", listener, attribute, value);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-
-       error = sensord_set_attribute_int(id, (int)attribute, (int)value);
-
-       if (error == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (error != SENSOR_ERROR_NONE)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       if (attribute == SENSOR_ATTRIBUTE_PAUSE_POLICY)
-               listener->pause = value;
-
-       _D("success sensor_set_attribute_int");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_set_option(sensor_listener_h listener, sensor_option_e option)
-{
-       int id;
-
-       _D("called sensor_set_option : listener[%p], option[%d]", listener, option);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-
-       if (sensord_set_attribute_int(id, SENSOR_ATTRIBUTE_PAUSE_POLICY, CONVERT_OPTION_PAUSE_POLICY(option)) < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       listener->pause = CONVERT_OPTION_PAUSE_POLICY(option);
-
-       _D("success sensor_set_option");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_read_data(sensor_listener_h listener, sensor_event_s *event)
-{
-       int id;
-       int type;
-       sensor_data_t data;
-       unsigned int data_id;
-
-       _W("DEPRECATION WARNING: sensor_listener_read_data() is deprecated and will be removed from next release. Use sensor_listener_read_data_list() instead.");
-       _D("called sensor_read_data : listener[%p]", listener);
-
-       if (!listener || !event)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       type = (int)listener->type;
-       data_id = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       if (!sensord_get_data(id, data_id, &data))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       event->accuracy = data.accuracy;
-       event->timestamp = data.timestamp;
-       event->value_count = data.value_count;
-
-       for (int i = 0; i < data.value_count; ++i)
-               event->values[i] = data.values[i];
-
-       _D("success sensor_read_data");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_read_data_list(sensor_listener_h listener, sensor_event_s **events, int *count)
-{
-       int id;
-       int type;
-       sensor_data_t* data_list = NULL;
-       int data_list_count = 0;
-       unsigned int data_id;
-
-       _D("called sensor_get_data_list : listener[%p]", listener);
-
-       if (!listener || !events || !count)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-       type = (int)listener->type;
-       data_id = type << SENSOR_SHIFT_TYPE | 0x1;
-
-       if (!sensord_get_data_list(id, data_id, &data_list, &data_list_count))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *events = (sensor_event_s *)data_list;
-       *count = data_list_count;
-
-       _D("success sensor_get_data_list");
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_listener_flush(sensor_listener_h listener)
-{
-       int id;
-
-       _D("called sensor_flush : listener[%p]", listener);
-
-       if (!listener)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (listener->magic != SENSOR_LISTENER_MAGIC)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       id = listener->id;
-
-       if (!sensord_flush(id))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_flush");
-
-       return SENSOR_ERROR_NONE;;
-}
-
-int sensor_get_uri(sensor_h sensor, char **uri)
-{
-       const char *ret_url;
-
-       if (!sensor || !uri)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if ((ret_url = sensord_get_uri(sensor)) == NULL)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *uri = strdup(ret_url);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_name(sensor_h sensor, char** name)
-{
-       _D("called sensor_get_name");
-
-       const char *ret_name;
-
-       if (!sensor || !name)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if ((ret_name = sensord_get_name(sensor)) == NULL)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *name = strdup(ret_name);
-
-       _D("success sensor_get_vendor : [%s]", *name);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_vendor(sensor_h sensor, char** vendor)
-{
-       _D("called sensor_get_vendor");
-
-       const char *ret_vendor;
-
-       if (!sensor || !vendor)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if  ((ret_vendor = sensord_get_vendor(sensor)) == NULL)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *vendor = strdup(ret_vendor);
-
-       _D("success sensor_vendor : [%s]", *vendor);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_type(sensor_h sensor, sensor_type_e *type)
-{
-       sensor_type_t _type;
-       //_D("called sensor_get_type");
-
-       if (!sensor || !type)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_type(sensor, &_type))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       *type = (sensor_type_e) _type;
-
-       //_D("success sensor_get_type : [%d]", *type);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_min_range(sensor_h sensor, float *min_range)
-{
-       _D("called sensor_get_min_range");
-
-       if (!sensor || !min_range)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_min_range(sensor, min_range))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_min_range : [%f]", *min_range);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_max_range(sensor_h sensor, float *max_range)
-{
-       _D("called sensor_get_max_range");
-
-       if (!sensor || !max_range)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_max_range(sensor, max_range))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_max_range : [%f]", *max_range);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_resolution(sensor_h sensor, float *resolution)
-{
-       _D("called sensor_get_resolution");
-
-       if (!sensor || !resolution)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_resolution(sensor, resolution))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_resolution : [%f]", *resolution);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_min_interval(sensor_h sensor, int *min_interval)
-{
-       _D("called sensor_get_min_interval");
-
-       if (!sensor || !min_interval)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_min_interval(sensor, min_interval))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_min_interval : [%d]", *min_interval);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_fifo_count(sensor_h sensor, int *fifo_count)
-{
-       _D("called sensor_get_fifo_count");
-
-       if (!sensor || !fifo_count)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_fifo_count(sensor, fifo_count))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_fifo_count : [%d]", *fifo_count);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_get_max_batch_count(sensor_h sensor, int *max_batch_count)
-{
-       _D("called sensor_get_max_batch_count");
-
-       if (!sensor || !max_batch_count)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       if (!sensord_get_max_batch_count(sensor, max_batch_count))
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       _D("success sensor_get_max_batch_count : [%d]", *max_batch_count);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_add_sensor_added_cb(sensor_added_cb callback, void *user_data)
-{
-       int result;
-       result = sensord_add_sensor_added_cb(callback, user_data);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_remove_sensor_added_cb(sensor_added_cb callback)
-{
-       int result;
-       result = sensord_remove_sensor_added_cb(callback);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_add_sensor_removed_cb(sensor_removed_cb callback, void *user_data)
-{
-       int result;
-       result = sensord_add_sensor_removed_cb(callback, user_data);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_remove_sensor_removed_cb(sensor_removed_cb callback)
-{
-       int result;
-       result = sensord_remove_sensor_removed_cb(callback);
-       if (result == -EINVAL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       else if (result < 0)
-               return SENSOR_ERROR_OPERATION_FAILED;
-
-       return SENSOR_ERROR_NONE;
-}
-
-/*
- *     FUNCTIONS : SENSOR_UTIL_*
- */
-
-int sensor_util_get_declination(float latitude, float longitude, float altitude, float *declination)
-{
-       if (!declination)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       setCoordinate(latitude, longitude, altitude, declination, NULL, 1);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_angle_change(float R[], float prevR[], float angleChange[])
-{
-       if (getAngleChange(R, prevR, angleChange) < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_orientation(float R[], float values[])
-{
-       if (!R || !values)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       values[0] = (float) atan2(R[1], R[4]);
-       values[1] = (float) asin(-R[7]);
-       values[2] = (float) atan2(-R[6], R[8]);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_inclination(float I[], float* inclination)
-{
-       if (!I || !inclination)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *inclination = atan2(I[5], I[4]);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_remap_coordinate_system(float inR[], sensor_util_axis_e x, sensor_util_axis_e y, float outR[])
-{
-       if (remapCoordinateSystem(inR, CONVERT_AXIS_ENUM(x), CONVERT_AXIS_ENUM(y), outR) < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_rotation_matrix_from_vector(float Vx, float Vy, float Vz, float R[])
-{
-       float RV[4] = {0, Vx, Vy, Vz};
-
-       RV[0] = 1 - Vx * Vx - Vy * Vy - Vz * Vz;
-       RV[0] = (Vx > 0) ? (float) (sqrt(Vx)) : 0;
-
-       if (quatToMatrix(RV, R) < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_rotation_matrix(float Gx, float Gy, float Gz, float Mx, float My, float Mz, float R[], float I[])
-{
-       float G[3] = {Gx, Gy, Gz};
-       float M[3] = {Mx, My, Mz};
-
-       if (getRotationMatrix(G, M, R, I) < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_util_get_altitude(float pressure, float sea_level_pressure, float temperature, float* altitude)
-{
-       if (pressure <= 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (sea_level_pressure <= 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!altitude)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *altitude = (temperature + 273.15f) / 0.0065f * (1.0f - pow(pressure/sea_level_pressure, 1.0f/5.255f));
-
-       return SENSOR_ERROR_NONE;
-}
diff --git a/src/sensor_provider.cpp b/src/sensor_provider.cpp
deleted file mode 100644 (file)
index 1f0dc26..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sensor.h>
-#include <sensor_private.h>
-#include <sensor_internal.h>
-#include <new>
-#include <map>
-
-#include "include/sensor_log.h"
-
-#define RETV_IF(expr, val) \
-       do { if (expr) { return (val); } } while (0)
-
-typedef struct _sensor_provider_s {
-       sensord_provider_h sensor;
-       sensor_provider_start_cb start_cb;
-       sensor_provider_stop_cb  stop_cb;
-       sensor_provider_interval_changed_cb interval_cb;
-       void *start_user_data;
-       void *stop_user_data;
-       void *interval_user_data;
-} sensor_provider_handle;
-
-int sensor_create_provider(const char *uri, sensor_provider_h *provider)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       *provider = new(std::nothrow) sensor_provider_handle();
-       RETV_IF(!*provider, SENSOR_ERROR_OUT_OF_MEMORY);
-
-       (*provider)->sensor = NULL;
-       (*provider)->stop_cb = NULL;
-       (*provider)->interval_cb = NULL;
-       (*provider)->start_cb = NULL;
-       (*provider)->start_user_data = NULL;
-       (*provider)->stop_user_data = NULL;
-       (*provider)->interval_user_data = NULL;
-
-       return sensord_create_provider(uri, &(*provider)->sensor);
-}
-
-int sensor_add_provider(sensor_provider_h provider)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       int result;
-       result = sensord_add_provider(provider->sensor);
-       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(result == -EACCES, SENSOR_ERROR_PERMISSION_DENIED);
-       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_remove_provider(sensor_provider_h provider)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       int result;
-       result = sensord_remove_provider(provider->sensor);
-       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_destroy_provider(sensor_provider_h provider)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       int result;
-       result = sensord_destroy_provider(provider->sensor);
-
-       if (result == SENSOR_ERROR_NONE)
-               delete provider;
-
-       return result;
-}
-
-int sensor_provider_set_name(sensor_provider_h provider, const char *name)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       return sensord_provider_set_name(provider->sensor, name);
-}
-
-int sensor_provider_set_vendor(sensor_provider_h provider, const char *vendor)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       return sensord_provider_set_vendor(provider->sensor, vendor);
-}
-
-int sensor_provider_set_range(sensor_provider_h provider, float min_range, float max_range)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       return sensord_provider_set_range(provider->sensor, min_range, max_range);
-}
-
-int sensor_provider_set_resolution(sensor_provider_h provider, float resolution)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       return sensord_provider_set_resolution(provider->sensor, resolution);
-}
-
-static void sensor_start_callback(sensord_provider_h provider, void *user_data)
-{
-       sensor_provider_h p = (sensor_provider_h)user_data;
-       if (p->start_cb)
-               p->start_cb(p, p->start_user_data);
-}
-
-int sensor_provider_set_start_cb(sensor_provider_h provider,
-               sensor_provider_start_cb callback, void *user_data)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
-
-       provider->start_cb = callback;
-       provider->start_user_data = user_data;
-
-       return sensord_provider_set_start_cb(provider->sensor, sensor_start_callback, provider);
-}
-
-static void sensor_stop_callback(sensord_provider_h provider, void *user_data)
-{
-       sensor_provider_h p = (sensor_provider_h)user_data;
-       if (p->stop_cb)
-               p->stop_cb(p, p->stop_user_data);
-}
-
-int sensor_provider_set_stop_cb(sensor_provider_h provider,
-               sensor_provider_stop_cb callback, void *user_data)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
-
-       provider->stop_cb = callback;
-       provider->stop_user_data = user_data;
-
-       return sensord_provider_set_stop_cb(provider->sensor, sensor_stop_callback, provider);
-}
-
-static void sensor_interval_changed_callback(sensord_provider_h provider,
-               unsigned int interval_ms, void *user_data)
-{
-       sensor_provider_h p = (sensor_provider_h)user_data;
-       if (p->interval_cb)
-               p->interval_cb(p, interval_ms, p->interval_user_data);
-}
-
-int sensor_provider_set_interval_changed_cb(sensor_provider_h provider,
-               sensor_provider_interval_changed_cb callback, void *user_data)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(!callback, SENSOR_ERROR_INVALID_PARAMETER);
-
-       provider->interval_cb = callback;
-       provider->interval_user_data = user_data;
-
-       return sensord_provider_set_interval_changed_cb(provider->sensor,
-                       sensor_interval_changed_callback, provider);
-}
-
-int sensor_provider_publish(sensor_provider_h provider, sensor_event_s event)
-{
-       _W("DEPRECATION WARNING: sensor_provider_publish() is deprecated and will be removed from next release. Use sensor_provider_publish_events() instead.");
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       int result;
-       sensor_data_t* data = (sensor_data_t *)&event;
-
-       result = sensord_provider_publish(provider->sensor, *data);
-
-       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_provider_publish_events(sensor_provider_h provider, sensor_event_s events[], int count)
-{
-       RETV_IF(!provider, SENSOR_ERROR_INVALID_PARAMETER);
-
-       int result;
-       result = sensord_provider_publish_events(provider->sensor, (sensor_data_t*) events, count);
-
-       RETV_IF(result == -EINVAL, SENSOR_ERROR_INVALID_PARAMETER);
-       RETV_IF(result < 0, SENSOR_ERROR_OPERATION_FAILED);
-
-       return SENSOR_ERROR_NONE;
-}
\ No newline at end of file
diff --git a/src/sensor_recorder.cpp b/src/sensor_recorder.cpp
deleted file mode 100644 (file)
index 3139bc1..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <stdlib.h>
-#include <sensor.h>
-#include <sensor_log.h>
-#include <sensor_recorder_internal.h>
-#include <map>
-#include <string>
-
-static std::map<sensor_type_e, std::string> sensor_keys = {
-       {SENSOR_HRM,                              CTX_SENSOR_RECORDER_HEART_RATE},
-       {SENSOR_HUMAN_PEDOMETER,                  CTX_SENSOR_RECORDER_PEDOMETER},
-       {SENSOR_HUMAN_SLEEP_MONITOR,              CTX_SENSOR_RECORDER_SLEEP_MONITOR},
-       {SENSOR_PRESSURE,                         CTX_SENSOR_RECORDER_PRESSURE},
-};
-
-static std::map<sensor_recorder_option_e, std::string> option_keys = {
-       {SENSOR_RECORDER_OPTION_RETENTION_PERIOD, CTX_SENSOR_RECORDER_KEY_RETENTION},
-       {SENSOR_RECORDER_OPTION_INTERVAL,         CTX_SENSOR_RECORDER_KEY_INTERVAL}
-};
-
-static std::map<sensor_recorder_query_e, std::string> query_keys = {
-       {SENSOR_RECORDER_QUERY_START_TIME,        CTX_SENSOR_RECORDER_KEY_START_TIME},
-       {SENSOR_RECORDER_QUERY_END_TIME,          CTX_SENSOR_RECORDER_KEY_END_TIME},
-       {SENSOR_RECORDER_QUERY_ANCHOR_TIME,       CTX_SENSOR_RECORDER_KEY_ANCHOR},
-       {SENSOR_RECORDER_QUERY_TIME_INTERVAL,     CTX_SENSOR_RECORDER_KEY_INTERVAL},
-};
-
-static std::map<sensor_recorder_data_e, std::string> data_keys = {
-       {SENSOR_RECORDER_DATA_STEPS,              CTX_SENSOR_RECORDER_KEY_STEPS},
-       {SENSOR_RECORDER_DATA_WALK_STEPS,         CTX_SENSOR_RECORDER_KEY_WALK_STEPS},
-       {SENSOR_RECORDER_DATA_RUN_STEPS,          CTX_SENSOR_RECORDER_KEY_RUN_STEPS},
-       {SENSOR_RECORDER_DATA_DISTANCE,           CTX_SENSOR_RECORDER_KEY_DISTANCE},
-       {SENSOR_RECORDER_DATA_CALORIE,            CTX_SENSOR_RECORDER_KEY_CALORIES},
-       {SENSOR_RECORDER_DATA_HEART_RATE,         CTX_SENSOR_RECORDER_KEY_HEART_RATE},
-       {SENSOR_RECORDER_DATA_SLEEP_STATE,        CTX_SENSOR_RECORDER_KEY_SLEEP_STATE},
-       {SENSOR_RECORDER_DATA_PRESSURE,           CTX_SENSOR_RECORDER_KEY_PRESSURE},
-       {SENSOR_RECORDER_DATA_MAX_PRESSURE,       CTX_SENSOR_RECORDER_KEY_MAX_PRESSURE},
-       {SENSOR_RECORDER_DATA_MIN_PRESSURE,       CTX_SENSOR_RECORDER_KEY_MIN_PRESSURE},
-       {SENSOR_RECORDER_DATA_AVERAGE_PRESSURE,   CTX_SENSOR_RECORDER_KEY_AVG_PRESSURE}
-};
-
-static sensor_error_e convert_error(int error)
-{
-       switch (error) {
-       case SENSOR_ERROR_NONE:
-       case SENSOR_ERROR_IO_ERROR:
-       case SENSOR_ERROR_INVALID_PARAMETER:
-       case SENSOR_ERROR_NOT_SUPPORTED:
-       case SENSOR_ERROR_PERMISSION_DENIED:
-       case SENSOR_ERROR_OUT_OF_MEMORY:
-       case SENSOR_ERROR_NO_DATA:
-               return (sensor_error_e)error;
-       case CTX_SENSOR_RECORDER_ERROR_STARTED:
-               return SENSOR_ERROR_NOT_AVAILABLE;
-       default:
-               break;
-       }
-       return SENSOR_ERROR_OPERATION_FAILED;
-}
-
-int sensor_recorder_is_supported(sensor_type_e type, bool *supported)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!supported)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       ret = ctx_sensor_rec_is_supported(sensor_keys[type].c_str(), supported);
-
-       if (ret == SENSOR_ERROR_NONE || ret == SENSOR_ERROR_NOT_SUPPORTED)
-               return SENSOR_ERROR_NONE;
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_start(sensor_type_e type, sensor_recorder_option_h option)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       ret = ctx_sensor_rec_start(sensor_keys[type].c_str(),
-                       reinterpret_cast<ctx_sensor_rec_option_h>(option));
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_stop(sensor_type_e type)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       ret = ctx_sensor_rec_stop(sensor_keys[type].c_str());
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_create_option(sensor_recorder_option_h *option)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_create_option(reinterpret_cast<ctx_sensor_rec_option_h *>(option));
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_destroy_option(sensor_recorder_option_h option)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_destroy_option(reinterpret_cast<ctx_sensor_rec_option_h>(option));
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_option_set_int(sensor_recorder_option_h option, sensor_recorder_option_e attribute, int value)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_option_set_int(
-                       reinterpret_cast<ctx_sensor_rec_option_h>(option), option_keys[attribute].c_str(), value);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_create_query(sensor_recorder_query_h *query)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_create_query(reinterpret_cast<ctx_sensor_rec_query_h *>(query));
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_destroy_query(sensor_recorder_query_h query)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_destroy_query(
-                       reinterpret_cast<ctx_sensor_rec_query_h>(query));
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_query_set_int(sensor_recorder_query_h query, sensor_recorder_query_e attribute, int value)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_query_set_int(
-                       reinterpret_cast<ctx_sensor_rec_query_h>(query), query_keys[attribute].c_str(), value);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_query_set_time(sensor_recorder_query_h query, sensor_recorder_query_e attribute, time_t t)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_query_set_time(
-                       reinterpret_cast<ctx_sensor_rec_query_h>(query), query_keys[attribute].c_str(), t);
-
-       return convert_error(ret);
-}
-
-struct _sensor_rec_info {
-       sensor_type_e type;
-       sensor_recorder_data_cb cb;
-       void *user_data;
-};
-
-static bool sensor_rec_data_callback(const char* subject, ctx_sensor_rec_data_h data,
-               int remains, ctx_sensor_rec_error_e error, void *user_data)
-{
-       _sensor_rec_info *info = (_sensor_rec_info *)user_data;
-
-       bool ret = info->cb(info->type, data, remains, convert_error(error), info->user_data);
-
-       if (remains == 0 || ret == false)
-               delete info;
-
-       return ret;
-}
-
-int sensor_recorder_read(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       if (sensor_keys.find(type) == sensor_keys.end())
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!query || !cb)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _sensor_rec_info *info = new(std::nothrow) _sensor_rec_info;
-       if (!info)
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-
-       info->type = type;
-       info->cb = cb;
-       info->user_data = user_data;
-
-       ret = ctx_sensor_rec_read(sensor_keys[type].c_str(),
-                       reinterpret_cast<ctx_sensor_rec_query_h>(query), sensor_rec_data_callback, info);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_read_sync(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       if (sensor_keys.find(type) == sensor_keys.end())
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!query || !cb)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       _sensor_rec_info *info = new(std::nothrow) _sensor_rec_info;
-       if (!info)
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-
-       info->type = type;
-       info->cb = cb;
-       info->user_data = user_data;
-
-       ret = ctx_sensor_rec_read_sync(sensor_keys[type].c_str(),
-                       reinterpret_cast<ctx_sensor_rec_query_h>(query), sensor_rec_data_callback, info);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_data_get_time(sensor_recorder_data_h data, time_t *start_time, time_t *end_time)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_data_get_time(
-                       reinterpret_cast<ctx_sensor_rec_data_h>(data), start_time, end_time);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_data_get_int(sensor_recorder_data_h data, sensor_recorder_data_e key, int *value)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_data_get_int(
-                       reinterpret_cast<ctx_sensor_rec_data_h>(data), data_keys[key].c_str(), value);
-
-       return convert_error(ret);
-}
-
-int sensor_recorder_data_get_double(sensor_recorder_data_h data, sensor_recorder_data_e key, double *value)
-{
-       int ret = SENSOR_ERROR_NONE;
-
-       ret = ctx_sensor_rec_data_get_double(
-                       reinterpret_cast<ctx_sensor_rec_data_h>(data), data_keys[key].c_str(), value);
-
-       return convert_error(ret);
-}
diff --git a/src/sensor_recorder_dummy.cpp b/src/sensor_recorder_dummy.cpp
deleted file mode 100644 (file)
index 669afae..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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 <stdlib.h>
-#include <sensor.h>
-#include <sensor_log.h>
-
-int sensor_recorder_is_supported(sensor_type_e type, bool *supported)
-{
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!supported)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *supported = false;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_start(sensor_type_e type, sensor_recorder_option_h option)
-{
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NOT_SUPPORTED;
-}
-
-int sensor_recorder_stop(sensor_type_e type)
-{
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NOT_SUPPORTED;
-}
-
-int sensor_recorder_create_option(sensor_recorder_option_h *option)
-{
-       if (!option)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *option = (sensor_recorder_option_h)malloc(sizeof(sensor_recorder_option_h));
-       if (!*option)
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_destroy_option(sensor_recorder_option_h option)
-{
-       if (!option)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_option_set_int(sensor_recorder_option_h option, sensor_recorder_option_e attribute, int value)
-{
-       if (!option)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (attribute < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_create_query(sensor_recorder_query_h *query)
-{
-       if (!query)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       *query = (sensor_recorder_query_h)malloc(sizeof(sensor_recorder_query_h));
-       if (!*query)
-               return SENSOR_ERROR_OUT_OF_MEMORY;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_destroy_query(sensor_recorder_query_h query)
-{
-       if (!query)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_query_set_int(sensor_recorder_query_h query, sensor_recorder_query_e attribute, int value)
-{
-       if (!query)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (attribute < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_query_set_time(sensor_recorder_query_h query, sensor_recorder_query_e attribute, time_t t)
-{
-       if (!query)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (attribute < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (t < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_read(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
-{
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!query || !cb)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_read_sync(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
-{
-       if (type <= SENSOR_ALL)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (!query || !cb)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_data_get_time(sensor_recorder_data_h data, time_t *start_time, time_t *end_time)
-{
-       if (!data || !start_time || !end_time)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_data_get_int(sensor_recorder_data_h data, sensor_recorder_data_e key, int *value)
-{
-       if (!data || !value)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (key < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
-
-int sensor_recorder_data_get_double(sensor_recorder_data_h data, sensor_recorder_data_e key, double *value)
-{
-       if (!data || !value)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-       if (key < 0)
-               return SENSOR_ERROR_INVALID_PARAMETER;
-
-       return SENSOR_ERROR_NONE;
-}
diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b9b59ef
--- /dev/null
@@ -0,0 +1,19 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sensor-shared CXX)
+
+SET(DEPENDENTS "dlog libsystemd glib-2.0 gio-2.0 vconf libtzplatform-config")
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(SHARED_PKGS REQUIRED ${DEPENDENTS})
+
+FOREACH(flag ${SHARED_PKGS_CFLAGS})
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+FILE(GLOB_RECURSE SRCS *.cpp)
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SHARED_PKGS_LDFLAGS})
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
diff --git a/src/shared/accept_event_handler.cpp b/src/shared/accept_event_handler.cpp
new file mode 100644 (file)
index 0000000..419d912
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "accept_event_handler.h"
+
+#include "sensor_log.h"
+#include "ipc_server.h"
+
+using namespace ipc;
+
+accept_event_handler::accept_event_handler(ipc_server *server)
+: m_server(server)
+{
+}
+
+bool accept_event_handler::handle(int fd, event_condition condition, void **data)
+{
+       retv_if((condition & (EVENT_HUP)), false);
+
+       stream_socket *cli_sock = new(std::nothrow) stream_socket();
+       retvm_if(!cli_sock, false, "Failed to allocate memory");
+
+       m_server->accept(*cli_sock);
+
+       channel *_ch = new(std::nothrow) channel(cli_sock);
+       if (!_ch) {
+               delete cli_sock;
+               _E("Failed to allocate memory");
+               return false;
+       }
+
+       m_server->register_channel(cli_sock->get_fd(), _ch);
+
+       return true;
+}
diff --git a/src/shared/accept_event_handler.h b/src/shared/accept_event_handler.h
new file mode 100644 (file)
index 0000000..b732238
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ACCEPT_EVENT_HANDLER__
+#define __ACCEPT_EVENT_HANDLER__
+
+#include "event_handler.h"
+
+namespace ipc {
+
+class ipc_server;
+
+class accept_event_handler : public event_handler
+{
+public:
+       accept_event_handler(ipc_server *server);
+
+       bool handle(int fd, event_condition condition, void **data);
+
+private:
+       ipc_server *m_server;
+};
+
+}
+
+#endif /* __ACCEPT_EVENT_HANDLER__ */
diff --git a/src/shared/cbase_lock.cpp b/src/shared/cbase_lock.cpp
new file mode 100644 (file)
index 0000000..eafd601
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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 <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <cbase_lock.h>
+#include <sensor_log.h>
+
+using namespace sensor;
+
+cbase_lock::cbase_lock()
+{
+       m_history_mutex = PTHREAD_MUTEX_INITIALIZER;
+}
+
+cbase_lock::~cbase_lock()
+{
+       pthread_mutex_destroy(&m_history_mutex);
+}
+
+void cbase_lock::lock(lock_type type, const char* expr, const char *module, const char *func, int line)
+{
+       int ret = 0;
+       char m_curent_info[OWNER_INFO_LEN];
+       struct timeval sv;
+       unsigned long long lock_waiting_start_time = 0;
+       unsigned long long lock_acquired_time = 0;
+       unsigned long long waiting_time = 0;
+
+       snprintf(m_curent_info, OWNER_INFO_LEN, "%s:%s(%d)", module, func, line); 
+
+       if (type == LOCK_TYPE_MUTEX)
+               ret = try_lock_impl();
+       else if (type == LOCK_TYPE_READ)
+               ret = try_read_lock_impl();
+       else if (type == LOCK_TYPE_WRITE)
+               ret = try_write_lock_impl();
+
+       if (ret == 0) {
+               pthread_mutex_lock(&m_history_mutex);
+               snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info);
+               pthread_mutex_unlock(&m_history_mutex);
+               return;
+       }
+
+       gettimeofday(&sv, NULL);
+       lock_waiting_start_time = MICROSECONDS(sv);
+
+       pthread_mutex_lock(&m_history_mutex);
+       _I("%s is waiting for getting %s(%p) owned in %s",
+               m_curent_info, expr, this, m_owner_info);
+       pthread_mutex_unlock(&m_history_mutex);
+
+       if (type == LOCK_TYPE_MUTEX)
+               lock_impl();
+       else if (type == LOCK_TYPE_READ)
+               read_lock_impl();
+       else if (type == LOCK_TYPE_WRITE)
+               write_lock_impl();
+
+       gettimeofday(&sv, NULL);
+       lock_acquired_time = MICROSECONDS(sv);
+
+       waiting_time = lock_acquired_time - lock_waiting_start_time;
+
+       pthread_mutex_lock(&m_history_mutex);
+       _I("%s acquires lock after waiting %lluus, %s(%p) was previously owned in %s",
+               m_curent_info, waiting_time, expr, this, m_owner_info);
+       snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info);
+       pthread_mutex_unlock(&m_history_mutex);
+}
+
+void cbase_lock::lock(lock_type type)
+{
+       if (type == LOCK_TYPE_MUTEX)
+               lock_impl();
+       else if (type == LOCK_TYPE_READ)
+               read_lock_impl();
+       else if (type == LOCK_TYPE_WRITE)
+               write_lock_impl();
+}
+
+void cbase_lock::unlock(void)
+{
+       unlock_impl();
+}
+
+int cbase_lock::lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::read_lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::write_lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::try_lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::try_read_lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::try_write_lock_impl(void)
+{
+       return 0;
+}
+
+int cbase_lock::unlock_impl(void)
+{
+       return 0;
+}
+
+Autolock::Autolock(cbase_lock &m, lock_type type, const char* expr, const char *module, const char *func, int line)
+: m_lock(m)
+{
+       m_lock.lock(type, expr, module, func, line);
+}
+
+Autolock::Autolock(cbase_lock &m, lock_type type)
+: m_lock(m)
+{
+       m_lock.lock(type);
+}
+
+Autolock::~Autolock()
+{
+       m_lock.unlock();
+}
diff --git a/src/shared/cbase_lock.h b/src/shared/cbase_lock.h
new file mode 100644 (file)
index 0000000..5c76040
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 _CBASE_LOCK_H_
+#define _CBASE_LOCK_H_
+
+#include <pthread.h>
+
+namespace sensor {
+
+enum lock_type {
+       LOCK_TYPE_MUTEX,
+       LOCK_TYPE_READ,
+       LOCK_TYPE_WRITE,
+};
+
+#ifndef MICROSECONDS
+#define MICROSECONDS(tv)        ((tv.tv_sec * 1000000ll) + tv.tv_usec)
+#endif
+
+#ifdef _LOCK_DEBUG
+#define AUTOLOCK(x) Autolock x##_autolock((x), LOCK_TYPE_MUTEX, #x, __MODULE__, __func__, __LINE__)
+#define AUTOLOCK_R(x) Autolock x##_autolock_r((x), LOCK_TYPE_READ, #x,  __MODULE__, __func__, __LINE__)
+#define AUTOLOCK_W(x) Autolock x##_autolock_w((x), LOCK_TYPE_WRITE, #x, __MODULE__, __func__, __LINE__)
+#define LOCK(x)                (x).lock(#x, __MODULE__, __func__, __LINE__)
+#define LOCK_R(x)      (x).lock(LOCK_TYPE_READ, #x, __MODULE__, __func__, __LINE__)
+#define LOCK_W(x)      (x).lock(LOCK_TYPE_WRITE, #x, __MODULE__, __func__, __LINE__)
+#define UNLOCK(x)      (x).unlock()
+#else
+#define AUTOLOCK(x) Autolock x##_autolock((x), LOCK_TYPE_MUTEX)
+#define AUTOLOCK_R(x) Autolock x##_autolock_r((x), LOCK_TYPE_READ)
+#define AUTOLOCK_W(x) Autolock x##_autolock_w((x), LOCK_TYPE_WRITE)
+#define LOCK(x)                (x).lock()
+#define LOCK_R(x)      (x).lock(LOCK_TYPE_READ)
+#define LOCK_W(x)      (x).lock(LOCK_TYPE_WRITE)
+#define UNLOCK(x)      (x).unlock()
+#endif
+
+class cbase_lock {
+public:
+       cbase_lock();
+       virtual ~cbase_lock();
+
+       void lock(lock_type type, const char* expr, const char *module, const char *func, int line);
+       void lock(lock_type type);
+       void unlock(void);
+
+protected:
+       virtual int lock_impl(void);
+       virtual int read_lock_impl(void);
+       virtual int write_lock_impl(void);
+
+       virtual int try_lock_impl(void);
+       virtual int try_read_lock_impl(void);
+       virtual int try_write_lock_impl(void);
+
+       virtual int unlock_impl(void);
+private:
+       pthread_mutex_t m_history_mutex;
+       static const int OWNER_INFO_LEN = 256;
+       char m_owner_info[OWNER_INFO_LEN];
+};
+
+class Autolock {
+private:
+       cbase_lock& m_lock;
+public:
+       Autolock(cbase_lock &m, lock_type type, const char* expr, const char *module, const char *func, int line);
+       Autolock(cbase_lock &m, lock_type type);
+       ~Autolock();
+};
+}
+
+#endif /* _CBASE_LOCK_H_ */
diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp
new file mode 100644 (file)
index 0000000..26b654c
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "channel.h"
+
+#include <stdint.h>
+#include <unistd.h>
+#include <memory>
+#include <algorithm>
+
+#include "sensor_log.h"
+#include "channel_event_handler.h"
+
+#define SYSTEMD_SOCK_BUF_SIZE (128*1024)
+
+using namespace ipc;
+using namespace sensor;
+
+class send_event_handler : public event_handler
+{
+public:
+       send_event_handler(channel *ch, std::shared_ptr<message> msg)
+       : m_ch(ch)
+       , m_msg(msg)
+       { }
+
+       virtual ~send_event_handler()
+       {
+               if (m_ch) {
+                       m_ch->remove_pending_event_id(m_event_id);
+               }
+       }
+
+       bool handle(int fd, event_condition condition, void** data)
+       {
+               if (!m_ch) {
+                       return false;
+               }
+
+               m_ch->remove_pending_event_id(m_event_id);
+
+               if (!m_ch->is_connected()) {
+                       return false;
+               }
+
+               if (condition & (EVENT_IN | EVENT_HUP)) {
+                       return false;
+               }
+
+               if (!m_ch->send_sync(*m_msg)) {
+                       return false;
+               }
+
+               return false;
+       }
+
+private:
+       channel *m_ch;
+       std::shared_ptr<message> m_msg;
+};
+
+class read_event_handler : public event_handler
+{
+public:
+       read_event_handler(channel *ch)
+       : m_ch(ch)
+       { }
+
+       bool handle(int fd, event_condition condition, void **data)
+       {
+               if (!m_ch) {
+                       return false;
+               }
+
+               m_ch->remove_pending_event_id(m_event_id);
+
+               if (!m_ch->is_connected()) {
+                       return false;
+               }
+
+               if (condition & (EVENT_OUT | EVENT_HUP)) {
+                       return false;
+               }
+
+               message msg;
+               if (!m_ch->read_sync(msg, false)) {
+                       return false;
+               }
+
+               return false;
+       }
+
+private:
+       channel *m_ch;
+};
+
+channel::channel(socket *sock)
+: m_fd(sock->get_fd())
+, m_event_id(0)
+, m_socket(sock)
+, m_handler(NULL)
+, m_loop(NULL)
+, m_connected(false)
+{
+       _D("Create[%p]", this);
+}
+
+channel::~channel()
+{
+       _D("Destroy[%p]", this);
+       if (is_connected()) {
+               disconnect();
+       }
+}
+
+uint64_t channel::bind(void)
+{
+       retv_if(!m_loop, 0);
+       channel_event_handler* handler = dynamic_cast<channel_event_handler *>(m_handler);
+
+       if (!handler) {
+               _E("Failed to bind channel[%p] : handler[%p]", this, m_handler);
+               m_event_id = 0;
+               return 0;
+       }
+       m_event_id = m_loop->add_event(m_socket->get_fd(),
+                       (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler);
+
+       _D("Bind channel[%p] : handler[%p] event_id[%llu]", this, m_handler, m_event_id);
+       return m_event_id;
+}
+
+uint64_t channel::bind(channel_handler *handler, event_loop *loop, bool loop_bind)
+{
+       m_handler = handler;
+       m_loop = loop;
+       m_connected.store(true);
+
+       if (m_handler)
+               m_handler->connected(this);
+
+       if (loop_bind)
+               bind();
+
+       return m_event_id;
+}
+
+uint64_t channel::connect(channel_handler *handler, event_loop *loop, bool loop_bind)
+{
+       if (!m_socket->connect())
+               return false;
+
+       if (handler)
+               bind(handler, loop, loop_bind);
+
+       _D("Connect channel[%p] : event id[%llu]", this, m_event_id);
+       return m_event_id;
+}
+
+void channel::disconnect(void)
+{
+       AUTOLOCK(m_cmutex);
+       if (!is_connected()) {
+               _D("Channel[%p] is not connected", this);
+               return;
+       }
+
+       m_connected.store(false);
+
+       _D("Disconnect channel[%p]", this);
+
+       if (m_handler) {
+               _D("Disconnect channel[%p] handler[%p]", this, m_handler);
+               m_handler->disconnected(this);
+               if (!m_loop)
+                       delete m_handler;
+               m_handler = NULL;
+       }
+
+       if (m_loop) {
+               for(auto id : m_pending_event_id) {
+                       _D("Remove channel[%p] pending event id[%llu]", this, id);
+                       m_loop->remove_event(id);
+               }
+               _D("Remove channel[%p] event[%llu]",this, m_event_id);
+               m_loop->remove_event(m_event_id);
+               m_event_id = 0;
+       }
+
+       if (m_socket) {
+               _D("Release channel[%p] socket[%d]", this, m_socket->get_fd());
+               delete m_socket;
+               m_socket = NULL;
+       }
+       _D("Channel[%p] is disconnected", this);
+}
+
+bool channel::send(std::shared_ptr<message> msg)
+{
+       int retry_cnt = 0;
+       int cur_buffer_size = 0;
+
+       retv_if(!m_loop, false);
+
+       while (retry_cnt < 3) {
+               cur_buffer_size = m_socket->get_current_buffer_size();
+               if (cur_buffer_size <= SYSTEMD_SOCK_BUF_SIZE)
+                       break;
+               usleep(3000);
+               retry_cnt++;
+       }
+       retvm_if(retry_cnt >= 3, false, "Socket buffer[%d] is exceeded", cur_buffer_size);
+
+       send_event_handler *handler = new(std::nothrow) send_event_handler(this, msg);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       uint64_t event_id = m_loop->add_event(m_socket->get_fd(), (EVENT_OUT | EVENT_HUP | EVENT_NVAL), handler);
+       if (event_id == 0) {
+               _D("Failed to add send event handler");
+               delete handler;
+               return false;
+       }
+
+       m_pending_event_id.push_back(event_id);
+       return true;
+}
+
+bool channel::send_sync(message &msg)
+{
+       AUTOLOCK(m_cmutex);
+       if (!is_connected()) {
+               _D("Channel is not connected");
+               return false;
+       }
+
+       retvm_if(msg.size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg.size());
+
+       ssize_t size = 0;
+       char *buf = msg.body();
+
+       /* header */
+       size = m_socket->send(reinterpret_cast<void *>(msg.header()),
+           sizeof(message_header), true);
+       retvm_if(size <= 0, false, "Failed to send header");
+
+       /* if body size is zero, skip to send body message */
+       retv_if(msg.size() == 0, true);
+
+       /* body */
+       size = m_socket->send(buf, msg.size(), true);
+       retvm_if(size <= 0, false, "Failed to send body");
+
+       return true;
+}
+
+bool channel::read(void)
+{
+       retv_if(!m_loop, false);
+
+       read_event_handler *handler = new(std::nothrow) read_event_handler(this);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       uint64_t event_id = m_loop->add_event(m_socket->get_fd(), (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler);
+       if (event_id == 0) {
+               _D("Failed to add read event handler");
+               delete handler;
+               return false;
+       }
+
+       m_pending_event_id.push_back(event_id);
+       return true;
+}
+
+bool channel::read_sync(message &msg, bool select)
+{
+       AUTOLOCK(m_cmutex);
+       if (!is_connected()) {
+               _D("Channel is not connected");
+               return false;
+       }
+
+       message_header header;
+       ssize_t size = 0;
+       char buf[MAX_MSG_CAPACITY];
+
+       /* header */
+       size = m_socket->recv(&header, sizeof(message_header), select);
+       if (size <= 0)
+               return false;
+
+       /* check error from header */
+       if (m_handler && header.err != 0) {
+               m_handler->error_caught(this, header.err);
+               msg.header()->err = header.err;
+               return true;
+       }
+
+       /* body */
+       if (header.length >= MAX_MSG_CAPACITY) {
+               _E("header.length error %u", header.length);
+               return false;
+       }
+
+       if (header.length > 0) {
+               size = m_socket->recv(&buf, header.length, select);
+               if (size <= 0)
+                       return false;
+       }
+
+       buf[header.length] = '\0';
+       msg.enclose(reinterpret_cast<const void *>(buf), header.length);
+       msg.set_type(header.type);
+       msg.header()->err = header.err;
+
+       if (m_handler)
+               m_handler->read(this, msg);
+
+       return true;
+}
+
+bool channel::is_connected(void)
+{
+       return m_connected.load();
+}
+
+bool channel::set_option(int type, int value)
+{
+       switch (type) {
+       case SO_SNDBUF:
+               m_socket->set_buffer_size(type, value);
+               break;
+       case SO_RCVBUF:
+               m_socket->set_buffer_size(type, value);
+               break;
+       default:
+               break;
+       }
+
+       return true;
+}
+
+bool channel::get_option(int type, int &value) const
+{
+       switch (type) {
+       case 0:
+               value = m_socket->get_current_buffer_size();
+               break;
+       case SO_SNDBUF:
+               value = m_socket->get_buffer_size(type);
+               break;
+       case SO_RCVBUF:
+               value = m_socket->get_buffer_size(type);
+               break;
+       default:
+               break;
+       }
+
+       return true;
+}
+
+int channel::get_fd(void) const
+{
+       return m_fd;
+}
+
+void channel::remove_pending_event_id(uint64_t id)
+{
+       auto it = std::find(m_pending_event_id.begin(), m_pending_event_id.end(), id);
+       if (it != m_pending_event_id.end()) {
+               m_pending_event_id.erase(it);
+       }
+}
diff --git a/src/shared/channel.h b/src/shared/channel.h
new file mode 100644 (file)
index 0000000..5af06da
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CHANNEL_H__
+#define __CHANNEL_H__
+
+#include <unistd.h>
+#include <atomic>
+#include <vector>
+
+#include "socket.h"
+#include "message.h"
+#include "event_loop.h"
+#include "channel_handler.h"
+#include "cmutex.h"
+
+namespace ipc {
+
+class channel_handler;
+
+class channel {
+public:
+       /* move owernership of the socket to the channel */
+       channel(socket *sock);
+       ~channel();
+
+       uint64_t bind(void);
+       uint64_t bind(channel_handler *handler, event_loop *loop, bool loop_bind);
+
+       uint64_t connect(channel_handler *handler, event_loop *loop, bool loop_bind);
+       void disconnect(void);
+
+       bool is_connected(void);
+
+       bool send(std::shared_ptr<message> msg);
+       bool send_sync(message &msg);
+
+       bool read(void);
+       bool read_sync(message &msg, bool select = true);
+
+       bool get_option(int type, int &value) const;
+       bool set_option(int type, int value);
+
+       int get_fd(void) const;
+       void remove_pending_event_id(uint64_t id);
+
+       event_loop *loop()
+       {
+               return m_loop;
+       }
+
+private:
+       int m_fd;
+       uint64_t m_event_id;
+       socket *m_socket;
+       channel_handler *m_handler;
+       event_loop *m_loop;
+       std::vector<uint64_t> m_pending_event_id;
+
+       std::atomic<bool> m_connected;
+       sensor::cmutex m_cmutex;
+};
+
+}
+
+#endif /* __CHANNEL_H__ */
diff --git a/src/shared/channel_event_handler.cpp b/src/shared/channel_event_handler.cpp
new file mode 100644 (file)
index 0000000..460b6a0
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "channel_event_handler.h"
+
+#include "channel.h"
+#include "channel_handler.h"
+#include "sensor_log.h"
+
+using namespace ipc;
+
+channel_event_handler::channel_event_handler(channel *ch, channel_handler *handler)
+: m_ch(ch)
+, m_handler(handler)
+{
+       _D("Create[%p]", this);
+}
+
+channel_event_handler::~channel_event_handler()
+{
+       _D("Destroy[%p]", this);
+       m_ch = NULL;
+       m_handler = NULL;
+}
+
+bool channel_event_handler::handle(int fd, event_condition condition, void **data)
+{
+       message msg;
+
+       if (!m_ch || !m_ch->is_connected())
+               return false;
+
+       if (condition & (EVENT_HUP)) {
+               //delete m_ch in g_io_handler to prevent double delete.
+               if (data)
+                       *data = m_ch;
+               m_ch = NULL;
+               return false;
+       }
+
+       if (!m_ch->read_sync(msg, false)) {
+               m_ch = NULL;
+               return false;
+       }
+
+       return true;
+}
+
+void channel_event_handler::connected(channel *ch)
+{
+       if (m_handler)
+               m_handler->connected(ch);
+}
+
+void channel_event_handler::disconnected(channel *ch)
+{
+       if (m_handler)
+               m_handler->disconnected(ch);
+}
+
+void channel_event_handler::read(channel *ch, message &msg)
+{
+       if (m_handler)
+               m_handler->read(ch, msg);
+}
+
+void channel_event_handler::read_complete(channel *ch)
+{
+       if (m_handler)
+               m_handler->read_complete(ch);
+}
+
+void channel_event_handler::error_caught(channel *ch, int error)
+{
+       if (m_handler)
+               m_handler->error_caught(ch, error);
+}
diff --git a/src/shared/channel_event_handler.h b/src/shared/channel_event_handler.h
new file mode 100644 (file)
index 0000000..85a3efd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CHANNEL_EVENT_HANDLER_H__
+#define __CHANNEL_EVENT_HANDLER_H__
+
+#include <unordered_map>
+
+#include "event_handler.h"
+#include "channel_handler.h"
+
+namespace ipc {
+
+class channel;
+
+class channel_event_handler : public event_handler, public channel_handler {
+public:
+       channel_event_handler(channel *ch, channel_handler *handler);
+       virtual ~channel_event_handler();
+
+       bool handle(int fd, event_condition condition, void **data);
+
+       void connected(channel *ch);
+       void disconnected(channel *ch);
+       void read(channel *ch, message &msg);
+       void read_complete(channel *ch);
+       void error_caught(channel *ch, int error);
+
+       void set_handler(int num, channel_handler* handler) {}
+       void disconnect(void) {}
+
+private:
+       channel *m_ch;
+       channel_handler *m_handler;
+};
+
+}
+
+#endif /* __CHANNEL_EVENT_HANDLER_H__ */
diff --git a/src/shared/channel_handler.h b/src/shared/channel_handler.h
new file mode 100644 (file)
index 0000000..abcab19
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CHANNEL_HANDLER_H__
+#define __CHANNEL_HANDLER_H__
+
+namespace ipc {
+
+class channel;
+class message;
+class channel_handler;
+
+class channel_handler {
+public:
+       virtual ~channel_handler() {}
+
+       virtual void connected(channel *ch) = 0;
+       virtual void disconnected(channel *ch) = 0;
+       virtual void disconnect(void) = 0;
+       virtual void read(channel *ch, message &msg) = 0;
+       virtual void read_complete(channel *ch) = 0;
+       virtual void error_caught(channel *ch, int error) = 0;
+       virtual void set_handler(int num, channel_handler* handler) = 0;
+};
+
+}
+
+#endif /* __CHANNEL_HANDLER_H__ */
diff --git a/src/shared/cmutex.cpp b/src/shared/cmutex.cpp
new file mode 100644 (file)
index 0000000..d3d19dd
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 <cmutex.h>
+#include <sensor_log.h>
+
+using namespace sensor;
+
+cmutex::cmutex()
+{
+       pthread_mutexattr_t mutex_attr;
+       pthread_mutexattr_init(&mutex_attr);
+       pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
+       pthread_mutex_init(&m_mutex, &mutex_attr);
+       pthread_mutexattr_destroy(&mutex_attr);
+}
+
+cmutex::~cmutex()
+{
+       pthread_mutex_destroy(&m_mutex);
+}
+
+void cmutex::lock(void)
+{
+#ifdef _LOCK_DEBUG
+       cbase_lock::lock(LOCK_TYPE_MUTEX, "mutex", __MODULE__, __func__, __LINE__);
+#else
+       cbase_lock::lock(LOCK_TYPE_MUTEX);
+#endif
+}
+
+void cmutex::lock(const char* expr, const char *module, const char *func, int line)
+{
+       cbase_lock::lock(LOCK_TYPE_MUTEX, expr, module, func, line);
+}
+
+int cmutex::try_lock(void)
+{
+       return try_lock_impl();
+}
+
+int cmutex::lock_impl(void)
+{
+       return pthread_mutex_lock(&m_mutex);
+}
+
+int cmutex::try_lock_impl(void)
+{
+       return pthread_mutex_trylock(&m_mutex);
+}
+
+int cmutex::unlock_impl(void)
+{
+       return pthread_mutex_unlock(&m_mutex);
+}
diff --git a/src/shared/cmutex.h b/src/shared/cmutex.h
new file mode 100644 (file)
index 0000000..b6c3d4d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 _CMUTEX_H_
+#define _CMUTEX_H_
+
+#include "cbase_lock.h"
+namespace sensor {
+
+class cmutex : public cbase_lock {
+public:
+       cmutex();
+       virtual ~cmutex();
+
+       void lock(void);
+       void lock(const char* expr, const char *module, const char *func, int line);
+       int try_lock(void);
+
+protected:
+       int lock_impl(void);
+       int try_lock_impl(void);
+       int unlock_impl(void);
+
+private:
+       pthread_mutex_t m_mutex;
+};
+
+}
+#endif /* _CMUTEX_H_ */
diff --git a/src/shared/command_types.h b/src/shared/command_types.h
new file mode 100644 (file)
index 0000000..29aaf86
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2016 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_TYPES_H__
+#define __COMMAND_TYPES_H__
+
+#include <sensor_types.h>
+#include "sensor_info.h"
+
+#define SENSOR_CHANNEL_PATH            "/run/.sensord.socket"
+#define MAX_BUF_SIZE (16*1024)
+
+/* TODO: OOP - create serializer interface */
+enum cmd_type_e {
+       CMD_DONE = -1,
+       CMD_NONE = 0,
+
+       /* Manager */
+       CMD_MANAGER_CONNECT = 0x100,
+       CMD_MANAGER_SENSOR_LIST,
+       CMD_MANAGER_SENSOR_ADDED,
+       CMD_MANAGER_SENSOR_REMOVED,
+
+       /* Listener */
+       CMD_LISTENER_EVENT = 0x200,
+       CMD_LISTENER_ACC_EVENT,
+       CMD_LISTENER_CONNECT,
+       CMD_LISTENER_START,
+       CMD_LISTENER_STOP,
+       CMD_LISTENER_SET_ATTR_INT,
+       CMD_LISTENER_SET_ATTR_STR,
+       CMD_LISTENER_GET_DATA,
+       CMD_LISTENER_GET_ATTR_INT,
+       CMD_LISTENER_GET_ATTR_STR,
+       CMD_LISTENER_GET_DATA_LIST,
+       CMD_LISTENER_CONNECTED,
+
+       /* Provider */
+       CMD_PROVIDER_CONNECT = 0x300,
+       CMD_PROVIDER_START,
+       CMD_PROVIDER_STOP,
+       CMD_PROVIDER_ATTR_INT,
+       CMD_PROVIDER_PUBLISH,
+       CMD_PROVIDER_ATTR_STR,
+
+       /* Etc */
+       CMD_HAS_PRIVILEGE = 0x1000,
+
+       CMD_CNT,
+};
+
+typedef struct {
+       int sensor_cnt;
+       char data[0];
+} cmd_manager_sensor_list_t;
+
+typedef struct {
+       int listener_id;
+       char sensor[NAME_MAX];
+} cmd_listener_connect_t;
+
+typedef struct {
+       int listener_id;
+} cmd_listener_start_t;
+
+typedef struct {
+       int listener_id;
+} cmd_listener_stop_t;
+
+typedef struct {
+       int listener_id;
+       int attribute;
+       int value;
+} cmd_listener_attr_int_t;
+
+typedef struct {
+       int listener_id;
+       int attribute;
+       int len;
+       char value[0];
+} cmd_listener_attr_str_t;
+
+typedef struct {
+       int listener_id;
+       int len;
+       sensor_data_t data;
+} cmd_listener_get_data_t;
+
+typedef struct {
+       int listener_id;
+       int len;
+       int data_count;
+       sensor_data_t data[0];
+} cmd_listener_get_data_list_t;
+
+typedef struct {
+       char info[0];
+} cmd_provider_connect_t;
+
+typedef struct {
+       sensor_data_t data;
+} cmd_provider_publish_t;
+
+typedef struct  {
+       int attribute;
+       int value;
+} cmd_provider_attr_int_t;
+
+typedef struct  {
+       int attribute;
+       int len;
+       char value[0];
+} cmd_provider_attr_str_t;
+
+typedef struct {
+       char sensor[NAME_MAX];
+} cmd_has_privilege_t ;
+
+#endif /* __COMMAND_TYPES_H__ */
diff --git a/src/shared/event_handler.h b/src/shared/event_handler.h
new file mode 100644 (file)
index 0000000..7d1696a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __EVENT_HANDLER_H__
+#define __EVENT_HANDLER_H__
+
+#include <stdint.h>
+namespace ipc {
+
+typedef unsigned int event_condition;
+
+class event_handler {
+public:
+       event_handler()
+               : m_event_id(0)
+       {
+       }
+
+       virtual ~event_handler() {}
+
+       virtual bool handle(int fd, event_condition condition, void **data) = 0;
+       void set_event_id(uint64_t event_id)
+       {
+               m_event_id = event_id;
+       }
+
+protected:
+       uint64_t m_event_id;
+};
+
+}
+
+#endif /* __EVENT_HANDLER_H__ */
diff --git a/src/shared/event_loop.cpp b/src/shared/event_loop.cpp
new file mode 100644 (file)
index 0000000..720687b
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "event_loop.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/eventfd.h>
+#include <glib.h>
+
+#include <vector>
+#include <queue>
+
+#include "channel_event_handler.h"
+#include "sensor_log.h"
+#include "event_handler.h"
+#include "channel.h"
+
+#define BAD_HANDLE 0
+
+using namespace ipc;
+using namespace sensor;
+
+static std::vector<channel_handler*> channel_handler_release_list;
+static std::priority_queue<channel*> channel_release_queue;
+static sensor::cmutex release_lock;
+
+static void release_res()
+{
+       AUTOLOCK(release_lock);
+
+       channel *prev = NULL, *current = NULL;
+       while (!channel_release_queue.empty()) {
+               current = channel_release_queue.top();
+               if (prev != current)
+                       delete current;
+               prev = current;
+               channel_release_queue.pop();
+       }
+
+       for (auto &it : channel_handler_release_list)
+               delete it;
+
+       /* To reduce memory allocation, swap to new data structure.
+          This prevents occasional over-allocation of memory. */
+       std::priority_queue<channel*>().swap(channel_release_queue);
+       std::vector<channel_handler*>().swap(channel_handler_release_list);
+}
+
+static gboolean g_io_handler(GIOChannel *ch, GIOCondition condition, gpointer data)
+{
+       uint64_t id;
+       int fd;
+       bool term;
+       bool ret;
+       event_loop *loop;
+       event_handler *handler;
+       unsigned int cond;
+
+       cond = (unsigned int)condition;
+
+       if (cond & (G_IO_HUP))
+               cond &= ~(G_IO_IN | G_IO_OUT);
+
+       handler_info *info = (handler_info *)data;
+       loop = info->loop;
+       handler = info->handler;
+       retvm_if(!loop || !handler, FALSE, "Invalid event info");
+
+       id = info->id;
+       fd = info->fd;
+       term = loop->is_terminator(fd);
+
+       if (cond & G_IO_NVAL)
+               return G_SOURCE_REMOVE;
+
+       void *addr = NULL;
+       ret = handler->handle(fd, (event_condition)cond, &addr);
+
+       if (!ret && !term) {
+               LOCK(release_lock);
+               channel_release_queue.push((channel*)addr);
+               UNLOCK(release_lock);
+               if (!addr)
+                       loop->remove_event(id);
+               ret = G_SOURCE_REMOVE;
+       } else {
+               ret = G_SOURCE_CONTINUE;
+       }
+
+       release_res();
+
+       return ret;
+}
+
+static gint on_timer(gpointer data)
+{
+       event_loop *loop = (event_loop *)data;
+       loop->stop();
+
+       return FALSE;
+}
+
+event_loop::event_loop()
+: m_mainloop(NULL)
+, m_running(false)
+, m_terminating(false)
+, m_sequence(1)
+, m_term_fd(-1)
+{
+       m_mainloop = g_main_loop_new(NULL, FALSE);
+}
+
+event_loop::event_loop(GMainLoop *mainloop)
+: m_mainloop(NULL)
+, m_running(true)
+, m_terminating(false)
+, m_sequence(1)
+, m_term_fd(-1)
+{
+       m_mainloop = mainloop;
+}
+
+event_loop::~event_loop()
+{
+       if (m_term_fd != -1)
+               close(m_term_fd);
+
+       _D("Destoryed");
+}
+
+void event_loop::set_mainloop(GMainLoop *mainloop)
+{
+       retm_if(!mainloop, "Invalid mainloop");
+
+       m_mainloop = mainloop;
+}
+
+uint64_t event_loop::add_event(const int fd, const event_condition cond, event_handler *handler)
+{
+       AUTOLOCK(m_cmutex);
+       GIOChannel *ch = NULL;
+       GSource *src = NULL;
+
+       retvm_if(m_terminating.load(), BAD_HANDLE,
+                       "Failed to add event, because event_loop is being terminated");
+
+       ch = g_io_channel_unix_new(fd);
+       retvm_if(!ch, BAD_HANDLE, "Failed to create g_io_channel_unix_new");
+
+       src = g_io_create_watch(ch, (GIOCondition)(cond));
+       if (!src) {
+               g_io_channel_unref(ch);
+               _E("Failed to create g_io_create_watch");
+               return BAD_HANDLE;
+       }
+
+       uint64_t id = m_sequence++;
+       if (m_sequence == 0) {
+               m_sequence = 1;
+       }
+
+       handler_info *info = new(std::nothrow) handler_info(id, fd, ch, src, handler, this);
+       retvm_if(!info, BAD_HANDLE, "Failed to allocate memory");
+
+       handler->set_event_id(id);
+       g_source_set_callback(src, (GSourceFunc) g_io_handler, info, NULL);
+       g_source_attach(src, g_main_loop_get_context(m_mainloop));
+
+       m_handlers[id] = info;
+
+       /* _D("Added event[%llu], fd[%d]", id, fd); */
+       return id;
+}
+
+struct idler_data {
+       void (*m_fn)(size_t, void*);
+       void* m_data;
+};
+
+size_t event_loop::add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data)
+{
+       AUTOLOCK(m_cmutex);
+       GSource *src;
+
+       retvm_if(m_terminating.load(), 0,
+                       "Failed to remove event, because event_loop is terminated");
+
+       src = g_idle_source_new();
+       retvm_if(!src, 0, "Failed to allocate memory");
+
+       idler_data *id = new idler_data();
+       id->m_fn = fn;
+       id->m_data = data;
+
+       g_source_set_callback(src, [](gpointer gdata) -> gboolean {
+               idler_data *id = (idler_data *)gdata;
+               id->m_fn((size_t)id, id->m_data);
+               delete id;
+               return G_SOURCE_REMOVE;
+       }, id, NULL);
+
+       g_source_attach(src, g_main_loop_get_context (m_mainloop));
+       g_source_unref(src);
+
+       return (size_t)id;
+}
+
+bool event_loop::remove_event(uint64_t id)
+{
+       AUTOLOCK(m_cmutex);
+       auto it = m_handlers.find(id);
+       retv_if(it == m_handlers.end(), false);
+
+       release_info(it->second);
+       m_handlers.erase(id);
+
+       /* _D("Removed event[%llu]", id); */
+       return true;
+}
+
+void event_loop::remove_all_events(void)
+{
+       AUTOLOCK(m_cmutex);
+       auto it = m_handlers.begin();
+       while (it != m_handlers.end()) {
+               release_info(it->second);
+               it = m_handlers.erase(it);
+       }
+}
+
+void event_loop::release_info(handler_info *info)
+{
+       retm_if(!info->g_ch || info->id == 0, "Invalid handler information");
+       /* _D("Releasing event..[%llu]", info->id); */
+
+       g_source_destroy(info->g_src);
+       g_source_unref(info->g_src);
+
+       g_io_channel_unref(info->g_ch);
+
+       info->g_ch = NULL;
+       delete info->handler;
+       info->handler = NULL;
+
+       delete info;
+
+       /* _D("Released event[%llu]", info->id); */
+}
+
+void event_loop::add_channel_release_queue(channel *ch)
+{
+       AUTOLOCK(release_lock);
+       channel_release_queue.push(ch);
+}
+
+void event_loop::add_channel_handler_release_list(channel_handler *handler)
+{
+       AUTOLOCK(release_lock);
+       channel_handler_release_list.push_back(handler);
+}
+
+class terminator : public event_handler
+{
+public:
+       terminator(event_loop *loop)
+       : m_loop(loop)
+       { }
+
+       bool handle(int fd, event_condition condition, void **data)
+       {
+               m_loop->terminate();
+               return false;
+       }
+
+private:
+       event_loop *m_loop;
+};
+
+bool event_loop::run(int timeout)
+{
+       retvm_if(!m_mainloop, false, "Invalid GMainLoop");
+       retvm_if(is_running(), false, "Already started");
+
+       if (timeout > 0) {
+               GSource *src = g_timeout_source_new(timeout);
+               g_source_set_callback(src, on_timer, this, NULL);
+               g_source_attach(src, g_main_loop_get_context(m_mainloop));
+               g_source_unref(src);
+       }
+
+       m_term_fd = eventfd(0, EFD_CLOEXEC);
+       retv_if(m_term_fd == -1, false);
+
+       terminator *handler = new(std::nothrow) terminator(this);
+       retvm_if(!handler, false, "Failed to allocate memory");
+
+       add_event(m_term_fd, EVENT_IN | EVENT_HUP | EVENT_NVAL, handler);
+
+       m_running.store(true);
+
+       _I("Started");
+       g_main_loop_run(m_mainloop);
+
+       return true;
+}
+
+void event_loop::stop(void)
+{
+       ret_if(!is_running() || m_terminating.load());
+
+       terminate();
+}
+
+void event_loop::terminate(void)
+{
+       remove_all_events();
+
+       if (m_mainloop) {
+               g_main_loop_quit(m_mainloop);
+               g_main_loop_unref(m_mainloop);
+               m_mainloop = NULL;
+       }
+
+       m_running.store(false);
+       m_terminating.store(false);
+
+       _I("Terminated");
+}
+
+bool event_loop::is_running(void)
+{
+       return m_running.load();
+}
+
+bool event_loop::is_terminator(int fd)
+{
+       return (m_term_fd == fd);
+}
diff --git a/src/shared/event_loop.h b/src/shared/event_loop.h
new file mode 100644 (file)
index 0000000..aeae959
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __EVENT_LOOP_H__
+#define __EVENT_LOOP_H__
+
+#include <stdint.h>
+#include <glib.h>
+#include <atomic>
+#include <map>
+
+#include "event_handler.h"
+#include "cmutex.h"
+
+namespace ipc {
+
+class channel;
+class channel_handler;
+
+enum event_condition_e {
+       EVENT_IN =  G_IO_IN,
+       EVENT_OUT = G_IO_OUT,
+       EVENT_HUP = G_IO_HUP,
+       EVENT_NVAL = G_IO_NVAL,
+};
+
+/* move it to file */
+class idle_handler {
+       virtual ~idle_handler();
+       bool handle(int fd);
+};
+
+class event_loop;
+
+class handler_info {
+public:
+       handler_info(uint64_t _id, int _fd, GIOChannel *_ch, GSource *_src, event_handler *_handler, event_loop *_loop)
+       : id(_id)
+       , fd(_fd)
+       , g_ch(_ch)
+       , g_src(_src)
+       , handler(_handler)
+       , loop(_loop)
+       {}
+
+       uint64_t id;
+       int fd;
+       GIOChannel *g_ch;
+       GSource *g_src;
+       event_handler *handler;
+       event_loop *loop;
+};
+
+class event_loop {
+public:
+       typedef unsigned int event_condition;
+       typedef bool (*idle_cb)(void *);
+
+       event_loop();
+       event_loop(GMainLoop *mainloop);
+       ~event_loop();
+
+       void set_mainloop(GMainLoop *mainloop);
+
+       uint64_t add_event(const int fd, const event_condition cond, event_handler *handler);
+       size_t add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data);
+
+       bool remove_event(uint64_t id);
+       void remove_all_events(void);
+       void release_info(handler_info *info);
+
+       void add_channel_release_queue(channel *ch);
+       void add_channel_handler_release_list(channel_handler *handler);
+
+       bool run(int timeout = 0);
+       void stop(void);
+       void terminate(void);
+
+       bool is_running(void);
+       bool is_terminator(int fd);
+
+private:
+       GMainLoop *m_mainloop;
+       std::atomic<bool> m_running;
+       std::atomic<bool> m_terminating;
+       std::atomic<uint64_t> m_sequence;
+       std::map<uint64_t, handler_info *> m_handlers;
+
+       int m_term_fd;
+       sensor::cmutex m_cmutex;
+};
+
+}
+
+#endif /* __EVENT_LOOP_H__ */
diff --git a/src/shared/ipc_client.cpp b/src/shared/ipc_client.cpp
new file mode 100644 (file)
index 0000000..26c20a3
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "ipc_client.h"
+
+#include "sensor_log.h"
+#include "stream_socket.h"
+#include "event_handler.h"
+#include "channel_event_handler.h"
+
+using namespace ipc;
+
+ipc_client::ipc_client(const std::string &path)
+{
+       m_path = path;
+}
+
+ipc_client::~ipc_client()
+{
+}
+
+bool ipc_client::set_option(int option, int value)
+{
+       return true;
+}
+
+bool ipc_client::set_option(const std::string &option, int value)
+{
+       return true;
+}
+
+channel *ipc_client::connect(channel_handler *handler)
+{
+       return connect(handler, NULL);
+}
+
+channel *ipc_client::connect(channel_handler *handler, event_loop *loop, bool bind)
+{
+       socket *sock = NULL;
+       channel *ch = NULL;
+       channel_event_handler *ev_handler = NULL;
+
+       sock = new(std::nothrow) stream_socket();
+       retvm_if(!sock, NULL, "Failed to allocate memory");
+
+       if (!sock->create(m_path)) {
+               delete sock;
+               return NULL;
+       }
+
+       ch = new(std::nothrow) channel(sock);
+       if (!ch) {
+               delete sock;
+               _E("Failed to allocate memory");
+               return NULL;
+       }
+
+       ev_handler = new(std::nothrow) channel_event_handler(ch, handler);
+       if (!ev_handler) {
+               delete ch;
+               _E("Failed to allocate memory");
+               return NULL;
+       }
+
+       uint64_t id = ch->connect(ev_handler, loop, bind);
+
+       _D("Connected[%llu]", id);
+
+       return ch;
+}
diff --git a/src/shared/ipc_client.h b/src/shared/ipc_client.h
new file mode 100644 (file)
index 0000000..40d9182
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __IPC_CLIENT_H__
+#define __IPC_CLIENT_H__
+
+#include <string>
+
+#include "channel.h"
+#include "channel_handler.h"
+#include "event_loop.h"
+
+namespace ipc {
+
+class ipc_client {
+public:
+       ipc_client(const std::string &path);
+       ~ipc_client();
+
+       bool set_option(int option, int value);
+       bool set_option(const std::string &option, int value);
+
+       /* call channel->disconnect() after you have used it */
+       channel *connect(channel_handler *handler);
+       /* TODO: remove bind parameter */
+       channel *connect(channel_handler *handler, event_loop *loop, bool bind = true);
+
+private:
+       std::string m_path;
+};
+
+}
+
+#endif /* __IPC_CLIENT_H__ */
diff --git a/src/shared/ipc_server.cpp b/src/shared/ipc_server.cpp
new file mode 100644 (file)
index 0000000..d25a562
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "ipc_server.h"
+
+#include "channel.h"
+#include "sensor_log.h"
+#include "event_loop.h"
+#include "channel_event_handler.h"
+#include "accept_event_handler.h"
+
+using namespace ipc;
+
+#define MAX_CONNECTIONS 1000
+
+ipc_server::ipc_server(const std::string &path)
+: m_event_loop(NULL)
+, m_handler(NULL)
+, m_accept_handler(NULL)
+{
+       m_accept_sock.create(path);
+}
+
+ipc_server::~ipc_server()
+{
+}
+
+bool ipc_server::set_option(int option, int value)
+{
+       /* TODO */
+       return true;
+}
+
+bool ipc_server::set_option(const std::string &option, int value)
+{
+       /* TODO */
+       return true;
+}
+
+void ipc_server::accept(ipc::socket &cli_sock)
+{
+       m_accept_sock.accept(cli_sock);
+
+       _D("Accepted[%d]", cli_sock.get_fd());
+}
+
+bool ipc_server::bind(channel_handler *handler, event_loop *loop)
+{
+       m_handler = handler;
+       m_event_loop = loop;
+
+       m_accept_sock.bind();
+       m_accept_sock.listen(MAX_CONNECTIONS);
+
+       register_acceptor();
+
+       _D("Bound[%d]", m_accept_sock.get_fd());
+       return true;
+}
+
+void ipc_server::register_channel(int fd, channel *ch)
+{
+       channel_event_handler *ev_handler = new(std::nothrow) channel_event_handler(ch, m_handler);
+       retm_if(!ev_handler, "Failed to allocate memory");
+
+       uint64_t id = ch->bind(ev_handler, m_event_loop, true);
+
+       if (id == 0) {
+               _E("Failed to register channel");
+               delete ev_handler;
+               return;
+       }
+
+       _D("Register channel[%p] : event_id[%llu]", ch, id);
+}
+
+void ipc_server::register_acceptor(void)
+{
+       int fd = m_accept_sock.get_fd();
+
+       m_accept_handler = new(std::nothrow) accept_event_handler(this);
+       retm_if(!m_accept_handler, "Failed to allocate memory");
+
+       uint64_t id = m_event_loop->add_event(fd,
+                       (event_condition)(EVENT_IN | EVENT_HUP | EVENT_NVAL), m_accept_handler);
+
+       if (id == 0) {
+               _D("Failed to add accept event handler");
+               delete m_accept_handler;
+               m_accept_handler = NULL;
+       }
+}
+
+bool ipc_server::close(void)
+{
+       m_accept_sock.close();
+
+       m_handler = NULL;
+
+       return true;
+}
diff --git a/src/shared/ipc_server.h b/src/shared/ipc_server.h
new file mode 100644 (file)
index 0000000..7e033d0
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __IPC_SERVER_H__
+#define __IPC_SERVER_H__
+
+#include <string>
+
+#include "stream_socket.h"
+#include "channel.h"
+#include "channel_handler.h"
+#include "accept_event_handler.h"
+#include "event_loop.h"
+
+namespace ipc {
+
+class ipc_server {
+public:
+       ipc_server(const std::string &path);
+       ~ipc_server();
+
+       bool set_option(int option, int value);
+       bool set_option(const std::string &option, int value);
+
+       bool bind(channel_handler *handler, event_loop *loop);
+       bool close(void);
+
+       /* TODO: only accept_handler should use these functions */
+       void accept(ipc::socket &cli_sock);
+       void register_channel(int fd, channel *ch);
+       void register_acceptor(void);
+
+private:
+       stream_socket m_accept_sock;
+
+       event_loop *m_event_loop;
+       channel_handler *m_handler;
+       accept_event_handler *m_accept_handler;
+};
+
+}
+
+#endif /* __IPC_SERVER_H__ */
diff --git a/src/shared/macro.h b/src/shared/macro.h
new file mode 100644 (file)
index 0000000..0ec7bcf
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define _cleanup_(x) __attribute__((cleanup(x)))
+
+static inline void __freep(void *p)
+{
+       free(*(void**) p);
+}
+
+static inline void __closep(int *fd)
+{
+       if (*fd >= 0)
+               close(*fd);
+}
+
+static inline void __fclosep(FILE **f)
+{
+       if (*f)
+               fclose(*f);
+}
+
+static inline void int_to_bytes(int value, int width, char data[])
+{
+       /* Big-endian */
+       for (int i = width - 1; i >= 0; i--) {
+               data[i] = (value & 0xff);
+               value = value >> 8;
+       }
+}
+
+static inline unsigned int bytes_to_uint(char data[], int &cursor, int width)
+{
+       unsigned int sum = 0;
+
+       /* Big-endian */
+       for (int i = 0; i < width; ++i)
+               sum = (sum << 8) + (unsigned char)data[cursor++];
+
+       return sum;
+}
+
+#define _cleanup_free_ _cleanup_(__freep)
+#define _cleanup_close_ _cleanup_(__closep)
+#define _cleanup_fclose_ _cleanup_(__fclosep)
+#define GET_BYTES(value, width, data) int_to_bytes(value, width, data)
+#define GET_UINT(data, cursor, width) bytes_to_uint(data, cursor, width)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/src/shared/message.cpp b/src/shared/message.cpp
new file mode 100644 (file)
index 0000000..5f12d23
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "message.h"
+
+#include <sensor_log.h>
+#include <atomic>
+
+using namespace ipc;
+
+#define UNDEFINED_TYPE -2
+
+static std::atomic<uint64_t> sequence(0);
+
+message::message(size_t capacity)
+       : m_size(0)
+       , m_capacity(capacity)
+       , m_msg((char *)malloc(sizeof(char) * capacity))
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = m_size;
+       m_header.err = 0;
+}
+
+message::message(const void *msg, size_t sz)
+       : m_size(sz)
+       , m_capacity(sz)
+       , m_msg((char *)msg)
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = m_size;
+       m_header.err = 0;
+}
+
+message::message(const message &msg)
+       : m_size(msg.m_size)
+       , m_capacity(msg.m_capacity)
+       , m_msg((char *)malloc(sizeof(char) * msg.m_capacity))
+{
+       ::memcpy(&m_header, &msg.m_header, sizeof(message_header));
+       ::memcpy(m_msg, msg.m_msg, msg.m_size);
+}
+
+message::message(int error)
+       : m_size(0)
+       , m_capacity(0)
+       , m_msg(NULL)
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = 0;
+       m_header.err = error;
+}
+
+message::~message()
+{
+       if (m_msg) {
+               free(m_msg);
+               m_msg = NULL;
+       }
+}
+
+void message::enclose(const void *msg, const size_t sz)
+{
+       if (!msg || sz == 0)
+               return;
+
+       if (m_capacity < sz)
+               return;
+
+       ::memcpy(reinterpret_cast<char *>(m_msg), msg, sz);
+       m_size = sz;
+       m_header.length = sz;
+}
+
+void message::enclose(int error)
+{
+       m_header.err = error;
+       m_header.length = 0;
+       m_size = 0;
+}
+
+void message::disclose(void *msg, const size_t size)
+{
+       if (!msg || !m_msg || m_size > size)
+               return;
+
+       ::memcpy(msg, m_msg, m_size);
+}
+
+uint32_t message::type(void)
+{
+       return m_header.type;
+}
+
+void message::set_type(uint32_t msg_type)
+{
+       m_header.type = msg_type;
+}
+
+size_t message::size(void)
+{
+       return m_size;
+}
+
+message_header *message::header(void)
+{
+       return &m_header;
+}
+
+char *message::body(void)
+{
+       return m_msg;
+}
diff --git a/src/shared/message.h b/src/shared/message.h
new file mode 100644 (file)
index 0000000..49055c3
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+#include <stdlib.h> /* size_t */
+#include <atomic>
+#include <memory>
+
+#define MAX_MSG_CAPACITY (32*1024)
+#define MAX_HEADER_RESERVED 3
+
+namespace ipc {
+
+typedef struct message_header {
+       uint64_t id { 0 };
+       uint32_t type { 0 };
+       size_t length { 0 };
+       int32_t err { 0 };
+       void *ancillary[MAX_HEADER_RESERVED] { nullptr };
+} message_header;
+
+class message {
+public:
+       template <class... Args>
+       static std::shared_ptr<message> create(Args&&... args)
+               noexcept(noexcept(message(std::forward<Args>(args)...)))
+       {
+               return std::shared_ptr<message>(new (std::nothrow) message(std::forward<Args>(args)...));
+       }
+
+       message(size_t capacity = MAX_MSG_CAPACITY);
+       message(const void *msg, size_t size);
+       message(const message &msg);
+       message(int err);
+       ~message();
+
+       void enclose(const void *msg, const size_t size);
+       void enclose(int error);
+       void disclose(void *msg, const size_t size);
+
+       uint32_t type(void);
+       void set_type(uint32_t type);
+
+       size_t size(void);
+
+       void ref(void);
+       void unref(void);
+       int  ref_count(void);
+
+       message_header *header(void);
+       char *body(void);
+
+private:
+       message_header m_header;
+       size_t m_size;
+       size_t m_capacity;
+
+       char *m_msg;
+};
+
+}
+
+#endif /* __MESSAGE_H__ */
diff --git a/src/shared/sensor_info.cpp b/src/shared/sensor_info.cpp
new file mode 100644 (file)
index 0000000..f060083
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_info.h"
+
+#include <sensor_types.h>
+#include <sensor_types_private.h>
+#include <sensor_log.h>
+#include <cfloat>
+#include <algorithm>
+#include <string>
+#include <cmath>
+
+#include "sensor_utils.h"
+
+#define MIN_RANGE -FLT_MAX
+#define MAX_RANGE FLT_MAX
+
+using namespace sensor;
+
+sensor_info::sensor_info()
+: m_type(UNKNOWN_SENSOR)
+, m_uri(SENSOR_UNKNOWN_NAME)
+, m_model(SENSOR_UNKNOWN_NAME)
+, m_vendor(SENSOR_UNKNOWN_NAME)
+, m_min_range(0)
+, m_max_range(0)
+, m_resolution(0)
+, m_min_interval(0)
+, m_max_interval(0)
+, m_max_batch_count(0)
+, m_wakeup_supported(false)
+, m_privilege("")
+{
+}
+
+sensor_info::sensor_info(const sensor_info &info)
+: m_type(info.m_type)
+, m_uri(info.m_uri)
+, m_model(info.m_model)
+, m_vendor(info.m_vendor)
+, m_min_range(info.m_min_range)
+, m_max_range(info.m_max_range)
+, m_resolution(info.m_resolution)
+, m_min_interval(info.m_min_interval)
+, m_max_interval(info.m_max_interval)
+, m_max_batch_count(info.m_max_batch_count)
+, m_wakeup_supported(info.m_wakeup_supported)
+, m_privilege(info.m_privilege)
+{
+}
+
+sensor_info::sensor_info(const sensor_info_t &info)
+{
+       /* TODO: HAL should change name from single name to URI */
+       const char *type = sensor::utils::get_uri((sensor_type_t)info.type);
+       std::string uri(type);
+       uri.append("/").append(info.name);
+
+       set_type((sensor_type_t)info.type);
+       set_uri(uri.c_str());
+       set_model(info.model_name);
+       set_vendor(info.vendor);
+       set_min_range(info.min_range);
+       set_max_range(info.max_range);
+       set_resolution(info.resolution);
+       set_min_interval(info.min_interval);
+       set_max_interval(info.max_interval);
+       set_max_batch_count(info.max_batch_count);
+       set_wakeup_supported(info.wakeup_supported);
+       /* TODO: sensor_info_t should have privilege string */
+       set_privilege("");
+}
+
+sensor_info::sensor_info(const sensor_info2_t &info)
+{
+       std::string uri(info.uri);
+       std::size_t found = uri.find_last_of("/\\");
+
+       set_type(info.type);
+       set_uri(uri.c_str());
+       set_model(uri.substr(found + 1, uri.length()).c_str());
+       set_vendor(info.vendor);
+       set_min_range(info.min_range);
+       set_max_range(info.max_range);
+       set_resolution(info.resolution);
+       set_min_interval(info.min_interval);
+       set_max_interval(info.max_interval);
+       set_max_batch_count(info.max_batch_count);
+       set_wakeup_supported(info.wakeup_supported);
+       set_privilege(info.privilege);
+}
+
+sensor_type_t sensor_info::get_type(void)
+{
+       return m_type;
+}
+
+std::string &sensor_info::get_uri(void)
+{
+       return m_uri;
+}
+
+std::string &sensor_info::get_model(void)
+{
+       return m_model;
+}
+
+std::string &sensor_info::get_vendor(void)
+{
+       return m_vendor;
+}
+
+float sensor_info::get_min_range(void)
+{
+       return m_min_range;
+}
+
+float sensor_info::get_max_range(void)
+{
+       return m_max_range;
+}
+
+float sensor_info::get_resolution(void)
+{
+       return m_resolution;
+}
+
+int sensor_info::get_min_interval(void)
+{
+       return m_min_interval;
+}
+
+int sensor_info::get_max_interval(void)
+{
+       return m_max_interval;
+}
+
+int sensor_info::get_max_batch_count(void)
+{
+       return m_max_batch_count;
+}
+
+bool sensor_info::is_wakeup_supported(void)
+{
+       return m_wakeup_supported;
+}
+
+std::string &sensor_info::get_privilege(void)
+{
+       return m_privilege;
+}
+
+void sensor_info::set_type(sensor_type_t type)
+{
+       m_type = type;
+}
+
+void sensor_info::set_uri(const char *name)
+{
+       m_uri = name;
+}
+
+void sensor_info::set_model(const char *model)
+{
+       m_model = model;
+}
+
+void sensor_info::set_vendor(const char *vendor)
+{
+       m_vendor = vendor;
+}
+
+void sensor_info::set_min_range(float min_range)
+{
+       m_min_range = min_range;
+
+       if (!std::isnormal(m_min_range))
+               m_min_range = 0; /* set value to 0 when the value is NaN, infinity, zero or subnormal */
+       if (m_min_range < MIN_RANGE)
+               m_min_range = MIN_RANGE;
+       if (m_min_range > MAX_RANGE)
+               m_min_range = MAX_RANGE;
+}
+
+void sensor_info::set_max_range(float max_range)
+{
+       m_max_range = max_range;
+
+       if (!std::isnormal(m_max_range))
+               m_max_range = 0; /* set value to 0 when the value is NaN, infinity, zero or subnormal */
+       if (m_max_range < MIN_RANGE)
+               m_max_range = MIN_RANGE;
+       if (m_max_range > MAX_RANGE)
+               m_max_range = MAX_RANGE;
+}
+
+void sensor_info::set_resolution(float resolution)
+{
+       m_resolution = resolution;
+}
+
+void sensor_info::set_min_interval(int min_interval)
+{
+       m_min_interval = min_interval;
+}
+
+void sensor_info::set_max_interval(int max_interval)
+{
+       m_max_interval = max_interval;
+}
+
+void sensor_info::set_max_batch_count(int max_batch_count)
+{
+       m_max_batch_count = max_batch_count;
+}
+
+void sensor_info::set_wakeup_supported(bool supported)
+{
+       m_wakeup_supported = supported;
+}
+
+void sensor_info::set_privilege(const char *privilege)
+{
+       m_privilege = privilege;
+}
+
+void sensor_info::add_privilege(const char *privilege)
+{
+       if (!m_privilege.empty())
+               m_privilege.append(PRIV_DELIMITER);
+       m_privilege.append(privilege);
+}
+
+void sensor_info::serialize(raw_data_t &data)
+{
+       put(data, m_type);
+       put(data, m_uri);
+       put(data, m_model);
+       put(data, m_vendor);
+       put(data, m_min_range);
+       put(data, m_max_range);
+       put(data, m_resolution);
+       put(data, m_min_interval);
+       //put(data, m_max_interval); to do
+       put(data, m_max_batch_count);
+       put(data, m_wakeup_supported);
+       put(data, m_privilege);
+}
+
+void sensor_info::deserialize(const char *data, int data_len)
+{
+       int type;
+
+       raw_data_t raw_data(&data[0], &data[data_len]);
+       auto it = raw_data.begin();
+       it = get(it, type);
+       m_type = (sensor_type_t)type;
+
+       it = get(it, m_uri);
+       it = get(it, m_model);
+       it = get(it, m_vendor);
+       it = get(it, m_min_range);
+       it = get(it, m_max_range);
+       it = get(it, m_resolution);
+       it = get(it, m_min_interval);
+       //it = get(it, m_max_interval); to do
+       it = get(it, m_max_batch_count);
+       it = get(it, m_wakeup_supported);
+       it = get(it, m_privilege);
+}
+
+void sensor_info::show(void)
+{
+       _I("URI = %s", m_uri.c_str());
+       _I("Model = %s", m_model.c_str());
+       _I("Vendor = %s", m_vendor.c_str());
+       _I("Min_range = %f", m_min_range);
+       _I("Max_range = %f", m_max_range);
+       _I("Resolution = %f", m_resolution);
+       _I("Min_interval = %d", m_min_interval);
+       _I("Max_batch_count = %d", m_max_batch_count);
+       _I("Wakeup_supported = %d", m_wakeup_supported);
+       _I("Privilege = %s", m_privilege.c_str());
+}
+
+void sensor_info::clear(void)
+{
+       m_type = UNKNOWN_SENSOR;
+       m_uri.clear();
+       m_model.clear();
+       m_vendor.clear();
+       m_min_range = 0.0f;
+       m_max_range = 0.0f;
+       m_resolution = 0.0f;
+       m_min_interval = 0;
+       m_max_interval = 0;
+       m_max_batch_count = 0;
+       m_wakeup_supported = false;
+       m_privilege.clear();
+}
+
+void sensor_info::put(raw_data_t &data, int value)
+{
+       char buffer[sizeof(value)];
+
+       int *temp = reinterpret_cast<int *>(buffer);
+       *temp = value;
+
+       copy(&buffer[0], &buffer[sizeof(buffer)], back_inserter(data));
+}
+
+void sensor_info::put(raw_data_t &data, unsigned int value)
+{
+       char buffer[sizeof(value)];
+
+       unsigned int *temp = reinterpret_cast<unsigned int *>(buffer);
+       *temp = value;
+
+       copy(&buffer[0], &buffer[sizeof(buffer)], back_inserter(data));
+}
+
+void sensor_info::put(raw_data_t &data, int64_t value)
+{
+       char buffer[sizeof(value)];
+
+       int64_t *temp = reinterpret_cast<int64_t *>(buffer);
+       *temp = value;
+
+       copy(&buffer[0], &buffer[sizeof(buffer)], back_inserter(data));
+}
+
+void sensor_info::put(raw_data_t &data, float value)
+{
+       char buffer[sizeof(value)];
+
+       float *temp = reinterpret_cast<float *>(buffer);
+       *temp = value;
+
+       copy(&buffer[0], &buffer[sizeof(buffer)], back_inserter(data));
+}
+
+void sensor_info::put(raw_data_t &data, std::string &value)
+{
+       put(data, (int) value.size());
+
+       copy(value.begin(), value.end(), back_inserter(data));
+}
+
+void sensor_info::put(raw_data_t &data, bool value)
+{
+       char buffer[sizeof(value)];
+
+       bool *temp = (bool *) buffer;
+       *temp = value;
+
+       copy(&buffer[0], &buffer[sizeof(buffer)], back_inserter(data));
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, int &value)
+{
+       copy(it, it + sizeof(value), (char*) &value);
+
+       return it + sizeof(value);
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, unsigned int &value)
+{
+       copy(it, it + sizeof(value), (char*) &value);
+
+       return it + sizeof(value);
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, int64_t &value)
+{
+       copy(it, it + sizeof(value), (char*) &value);
+
+       return it + sizeof(value);
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, float &value)
+{
+       copy(it, it + sizeof(value), (char*) &value);
+
+       return it + sizeof(value);
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, std::string &value)
+{
+       int len;
+
+       it = get(it, len);
+
+       copy(it, it + len, back_inserter(value));
+
+       return it + len;
+}
+
+raw_data_iterator sensor_info::get(raw_data_iterator it, bool &value)
+{
+       copy(it, it + sizeof(value), (char*) &value);
+
+       return it + sizeof(value);
+}
diff --git a/src/shared/sensor_info.h b/src/shared/sensor_info.h
new file mode 100644 (file)
index 0000000..cbd5406
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_INFO_H__
+#define __SENSOR_INFO_H__
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <hal/hal-sensor-types.h>
+#include <sensor_types.h>
+
+namespace sensor {
+
+typedef std::vector<char> raw_data_t;
+typedef raw_data_t::iterator raw_data_iterator;
+
+/* TODO: builder */
+class sensor_info {
+public:
+       sensor_info();
+       sensor_info(const sensor_info &info);
+       sensor_info(const sensor_info_t &info);
+       sensor_info(const sensor_info2_t &info);
+
+       /* TODO: it would be better to return type(URI) */
+       sensor_type_t get_type(void);
+       std::string &get_uri(void);
+       std::string &get_model(void);
+       std::string &get_vendor(void);
+       float get_min_range(void);
+       float get_max_range(void);
+       float get_resolution(void);
+       int get_min_interval(void);
+       int get_max_interval(void);
+       int get_max_batch_count(void);
+       bool is_wakeup_supported(void);
+       std::string &get_privilege(void);
+
+       void set_type(sensor_type_t type);
+       void set_uri(const char *name);
+       void set_model(const char *name);
+       void set_vendor(const char *vendor);
+       void set_min_range(float min_range);
+       void set_max_range(float max_range);
+       void set_resolution(float resolution);
+       void set_min_interval(int min_interval);
+       void set_max_interval(int max_interval);
+       void set_max_batch_count(int max_batch_count);
+       void set_wakeup_supported(bool supported);
+       void set_privilege(const char *privilege);
+       void add_privilege(const char *privilege);
+
+       void clear(void);
+
+       void serialize(raw_data_t &data);
+       void deserialize(const char *data, int data_len);
+       void show(void);
+
+private:
+       sensor_type_t m_type;
+       std::string m_uri;
+       std::string m_model;
+       std::string m_vendor;
+       float m_min_range;
+       float m_max_range;
+       float m_resolution;
+       int m_min_interval;
+       int m_max_interval;
+       int m_max_batch_count;
+       bool m_wakeup_supported;
+       std::string m_privilege;
+
+       /* TODO: use template */
+       void put(raw_data_t &data, int value);
+       void put(raw_data_t &data, unsigned int value);
+       void put(raw_data_t &data, int64_t value);
+       void put(raw_data_t &data, float value);
+       void put(raw_data_t &data, std::string &value);
+       void put(raw_data_t &data, bool value);
+
+       /* TODO: use template */
+       raw_data_iterator get(raw_data_iterator it, int &value);
+       raw_data_iterator get(raw_data_iterator it, unsigned int &value);
+       raw_data_iterator get(raw_data_iterator it, int64_t &value);
+       raw_data_iterator get(raw_data_iterator it, float &value);
+       raw_data_iterator get(raw_data_iterator it, std::string &value);
+       raw_data_iterator get(raw_data_iterator it, bool &value);
+};
+
+}
+
+#endif /* __SENSOR_INFO_H__ */
diff --git a/src/shared/sensor_types_private.h b/src/shared/sensor_types_private.h
new file mode 100644 (file)
index 0000000..b76a6fe
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_TYPES_PRIVATE__
+#define __SENSOR_TYPES_PRIVATE__
+
+#define URI_REGEX(CATEGORY) R"~(^http:\/\/[\w-]+(\.[\w-]+)*\/)~" CATEGORY R"~(\/(general|healthinfo)\/[\w-]+(\.[\w-]+)*(\/[\w-]+(\.[\w-]+)*)$)~"
+#define SENSOR_URI_REGEX URI_REGEX("sensor")
+
+#define PREDEFINED_TYPE_URI "http://tizen.org/sensor/"
+
+#define PRIV_DELIMITER ";"
+#define URI_DELIMITER "/"
+
+#define PRIVILEGE_HEALTHINFO_STR "healthinfo"
+#define PRIVILEGE_HEALTHINFO_URI "http://tizen.org/privilege/healthinfo"
+
+#define PRIVILEGE_LOCATION_STR "location"
+#define PRIVILEGE_LOCATION_URI "http://tizen.org/privilege/location"
+
+#define PRIVILEGE_PLATFORM_STR "platform"
+#define PRIVILEGE_PLATFORM_URI "http://tizen.org/privilege/internal/default/platform"
+
+#define URI_PRIV_INDEX 4
+#define URI_SENSOR_TYPE_INDEX 5
+
+#endif /* __SENSOR_TYPES_PRIVATE__ */
diff --git a/src/shared/sensor_utils.cpp b/src/shared/sensor_utils.cpp
new file mode 100644 (file)
index 0000000..58a5978
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_utils.h"
+
+#include <glib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stddef.h>
+#include <map>
+
+#include <sensor_log.h>
+#include <sensor_types.h>
+#include <sensor_types_private.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+
+/* TODO: move and define string type to sensor_type.h */
+static std::map<sensor_type_t, const char *> types = {
+       {UNKNOWN_SENSOR,                 "http://tizen.org/sensor/general/unknown"},
+       {ALL_SENSOR,                     "http://tizen.org/sensor/general/all"},
+       {ACCELEROMETER_SENSOR,           "http://tizen.org/sensor/general/accelerometer"},
+       {GRAVITY_SENSOR,                 "http://tizen.org/sensor/general/gravity"},
+       {LINEAR_ACCEL_SENSOR,            "http://tizen.org/sensor/general/linear_acceleration"},
+       {GEOMAGNETIC_SENSOR,             "http://tizen.org/sensor/general/magnetic"},
+       {ROTATION_VECTOR_SENSOR,         "http://tizen.org/sensor/general/rotation_vector"},
+       {ORIENTATION_SENSOR,             "http://tizen.org/sensor/general/orientation"},
+       {GYROSCOPE_SENSOR,               "http://tizen.org/sensor/general/gyroscope"},
+       {LIGHT_SENSOR,                   "http://tizen.org/sensor/general/light"},
+       {PROXIMITY_SENSOR,               "http://tizen.org/sensor/general/proximity"},
+       {PRESSURE_SENSOR,                "http://tizen.org/sensor/general/pressure"},
+       {ULTRAVIOLET_SENSOR,             "http://tizen.org/sensor/general/ultraviolet"},
+       {TEMPERATURE_SENSOR,             "http://tizen.org/sensor/general/temperature"},
+       {HUMIDITY_SENSOR,                "http://tizen.org/sensor/general/humidity"},
+       {HRM_SENSOR,                     "http://tizen.org/sensor/healthinfo/heart_rate_monitor"},
+       {HRM_LED_GREEN_SENSOR,           "http://tizen.org/sensor/healthinfo/heart_rate_monitor.led_green"},
+       {HRM_LED_IR_SENSOR,              "http://tizen.org/sensor/healthinfo/heart_rate_monitor.led_ir"},
+       {HRM_LED_RED_SENSOR,             "http://tizen.org/sensor/healthinfo/heart_rate_monitor.led_red"},
+       {GYROSCOPE_UNCAL_SENSOR,         "http://tizen.org/sensor/general/gyroscope.uncalibrated"},
+       {GEOMAGNETIC_UNCAL_SENSOR,       "http://tizen.org/sensor/general/geomagnetic.uncalibrated"},
+       {GYROSCOPE_RV_SENSOR,            "http://tizen.org/sensor/general/gyroscope_rotation_vector"},
+       {GEOMAGNETIC_RV_SENSOR,          "http://tizen.org/sensor/general/geomagnetic_rotation_vector"},
+       {GYROSCOPE_ORIENTATION_SENSOR,   "http://tizen.org/sensor/general/gyroscope_orientation"},
+       {GEOMAGNETIC_ORIENTATION_SENSOR, "http://tizen.org/sensor/general/geomagnetic_orientation"},
+
+       {SIGNIFICANT_MOTION_SENSOR,      "http://tizen.org/sensor/general/significant_motion"},
+
+       {HRM_BATCH_SENSOR,               "http://tizen.org/sensor/healthinfo/heart_rate_monitor.batch"},
+       {HRM_LED_GREEN_BATCH_SENSOR,     "http://tizen.org/sensor/healthinfo/heart_rate_monitor.led_green.batch"},
+
+       {HUMAN_PEDOMETER_SENSOR,         "http://tizen.org/sensor/healthinfo/human_pedometer"},
+       {HUMAN_SLEEP_MONITOR_SENSOR,     "http://tizen.org/sensor/healthinfo/human_sleep_monitor"},
+       {HUMAN_SLEEP_DETECTOR_SENSOR,    "http://tizen.org/sensor/healthinfo/human_sleep_detector"},
+       {HUMAN_STRESS_MONITOR_SENSOR,    "http://tizen.org/sensor/healthinfo/human_stress_monitor"},
+
+       {LIDAR_SENSOR,                   "http://tizen.org/sensor/general/lidar"},
+
+       {EXERCISE_WALKING_SENSOR,        "http://tizen.org/sensor/healthinfo/exercise.walking"},
+       {EXERCISE_RUNNING_SENSOR,        "http://tizen.org/sensor/healthinfo/exercise.running"},
+       {EXERCISE_HIKING_SENSOR,         "http://tizen.org/sensor/healthinfo/exercise.hiking"},
+       {EXERCISE_CYCLING_SENSOR,        "http://tizen.org/sensor/healthinfo/exercise.cycling"},
+       {EXERCISE_ELLIPTICAL_SENSOR,     "http://tizen.org/sensor/healthinfo/exercise.elliptical"},
+       {EXERCISE_INDOOR_CYCLING_SENSOR, "http://tizen.org/sensor/healthinfo/exercise.indoor_cycling"},
+       {EXERCISE_ROWING_SENSOR,         "http://tizen.org/sensor/healthinfo/exercise.rowing"},
+       {EXERCISE_STEPPER_SENSOR,        "http://tizen.org/sensor/healthinfo/exercise.stepper"},
+
+
+       {FUSION_SENSOR,                  "http://tizen.org/sensor/general/fusion"},
+       {AUTO_ROTATION_SENSOR,           "http://tizen.org/sensor/general/auto_rotation"},
+       {AUTO_BRIGHTNESS_SENSOR,         "http://tizen.org/sensor/general/auto_brightness"},
+
+       {GESTURE_MOVEMENT_SENSOR,        "http://tizen.org/sensor/general/gesture_movement"},
+       {GESTURE_WRIST_UP_SENSOR,        "http://tizen.org/sensor/general/gesture_wrist_up"},
+       {GESTURE_WRIST_DOWN_SENSOR,      "http://tizen.org/sensor/general/gesture_wrist_down"},
+       {GESTURE_MOVEMENT_STATE_SENSOR,  "http://tizen.org/sensor/general/gesture_movement_state"},
+       {GESTURE_PICK_UP_SENSOR,         "http://tizen.org/sensor/general/gesture_pick_up"},
+       {GESTURE_FACE_DOWN_SENSOR,       "http://tizen.org/sensor/general/gesture_face_down"},
+
+       {ACTIVITY_TRACKER_SENSOR,        "http://tizen.org/sensor/general/activity_tracker"},
+       {ACTIVITY_LEVEL_MONITOR_SENSOR,  "http://tizen.org/sensor/general/activity_level_monitor"},
+       {GPS_BATCH_SENSOR,               "http://tizen.org/sensor/location/gps_batch"},
+       {PPG_BATCH_SENSOR,               "http://tizen.org/sensor/healthinfo/ppg_batch"},
+       {GPS_TIMESYNC_SENSOR,            "http://tizen.org/sensor/location/gps_timesync"},
+
+       {HRM_CTRL_SENSOR,                "http://tizen.org/sensor/general/hrm_ctrl"},
+       {REG_CTRL_SENSOR,                "http://tizen.org/sensor/general/reg_ctrl"},
+       {GPS_CTRL_SENSOR,                "http://tizen.org/sensor/general/gps_ctrl"},
+
+       {WEAR_STATUS_SENSOR,             "http://tizen.org/sensor/general/wear_status"},
+       {WEAR_ON_MONITOR_SENSOR,         "http://tizen.org/sensor/general/wear_on_monitor"},
+       {NO_MOVE_DETECTOR_SENSOR,        "http://tizen.org/sensor/general/no_move_detector"},
+       {RESTING_HR_SENSOR,              "http://tizen.org/sensor/healthinfo/resting_hr"},
+       {STEP_LEVEL_MONITOR_SENSOR,      "http://tizen.org/sensor/healthinfo/step_level_monitor"},
+       {EXERCISE_STANDALONE_SENSOR,     "http://tizen.org/sensor/healthinfo/exercise_standalone"},
+       {EXERCISE_HR_SENSOR,             "http://tizen.org/sensor/healthinfo/exercise_hr"},
+       {WORKOUT_SENSOR,                 "http://tizen.org/sensor/healthinfo/workout"},
+       {CYCLE_MONITOR_SENSOR,           "http://tizen.org/sensor/healthinfo/cycle_monitor"},
+       {STAIR_TRACKER_SENSOR,           "http://tizen.org/sensor/healthinfo/stair_tracker"},
+       {PRESSURE_INDICATOR_SENSOR,      "http://tizen.org/sensor/general/pressure_indicator"},
+       {PRESSURE_ALERT_SENSOR,          "http://tizen.org/sensor/general/pressure_alert"},
+       {HR_CALORIE_SENSOR,              "http://tizen.org/sensor/healthinfo/hr_calorie"},
+       {SWIMMING_TRACKER_SENSOR,        "http://tizen.org/sensor/healthinfo/swimming_tracker"},
+       {SWIMMING_OUTDOOR_SENSOR,        "http://tizen.org/sensor/healthinfo/swimming_outdoor"},
+       {AUTO_SWIMMING_SENSOR,           "http://tizen.org/sensor/healthinfo/auto_swimming"},
+       {INACTIVITY_DETECTOR_SENSOR,     "http://tizen.org/sensor/general/inactivity_detector"},
+       {STRESS_TRACKER_SENSOR,          "http://tizen.org/sensor/healthinfo/stress_tracker"},
+       {FAKE_MOTION_SENSOR,             "http://tizen.org/sensor/general/fake_motion"},
+       {GEOFENCE_SENSOR,                "http://tizen.org/sensor/general/geofence"},
+       {INACTIVITY_DETECTOR_SENSOR,     "http://tizen.org/sensor/healthinfo/inactivity_detector"},
+       {HRM_BP_SENSOR,                  "http://tizen.org/sensor/healthinfo/hrm_bp"},
+       {ECG_SENSOR,                     "http://tizen.org/sensor/healthinfo/ecg"},
+       {FALL_DETECTION_SENSOR,          "http://tizen.org/sensor/general/fall_detection"},
+
+       {CONTEXT_SENSOR,                 "http://tizen.org/sensor/general/context"},
+       {MOTION_SENSOR,                  "http://tizen.org/sensor/general/motion"},
+       {PIR_SENSOR,                     "http://tizen.org/sensor/general/pir"},
+       {PIR_LONG_SENSOR,                "http://tizen.org/sensor/general/pir_long"},
+       {DUST_SENSOR,                    "http://tizen.org/sensor/general/dust"},
+       {THERMOMETER_SENSOR,             "http://tizen.org/sensor/general/thermometer"},
+       {PEDOMETER_SENSOR,               "http://tizen.org/sensor/healthinfo/pedometer"},
+       {FLAT_SENSOR,                    "http://tizen.org/sensor/general/flat"},
+       {HRM_RAW_SENSOR,                 "http://tizen.org/sensor/healthinfo/hrm_raw"},
+       {TILT_SENSOR,                    "http://tizen.org/sensor/general/tilt"},
+       {RV_RAW_SENSOR,                  "http://tizen.org/sensor/general/rv_raw"},
+       {GSR_SENSOR,                     "http://tizen.org/sensor/healthinfo/gsr"},
+       {SIMSENSE_SENSOR,                "http://tizen.org/sensor/healthinfo/simsense"},
+       {PPG_SENSOR,                     "http://tizen.org/sensor/healthinfo/ppg"},
+};
+
+const char *sensor::utils::get_uri(sensor_type_t type)
+{
+       auto it = types.find(type);
+       if (it == types.end())
+               return types[UNKNOWN_SENSOR];
+       return it->second;
+}
+
+const char *sensor::utils::get_privilege(std::string uri)
+{
+       std::size_t start = 0;
+       std::size_t end = uri.length();
+       std::size_t size = uri.size();
+
+       for (int i = 0; i < URI_PRIV_INDEX; ++i) {
+               retv_if(start >= uri.length(), "");
+               start = uri.find(URI_DELIMITER, start + 1);
+               retv_if(start == std::string::npos, "");
+       }
+
+       end = uri.find(URI_DELIMITER, start + 1);
+       retv_if(end == std::string::npos, "");
+
+       size = end - (start + 1);
+
+       if (uri.substr(start + 1, size) == PRIVILEGE_HEALTHINFO_STR)
+               return PRIVILEGE_HEALTHINFO_URI;
+       else if (uri.substr(start + 1, size) == PRIVILEGE_LOCATION_STR)
+               return PRIVILEGE_LOCATION_URI;
+       else if (uri.substr(start + 1, size) == PRIVILEGE_PLATFORM_STR)
+               return PRIVILEGE_PLATFORM_URI;
+
+       return "";
+}
+
+static void init_types(std::map<std::string, sensor_type_t> &sensor_types)
+{
+       ret_if(!sensor_types.empty());
+
+       for (auto it = types.begin(); it != types.end(); ++it) {
+               std::string uri(it->second);
+               std::size_t found = uri.find_last_of("/");
+               std::size_t len = uri.length() - (found + 1);
+
+               sensor_types.emplace(uri.substr(found + 1, len), it->first);
+       }
+}
+
+sensor_type_t sensor::utils::get_type(std::string uri)
+{
+       static std::map<std::string, sensor_type_t> sensor_types;
+       init_types(sensor_types);
+
+       std::size_t start = 0;
+       std::size_t end = uri.length();
+       std::size_t size = uri.size();
+
+       for (int i = 0; i < URI_SENSOR_TYPE_INDEX; ++i) {
+               retv_if(start >= uri.length(), UNKNOWN_SENSOR);
+               start = uri.find(URI_DELIMITER, start + 1);
+               retv_if(start == std::string::npos, UNKNOWN_SENSOR);
+       }
+
+       end = uri.find(URI_DELIMITER, start + 1);
+       retv_if(end == std::string::npos, UNKNOWN_SENSOR);
+
+       size = end - (start + 1);
+
+       auto it = sensor_types.find(uri.substr(start + 1, size));
+       retv_if(it == sensor_types.end(), UNKNOWN_SENSOR);
+
+       return it->second;
+}
+
+unsigned long long sensor::utils::get_timestamp(void)
+{
+       struct timespec t;
+       clock_gettime(CLOCK_MONOTONIC, &t);
+       return ((unsigned long long)(t.tv_sec)*1000000000LL + t.tv_nsec) / 1000;
+}
+
+unsigned long long sensor::utils::get_timestamp(timeval *t)
+{
+       if (!t)
+               return 0;
+
+       return ((unsigned long long)(t->tv_sec)*1000000LL +t->tv_usec);
+}
+
+bool sensor::utils::get_proc_name(pid_t pid, char *process_name)
+{
+       char buf[NAME_MAX];
+
+       if (snprintf(buf, sizeof(buf), "%d process", pid) < 1) {
+               return false;
+       }
+
+       strncpy(process_name, buf, NAME_MAX-1);
+       process_name[NAME_MAX-1] = '\0';
+
+       return true;
+}
+
+const char* sensor::utils::get_client_name(void)
+{
+       const int pid_string_size = 10;
+       static pid_t pid = -1;
+       static char client_name[NAME_MAX + pid_string_size];
+
+       char proc_name[NAME_MAX];
+
+       if (pid == -1)
+       {
+               pid = getpid();
+               get_proc_name(pid, proc_name);
+               snprintf(client_name, sizeof(client_name), "%s(%d)", proc_name, pid);
+       }
+
+       return client_name;
+}
+
+std::vector<std::string> sensor::utils::tokenize(const std::string &in, const char *delim)
+{
+       std::vector<std::string> tokens;
+       char *input = g_strdup(in.c_str());
+
+       char *save = NULL;
+       char *token = strtok_r(input, delim, &save);
+
+       while (token != NULL) {
+               tokens.push_back(token);
+               token = strtok_r(NULL, delim, &save);
+       }
+
+       g_free(input);
+       return tokens;
+}
diff --git a/src/shared/sensor_utils.h b/src/shared/sensor_utils.h
new file mode 100644 (file)
index 0000000..3497dc7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_UTILS_H__
+#define __SENSOR_UTILS_H__
+
+#include <time.h>
+#include <sensor_types.h>
+#include <string>
+#include <vector>
+
+namespace sensor {
+
+namespace utils {
+       const char *get_uri(sensor_type_t type);
+       const char *get_privilege(std::string uri);
+       sensor_type_t get_type(std::string uri);
+
+       unsigned long long get_timestamp(void);
+       unsigned long long get_timestamp(timeval *t);
+
+       const char* get_client_name(void);
+       bool get_proc_name(pid_t pid, char *process_name);
+
+       std::vector<std::string> tokenize(const std::string &in, const char *delim);
+}
+
+}
+
+#endif /* __SENSOR_UTILS_H__ */
diff --git a/src/shared/seqpacket_socket.cpp b/src/shared/seqpacket_socket.cpp
new file mode 100644 (file)
index 0000000..ad27394
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "seqpacket_socket.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "sensor_log.h"
+
+using namespace ipc;
+
+seqpacket_socket::seqpacket_socket()
+: socket()
+{
+}
+
+seqpacket_socket::~seqpacket_socket()
+{
+}
+
+bool seqpacket_socket::create(const std::string &path)
+{
+       return socket::create_by_type(path, SOCK_SEQPACKET);
+}
+
+ssize_t seqpacket_socket::on_send(const void *buffer, size_t size) const
+{
+       ssize_t err, len;
+
+       do {
+               len = ::send(socket::get_fd(),
+                               reinterpret_cast<const char *>(buffer),
+                               size,
+                               socket::get_mode());
+
+               err = len < 0 ? errno : 0;
+       } while (err == EINTR);
+
+       if (err) {
+               _ERRNO(errno, _E, "Failed to send(%d, %p, %u) = %d",
+                       socket::get_fd(), buffer, size, len);
+       }
+
+       return err == 0 ? len : -err;
+}
+
+ssize_t seqpacket_socket::on_recv(void *buffer, size_t size) const
+{
+       ssize_t err, len;
+
+       do {
+               len = ::recv(socket::get_fd(),
+                               reinterpret_cast<char *>(buffer),
+                               size,
+                               socket::get_mode());
+
+               if (len > 0) {
+                       err = 0;
+               } else if (len == 0) {
+                       _E("Failed to recv(%d, %p , %u) = %d, because the peer performed shutdown!",
+                               socket::get_fd(), buffer, size, len);
+                       err = 1;
+               } else {
+                       err = errno;
+               }
+       } while (err == EINTR);
+
+       if ((err == EAGAIN) || (err == EWOULDBLOCK))
+               return 0;
+
+       if (err) {
+               _ERRNO(errno, _E, "Failed to recv(%d, %p, %u) = %d",
+                       socket::get_fd(), buffer, size, len);
+       }
+
+       return err == 0 ? len : -err;
+}
+
diff --git a/src/shared/seqpacket_socket.h b/src/shared/seqpacket_socket.h
new file mode 100644 (file)
index 0000000..05c25d8
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SEQPACKET_SOCKET_H__
+#define __SEQPACKET_SOCKET_H__
+
+#include "socket.h"
+
+namespace ipc {
+
+class seqpacket_socket : public socket {
+public:
+       seqpacket_socket();
+       ~seqpacket_socket();
+
+       bool create(const std::string &path);
+
+private:
+       ssize_t on_send(const void *buffer, size_t size) const;
+       ssize_t on_recv(void *buffer, size_t size) const;
+};
+
+}
+
+#endif /* __SEQPACKET_SOCKET_H__ */
diff --git a/src/shared/socket.cpp b/src/shared/socket.cpp
new file mode 100644 (file)
index 0000000..6d11076
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "socket.h"
+
+#include <fcntl.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <systemd/sd-daemon.h>
+
+#include "sensor_log.h"
+
+#define SOCK_TIMEOUT 10
+
+using namespace ipc;
+
+static bool set_close_on_exec(int fd)
+{
+       if (::fcntl(fd, F_SETFL, FD_CLOEXEC) == -1)
+               return false;
+
+       return true;
+}
+
+static int create_systemd_socket(const std::string &path, int type)
+{
+       int n;
+       int listening;
+
+       listening = (type == SOCK_STREAM) ? 1 : -1;
+
+       n = sd_listen_fds(0);
+       retvm_if(n < 0, -EPERM, "Failed to listen fds from systemd");
+
+       for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) {
+               if (sd_is_socket_unix(fd, type, listening, path.c_str(), 0) > 0) {
+                       set_close_on_exec(fd);
+                       return fd;
+               }
+       }
+
+       return -EPERM;
+}
+
+static int create_unix_socket(int type)
+{
+       int sock_fd = ::socket(AF_UNIX, type, 0);
+
+       if (sock_fd < 0) {
+               _ERRNO(errno, _E, "Failed to create socket");
+               return -EPERM;
+       }
+
+       set_close_on_exec(sock_fd);
+
+       int optval = 1;
+       if (::setsockopt(sock_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
+               _ERRNO(errno, _E, "Failed to create socket[%d]", sock_fd);
+               ::close(sock_fd);
+               return -EPERM;
+       }
+
+       return sock_fd;
+}
+
+static bool select_fds(int fd, fd_set *read_fds, fd_set *write_fds, const int timeout)
+{
+       struct timeval tv;
+       int err;
+
+       tv.tv_sec = timeout;
+       tv.tv_usec = 0;
+
+       while (true) {
+               err = ::select(fd + 1, read_fds, write_fds, NULL, &tv);
+               if (err <= 0)
+                       return false;
+
+               if (read_fds && FD_ISSET(fd, read_fds))
+                       break;
+               if (write_fds && FD_ISSET(fd, write_fds))
+                       break;
+       }
+
+       return true;
+}
+
+socket::socket()
+: m_sock_fd(-1)
+, m_mode(MSG_DONTWAIT | MSG_NOSIGNAL)
+, m_listening(false)
+{
+}
+
+socket::socket(int sock_fd)
+: m_sock_fd(sock_fd)
+, m_mode(MSG_DONTWAIT | MSG_NOSIGNAL)
+, m_listening(false)
+{
+}
+
+socket::socket(const socket &sock)
+: m_sock_fd(-1)
+, m_mode(MSG_DONTWAIT | MSG_NOSIGNAL)
+, m_listening(false)
+{
+       if (this == &sock)
+               return;
+
+       m_sock_fd = sock.m_sock_fd;
+       m_mode = sock.m_mode;
+       m_listening.store(sock.m_listening);
+}
+
+socket::~socket()
+{
+       close();
+}
+
+bool socket::connect(void)
+{
+       sockaddr_un addr;
+       fd_set write_fds;
+       FD_ZERO(&write_fds);
+       FD_SET(m_sock_fd, &write_fds);
+
+       retvm_if(m_path.size() >= sizeof(sockaddr_un::sun_path), false,
+                       "Failed to create socket[%s]", m_path.c_str());
+
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, m_path.c_str(), sizeof(sockaddr_un::sun_path));
+       addr.sun_path[m_path.size()] = '\0';
+
+       if (::connect(m_sock_fd,
+                               reinterpret_cast<struct sockaddr *>(&addr),
+                               sizeof(struct sockaddr_un)) < 0) {
+               _ERRNO(errno, _E, "Failed to connect() for socket[%d]", m_sock_fd);
+               close();
+               return false;
+       }
+
+       if (!select_fds(m_sock_fd, NULL, &write_fds, SOCK_TIMEOUT)) {
+               _E("Failed to select for socket[%d]", m_sock_fd);
+               close();
+               return false;
+       }
+
+       if (!has_connected()) {
+               close();
+               return false;
+       }
+
+       return true;
+}
+
+bool socket::bind(void)
+{
+       sockaddr_un addr;
+       int file_mode;
+
+       retvm_if(m_path.size() >= sizeof(sockaddr_un::sun_path), false,
+                       "Failed to create socket[%s]", m_path.c_str());
+       retv_if(m_listening.load(), true);
+
+       if (!access(m_path.c_str(), F_OK))
+               unlink(m_path.c_str());
+
+       addr.sun_family = AF_UNIX;
+       ::strncpy(addr.sun_path, m_path.c_str(), sizeof(sockaddr_un::sun_path));
+       addr.sun_path[m_path.size()] = '\0';
+
+       if (::bind(m_sock_fd,
+                               reinterpret_cast<struct sockaddr *>(&addr),
+                               sizeof(struct sockaddr_un)) < 0) {
+               _ERRNO(errno, _E, "Failed to bind for socket[%d]", m_sock_fd);
+               close();
+               return false;
+       }
+
+       /* TODO: Is this really necessary? */
+       file_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
+       if (chmod(m_path.c_str(), file_mode) < 0) {
+               _ERRNO(errno, _E, "Failed to create socket[%d]", m_sock_fd);
+               close();
+               return false;
+       }
+
+       return true;
+}
+
+bool socket::listen(const int max_connections)
+{
+       retv_if(m_listening.load(), true);
+
+       if (::listen(m_sock_fd, max_connections) < 0) {
+               _ERRNO(errno, _E, "Failed to listen() for socket[%d]", m_sock_fd);
+               close();
+               return false;
+       }
+
+       m_listening.store(true);
+
+       _D("Listened[%d]", m_sock_fd);
+
+       return true;
+}
+
+bool socket::accept(socket &client_sock)
+{
+       int fd;
+       fd_set read_fds;
+       FD_ZERO(&read_fds);
+       FD_SET(m_sock_fd, &read_fds);
+
+       fd = ::accept(m_sock_fd, NULL, NULL);
+
+       if (fd < 0) {
+               _ERRNO(errno, _E, "Failed to accept[%d]", m_sock_fd);
+               return false;
+       }
+
+       set_close_on_exec(fd);
+       client_sock.set_fd(fd);
+       /* TODO : socket type should be adjusted here */
+
+       return true;
+}
+
+bool socket::close(void)
+{
+       retv_if(m_sock_fd < 0, false);
+
+       if (::close(m_sock_fd) < 0)
+               return false;
+
+       _D("Closed[%d]", m_sock_fd);
+
+       m_sock_fd = -1;
+       m_listening.store(false);
+
+       return true;
+}
+
+int socket::get_fd(void) const
+{
+       return m_sock_fd;
+}
+
+void socket::set_fd(int sock_fd)
+{
+       m_sock_fd = sock_fd;
+}
+
+int socket::get_mode(void) const
+{
+       return m_mode;
+}
+
+bool socket::set_mode(int mode)
+{
+       /* TODO : implement send/recv message mode */
+       return true;
+}
+
+bool socket::create(const std::string &path)
+{
+       return false;
+}
+
+ssize_t socket::send(const void *buffer, size_t size, bool select) const
+{
+       if (select) {
+               fd_set write_fds;
+               FD_ZERO(&write_fds);
+               FD_SET(m_sock_fd, &write_fds);
+
+               if (!select_fds(m_sock_fd, NULL, &write_fds, SOCK_TIMEOUT)) {
+                       _E("Failed to send message(timeout)");
+                       return 0;
+               }
+       }
+
+       return on_send(buffer, size);
+}
+
+ssize_t socket::recv(void* buffer, size_t size, bool select) const
+{
+       if (select) {
+               fd_set read_fds;
+               FD_ZERO(&read_fds);
+               FD_SET(m_sock_fd, &read_fds);
+
+               if (!select_fds(m_sock_fd, &read_fds, NULL, SOCK_TIMEOUT)) {
+                       _E("Failed to receive message(timeout)");
+                       return 0;
+               }
+       }
+
+       return on_recv(buffer, size);
+}
+
+bool socket::create_by_type(const std::string &path, int type)
+{
+       m_sock_fd = ::create_systemd_socket(path, type);
+       if (m_sock_fd < 0)
+               m_sock_fd = create_unix_socket(type);
+       else
+               m_listening.store(true);
+
+       retvm_if((m_sock_fd < 0), false, "Failed to create socket");
+
+       /* non-blocking mode */
+       retvm_if(!set_blocking_mode(false), false, "Failed to set non-blocking mode");
+       /* recv timeout */
+       retvm_if(!set_recv_timeout(1), false, "Failed to set timeout");
+       /* TODO */
+       /*retvm_if(!set_reuse_addr(), false, "Failed to reuse address"); */
+
+       m_path = path;
+
+       return true;
+}
+
+int socket::get_sock_type(void)
+{
+       socklen_t opt_len;
+       int sock_type;
+       opt_len = sizeof(sock_type);
+
+       retvm_if(m_sock_fd < 0, false, "Invalid socket[%d]", m_sock_fd);
+
+       if (getsockopt(m_sock_fd, SOL_SOCKET, SO_TYPE, &sock_type, &opt_len) < 0) {
+          _ERRNO(errno, _E, "Failed to getsockopt from socket[%d]", m_sock_fd);
+          return false;
+       }
+
+       return sock_type;
+}
+
+bool socket::set_recv_timeout(int sec)
+{
+       struct timeval timeout = {sec, 0};
+
+       retvm_if(m_sock_fd < 0, false, "Invalid socket[%d]", m_sock_fd);
+
+       if (setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
+          _ERRNO(errno, _E, "Failed to setsockopt[%d]", m_sock_fd);
+          return false;
+       }
+
+       return true;
+}
+
+bool socket::set_sock_type(int type)
+{
+       socklen_t opt_len;
+       opt_len = sizeof(type);
+
+       retvm_if(m_sock_fd < 0, false, "Invalid socket[%d]", m_sock_fd);
+
+       if (setsockopt(m_sock_fd, SOL_SOCKET, SO_TYPE, &type, opt_len) < 0) {
+          _ERRNO(errno, _E, "Failed to setsockopt[%d]", m_sock_fd);
+          return false;
+       }
+
+       return true;
+}
+
+bool socket::set_blocking_mode(bool blocking)
+{
+       int flags;
+
+       flags = fcntl(m_sock_fd, F_GETFL);
+       retvm_if(flags == -1, false, "Failed to fcntl(F_GETFL)[%d]", m_sock_fd);
+
+       flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
+
+       flags = fcntl(m_sock_fd, F_SETFL, flags);
+       retvm_if(flags == -1, false, "Failed to fcntl(F_SETFL)[%d]", m_sock_fd);
+
+       return true;
+}
+
+bool socket::has_connected(void)
+{
+       int so_error;
+       socklen_t len = sizeof(so_error);
+
+       if (getsockopt(m_sock_fd, SOL_SOCKET, SO_ERROR, &so_error, &len) == -1) {
+               _E("Failed to call getsockopt[%d]", m_sock_fd);
+               return false;
+       }
+
+       if (so_error) {
+               _E("Failed to connect[%d] : %d", m_sock_fd, so_error);
+               return false;
+       }
+
+       return true;
+}
+
+bool socket::set_buffer_size(int type, int size)
+{
+       retv_if(m_sock_fd < 0, false);
+
+       int ret = 0;
+
+       ret = setsockopt(m_sock_fd, SOL_SOCKET, type, &size, sizeof(size));
+       retvm_if(ret < 0, false, "Failed to call setsocketopt()");
+
+       return true;
+}
+
+int socket::get_buffer_size(int type)
+{
+       retv_if(m_sock_fd < 0, false);
+
+       int ret = 0;
+       int buf_size = 0;
+       socklen_t len;
+
+       ret = getsockopt(m_sock_fd, SOL_SOCKET, type, &buf_size, &len);
+       retvm_if(ret < 0, -EPERM, "Failed to call getsocketopt()");
+
+       return buf_size;
+}
+
+int socket::get_current_buffer_size(void)
+{
+       retv_if(m_sock_fd < 0, false);
+
+       int queue_size = 0;
+       ioctl(m_sock_fd, TIOCOUTQ, &queue_size);
+
+       return queue_size;
+}
+
diff --git a/src/shared/socket.h b/src/shared/socket.h
new file mode 100644 (file)
index 0000000..e9b6b66
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SOCKET_H__
+#define __SOCKET_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string>
+#include <atomic>
+
+namespace ipc {
+
+class socket {
+public:
+       socket();
+       socket(int sock_fd);
+       socket(const socket &sock);
+       virtual ~socket();
+
+       virtual bool create(const std::string &path);
+
+       bool connect(void);
+       bool bind(void);
+       bool listen(const int max_connections);
+       bool accept(socket &client_sock);
+
+       bool close(void);
+
+       int  get_fd(void) const;
+       void set_fd(int sock_fd);
+
+       int  get_mode(void) const;
+       bool set_mode(int mode);
+
+       bool set_blocking_mode(bool blocking);
+       bool set_recv_timeout(int timeout);
+
+       /* type : SO_SNDBUF, SO_RCVBUF */
+       bool set_buffer_size(int type, int size);
+       int  get_buffer_size(int type);
+       int  get_current_buffer_size(void);
+
+       ssize_t send(const void *buffer, size_t size, bool select = false) const;
+       ssize_t recv(void* buffer, size_t size, bool select = false) const;
+
+protected:
+       bool create_by_type(const std::string &path, int type);
+
+private:
+       virtual ssize_t on_send(const void *buffer, size_t size) const = 0;
+       virtual ssize_t on_recv(void* buffer, size_t size) const = 0;
+
+       int  get_sock_type(void);
+       bool set_sock_type(int type);
+       bool has_connected(void);
+
+       int m_sock_fd;
+       int m_mode;
+       std::atomic<bool> m_listening;
+       std::string m_path;
+};
+
+}
+
+#endif /* __SOCKET_H__ */
diff --git a/src/shared/stream_socket.cpp b/src/shared/stream_socket.cpp
new file mode 100644 (file)
index 0000000..e583f26
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "stream_socket.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "sensor_log.h"
+
+#define SLEEP_10_MS usleep(10000)
+
+using namespace ipc;
+
+stream_socket::stream_socket()
+: socket()
+{
+}
+
+stream_socket::~stream_socket()
+{
+}
+
+bool stream_socket::create(const std::string &path)
+{
+       return socket::create_by_type(path, SOCK_STREAM);
+}
+
+ssize_t stream_socket::on_send(const void *buffer, size_t size) const
+{
+       ssize_t len = 0;
+       size_t total_size = 0;
+
+       do {
+               len = ::send(get_fd(),
+                               reinterpret_cast<const char *>(buffer) + total_size,
+                               size - total_size, get_mode());
+
+               if (len < 0) {
+                       if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
+                               SLEEP_10_MS;
+                               continue;
+                       }
+
+                       _ERRNO(errno, _E, "Failed to send(%d, %p, %u, %u) = %d",
+                                       get_fd(), buffer, total_size, size - total_size, len);
+                       return -errno;
+               }
+
+               total_size += len;
+       } while (total_size < size);
+
+       return total_size;
+}
+
+ssize_t stream_socket::on_recv(void *buffer, size_t size) const
+{
+       ssize_t len = 0;
+       size_t total_size = 0;
+
+       do {
+               len = ::recv(get_fd(),
+                               reinterpret_cast<char *>(buffer) + total_size,
+                               size - total_size,
+                               socket::get_mode());
+
+               if (len == 0) {
+                       _E("Failed to recv(%d, %p + %x, %u) = %d, because the peer performed shutdown",
+                               get_fd(), buffer, total_size, size - total_size, len);
+                       return -1;
+               }
+
+               if (len < 0) {
+                       if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
+                               SLEEP_10_MS;
+                               continue;
+                       }
+
+                       _ERRNO(errno, _E, "Failed to recv(%d, %p, %u, %u) = %d",
+                                       get_fd(), buffer, total_size, size - total_size, len);
+                       return -errno;
+               }
+
+               total_size += len;
+       } while (total_size < size);
+
+       return total_size;
+}
diff --git a/src/shared/stream_socket.h b/src/shared/stream_socket.h
new file mode 100644 (file)
index 0000000..42af03e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __STREAM_SOCKET_H__
+#define __STREAM_SOCKET_H__
+
+#include "socket.h"
+
+namespace ipc {
+
+class stream_socket : public socket {
+public:
+       stream_socket();
+       ~stream_socket();
+
+       bool create(const std::string &path);
+
+private:
+       ssize_t on_send(const void *buffer, size_t size) const;
+       ssize_t on_recv(void *buffer, size_t size) const;
+};
+
+}
+
+#endif /* __STREAM_SOCKET_H__ */
index 14287af979db2d3773f2b460c9fcf0a3af717480..eb334d570a77449c0dabe5e94eccd494ddbf9b77 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "spec_test.h"
 #include "stress_test.h"
-#include "sensor_info.h"
+#include "sensor_info_list.h"
 
 static void usage(void)
 {
@@ -40,9 +40,9 @@ static void usage(void)
                printf("\tspec : verifying measured value of range\n");
                printf("\tstress : giving stress to sensord\n");
                printf("[-s|--sensor_type] : (default is all in spec, accelerometer in stress)\n");
-               printf("\t0 : %s (It is valid in only spec test, not stress test)\n", sensor_infos[0].name);
+               printf("\t0 : %s (It is valid in only spec test, not stress test)\n", sensor_info_lists[0].name);
                for (int i = 1; i < SENSOR_NUM; ++i) {
-                       printf("\t%d : %s\n", i, sensor_infos[i].name);
+                       printf("\t%d : %s\n", i, sensor_info_lists[i].name);
                }
                printed = true;
        }
@@ -95,9 +95,9 @@ int main(int argc, char *argv[])
        if (sensor_type) {
                bool supported;
                int ret;
-               ret = sensor_is_supported(sensor_infos[sensor_type].type, &supported);
+               ret = sensor_is_supported(sensor_info_lists[sensor_type].type, &supported);
                if (ret < 0 || !supported) {
-                       printf("%s is not supported in this device.\n", sensor_infos[sensor_type].name);
+                       printf("%s is not supported in this device.\n", sensor_info_lists[sensor_type].name);
                        return 0;
                }
        }
index 2315ad934691f0fd0baa148f693d1d0ff6058cac..ac4aea96616e79208ffa662e5be0ef76e7a79b3a 100644 (file)
@@ -22,7 +22,7 @@
 #include <sensor.h>
 
 #include "spec_test.h"
-#include "sensor_info.h"
+#include "sensor_info_list.h"
 
 #define TEST_COUNT_ONE 100
 #define TEST_COUNT_ALL 1000
@@ -48,7 +48,7 @@ static void sensor_one_callback(sensor_h sensor, sensor_event_s events[], int ev
        ++callback_count;
 
        for (int i = 1; i < SENSOR_NUM; ++i){
-               if (sensor_infos[i].type == type){
+               if (sensor_info_lists[i].type == type){
                        num = i;
                        break;
                }
@@ -59,10 +59,10 @@ static void sensor_one_callback(sensor_h sensor, sensor_event_s events[], int ev
                ++called_num[num];
 
                int value_count;
-               if (events[i].value_count < sensor_infos[num].value_num)
+               if (events[i].value_count < sensor_info_lists[num].value_num)
                        value_count = events[i].value_count;
                else
-                       value_count = sensor_infos[num].value_num;
+                       value_count = sensor_info_lists[num].value_num;
 
                for (int j = 0; j < value_count; ++j) {
                        if (events[i].values[j] < min_range[num] || events[i].values[j] > max_range[num])
@@ -112,7 +112,7 @@ static void sensor_all_callback(sensor_h sensor, sensor_event_s events[], int ev
        ++callback_count;
 
        for (int i = 1; i < SENSOR_NUM; ++i){
-               if (sensor_infos[i].type == type){
+               if (sensor_info_lists[i].type == type){
                        num = i;
                        break;
                }
@@ -123,10 +123,10 @@ static void sensor_all_callback(sensor_h sensor, sensor_event_s events[], int ev
                ++called_num[num];
 
                int value_count;
-               if (events[i].value_count < sensor_infos[num].value_num)
+               if (events[i].value_count < sensor_info_lists[num].value_num)
                        value_count = events[i].value_count;
                else
-                       value_count = sensor_infos[num].value_num;
+                       value_count = sensor_info_lists[num].value_num;
 
                for (int j = 0; j < value_count; ++j) {
                        if (events[i].values[j] < min_range[num] || events[i].values[j] > max_range[num]) {
@@ -166,8 +166,8 @@ static int create_sensor_listener(int num, sensor_h *sensor, sensor_listener_h *
        bool supported;
        int ret = 0;
        float min, max;
-       const char *name = sensor_infos[num].name;
-       sensor_type_e type = sensor_infos[num].type;
+       const char *name = sensor_info_lists[num].name;
+       sensor_type_e type = sensor_info_lists[num].type;
 
        ret = sensor_is_supported(type, &supported);
        if (ret < 0) {
@@ -255,7 +255,7 @@ static void spec_test_one(int type)
        printf("=====================================\n");
 
        double rate = (double) (called_num[type] - miss[type]) / called_num[type] * 100;
-       printf("%s : %d / %d \n", sensor_infos[type].name, called_num[type] - miss[type], called_num[type]);
+       printf("%s : %d / %d \n", sensor_info_lists[type].name, called_num[type] - miss[type], called_num[type]);
 
        if (rate >= PASS)
                printf("PASS %.2lf%%\n", rate);
@@ -302,7 +302,7 @@ static void spec_test_all(void)
                if (turned_on[i]) {
                        if (called_num[i]) {
                                rate = (double) (called_num[i] - miss[i]) / called_num[i] * 100;
-                               printf("%s : %d / %d \n", sensor_infos[i].name, called_num[i] - miss[i], called_num[i]);
+                               printf("%s : %d / %d \n", sensor_info_lists[i].name, called_num[i] - miss[i], called_num[i]);
 
                                if (rate >= PASS)
                                        printf("PASS %.2lf%%\n", rate);
@@ -310,7 +310,7 @@ static void spec_test_all(void)
                                        printf("FAIL %.2lf%%\n", rate);
                        }
                        else {
-                               printf("%s value change was not occurred.\n", sensor_infos[i].name);
+                               printf("%s value change was not occurred.\n", sensor_info_lists[i].name);
                        }
                }
                total_miss += miss[i];
@@ -329,14 +329,14 @@ static void spec_test_all(void)
 
        for (int i = 1; i < SENSOR_NUM; ++i) {
                if (turned_on[i] == false)
-                       printf("%s\n", sensor_infos[i].name);
+                       printf("%s\n", sensor_info_lists[i].name);
        }
 }
 
 void spec_test(int type)
 {
        printf("=====================================\n");
-       printf("Sensor spec test (%s)\n", sensor_infos[type].name);
+       printf("Sensor spec test (%s)\n", sensor_info_lists[type].name);
        printf("=====================================\n");
 
        if (type == 0)
index bc835644a6a2051d7688c2e1c3605914791cb67a..ee52617841f5c8c35bbb5d453f6fc0bdd79da97c 100644 (file)
@@ -22,7 +22,7 @@
 #include <sensor.h>
 
 #include "stress_test.h"
-#include "sensor_info.h"
+#include "sensor_info_list.h"
 
 void sensor_events_callback(sensor_h sensor, sensor_event_s events[], int events_count, void *user_data)
 {
@@ -35,7 +35,7 @@ void sensor_listener_set_accuracy_callback(sensor_h sensor, unsigned long long t
 void stress_test(int type)
 {
        printf("=====================================\n");
-       printf("Sensor stress test (%s)\n", sensor_infos[type].name);
+       printf("Sensor stress test (%s)\n", sensor_info_lists[type].name);
        printf("=====================================\n");
        printf("Testing... Check sensord memory. (e.g. memps -s <pid>)\n");
        printf("If you need, additional execution of this stress test binary in another shell can add more stress to the sensord.\n.");
@@ -45,7 +45,7 @@ void stress_test(int type)
        sensor_event_s* events;
        int ret, count;
        while (1) {
-               ret = sensor_get_default_sensor(sensor_infos[type].type, &sh);
+               ret = sensor_get_default_sensor(sensor_info_lists[type].type, &sh);
                if (ret < 0) {
                        printf("fail \"get_default_sensor\": %d \n", ret);
                        break;
index 5ad4beb383dbc25f1f1b6213a3652c147651e0c2..06485f64176154afe606285f2dbdd619db64043c 100644 (file)
@@ -4,7 +4,7 @@
 #include <glib.h>
 #include <sensor.h>
 
-#include "sensor_info.h"
+#include "sensor_info_list.h"
 
 static GMainLoop *loop;
 static bool turned_on[40];
@@ -16,19 +16,19 @@ static void sensor_callback(sensor_h sensor, sensor_event_s events[], int events
        int num = 0;
 
        for (int i = 1; i < SENSOR_NUM; ++i){
-               if (sensor_infos[i].type == type){
+               if (sensor_info_lists[i].type == type){
                        num = i;
                        break;
                }
        }
 
-       g_print("[%s] : ", sensor_infos[num].alias);
+       g_print("[%s] : ", sensor_info_lists[num].alias);
        for (int i = 0; i < events_count; ++i) {
                int value_count;
-               if (events[i].value_count < sensor_infos[num].value_num)
+               if (events[i].value_count < sensor_info_lists[num].value_num)
                        value_count = events[i].value_count;
                else
-                       value_count = sensor_infos[num].value_num;
+                       value_count = sensor_info_lists[num].value_num;
 
                for (int j = 0; j < value_count; ++j)
                        g_print("%f ", events[i].values[j]);
@@ -42,8 +42,8 @@ static int create_sensor_listener(int num, int interval, sensor_h *sensor, senso
        bool supported;
        int ret;
        float min, max;
-       const char *name = sensor_infos[num].name;
-       sensor_type_e type = sensor_infos[num].type;
+       const char *name = sensor_info_lists[num].name;
+       sensor_type_e type = sensor_info_lists[num].type;
 
        sensor_is_supported(type, &supported);
        if (!supported) {
@@ -80,7 +80,7 @@ static void usage(void)
                printf("[-i|--interval] : The default is 10ms. range : 10 ~ 1000ms\n");
                printf("[-s|--sensor_type] : The default is all\n");
                for (int i = 0; i < SENSOR_NUM; ++i) {
-                       printf("\t%d : %s\n", i, sensor_infos[i].name);
+                       printf("\t%d : %s\n", i, sensor_info_lists[i].name);
                }
                printed = true;
        }
@@ -141,7 +141,7 @@ int main(int argc, char *argv[])
                        for (int i = 1; i < SENSOR_NUM; ++i) {
                                if (!turned_on[i])
                                        continue;
-                               printf("%s : [%s]\n", sensor_infos[i].name, sensor_infos[i].alias);
+                               printf("%s : [%s]\n", sensor_info_lists[i].name, sensor_info_lists[i].alias);
                        }
                        printf("\n");
                }