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)
+++ /dev/null
-#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},
-};
--- /dev/null
+#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},
+};
--- /dev/null
+/*
+ * 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__ */
{
#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"
#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_ */
--- /dev/null
+/*
+ * 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__ */
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"
%files
%manifest packaging/capi-system-sensor.manifest
%{_libdir}/libcapi-system-sensor.so.*
+%{_libdir}/libsensor-shared.so
%license LICENSE.APLv2
%files devel
--- /dev/null
+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})
--- /dev/null
+# 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}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_manager.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;
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_MANAGER_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_manager_channel_handler.h"
+
+#include <sensor_log.h>
+#include <command_types.h>
+#include "sensor_manager.h"
+
+using namespace sensor;
+
+sensor_manager::channel_handler::channel_handler(sensor_manager *manager)
+: m_manager(manager)
+{
+}
+
+void sensor_manager::channel_handler::connected(ipc::channel *ch)
+{
+}
+
+void sensor_manager::channel_handler::disconnected(ipc::channel *ch)
+{
+ /* If channel->disconnect() is not explicitly called, it will be restored */
+ m_manager->restore();
+}
+
+void sensor_manager::channel_handler::read(ipc::channel *ch, ipc::message &msg)
+{
+ switch (msg.header()->type) {
+ case CMD_MANAGER_SENSOR_ADDED:
+ on_sensor_added(ch, msg);
+ break;
+ case CMD_MANAGER_SENSOR_REMOVED:
+ on_sensor_removed(ch, msg);
+ break;
+ }
+}
+
+void sensor_manager::channel_handler::read_complete(ipc::channel *ch)
+{
+}
+
+void sensor_manager::channel_handler::error_caught(ipc::channel *ch, int error)
+{
+}
+
+void sensor_manager::channel_handler::on_sensor_added(ipc::channel *ch, ipc::message &msg)
+{
+ ret_if(msg.header()->err < OP_SUCCESS);
+
+ sensor_info info;
+ info.clear();
+ info.deserialize(msg.body(), msg.size());
+
+ m_manager->add_sensor(info);
+
+ auto it = m_sensor_added_callbacks.begin();
+ while (it != m_sensor_added_callbacks.end()) {
+ it->first(info.get_uri().c_str(), it->second);
+ ++it;
+ }
+}
+
+void sensor_manager::channel_handler::on_sensor_removed(ipc::channel *ch, ipc::message &msg)
+{
+ ret_if(msg.header()->err < 0);
+ char uri[NAME_MAX] = {0, };
+
+ msg.disclose(uri, NAME_MAX);
+ m_manager->remove_sensor(uri);
+
+ auto it = m_sensor_removed_callbacks.begin();
+ while (it != m_sensor_removed_callbacks.end()) {
+ it->first(uri, it->second);
+ ++it;
+ }
+}
+
+void sensor_manager::channel_handler::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
+{
+ m_sensor_added_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager::channel_handler::remove_sensor_added_cb(sensord_added_cb cb)
+{
+ m_sensor_added_callbacks.erase(cb);
+}
+
+void sensor_manager::channel_handler::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
+{
+ m_sensor_removed_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager::channel_handler::remove_sensor_removed_cb(sensord_removed_cb cb)
+{
+ m_sensor_removed_callbacks.erase(cb);
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_MANAGER_CHANNEL_HANDLER__
+#define __SENSOR_MANAGER_CHANNEL_HANDLER__
+
+#include <sensor_internal.h>
+#include <sensor_manager.h>
+#include <channel_handler.h>
+#include <map>
+
+namespace sensor {
+
+class sensor_manager::channel_handler : public ipc::channel_handler
+{
+public:
+ channel_handler(sensor_manager *manager);
+
+ void connected(ipc::channel *ch);
+ void disconnected(ipc::channel *ch);
+ void read(ipc::channel *ch, ipc::message &msg);
+ void read_complete(ipc::channel *ch);
+ void error_caught(ipc::channel *ch, int error);
+
+ void on_sensor_added(ipc::channel *ch, ipc::message &msg);
+ void on_sensor_removed(ipc::channel *ch, ipc::message &msg);
+
+ void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
+ void remove_sensor_added_cb(sensord_added_cb cb);
+
+ void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
+ void remove_sensor_removed_cb(sensord_removed_cb cb);
+
+ void set_handler(int num, ipc::channel_handler* handler) {}
+ void disconnect(void) {}
+
+private:
+ typedef std::map<sensord_added_cb, void *> sensor_added_cb_list_t;
+ typedef std::map<sensord_removed_cb, void *> sensor_removed_cb_list_t;
+
+ sensor_manager *m_manager;
+ sensor_added_cb_list_t m_sensor_added_callbacks;
+ sensor_removed_cb_list_t m_sensor_removed_callbacks;
+};
+
+}
+
+#endif /* __SENSOR_MANAGER_CHANNEL_HANDLER__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_provider_channel_handler.h"
+
+#include <command_types.h>
+#include <sensor_log.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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_PROVIDER_CHANNEL_HANDLER__
+#define __SENSOR_PROVIDER_CHANNEL_HANDLER__
+
+#include <channel_handler.h>
+#include <sensor_internal.h>
+#include "sensor_provider_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_provider_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);
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_PROVIDER_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__ */
--- /dev/null
+/*
+ * 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");
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+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})
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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);
+ }
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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);
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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);
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * 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]))
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_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);
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sensor_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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __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__ */
#include "spec_test.h"
#include "stress_test.h"
-#include "sensor_info.h"
+#include "sensor_info_list.h"
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;
}
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;
}
}
#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
++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;
}
++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])
++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;
}
++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]) {
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) {
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);
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);
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];
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)
#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)
{
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.");
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;
#include <glib.h>
#include <sensor.h>
-#include "sensor_info.h"
+#include "sensor_info_list.h"
static GMainLoop *loop;
static bool turned_on[40];
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]);
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) {
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;
}
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");
}