From 08c31a81531912d7ffe6f81621df328ffe5ffc8b Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Fri, 18 Dec 2015 09:46:35 +0900 Subject: [PATCH] sensor-plugin-tm1: plugins for tm1 supported sensors on TM1: accelerometer proximity code is copied from /platform/adaptation/samsung_exynos/sensor-plugins Signed-off-by: kibak.yoon Change-Id: If02dd5903cca6f5c2f181df9660f23a70264c1d1 --- CMakeLists.txt | 31 ++ LICENSE.APLv2 | 203 ++++++++++ packaging/sensor-hal.manifest | 5 + packaging/sensor-hal.spec | 61 +++ sensors.xml.in | 389 +++++++++++++++++++ src/CMakeLists.txt | 88 +++++ src/hal_module_create.cpp.in | 152 ++++++++ src/interface/sensor_hal.h | 65 ++++ src/interface/sensor_hal_base.cpp | 364 ++++++++++++++++++ src/interface/sensor_hal_base.h | 105 ++++++ src/lib/cbase_lock.cpp | 159 ++++++++ src/lib/cbase_lock.h | 87 +++++ src/lib/cconfig.cpp | 72 ++++ src/lib/cconfig.h | 41 ++ src/lib/cmutex.cpp | 65 ++++ src/lib/cmutex.h | 43 +++ src/lib/csensor_config.cpp | 279 ++++++++++++++ src/lib/csensor_config.h | 95 +++++ src/lib/sensor_common.h | 411 +++++++++++++++++++++ src/lib/sensor_logs.cpp | 197 ++++++++++ src/lib/sensor_logs.h | 232 ++++++++++++ src/plugins/accel/accel_sensor_hal.cpp | 363 ++++++++++++++++++ src/plugins/accel/accel_sensor_hal.h | 69 ++++ src/plugins/bio_led_red/bio_led_red_sensor_hal.cpp | 244 ++++++++++++ src/plugins/bio_led_red/bio_led_red_sensor_hal.h | 62 ++++ src/plugins/geo/geo_sensor_hal.cpp | 297 +++++++++++++++ src/plugins/geo/geo_sensor_hal.h | 67 ++++ src/plugins/gyro/gyro_sensor_hal.cpp | 286 ++++++++++++++ src/plugins/gyro/gyro_sensor_hal.h | 66 ++++ src/plugins/light/light_sensor_hal.cpp | 227 ++++++++++++ src/plugins/light/light_sensor_hal.h | 60 +++ src/plugins/pressure/pressure_sensor_hal.cpp | 351 ++++++++++++++++++ src/plugins/pressure/pressure_sensor_hal.h | 74 ++++ src/plugins/proxi/proxi_sensor_hal.cpp | 190 ++++++++++ src/plugins/proxi/proxi_sensor_hal.h | 56 +++ .../rotation_vector/rv_raw/rv_raw_sensor_hal.cpp | 268 ++++++++++++++ .../rotation_vector/rv_raw/rv_raw_sensor_hal.h | 65 ++++ src/plugins/temperature/temperature_sensor_hal.cpp | 255 +++++++++++++ src/plugins/temperature/temperature_sensor_hal.h | 60 +++ src/plugins/ultraviolet/ultraviolet_sensor_hal.cpp | 271 ++++++++++++++ src/plugins/ultraviolet/ultraviolet_sensor_hal.h | 66 ++++ 41 files changed, 6541 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 packaging/sensor-hal.manifest create mode 100644 packaging/sensor-hal.spec create mode 100644 sensors.xml.in create mode 100644 src/CMakeLists.txt create mode 100644 src/hal_module_create.cpp.in create mode 100644 src/interface/sensor_hal.h create mode 100644 src/interface/sensor_hal_base.cpp create mode 100644 src/interface/sensor_hal_base.h create mode 100755 src/lib/cbase_lock.cpp create mode 100755 src/lib/cbase_lock.h create mode 100755 src/lib/cconfig.cpp create mode 100755 src/lib/cconfig.h create mode 100755 src/lib/cmutex.cpp create mode 100755 src/lib/cmutex.h create mode 100755 src/lib/csensor_config.cpp create mode 100755 src/lib/csensor_config.h create mode 100644 src/lib/sensor_common.h create mode 100644 src/lib/sensor_logs.cpp create mode 100755 src/lib/sensor_logs.h create mode 100755 src/plugins/accel/accel_sensor_hal.cpp create mode 100755 src/plugins/accel/accel_sensor_hal.h create mode 100755 src/plugins/bio_led_red/bio_led_red_sensor_hal.cpp create mode 100755 src/plugins/bio_led_red/bio_led_red_sensor_hal.h create mode 100755 src/plugins/geo/geo_sensor_hal.cpp create mode 100755 src/plugins/geo/geo_sensor_hal.h create mode 100755 src/plugins/gyro/gyro_sensor_hal.cpp create mode 100755 src/plugins/gyro/gyro_sensor_hal.h create mode 100755 src/plugins/light/light_sensor_hal.cpp create mode 100755 src/plugins/light/light_sensor_hal.h create mode 100755 src/plugins/pressure/pressure_sensor_hal.cpp create mode 100755 src/plugins/pressure/pressure_sensor_hal.h create mode 100644 src/plugins/proxi/proxi_sensor_hal.cpp create mode 100755 src/plugins/proxi/proxi_sensor_hal.h create mode 100755 src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.cpp create mode 100755 src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.h create mode 100755 src/plugins/temperature/temperature_sensor_hal.cpp create mode 100755 src/plugins/temperature/temperature_sensor_hal.h create mode 100755 src/plugins/ultraviolet/ultraviolet_sensor_hal.cpp create mode 100755 src/plugins/ultraviolet/ultraviolet_sensor_hal.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..594f695 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 2.6) +project(sensor_hal_main CXX) +include(GNUInstallDirs) + +# Setup For pkgconfig File +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "${PREFIX}/bin") +SET(LIBDIR "${PREFIX}/${CMAKE_INSTALL_LIBDIR}") +SET(INCLUDEDIR "${PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") +SET(VERSION 1.0) + +# Common Options +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -omit-frame-pointer -std=gnu++0x") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-section -Wl,--print-gc-section") +MESSAGE("FLAGS: ${CMAKE_CXX_FLAGS}") +MESSAGE("FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") + +add_definitions(-DUSE_DLOG_LOG) +add_definitions(-DLIBDIR="${CMAKE_INSTALL_LIBDIR}") + +# Internal Debugging Options +#add_definitions(-Wall -g -D_DEBUG) + +# Installing files +CONFIGURE_FILE(sensors.xml.in sensors.xml @ONLY) + +INSTALL(FILES sensors.xml DESTINATION etc) + +# Sub-directory +add_subdirectory(src) \ No newline at end of file diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..8534b2c --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/packaging/sensor-hal.manifest b/packaging/sensor-hal.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/sensor-hal.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/sensor-hal.spec b/packaging/sensor-hal.spec new file mode 100644 index 0000000..940f715 --- /dev/null +++ b/packaging/sensor-hal.spec @@ -0,0 +1,61 @@ +Name: sensor-hal +Summary: Sensor HAL Plugins +Version: 1.0.0 +Release: 0 +Group: System/Sensor HAL +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: sensor-hal.manifest + +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libxml-2.0) + +%define accel_state ON +%define gyro_state OFF +%define proxi_state ON +%define light_state OFF +%define geo_state OFF +%define pressure_state OFF +%define temperature_state OFF +%define ultraviolet_state OFF +%define rv_state OFF +%define bio_led_red_state OFF + +%description +Sensor HAL Plugins + +%package sensor-hal +Summary: Sensor HAL Plugins +Group: System/Sensor Framework +Requires: %{name} = %{version}-%{release} + +%description sensor-hal +Sensor HAL Plugins + +%prep +%setup -q +cp %{SOURCE1} . + +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DACCEL=%{accel_state} \ +-DGYRO=%{gyro_state} -DPROXI=%{proxi_state} -DLIGHT=%{light_state} \ +-DGEO=%{geo_state} -DPRESSURE=%{pressure_state} -DTEMPERATURE=%{temperature_state} \ +-DRV=%{rv_state} -DULTRAVIOLET=%{ultraviolet_state} \ +-DBIO_LED_RED=%{bio_led_red_state} \ +-DLIBDIR=%{_libdir} -DINCLUDEDIR=%{_includedir} + +%build +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -n sensor-hal -p /sbin/ldconfig + +%postun -n sensor-hal -p /sbin/ldconfig + +%files -n sensor-hal +%manifest sensor-hal.manifest +%attr(0644,root,root)/usr/etc/sensors.xml +%{_libdir}/sensor-hal/libsensor-hal.so diff --git a/sensors.xml.in b/sensors.xml.in new file mode 100644 index 0000000..e460fb2 --- /dev/null +++ b/sensors.xml.in @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..0e584f7 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,88 @@ +cmake_minimum_required(VERSION 2.6) +project(sensor-hal CXX) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(plugin_pkgs REQUIRED dlog libxml-2.0) + +FOREACH(flag ${plugin_pkgs_LDFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +FOREACH(flag ${plugin_pkgs_CFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + +include_directories(${CMAKE_SOURCE_DIR}/src/lib) +include_directories(${CMAKE_SOURCE_DIR}/src/interface) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +IF("${ACCEL}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/accel) +list (APPEND SRCS "plugins/accel/accel_sensor_hal.cpp") +add_definitions(-DENABLE_ACCEL) +ENDIF() +IF("${GYRO}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/gyro) +list (APPEND SRCS "plugins/gyro/gyro_sensor_hal.cpp") +add_definitions(-DENABLE_GYRO) +ENDIF() +IF("${PROXI}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/proxi) +list (APPEND SRCS "plugins/proxi/proxi_sensor_hal.cpp") +add_definitions(-DENABLE_PROXI) +ENDIF() +IF("${LIGHT}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/light) +list (APPEND SRCS "plugins/light/light_sensor_hal.cpp") +add_definitions(-DENABLE_LIGHT) +ENDIF() +IF("${GEO}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/geo) +list (APPEND SRCS "plugins/geo/geo_sensor_hal.cpp") +add_definitions(-DENABLE_GEO) +ENDIF() +IF("${PRESSURE}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/pressure) +list (APPEND SRCS "plugins/pressure/pressure_sensor_hal.cpp") +add_definitions(-DENABLE_PRESSURE) +ENDIF() +IF("${TEMPERATURE}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/temperature) +list (APPEND SRCS "plugins/temperature/temperature_sensor_hal.cpp") +add_definitions(-DENABLE_TEMPERATURE) +ENDIF() +IF("${ULTRAVIOLET}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/ultraviolet) +list (APPEND SRCS "plugins/ultraviolet/ultraviolet_sensor_hal.cpp") +add_definitions(-DENABLE_ULTRAVIOLET) +ENDIF() +IF("${BIO_LED_RED}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/bio_led_red) +list (APPEND SRCS "plugins/bio_led_red/bio_led_red_sensor_hal.cpp") +add_definitions(-DENABLE_BIO_LED_RED) +ENDIF() +IF("${RV}" STREQUAL "ON") +include_directories(${CMAKE_SOURCE_DIR}/src/plugins/rotation_vector/rv_raw) +list (APPEND SRCS "plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.cpp") +add_definitions(-DENABLE_RV_RAW) +ENDIF() + +configure_file(hal_module_create.cpp.in hal_module_create.cpp) + +add_library(${PROJECT_NAME} SHARED + ${SRCS} + lib/cbase_lock.cpp + lib/cconfig.cpp + lib/cmutex.cpp + lib/csensor_config.cpp + lib/sensor_logs.cpp + interface/sensor_hal_base.cpp + interface/sensor_hal.h + hal_module_create.cpp +) + +target_link_libraries(${PROJECT_NAME} ${plugin_pkgs_LDFLAGS} "-lrt -ldl -pthread") + +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/sensor-hal) diff --git a/src/hal_module_create.cpp.in b/src/hal_module_create.cpp.in new file mode 100644 index 0000000..14a04b2 --- /dev/null +++ b/src/hal_module_create.cpp.in @@ -0,0 +1,152 @@ +#ifdef ENABLE_ACCEL +#include +#endif +#ifdef ENABLE_BIO_LED_RED +#include +#endif +#ifdef ENABLE_GEO +#include +#endif +#ifdef ENABLE_GYRO +#include +#endif +#ifdef ENABLE_LIGHT +#include +#endif +#ifdef ENABLE_PRESSURE +#include +#endif +#ifdef ENABLE_PROXI +#include +#endif +#ifdef ENABLE_RV_RAW +#include +#endif +#ifdef ENABLE_TEMPERATURE +#include +#endif +#ifdef ENABLE_ULTRAVIOLET +#include +#endif + +#include + +extern "C" sensor_module* create(void) +{ + sensor_module *module = new(std::nothrow) sensor_module; + retvm_if(!module, NULL, "Failed to allocate memory"); + +#ifdef ENABLE_ACCEL + accel_sensor_hal *accel_sensor = NULL; + try { + accel_sensor = new(std::nothrow) accel_sensor_hal; + } catch (int err) { + ERR("Failed to create accel_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + + if (accel_sensor != NULL) { + module->sensors.push_back(accel_sensor); + } +#endif + +#ifdef ENABLE_BIO_LED_RED + bio_led_red_sensor_hal *bio_led_red_sensor = NULL; + try { + bio_led_red_sensor = new(std::nothrow) bio_led_red_sensor_hal; + } catch (int err) { + ERR("Failed to create bio_led_red_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (bio_led_red_sensor != NULL) + module->sensors.push_back(bio_led_red_sensor); +#endif + +#ifdef ENABLE_GEO + geo_sensor_hal *geo_sensor = NULL; + try { + geo_sensor = new(std::nothrow) geo_sensor_hal; + } catch (int err) { + ERR("Failed to create geo_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (geo_sensor != NULL) + module->sensors.push_back(geo_sensor); +#endif + +#ifdef ENABLE_GYRO + gyro_sensor_hal *gyro_sensor = NULL; + try { + gyro_sensor = new(std::nothrow) gyro_sensor_hal; + } catch (int err) { + ERR("Failed to create gyro_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (gyro_sensor != NULL) + module->sensors.push_back(gyro_sensor); +#endif + +#ifdef ENABLE_LIGHT + light_sensor_hal *light_sensor = NULL; + try { + light_sensor = new(std::nothrow) light_sensor_hal; + } catch (int err) { + ERR("Failed to create light_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (light_sensor != NULL) + module->sensors.push_back(light_sensor); +#endif + +#ifdef ENABLE_PRESSURE + pressure_sensor_hal *pressure_sensor = NULL; + try { + pressure_sensor = new(std::nothrow) pressure_sensor_hal; + } catch (int err) { + ERR("Failed to create pressure_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (pressure_sensor != NULL) + module->sensors.push_back(pressure_sensor); +#endif + +#ifdef ENABLE_PROXI + proxi_sensor_hal *proxi_sensor = NULL; + try { + proxi_sensor = new(std::nothrow) proxi_sensor_hal; + } catch (int err) { + ERR("Failed to create proxi_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (proxi_sensor != NULL) + module->sensors.push_back(proxi_sensor); +#endif + +#ifdef ENABLE_RV_RAW + rv_raw_sensor_hal *rv_raw_sensor = NULL; + try { + rv_raw_sensor = new(std::nothrow) rv_raw_sensor_hal; + } catch (int err) { + ERR("Failed to create rv_raw_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (rv_raw_sensor != NULL) + module->sensors.push_back(rv_raw_sensor); +#endif + +#ifdef ENABLE_TEMPERATURE + temperature_sensor_hal *temperature_sensor = NULL; + try { + temperature_sensor = new(std::nothrow) temperature_sensor_hal; + } catch (int err) { + ERR("Failed to create temperature_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (temperature_sensor != NULL) + module->sensors.push_back(temperature_sensor); +#endif + +#ifdef ENABLE_ULTRAVIOLET + ultraviolet_sensor_hal *ultraviolet_sensor = NULL; + try { + ultraviolet_sensor = new(std::nothrow) ultraviolet_sensor_hal; + } catch (int err) { + ERR("Failed to create ultraviolet_sensor_hal module, err: %d, cause: %s", err, strerror(err)); + } + if (ultraviolet_sensor != NULL) + module->sensors.push_back(ultraviolet_sensor); +#endif + + return module; +} diff --git a/src/interface/sensor_hal.h b/src/interface/sensor_hal.h new file mode 100644 index 0000000..2da6406 --- /dev/null +++ b/src/interface/sensor_hal.h @@ -0,0 +1,65 @@ +/* + * libsensord-share + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _SENSOR_HAL_H_ +#define _SENSOR_HAL_H_ + +typedef enum { + SENSOR_HAL_TYPE_ACCELEROMETER, + SENSOR_HAL_TYPE_GEOMAGNETIC, + SENSOR_HAL_TYPE_LIGHT, + SENSOR_HAL_TYPE_PROXIMITY, + SENSOR_HAL_TYPE_GYROSCOPE, + SENSOR_HAL_TYPE_PRESSURE, + SENSOR_HAL_TYPE_CONTEXT, + SENSOR_HAL_TYPE_BIO, + SENSOR_HAL_TYPE_BIO_HRM, + SENSOR_HAL_TYPE_PIR, + SENSOR_HAL_TYPE_PIR_LONG, + SENSOR_HAL_TYPE_TEMPERATURE, + SENSOR_HAL_TYPE_HUMIDITY, + SENSOR_HAL_TYPE_ULTRAVIOLET, + SENSOR_HAL_TYPE_DUST, + SENSOR_HAL_TYPE_BIO_LED_IR, + SENSOR_HAL_TYPE_BIO_LED_RED, + SENSOR_HAL_TYPE_BIO_LED_GREEN, + SENSOR_HAL_TYPE_RV_RAW, + SENSOR_HAL_TYPE_GYROSCOPE_UNCAL, + SENSOR_HAL_TYPE_GEOMAGNETIC_UNCAL, + SENSOR_HAL_TYPE_FUSION, +} sensor_hal_type_t; + + + +class sensor_hal +{ +public: + sensor_hal(){}; + virtual ~sensor_hal(){}; + + virtual std::string get_model_id(void) = 0; + virtual sensor_hal_type_t get_type(void) = 0; + virtual bool enable(void) = 0; + virtual bool disable(void) = 0; + virtual bool is_data_ready(void) = 0; + virtual bool set_interval(unsigned long val) = 0; + virtual int get_sensor_data(sensor_data_t &data) = 0; + virtual bool get_properties(sensor_properties_s &properties) = 0; +}; +#endif /*_SENSOR_HAL_H_*/ diff --git a/src/interface/sensor_hal_base.cpp b/src/interface/sensor_hal_base.cpp new file mode 100644 index 0000000..30147c9 --- /dev/null +++ b/src/interface/sensor_hal_base.cpp @@ -0,0 +1,364 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +using std::ifstream; +using std::ofstream; +using std::fstream; +using std::string; + +cmutex sensor_hal_base::m_shared_mutex; + +sensor_hal_base::sensor_hal_base() +{ +} + +sensor_hal_base::~sensor_hal_base() +{ +} + +unsigned long long sensor_hal_base::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_hal_base::get_timestamp(timeval *t) +{ + if (!t) { + ERR("t is NULL"); + return 0; + } + + return ((unsigned long long)(t->tv_sec)*1000000LL +t->tv_usec); +} + +bool sensor_hal_base::is_sensorhub_controlled(const string &key) +{ + string key_node = string("/sys/class/sensors/ssp_sensor/") + key; + + if (access(key_node.c_str(), F_OK) == 0) + return true; + + return false; +} + +bool sensor_hal_base::get_node_info(const node_info_query &query, node_info &info) +{ + bool ret = false; + int method; + string device_num; + + if (!get_input_method(query.key, method, device_num)) { + ERR("Failed to get input method for %s", query.key.c_str()); + return false; + } + + info.method = method; + + if (method == IIO_METHOD) { + if (query.sensorhub_controlled) + ret = get_sensorhub_iio_node_info(query.sensorhub_interval_node_name, device_num, info); + else + ret = get_iio_node_info(query.iio_enable_node_name, device_num, info); + } else { + if (query.sensorhub_controlled) + ret = get_sensorhub_input_event_node_info(query.sensorhub_interval_node_name, device_num, info); + else + ret = get_input_event_node_info(device_num, info); + } + + return ret; +} + + +void sensor_hal_base::show_node_info(node_info &info) +{ + if (info.data_node_path.size()) + INFO("Data node: %s", info.data_node_path.c_str()); + if (info.enable_node_path.size()) + INFO("Enable node: %s", info.enable_node_path.c_str()); + if (info.interval_node_path.size()) + INFO("Interval node: %s", info.interval_node_path.c_str()); + if (info.buffer_enable_node_path.size()) + INFO("Buffer enable node: %s", info.buffer_enable_node_path.c_str()); + if (info.buffer_length_node_path.size()) + INFO("Buffer length node: %s", info.buffer_length_node_path.c_str()); + if (info.trigger_node_path.size()) + INFO("Trigger node: %s", info.trigger_node_path.c_str()); +} + +bool sensor_hal_base::get_iio_node_info(const string& enable_node_name, const string& device_num, node_info &info) +{ + const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/"); + + info.data_node_path = string("/dev/iio:device") + device_num; + info.enable_node_path = base_dir + enable_node_name; + info.interval_node_path = base_dir + string("sampling_frequency"); + info.buffer_enable_node_path = base_dir + string("buffer/enable"); + info.buffer_length_node_path = base_dir + string("buffer/length"); + info.trigger_node_path = base_dir + string("trigger/current_trigger"); + + return true; +} + +bool sensor_hal_base::get_sensorhub_iio_node_info(const string &interval_node_name, const string& device_num, node_info &info) +{ + const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/"); + const string hub_dir = "/sys/class/sensors/ssp_sensor/"; + + info.data_node_path = string("/dev/iio:device") + device_num; + info.enable_node_path = hub_dir + string("enable"); + info.interval_node_path = hub_dir + interval_node_name; + info.buffer_enable_node_path = base_dir + string("buffer/enable"); + info.buffer_length_node_path = base_dir + string("buffer/length"); + return true; +} + +bool sensor_hal_base::get_input_event_node_info(const string& device_num, node_info &info) +{ + string base_dir; + string event_num; + + base_dir = string("/sys/class/input/input") + device_num + string("/"); + + if (!get_event_num(base_dir, event_num)) + return false; + + info.data_node_path = string("/dev/input/event") + event_num; + + info.enable_node_path = base_dir + string("enable"); + info.interval_node_path = base_dir + string("poll_delay"); + return true; +} + +bool sensor_hal_base::get_sensorhub_input_event_node_info(const string &interval_node_name, const string& device_num, node_info &info) +{ + const string base_dir = "/sys/class/sensors/ssp_sensor/"; + string event_num; + + string input_dir = string("/sys/class/input/input") + device_num + string("/"); + + if (!get_event_num(input_dir, event_num)) + return false; + + info.data_node_path = string("/dev/input/event") + event_num; + info.enable_node_path = base_dir + string("enable"); + info.interval_node_path = base_dir + interval_node_name; + return true; +} + +bool sensor_hal_base::set_node_value(const string &node_path, int value) +{ + ofstream node(node_path, ofstream::binary); + + if (!node) + return false; + + node << value; + + return true; +} + +bool sensor_hal_base::set_node_value(const string &node_path, unsigned long long value) +{ + ofstream node(node_path, ofstream::binary); + + if (!node) + return false; + + node << value; + + return true; +} + + +bool sensor_hal_base::get_node_value(const string &node_path, int &value) +{ + ifstream node(node_path, ifstream::binary); + + if (!node) + return false; + + node >> value; + + return true; +} + +bool sensor_hal_base::set_enable_node(const string &node_path, bool sensorhub_controlled, bool enable, int enable_bit) +{ + int prev_status, status; + + AUTOLOCK(m_shared_mutex); + + if (!get_node_value(node_path, prev_status)) { + ERR("Failed to get node: %s", node_path.c_str()); + return false; + } + + int _enable_bit = sensorhub_controlled ? enable_bit : 0; + + if (enable) + status = prev_status | (1 << _enable_bit); + else + status = prev_status & (~(1 << _enable_bit)); + + if (!set_node_value(node_path, status)) { + ERR("Failed to set node: %s", node_path.c_str()); + return false; + } + + return true; +} + + +bool sensor_hal_base::find_model_id(const string &sensor_type, string &model_id) +{ + string dir_path = "/sys/class/sensors/"; + string name_node, name; + string d_name; + DIR *dir = NULL; + struct dirent *dir_entry = NULL; + bool find = false; + + dir = opendir(dir_path.c_str()); + if (!dir) { + DBG("Failed to open dir: %s", dir_path.c_str()); + return false; + } + + while (!find && (dir_entry = readdir(dir))) { + d_name = string(dir_entry->d_name); + + if ((d_name != ".") && (d_name != "..") && (dir_entry->d_ino != 0)) { + name_node = dir_path + d_name + string("/name"); + + ifstream infile(name_node.c_str()); + + if (!infile) + continue; + + infile >> name; + + if (csensor_config::get_instance().is_supported(sensor_type, name)) { + model_id = name; + find = true; + break; + } + } + } + + closedir(dir); + + return find; +} + +bool sensor_hal_base::get_event_num(const string &input_path, string &event_num) +{ + const string event_prefix = "event"; + DIR *dir = NULL; + struct dirent *dir_entry = NULL; + string node_name; + bool find = false; + + dir = opendir(input_path.c_str()); + if (!dir) { + ERR("Failed to open dir: %s", input_path.c_str()); + return false; + } + + int prefix_size = event_prefix.size(); + + while (!find && (dir_entry = readdir(dir))) { + node_name = dir_entry->d_name; + + if (node_name.compare(0, prefix_size, event_prefix) == 0) { + event_num = node_name.substr(prefix_size, node_name.size() - prefix_size); + find = true; + break; + } + } + + closedir(dir); + + return find; +} + +bool sensor_hal_base::get_input_method(const string &key, int &method, string &device_num) +{ + input_method_info input_info[2] = { + {INPUT_EVENT_METHOD, "/sys/class/input/", "input"}, + {IIO_METHOD, "/sys/bus/iio/devices/", "iio:device"} + }; + + const int input_info_len = sizeof(input_info)/sizeof(input_info[0]); + size_t prefix_size; + string name_node, name; + string d_name; + DIR *dir = NULL; + struct dirent *dir_entry = NULL; + bool find = false; + + for (int i = 0; i < input_info_len; ++i) { + + prefix_size = input_info[i].prefix.size(); + + dir = opendir(input_info[i].dir_path.c_str()); + if (!dir) { + ERR("Failed to open dir: %s", input_info[i].dir_path.c_str()); + return false; + } + + find = false; + + while (!find && (dir_entry = readdir(dir))) { + d_name = string(dir_entry->d_name); + + if (d_name.compare(0, prefix_size, input_info[i].prefix) == 0) { + name_node = input_info[i].dir_path + d_name + string("/name"); + + ifstream infile(name_node.c_str()); + if (!infile) + continue; + + infile >> name; + + if (name == key) { + device_num = d_name.substr(prefix_size, d_name.size() - prefix_size); + find = true; + method = input_info[i].method; + break; + } + } + } + + closedir(dir); + + if (find) + break; + } + + return find; +} diff --git a/src/interface/sensor_hal_base.h b/src/interface/sensor_hal_base.h new file mode 100644 index 0000000..ee53879 --- /dev/null +++ b/src/interface/sensor_hal_base.h @@ -0,0 +1,105 @@ +/* + * libsensord-share + * + * 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 _SENSOR_HAL_BASE_H_ +#define _SENSOR_HAL_BASE_H_ +#include +#include +#include +#include +#include +#include + +/* +* As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock +* Current kernel-headers package doesn't have it so we should define it here. +*/ + +#ifndef EVIOCSCLOCKID +#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */ +#endif + + +typedef struct { + int method; + std::string data_node_path; + std::string enable_node_path; + std::string interval_node_path; + std::string buffer_enable_node_path; + std::string buffer_length_node_path; + std::string trigger_node_path; +} node_info; + +typedef struct { + bool sensorhub_controlled; + std::string sensor_type; + std::string key; + std::string iio_enable_node_name; + std::string sensorhub_interval_node_name; +} node_info_query; + +enum input_method { + IIO_METHOD = 0, + INPUT_EVENT_METHOD = 1, +}; + +typedef struct { + int method; + std::string dir_path; + std::string prefix; +} input_method_info; + +#define DEFAULT_WAIT_TIME 0 + +class sensor_hal_base : public sensor_hal +{ +public: + sensor_hal_base(); + virtual ~sensor_hal_base(); + + bool init(void *data = NULL); + long set_command(unsigned int cmd, long val); + bool set_wakeup(int wakeup); + int send_sensorhub_data(const char *data, int data_len); + +protected: + cmutex m_mutex; + static cmutex m_shared_mutex; + + bool set_enable_node(const std::string &node_path, bool sensorhub_controlled, bool enable, int enable_bit = 0); + + static unsigned long long get_timestamp(void); + static unsigned long long get_timestamp(timeval *t); + static bool find_model_id(const std::string &sensor_type, std::string &model_id); + static bool is_sensorhub_controlled(const std::string &key); + static bool get_node_info(const node_info_query &query, node_info &info); + static void show_node_info(node_info &info); + static bool set_node_value(const std::string &node_path, int value); + static bool set_node_value(const std::string &node_path, unsigned long long value); + static bool get_node_value(const std::string &node_path, int &value); +private: + static bool get_event_num(const std::string &node_path, std::string &event_num); + static bool get_input_method(const std::string &key, int &method, std::string &device_num); + + static bool get_iio_node_info(const std::string& enable_node_name, const std::string& device_num, node_info &info); + static bool get_sensorhub_iio_node_info(const std::string &interval_node_name, const std::string& device_num, node_info &info); + static bool get_input_event_node_info(const std::string& device_num, node_info &info); + static bool get_sensorhub_input_event_node_info(const std::string &interval_node_name, const std::string& device_num, node_info &info); +}; +#endif /*_SENSOR_HAL_BASE_H_*/ diff --git a/src/lib/cbase_lock.cpp b/src/lib/cbase_lock.cpp new file mode 100755 index 0000000..5a1a639 --- /dev/null +++ b/src/lib/cbase_lock.cpp @@ -0,0 +1,159 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include + + +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); + INFO("%s is waiting for getting %s(0x%x) 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); + INFO("%s acquires lock after waiting %lluus, %s(0x%x) was previously owned in %s", + m_curent_info, waiting_time, expr, this, m_owner_info); + snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info); + pthread_mutex_unlock(&m_history_mutex); +} + + +void cbase_lock::lock(lock_type type) +{ + if (type == LOCK_TYPE_MUTEX) + lock_impl(); + else if (type == LOCK_TYPE_READ) + read_lock_impl(); + else if (type == LOCK_TYPE_WRITE) + write_lock_impl(); +} + +void cbase_lock::unlock(void) +{ + unlock_impl(); +} + + +int cbase_lock::lock_impl(void) +{ + return 0; +} + +int cbase_lock::read_lock_impl(void) +{ + return 0; +} + +int cbase_lock::write_lock_impl(void) +{ + return 0; +} + +int cbase_lock::try_lock_impl(void) +{ + return 0; +} + +int cbase_lock::try_read_lock_impl(void) +{ + return 0; +} + +int cbase_lock::try_write_lock_impl(void) +{ + return 0; +} + +int cbase_lock::unlock_impl(void) +{ + return 0; +} + +Autolock::Autolock(cbase_lock &m, lock_type type, const char* expr, const char *module, const char *func, int line) +: m_lock(m) +{ + m_lock.lock(type, expr, module, func, line); +} + +Autolock::Autolock(cbase_lock &m, lock_type type) +: m_lock(m) +{ + m_lock.lock(type); +} + +Autolock::~Autolock() +{ + m_lock.unlock(); +} diff --git a/src/lib/cbase_lock.h b/src/lib/cbase_lock.h new file mode 100755 index 0000000..2b0082a --- /dev/null +++ b/src/lib/cbase_lock.h @@ -0,0 +1,87 @@ +/* + * libsensord-share + * + * 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. + * + */ + +#if !defined(_CBASE_LOCK_CLASS_H_) +#define _CBASE_LOCK_CLASS_H_ + +#include + +enum lock_type { + LOCK_TYPE_MUTEX, + LOCK_TYPE_READ, + LOCK_TYPE_WRITE, +}; + +#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 +// End of a file diff --git a/src/lib/cconfig.cpp b/src/lib/cconfig.cpp new file mode 100755 index 0000000..14c7f01 --- /dev/null +++ b/src/lib/cconfig.cpp @@ -0,0 +1,72 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +using std::ifstream; +using std::string; +using std::istringstream; + +cconfig::cconfig(void) +{ + +} + +cconfig::~cconfig(void) +{ + +} + +bool cconfig::get_device_id(void) +{ + const string INFO_INI_PATH = "/etc/info.ini"; + const string START_DELIMETER = "Model="; + const string END_DELIMETER = ";"; + string line; + ifstream in_file; + std::size_t start_pos, end_pos; + bool ret = false; + + in_file.open(INFO_INI_PATH); + + if (!in_file.is_open()) + return false; + + while (!in_file.eof()) { + getline(in_file, line); + start_pos = line.find(START_DELIMETER); + + if (start_pos != std::string::npos) { + start_pos = start_pos + START_DELIMETER.size(); + end_pos = line.find(END_DELIMETER, start_pos); + + if (end_pos != std::string::npos) { + m_device_id = line.substr(start_pos, end_pos - start_pos); + ret = true; + break; + } + } + } + + in_file.close(); + + return ret; +} diff --git a/src/lib/cconfig.h b/src/lib/cconfig.h new file mode 100755 index 0000000..ef2802f --- /dev/null +++ b/src/lib/cconfig.h @@ -0,0 +1,41 @@ +/* + * libsensord-share + * + * 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 _CCONFIG_H_ +#define _CCONFIG_H_ + +#include +#include +#include + +class cconfig +{ +protected: + virtual bool load_config(const std::string& config_path) = 0; + + std::string m_device_id; +public: + cconfig(); + virtual ~cconfig(); + + bool get_device_id(void); + +}; + +#endif /* _CCONFIG_H_ */ diff --git a/src/lib/cmutex.cpp b/src/lib/cmutex.cpp new file mode 100755 index 0000000..fb09f7c --- /dev/null +++ b/src/lib/cmutex.cpp @@ -0,0 +1,65 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include "sensor_logs.h" + +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() +{ +#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::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() +{ + return pthread_mutex_unlock(&m_mutex); +} diff --git a/src/lib/cmutex.h b/src/lib/cmutex.h new file mode 100755 index 0000000..bfdd5d0 --- /dev/null +++ b/src/lib/cmutex.h @@ -0,0 +1,43 @@ +/* + * libsensord-share + * + * 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. + * + */ + +#if !defined(_CMUTEX_CLASS_H_) +#define _CMUTEX_CLASS_H_ + +#include "cbase_lock.h" + +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); + +protected: + int lock_impl(void); + int try_lock_impl(void); + int unlock_impl(); +private: + pthread_mutex_t m_mutex; +}; + +#endif +// End of a file diff --git a/src/lib/csensor_config.cpp b/src/lib/csensor_config.cpp new file mode 100755 index 0000000..ba8111b --- /dev/null +++ b/src/lib/csensor_config.cpp @@ -0,0 +1,279 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include "sensor_logs.h" +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; +using std::istringstream; + +#define ROOT_ELEMENT "SENSOR" +#define TEXT_ELEMENT "text" +#define MODEL_ID_ATTR "id" +#define DEFAULT_ATTR "value" + +csensor_config::csensor_config() +{ +} + +csensor_config& csensor_config::get_instance(void) +{ + static bool load_done = false; + static csensor_config inst; + + if (!load_done) { + inst.load_config(SENSOR_CONFIG_FILE_PATH); + inst.get_device_id(); + if (!inst.m_device_id.empty()) + INFO("Device ID = %s", inst.m_device_id.c_str()); + else + ERR("Failed to get Device ID"); + load_done = true; + } + + return inst; +} + +bool csensor_config::load_config(const string& config_path) +{ + xmlDocPtr doc; + xmlNodePtr cur; + + DBG("csensor_config::load_config(\"%s\") is called!\n",config_path.c_str()); + + doc = xmlParseFile(config_path.c_str()); + + if (doc == NULL) { + ERR("There is no %s\n",config_path.c_str()); + return false; + } + + cur = xmlDocGetRootElement(doc); + if(cur == NULL) { + ERR("There is no root element in %s\n",config_path.c_str()); + xmlFreeDoc(doc); + return false; + } + + if(xmlStrcmp(cur->name, (const xmlChar *)ROOT_ELEMENT)) { + ERR("Wrong type document: there is no [%s] root element in %s\n",ROOT_ELEMENT,config_path.c_str()); + xmlFreeDoc(doc); + return false; + } + + xmlNodePtr model_list_node_ptr; + xmlNodePtr model_node_ptr; + xmlNodePtr element_node_ptr; + xmlAttrPtr attr_ptr; + char* prop = NULL; + + model_list_node_ptr = cur->xmlChildrenNode; + + while (model_list_node_ptr != NULL) { + //skip garbage element, [text] + if (!xmlStrcmp(model_list_node_ptr->name,(const xmlChar *)TEXT_ELEMENT)) { + model_list_node_ptr = model_list_node_ptr->next; + continue; + } + + //insert Model_list to config map + m_sensor_config[(const char*)model_list_node_ptr->name]; + DBG("<%s>\n",(const char*)model_list_node_ptr->name); + + model_node_ptr = model_list_node_ptr->xmlChildrenNode; + while (model_node_ptr != NULL){ + //skip garbage element, [text] + if (!xmlStrcmp(model_node_ptr->name,(const xmlChar *)TEXT_ELEMENT)) { + model_node_ptr = model_node_ptr->next; + continue; + } + + + string model_id; + prop = (char*)xmlGetProp(model_node_ptr,(const xmlChar*)MODEL_ID_ATTR); + model_id = prop; + free(prop); + + //insert Model to Model_list + m_sensor_config[(const char*)model_list_node_ptr->name][model_id]; + DBG("<%s id=\"%s\">\n",(const char*)model_list_node_ptr->name,model_id.c_str()); + + element_node_ptr = model_node_ptr->xmlChildrenNode; + while (element_node_ptr != NULL) { + //skip garbage element, [text] + if (!xmlStrcmp(element_node_ptr->name,(const xmlChar *)TEXT_ELEMENT)) { + element_node_ptr = element_node_ptr->next; + continue; + } + + //insert Element to Model + m_sensor_config[(const char*)model_list_node_ptr->name][model_id][(const char*)element_node_ptr->name]; + DBG("<%s id=\"%s\"><%s>\n",(const char*)model_list_node_ptr->name,model_id.c_str(),(const char*)element_node_ptr->name); + + attr_ptr = element_node_ptr->properties; + while (attr_ptr != NULL) { + + string key,value; + key = (char*)attr_ptr->name; + prop = (char*)xmlGetProp(element_node_ptr,attr_ptr->name); + value = prop; + free(prop); + + //insert attribute to Element + m_sensor_config[(const char*)model_list_node_ptr->name][model_id][(const char*)element_node_ptr->name][key]=value; + DBG("<%s id=\"%s\"><%s \"%s\"=\"%s\">\n",(const char*)model_list_node_ptr->name,model_id.c_str(),(const char*)element_node_ptr->name,key.c_str(),value.c_str()); + attr_ptr = attr_ptr->next; + } + + + element_node_ptr = element_node_ptr->next; + } + + DBG("\n"); + model_node_ptr = model_node_ptr->next; + } + + DBG("\n"); + model_list_node_ptr = model_list_node_ptr->next; + } + + xmlFreeDoc(doc); + return true; +} + + +bool csensor_config::get(const string& sensor_type,const string& model_id, const string& element, const string& attr, string& value) +{ + auto it_model_list = m_sensor_config.find(sensor_type); + + if (it_model_list == m_sensor_config.end()) { + ERR("There is no <%s> element\n",sensor_type.c_str()); + return false; + } + + auto it_model = it_model_list->second.find(model_id); + + if (it_model == it_model_list->second.end()) { + ERR("There is no <%s id=\"%s\"> element\n",sensor_type.c_str(),model_id.c_str()); + return false; + } + + auto it_element = it_model->second.find(element); + + if (it_element == it_model->second.end()) { + DBG("There is no <%s id=\"%s\"><%s> element\n",sensor_type.c_str(),model_id.c_str(),element.c_str()); + return false; + } + + auto it_attr = it_element->second.find(attr); + + if (it_attr == it_element->second.end()) { + DBG("There is no <%s id=\"%s\"><%s \"%s\">\n",sensor_type.c_str(),model_id.c_str(),element.c_str(),attr.c_str()); + return false; + } + + value = it_attr->second; + + return true; +} + +bool csensor_config::get(const string& sensor_type, const string& model_id, const string& element, const string& attr, double& value) +{ + string str_value; + + if (get(sensor_type,model_id,element,attr,str_value) == false) + return false; + + istringstream convert(str_value); + + if ( !(convert >> value)) + value = 0; + + return true; +} + +bool csensor_config::get(const string& sensor_type, const string& model_id, const string& element, const string& attr, long& value) +{ + string str_value; + + if (get(sensor_type,model_id,element,attr,str_value) == false) + return false; + + istringstream convert(str_value); + + if ( !(convert >> value)) + value = 0; + + return true; +} + +bool csensor_config::get(const string& sensor_type, const string& model_id, const string& element, string& value) +{ + if (get(sensor_type, model_id, element, m_device_id, value)) + return true; + + if (get(sensor_type, model_id, element, DEFAULT_ATTR, value)) + return true; + + return false; +} + +bool csensor_config::get(const string& sensor_type, const string& model_id, const string& element, double& value) +{ + if (get(sensor_type, model_id, element, m_device_id, value)) + return true; + + if (get(sensor_type, model_id, element, DEFAULT_ATTR, value)) + return true; + + return false; +} + +bool csensor_config::get(const string& sensor_type, const string& model_id, const string& element, long& value) +{ + if (get(sensor_type, model_id, element, m_device_id, value)) + return true; + + if (get(sensor_type, model_id, element, DEFAULT_ATTR, value)) + return true; + + return false; +} + +bool csensor_config::is_supported(const string& sensor_type,const string& model_id) +{ + auto it_model_list = m_sensor_config.find(sensor_type); + + if (it_model_list == m_sensor_config.end()) + return false; + + auto it_model = it_model_list->second.find(model_id); + + if (it_model == it_model_list->second.end()) + return false; + + return true; +} diff --git a/src/lib/csensor_config.h b/src/lib/csensor_config.h new file mode 100755 index 0000000..5ce6c74 --- /dev/null +++ b/src/lib/csensor_config.h @@ -0,0 +1,95 @@ +/* + * libsensord-share + * + * 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. + * + */ + +#if !defined(_CSENSOR_CONFIG_CLASS_H_) +#define _CSENSOR_CONFIG_CLASS_H_ + +#include + +#define SENSOR_CONFIG_FILE_PATH "/usr/etc/sensors.xml" + +typedef std::unordered_map Element; +/* +* an Element is a group of attributes +* +* +* "value" -> "LSM330DLC" +* +*/ + +typedef std::unordered_map Model; +/* +* a Model is a group of elements to consist of specific vendor's one sensor configuration +* +* +* +* +* +* -> +* +*/ + +typedef std::unordered_map Model_list; +/* +* a Model_list is a group of Model +* +* +* +* +* +* "lsm330dlc_accel" -> +* +*/ + +typedef std::unordered_map Sensor_config; +/* +* a SensorConfig represents sensors.xml +* +* +* +* +* "ACCEL" -> Model_list +* +*/ + +class csensor_config : public cconfig +{ +private: + csensor_config(); + csensor_config(csensor_config const&) {}; + csensor_config& operator=(csensor_config const&); + + bool load_config(const std::string& config_path); + + Sensor_config m_sensor_config; +public: + static csensor_config& get_instance(void); + + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, const std::string& attr, std::string& value); + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, const std::string& attr, double& value); + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, const std::string& attr, long& value); + + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, std::string& value); + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, double& value); + bool get(const std::string& sensor_type, const std::string& model_id, const std::string& element, long& value); + + bool is_supported(const std::string &sensor_type, const std::string &model_id); +}; + +#endif diff --git a/src/lib/sensor_common.h b/src/lib/sensor_common.h new file mode 100644 index 0000000..5388e26 --- /dev/null +++ b/src/lib/sensor_common.h @@ -0,0 +1,411 @@ +/* + * libsensord-share + * + * 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 __SENSOR_COMMON_H__ +#define __SENSOR_COMMON_H__ + +#include +#include +#include +#include + +#ifndef DEPRECATED +#define DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup SENSOR_FRAMEWORK SensorFW + * To support the unified API for the various sensors + */ + +/** + * @defgroup SENSOR_FRAMEWORK_COMMON Sensor Framework Common API + * @ingroup SENSOR_FRAMEWORK + * + * These APIs are used to control the sensors. + * @{ + */ + +typedef enum { + ALL_SENSOR = -1, + UNKNOWN_SENSOR = 0, + ACCELEROMETER_SENSOR, + GEOMAGNETIC_SENSOR, + LIGHT_SENSOR, + PROXIMITY_SENSOR, + THERMOMETER_SENSOR, + GYROSCOPE_SENSOR, + PRESSURE_SENSOR, + MOTION_SENSOR, + FUSION_SENSOR, + PEDOMETER_SENSOR, + CONTEXT_SENSOR, + FLAT_SENSOR, + BIO_SENSOR, + BIO_HRM_SENSOR, + AUTO_ROTATION_SENSOR, + GRAVITY_SENSOR, + LINEAR_ACCEL_SENSOR, + ROTATION_VECTOR_SENSOR, + GEOMAGNETIC_RV_SENSOR, + GAMING_RV_SENSOR, + ORIENTATION_SENSOR, + TILT_SENSOR, + PIR_SENSOR, + PIR_LONG_SENSOR, + TEMPERATURE_SENSOR, + HUMIDITY_SENSOR, + ULTRAVIOLET_SENSOR, + DUST_SENSOR, + BIO_LED_GREEN_SENSOR, + BIO_LED_IR_SENSOR, + BIO_LED_RED_SENSOR, + RV_RAW_SENSOR, + UNCAL_GYROSCOPE_SENSOR, + UNCAL_GEOMAGNETIC_SENSOR +} sensor_type_t; + +typedef unsigned int sensor_id_t; + +typedef void *sensor_t; + +typedef enum { + SENSOR_PRIVILEGE_PUBLIC, + SENSOR_PRIVILEGE_INTERNAL, +} sensor_privilege_t; + +#define SENSOR_DATA_VALUE_SIZE 16 + +/* + * When modifying it, check copy_sensor_data() + */ +typedef struct sensor_data_t { +/* + * Use "accuracy" instead of "data_accuracy" + * which is going to be removed soon + */ + union { + int accuracy; + int data_accuracy; //deprecated + }; + + union { + unsigned long long timestamp; + unsigned long long time_stamp; //deprecated + }; + +/* + * Use "value_count" instead of "values_num" + * which is going to be removed soon + */ + union { + int value_count; + int values_num; //deprecated + }; + + float values[SENSOR_DATA_VALUE_SIZE]; + +/* + * If extra_data_size > 0, + * then use extra_data. + */ + int extra_data_size; + void *extra_data; +} sensor_data_t; + +#define SENSOR_HUB_DATA_SIZE 4096 + +typedef struct sensorhub_data_t { + int version; + int sensorhub; + int type; + int hub_data_size; + unsigned long long timestamp; + char hub_data[SENSOR_HUB_DATA_SIZE]; + float data[16]; +} sensorhub_data_t; + +enum sensor_accuracy_t { + SENSOR_ACCURACY_UNDEFINED = -1, + SENSOR_ACCURACY_BAD = 0, + SENSOR_ACCURACY_NORMAL =1, + SENSOR_ACCURACY_GOOD = 2, + SENSOR_ACCURACY_VERYGOOD = 3 +}; + +/* + * 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 + +/* + * To prevent naming confliction as using same enums as sensor CAPI use + */ +#ifndef __SENSOR_H__ +enum sensor_wakeup_t { + SENSOR_WAKEUP_UNKNOWN = -1, + SENSOR_WAKEUP_OFF = 0, + SENSOR_WAKEUP_ON = 1, +}; + +typedef enum sensor_wakeup_t sensor_wakeup_e; +#endif + +enum sensor_interval_t { + SENSOR_INTERVAL_FASTEST = 0, + SENSOR_INTERVAL_NORMAL = 200, +}; + +typedef enum { + CONDITION_NO_OP, + CONDITION_EQUAL, + CONDITION_GREAT_THAN, + CONDITION_LESS_THAN, +} condition_op_t; + +#define COMMAND_CHANNEL_PATH "/tmp/sensord_command_socket" +#define EVENT_CHANNEL_PATH "/tmp/sensord_event_socket" + +#define MAX_HANDLE 256 +#define MAX_HANDLE_REACHED -2 + +#define CLIENT_ID_INVALID -1 + +#define SENSOR_TYPE_MASK 0xFFFF + +enum packet_type_t { + CMD_NONE = 0, + CMD_GET_ID, + CMD_GET_SENSOR_LIST, + CMD_HELLO, + CMD_BYEBYE, + CMD_DONE, + CMD_START, + CMD_STOP, + CMD_REG, + CMD_UNREG, + CMD_SET_OPTION, + CMD_SET_WAKEUP, + CMD_SET_BATCH, + CMD_UNSET_BATCH, + CMD_SET_COMMAND, + CMD_GET_DATA, + CMD_SEND_SENSORHUB_DATA, + CMD_CNT, +}; + +enum sensor_state_t { + SENSOR_STATE_UNKNOWN = -1, + SENSOR_STATE_STOPPED = 0, + SENSOR_STATE_STARTED = 1, + SENSOR_STATE_PAUSED = 2 +}; + +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 = POLL_1HZ_MS, +}; + +typedef struct { + char name[NAME_MAX]; +} cmd_get_id_t; + +typedef struct { +} cmd_get_sensor_list_t; + +typedef struct { + int client_id; + int sensor; +} cmd_hello_t; + +typedef struct { +} cmd_byebye_t; + + +typedef struct { + unsigned int type; +} cmd_get_data_t; + +typedef struct { + long value; +} cmd_done_t; + + +typedef struct { + int client_id; +} cmd_get_id_done_t; + +typedef struct { + int sensor_cnt; + char data[0]; +} cmd_get_sensor_list_done_t; + +typedef struct { + int state; + sensor_data_t base_data; +} cmd_get_data_done_t; + +typedef struct { +} cmd_start_t; + +typedef struct { +} cmd_stop_t; + +typedef struct { + unsigned int event_type; +} cmd_reg_t; + +typedef struct { + unsigned int event_type; +} cmd_unreg_t; + +typedef struct { + unsigned int interval; + unsigned int latency; +} cmd_set_batch_t; + +typedef struct { +} cmd_unset_batch_t; + +typedef struct { + int option; +} cmd_set_option_t; + +typedef struct { + int wakeup; +} cmd_set_wakeup_t; + +typedef struct { + unsigned int cmd; + long value; +} cmd_set_command_t; + +typedef struct { + int data_len; + char data[0]; +} cmd_send_sensorhub_data_t; + +#define EVENT_CHANNEL_MAGIC 0xCAFECAFE + +typedef struct { + unsigned int magic; + int client_id; +} event_channel_ready_t; + +typedef struct { + std::string name; + std::string vendor; + float min_range; + float max_range; + float resolution; + int min_interval; + int fifo_count; + int max_batch_count; + bool wakeup_supported; +} sensor_properties_s; + +/* + * When modifying it, check copy_sensor*_data() + */ +typedef struct sensor_event_t { + unsigned int event_type; + sensor_id_t sensor_id; + sensor_data_t data; +} sensor_event_t; + +typedef struct sensorhub_event_t { + unsigned int event_type; + sensor_id_t sensor_id; + sensorhub_data_t data; +} sensorhub_event_t; + +typedef struct { + std::vector sensors; +} sensor_module; + +typedef sensor_module* (*create_t)(void); + +typedef void *(*cmd_func_t)(void *data, void *cb_data); + +typedef std::vector event_type_vector; + +enum sensorhub_enable_bit { + SENSORHUB_ACCELEROMETER_ENABLE_BIT = 0, + SENSORHUB_GYROSCOPE_ENABLE_BIT, + SENSORHUB_GEOMAGNETIC_UNCALIB_ENABLE_BIT, + SENSORHUB_GEOMAGNETIC_RAW_ENABLE_BIT, + SENSORHUB_GEOMAGNETIC_ENABLE_BIT, + SENSORHUB_PRESSURE_ENABLE_BIT, + SENSORHUB_GESTURE_ENABLE_BIT, + SENSORHUB_PROXIMITY_ENABLE_BIT, + SENSORHUB_TEMPERATURE_HUMIDITY_ENABLE_BIT, + SENSORHUB_LIGHT_ENABLE_BIT, + SENSORHUB_PROXIMITY_RAW_ENABLE_BIT, + SENSORHUB_ORIENTATION_ENABLE_BIT, + SENSORHUB_STEP_DETECTOR_ENABLE_BIT = 12, + SENSORHUB_SIG_MOTION_ENABLE_BIT, + SENSORHUB_GYRO_UNCALIB_ENABLE_BIT, + SENSORHUB_GAME_ROTATION_VECTOR_ENABLE_BIT = 15, + SENSORHUB_ROTATION_VECTOR_ENABLE_BIT, + SENSORHUB_STEP_COUNTER_ENABLE_BIT, + SENSORHUB_BIO_HRM_RAW_ENABLE_BIT, + SENSORHUB_BIO_HRM_RAW_FAC_ENABLE_BIT, + SENSORHUB_BIO_HRM_LIB_ENABLE_BIT, + SENSORHUB_TILT_MOTION, + SENSORHUB_UV_SENSOR, + SENSORHUB_PIR_ENABLE_BIT, + SENSORHUB_ENABLE_BIT_MAX, +}; + +enum sensor_permission_t { + SENSOR_PERMISSION_NONE = 0, + SENSOR_PERMISSION_STANDARD = (1 << 0), + SENSOR_PERMISSION_BIO = (1 << 1), +}; + +#define BIO_SENSOR_PRIVELEGE_NAME "sensord::bio" +#define BIO_SENSOR_ACCESS_RIGHT "rw" + +#ifdef __cplusplus +} +#endif + +#endif +//! End of a file diff --git a/src/lib/sensor_logs.cpp b/src/lib/sensor_logs.cpp new file mode 100644 index 0000000..f482c58 --- /dev/null +++ b/src/lib/sensor_logs.cpp @@ -0,0 +1,197 @@ +/* + * libsensord-share + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sensor_logs.h" +#include +#include +#include +#include + +#ifndef EXTAPI +#define EXTAPI __attribute__((visibility("default"))) +#endif + +#define SF_SERVER_MSG_LOG_FILE "/var/log/messages" +#define FILE_LENGTH 255 + +static int sf_debug_file_fd; +static char sf_debug_file_buf[FILE_LENGTH]; + +EXTAPI void sf_log(int type , int priority , const char *tag , const char *fmt , ...) +{ + va_list ap; + va_start(ap, fmt); + + switch (type) { + case SF_LOG_PRINT_FILE: + sf_debug_file_fd = open(SF_SERVER_MSG_LOG_FILE, O_WRONLY|O_CREAT|O_APPEND, 0644); + if (sf_debug_file_fd != -1) { + vsnprintf(sf_debug_file_buf,255, fmt , ap ); + int total_bytes_written = 0; + while (total_bytes_written < (int) strlen(sf_debug_file_buf)){ + int bytes_written = write(sf_debug_file_fd, (sf_debug_file_buf + total_bytes_written), strlen(sf_debug_file_buf) - total_bytes_written); + if (bytes_written == -1) + break; + total_bytes_written = total_bytes_written + bytes_written; + } + close(sf_debug_file_fd); + } + break; + + case SF_LOG_SYSLOG: + int syslog_prio; + switch (priority) { + case SF_LOG_ERR: + syslog_prio = LOG_ERR|LOG_DAEMON; + break; + case SF_LOG_WARN: + syslog_prio = LOG_WARNING|LOG_DAEMON; + break; + + case SF_LOG_DBG: + syslog_prio = LOG_DEBUG|LOG_DAEMON; + break; + + case SF_LOG_INFO: + syslog_prio = LOG_INFO|LOG_DAEMON; + break; + + default: + syslog_prio = priority; + break; + } + + vsyslog(syslog_prio, fmt, ap); + break; + + case SF_LOG_DLOG: + if (tag) { + switch (priority) { + case SF_LOG_ERR: + SLOG_VA(LOG_ERROR, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap); + break; + + case SF_LOG_WARN: + SLOG_VA(LOG_WARN, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap); + break; + + case SF_LOG_DBG: + SLOG_VA(LOG_DEBUG, tag ? tag : "NULL", fmt ? fmt : "NULL" , ap); + break; + + case SF_LOG_INFO: + SLOG_VA(LOG_INFO, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap); + break; + } + } + break; + } + + va_end(ap); +} + +#if defined(_DEBUG) +bool get_proc_name(pid_t pid, char *process_name) +{ + FILE *fp; + char buf[NAME_MAX]; + char filename[PATH_MAX]; + + sprintf(filename, "/proc/%d/stat", pid); + fp = fopen(filename, "r"); + + if (fp == NULL) + return false; + + if (fscanf(fp, "%*s (%[^)]", buf) < 1) { + fclose(fp); + return false; + } + + strncpy(process_name, buf, NAME_MAX-1); + process_name[NAME_MAX-1] = '\0'; + fclose(fp); + + return true; +} +#else +bool get_proc_name(pid_t pid, char *process_name) +{ + char buf[NAME_MAX]; + + if (sprintf(buf, "%d process", pid) < 1) { + return false; + } + + strncpy(process_name, buf, NAME_MAX-1); + process_name[NAME_MAX-1] = '\0'; + + return true; +} +#endif + +const char* 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; +} + + +bool is_sensorhub_event(unsigned int event_type) +{ + if ((event_type >> SENSOR_TYPE_SHIFT) == CONTEXT_SENSOR) + return true; + + return false; +} + +void copy_sensor_data(sensor_data_t *dest, sensor_data_t *src) +{ + memcpy(dest, src, offsetof(sensor_data_t, values)); + memcpy(dest->values, src->values, src->value_count * sizeof(src->values[0])); + + dest->extra_data_size = src->extra_data_size; + dest->extra_data = src->extra_data; +} + +void copy_sensorhub_data(sensorhub_data_t *dest, sensorhub_data_t *src) +{ + memcpy(dest, src, offsetof(sensorhub_data_t, hub_data)); + memcpy(dest->hub_data, src->hub_data, src->hub_data_size); + memcpy(dest->data, src->data, sizeof(src->data)); +} diff --git a/src/lib/sensor_logs.h b/src/lib/sensor_logs.h new file mode 100755 index 0000000..ea2a8b9 --- /dev/null +++ b/src/lib/sensor_logs.h @@ -0,0 +1,232 @@ +/* + * libsensord-share + * + * 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. + * + */ + +#if !defined(_COMMON_H_) +#define _COMMON_H_ + +#ifndef __cplusplus +#include +#endif /* !__cplusplus */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +#if !defined(PATH_MAX) +#define PATH_MAX 256 +#endif + +#if !defined(NAME_MAX) +#define NAME_MAX 256 +#endif + + +#define SENSOR_TYPE_SHIFT 16 + +enum sf_log_type { + SF_LOG_PRINT_FILE = 1, + SF_LOG_SYSLOG = 2, + SF_LOG_DLOG = 3, +}; + +enum sf_priority_type { + SF_LOG_ERR = 1, + SF_LOG_DBG = 2, + SF_LOG_INFO = 3, + SF_LOG_WARN = 4, +}; + +void sf_log(int type , int priority , const char *tag , const char *fmt , ...); + +#define MICROSECONDS(tv) ((tv.tv_sec * 1000000ll) + tv.tv_usec) + +#ifndef __MODULE__ +#include +#define __MODULE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +#endif + +//for new log system - dlog +#ifdef LOG_TAG + #undef LOG_TAG +#endif +#define LOG_TAG "SENSOR" + +#if defined(_DEBUG) || defined(USE_FILE_DEBUG) + +#define DbgPrint(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG , " [SF_MSG_PRT][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) + +#endif + +#if defined(USE_SYSLOG_DEBUG) + +#define ERR(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define WARN(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define INFO(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define DBG(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) + +#define _E(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _W(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _I(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _D(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _T(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) + + +#elif defined(_DEBUG) || defined(USE_DLOG_DEBUG) + +#define ERR(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define WARN(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define INFO(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define DBG(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) + +#define _E(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _W(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _I(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _D(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _T(fmt, arg...) do { sf_log(SF_LOG_SYSLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) + +#elif defined(USE_FILE_DEBUG) + +#define ERR(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG, "[SF_MSG_ERR][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define WARN(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG, "[SF_MSG_WARN][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define DBG(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG, "[SF_MSG_DBG][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define INFO(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG, "[SF_MSG_INFO][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) + +#define _E(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG ,"[SF_MSG_ERR][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define _W(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG ,"[SF_MSG_WARN][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define _I(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG ,"[SF_MSG_INFO][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define _D(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG ,"[SF_MSG_DBG][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) +#define _T(fmt, arg...) do { sf_log(SF_LOG_PRINT_FILE, 0, LOG_TAG ,"[SF_MSG_TEMP][%s:%d] " fmt"\n",__MODULE__, __LINE__, ##arg); } while(0) + +#elif defined(USE_DLOG_LOG) + +#define ERR(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define WARN(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define INFO(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) + +#define DBG(...) do{} while(0) +#define DbgPrint(...) do{} while(0) + + +#define _E(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _W(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _I(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _D(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _T(...) + +#else +#define ERR(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define WARN(...) do{} while(0) +#define DbgPrint(...) do{} while(0) +#define DBG(...) do{} while(0) +#define INFO(...) do{} while(0) + +#define _E(fmt, arg...) do { sf_log(SF_LOG_DLOG, SF_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while(0) +#define _W(...) do{} while(0) +#define _I(...) do{} while(0) +#define _D(...) do{} while(0) +#define _T(...) do{} while(0) + +#endif + + +#if defined(_DEBUG) +# define warn_if(expr, fmt, arg...) do { \ + if(expr) { \ + DBG("(%s) -> " fmt, #expr, ##arg); \ + } \ + } while (0) +# define ret_if(expr) do { \ + if(expr) { \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ + } while (0) +# define retv_if(expr, val) do { \ + if(expr) { \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ + } while (0) +# define retm_if(expr, fmt, arg...) do { \ + if(expr) { \ + ERR(fmt, ##arg); \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ + } while (0) +# define retvm_if(expr, val, fmt, arg...) do { \ + if(expr) { \ + ERR(fmt, ##arg); \ + DBG("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ + } while (0) + +#else +# define warn_if(expr, fmt, arg...) do { \ + if(expr) { \ + ERR(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) { \ + ERR(fmt, ##arg); \ + return; \ + } \ + } while (0) +# define retvm_if(expr, val, fmt, arg...) do { \ + if(expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while (0) + +#endif + +struct sensor_data_t; +struct sensorhub_data_t; +typedef struct sensor_data_t sensor_data_t; +typedef struct sensorhub_data_t sensorhub_data_t; + +const char* get_client_name(void); +bool get_proc_name(pid_t pid, char *process_name); +bool is_sensorhub_event(unsigned int event_type); +void copy_sensor_data(sensor_data_t *dest, sensor_data_t *src); +void copy_sensorhub_data(sensorhub_data_t *dest, sensorhub_data_t *src); + +#ifdef __cplusplus +} +#endif + +#endif +//! End of a file diff --git a/src/plugins/accel/accel_sensor_hal.cpp b/src/plugins/accel/accel_sensor_hal.cpp new file mode 100755 index 0000000..af21cb3 --- /dev/null +++ b/src/plugins/accel/accel_sensor_hal.cpp @@ -0,0 +1,363 @@ +/* + * accel_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define GRAVITY 9.80665 +#define G_TO_MG 1000 +#define RAW_DATA_TO_G_UNIT(X) (((float)(X))/((float)G_TO_MG)) +#define RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(X) (GRAVITY * (RAW_DATA_TO_G_UNIT(X))) + +#define MIN_RANGE(RES) (-((1 << (RES))/2)) +#define MAX_RANGE(RES) (((1 << (RES))/2)-1) + +#define SENSOR_TYPE_ACCEL "ACCEL" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_RESOLUTION "RESOLUTION" + +#define ATTR_VALUE "value" + +#define INPUT_NAME "accelerometer_sensor" +#define ACCEL_SENSORHUB_POLL_NODE_NAME "accel_poll_delay" + +accel_sensor_hal::accel_sensor_hal() +: m_x(-1) +, m_y(-1) +, m_z(-1) +, m_node_handle(-1) +, m_polling_interval(POLL_1HZ_MS) +, m_fired_time(0) +{ + const string sensorhub_interval_node_name = "accel_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_ACCEL, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_ACCEL; + query.key = "accelerometer_sensor"; + query.iio_enable_node_name = "accel_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_method = info.method; + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + long resolution; + + if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RESOLUTION, resolution)) { + ERR("[RESOLUTION] is empty\n"); + throw ENXIO; + } + + m_resolution = (int)resolution; + + INFO("m_resolution = %d\n",m_resolution); + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + INFO("m_raw_data_unit = %f\n", m_raw_data_unit); + + if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) { + ERR("accel handle open fail for accel processor, error:%s\n", strerror(errno)); + throw ENXIO; + } + + if (m_method == INPUT_EVENT_METHOD) { + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + update_value = [=]() { + return this->update_value_input_event(); + }; + } else { + if (!info.buffer_length_node_path.empty()) + set_node_value(info.buffer_length_node_path, 480); + + if (!info.buffer_enable_node_path.empty()) + set_node_value(info.buffer_enable_node_path, 1); + + update_value = [=]() { + return this->update_value_iio(); + }; + } + + INFO("accel_sensor is created!\n"); +} + +accel_sensor_hal::~accel_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("accel_sensor is destroyed!\n"); +} + +string accel_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t accel_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_ACCELEROMETER; +} + +bool accel_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ACCELEROMETER_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Accel sensor real starting"); + return true; +} + +bool accel_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ACCELEROMETER_ENABLE_BIT); + + INFO("Accel sensor real stopping"); + return true; +} + +bool accel_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool accel_sensor_hal::update_value_input_event() +{ + int accel_raw[3] = {0,}; + bool x,y,z; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + x = y = z = false; + + struct input_event accel_input; + DBG("accel event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &accel_input, sizeof(accel_input)); + if (len != sizeof(accel_input)) { + ERR("accel_file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (accel_input.type == EV_REL) { + switch (accel_input.code) { + case REL_X: + accel_raw[0] = (int)accel_input.value; + x = true; + break; + case REL_Y: + accel_raw[1] = (int)accel_input.value; + y = true; + break; + case REL_Z: + accel_raw[2] = (int)accel_input.value; + z = true; + break; + default: + ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code); + return false; + break; + } + } else if (accel_input.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&accel_input.time); + } else { + ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code); + return false; + } + } + + if (syn == false) { + ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt); + return false; + } + + AUTOLOCK(m_value_mutex); + + if (x) + m_x = accel_raw[0]; + if (y) + m_y = accel_raw[1]; + if (z) + m_z = accel_raw[2]; + + m_fired_time = fired_time; + + DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time); + + return true; +} + +bool accel_sensor_hal::update_value_iio() +{ + const int READ_LEN = 14; + char data[READ_LEN] = {0,}; + + struct pollfd pfd; + + pfd.fd = m_node_handle; + pfd.events = POLLIN | POLLERR; + pfd.revents = 0; + + int ret = poll(&pfd, 1, -1); + + if (ret == -1) { + ERR("poll error:%s m_node_handle:d", strerror(errno), m_node_handle); + return false; + } else if (!ret) { + ERR("poll timeout m_node_handle:%d", m_node_handle); + return false; + } + + if (pfd.revents & POLLERR) { + ERR("poll exception occurred! m_node_handle:%d", m_node_handle); + return false; + } + + if (!(pfd.revents & POLLIN)) { + ERR("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents); + return false; + } + + int len = read(m_node_handle, data, sizeof(data)); + + if (len != sizeof(data)) { + ERR("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len); + return false; + } + + AUTOLOCK(m_value_mutex); + + short *short_data = (short *)(data); + m_x = *(short_data); + m_y = *((short *)(data + 2)); + m_z = *((short *)(data + 4)); + + m_fired_time = *((long long*)(data + 6)); + + INFO("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time); + + return true; + +} + +bool accel_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int accel_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time; + data.value_count = 3; + data.values[0] = m_x; + data.values[1] = m_y; + data.values[2] = m_z; + + return 0; +} + +bool accel_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = MIN_RANGE(m_resolution)* RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit); + properties.max_range = MAX_RANGE(m_resolution)* RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit); + properties.min_interval = 1; + properties.resolution = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit); + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/accel/accel_sensor_hal.h b/src/plugins/accel/accel_sensor_hal.h new file mode 100755 index 0000000..97c4af4 --- /dev/null +++ b/src/plugins/accel/accel_sensor_hal.h @@ -0,0 +1,69 @@ +/* + * accel_sensor_hal + * + * 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 _ACCEL_SENSOR_HAL_H_ +#define _ACCEL_SENSOR_HAL_H_ + +#include +#include + +class accel_sensor_hal : public sensor_hal_base +{ +public: + accel_sensor_hal(); + virtual ~accel_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); + +private: + int m_x; + int m_y; + int m_z; + int m_node_handle; + unsigned long m_polling_interval; + unsigned long long m_fired_time; + + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + int m_resolution; + float m_raw_data_unit; + + int m_method; + std::string m_data_node; + std::string m_enable_node; + std::string m_interval_node; + + std::function update_value; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value_input_event(void); + bool update_value_iio(void); +}; +#endif /*_ACCEL_SENSOR_HAL_CLASS_H_*/ diff --git a/src/plugins/bio_led_red/bio_led_red_sensor_hal.cpp b/src/plugins/bio_led_red/bio_led_red_sensor_hal.cpp new file mode 100755 index 0000000..ff4745e --- /dev/null +++ b/src/plugins/bio_led_red/bio_led_red_sensor_hal.cpp @@ -0,0 +1,244 @@ +/* + * bio_led_red_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_BIO_LED_RED "BIO_LED_RED" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ATTR_VALUE "value" +#define PATH_LED_RED_ENABLE "/sys/class/sensors/hrm_sensor/led_current1"; +#define LED_RED_ENABLE_VALUE 255 + +#define BIAS 1 + +bio_led_red_sensor_hal::bio_led_red_sensor_hal() +: m_polling_interval(POLL_1HZ_MS) +, m_bio_led_red(0) +, m_fired_time(0) +, m_node_handle(-1) +{ + const string sensorhub_interval_node_name = "hrm_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_BIO_LED_RED, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_BIO_LED_RED; + query.key = "hrm_sensor"; + query.iio_enable_node_name = "hrm_raw_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_BIO_LED_RED, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_BIO_LED_RED, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("bio_led_red_sensor_hal is created!\n"); +} + +bio_led_red_sensor_hal::~bio_led_red_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("bio_led_red_sensor_hal is destroyed!\n"); +} + +string bio_led_red_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t bio_led_red_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_BIO_LED_RED; +} + +bool bio_led_red_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + const string led_red_enable_path = PATH_LED_RED_ENABLE; + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_BIO_HRM_RAW_ENABLE_BIT); + + if (!set_node_value(led_red_enable_path, LED_RED_ENABLE_VALUE)) { + ERR("Failed to set led red enable node: %s", led_red_enable_path.c_str()); + return false; + } + + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("bio_led_red sensor starting"); + return true; +} + +bool bio_led_red_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_BIO_HRM_RAW_ENABLE_BIT); + + INFO("bio_led_red sensor real stopping"); + return true; +} + +bool bio_led_red_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; + +} + +bool bio_led_red_sensor_hal::update_value(void) +{ + int bio_led_red_raw = -1; + bool bio_led_red = false; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + struct input_event bio_led_red_event; + DBG("bio_led_red event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &bio_led_red_event, sizeof(bio_led_red_event)); + if (len != sizeof(bio_led_red_event)) { + ERR("bio_led_red file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (bio_led_red_event.type == EV_REL && bio_led_red_event.code == REL_X) { + bio_led_red_raw = (int)bio_led_red_event.value; + bio_led_red = true; + } else if (bio_led_red_event.type == EV_REL) { + ERR("bio_led_red event[type = %d, code = %d] is skipped.", bio_led_red_event.type, bio_led_red_event.code); + } else if (bio_led_red_event.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&bio_led_red_event.time); + } else { + ERR("bio_led_red event[type = %d, code = %d] is unknown.", bio_led_red_event.type, bio_led_red_event.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (bio_led_red) + m_bio_led_red = bio_led_red_raw - BIAS; + + m_fired_time = fired_time; + + DBG("m_bio_led_red = %d, time = %lluus", m_bio_led_red, m_fired_time); + + return true; +} + +bool bio_led_red_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int bio_led_red_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time; + data.value_count = 1; + data.values[0] = (float) m_bio_led_red; + + return 0; +} + +bool bio_led_red_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = 0.0f; + properties.max_range = 1.0f; + properties.min_interval = 1; + properties.resolution = 1.0f; + properties.fifo_count = 0; + properties.max_batch_count = 0; + + return true; +} diff --git a/src/plugins/bio_led_red/bio_led_red_sensor_hal.h b/src/plugins/bio_led_red/bio_led_red_sensor_hal.h new file mode 100755 index 0000000..3a13682 --- /dev/null +++ b/src/plugins/bio_led_red/bio_led_red_sensor_hal.h @@ -0,0 +1,62 @@ +/* + * hrm_red_sensor_hal + * + * 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 _BIO_LED_RED_SENSOR_HAL_H_ +#define _BIO_LED_RED_SENSOR_HAL_H_ + +#include + +class bio_led_red_sensor_hal : public sensor_hal_base +{ +public: + bio_led_red_sensor_hal(); + virtual ~bio_led_red_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); + +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + unsigned long m_polling_interval; + + int m_bio_led_red; + + unsigned long long m_fired_time; + int m_node_handle; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_BIO_LED_RED_SENSOR_HAL_CLASS_H_*/ + diff --git a/src/plugins/geo/geo_sensor_hal.cpp b/src/plugins/geo/geo_sensor_hal.cpp new file mode 100755 index 0000000..d88287f --- /dev/null +++ b/src/plugins/geo/geo_sensor_hal.cpp @@ -0,0 +1,297 @@ +/* + * geo_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_MAGNETIC "MAGNETIC" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_MIN_RANGE "MIN_RANGE" +#define ELEMENT_MAX_RANGE "MAX_RANGE" +#define ATTR_VALUE "value" + +geo_sensor_hal::geo_sensor_hal() +: m_x(0) +, m_y(0) +, m_z(0) +, m_hdst(0) +, m_fired_time(0) +, m_node_handle(-1) +, m_polling_interval(POLL_1HZ_MS) +{ + const string sensorhub_interval_node_name = "mag_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_MAGNETIC, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_MAGNETIC; + query.key = "geomagnetic_sensor"; + query.iio_enable_node_name = "geomagnetic_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + bool error = get_node_info(query, info); + + query.key = "magnetic_sensor"; + error |= get_node_info(query, info); + + if (!error) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + double min_range; + + if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_MIN_RANGE, min_range)) { + ERR("[MIN_RANGE] is empty\n"); + throw ENXIO; + } + + m_min_range = (float)min_range; + INFO("m_min_range = %f\n",m_min_range); + + double max_range; + + if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_MAX_RANGE, max_range)) { + ERR("[MAX_RANGE] is empty\n"); + throw ENXIO; + } + + m_max_range = (float)max_range; + INFO("m_max_range = %f\n",m_max_range); + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("m_raw_data_unit = %f\n", m_raw_data_unit); + INFO("geo_sensor_hal is created!\n"); +} + +geo_sensor_hal::~geo_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("geo_sensor is destroyed!\n"); +} + +string geo_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t geo_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_GEOMAGNETIC; +} + +bool geo_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_GEOMAGNETIC_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Geo sensor real starting"); + return true; +} + +bool geo_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_GEOMAGNETIC_ENABLE_BIT); + + INFO("Geo sensor real stopping"); + return true; +} + +bool geo_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool geo_sensor_hal::update_value(void) +{ + int geo_raw[4] = {0,}; + bool x,y,z,hdst; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + x = y = z = hdst = false; + + struct input_event geo_input; + DBG("geo event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &geo_input, sizeof(geo_input)); + if (len != sizeof(geo_input)) { + ERR("geo_file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (geo_input.type == EV_REL) { + switch (geo_input.code) { + case REL_RX: + geo_raw[0] = (int)geo_input.value; + x = true; + break; + case REL_RY: + geo_raw[1] = (int)geo_input.value; + y = true; + break; + case REL_RZ: + geo_raw[2] = (int)geo_input.value; + z = true; + break; + case REL_HWHEEL: + geo_raw[3] = (int)geo_input.value; + hdst = true; + break; + default: + ERR("geo_input event[type = %d, code = %d] is unknown.", geo_input.type, geo_input.code); + return false; + break; + } + } else if (geo_input.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&geo_input.time); + } else { + ERR("geo_input event[type = %d, code = %d] is unknown.", geo_input.type, geo_input.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (x) + m_x = geo_raw[0]; + if (y) + m_y = geo_raw[1]; + if (z) + m_z = geo_raw[2]; + if (hdst) + m_hdst = geo_raw[3] - 1; /* accuracy bias: -1 */ + + m_fired_time = fired_time; + + DBG("m_x = %d, m_y = %d, m_z = %d, m_hdst = %d, time = %lluus", m_x, m_y, m_z, m_hdst, m_fired_time); + + return true; +} + +bool geo_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int geo_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + data.accuracy = (m_hdst == 1) ? 0 : m_hdst; /* hdst 0 and 1 are needed to calibrate */ + data.timestamp = m_fired_time; + data.value_count = 3; + data.values[0] = (float)m_x; + data.values[1] = (float)m_y; + data.values[2] = (float)m_z; + return 0; +} + +bool geo_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = m_min_range; + properties.max_range = m_max_range; + properties.min_interval = 1; + properties.resolution = m_raw_data_unit; + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/geo/geo_sensor_hal.h b/src/plugins/geo/geo_sensor_hal.h new file mode 100755 index 0000000..99ee935 --- /dev/null +++ b/src/plugins/geo/geo_sensor_hal.h @@ -0,0 +1,67 @@ +/* + * geo_sensor_hal + * + * 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 _GEO_SENSOR_HAL_H_ +#define _GEO_SENSOR_HAL_H_ + +#include + +class geo_sensor_hal : public sensor_hal_base +{ +public: + geo_sensor_hal(); + virtual ~geo_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + float m_min_range; + float m_max_range; + float m_raw_data_unit; + + double m_x; + double m_y; + double m_z; + + int m_hdst; + + unsigned long long m_fired_time; + int m_node_handle; + unsigned long m_polling_interval; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_GEO_SENSOR_HAL_H_*/ diff --git a/src/plugins/gyro/gyro_sensor_hal.cpp b/src/plugins/gyro/gyro_sensor_hal.cpp new file mode 100755 index 0000000..8dab83d --- /dev/null +++ b/src/plugins/gyro/gyro_sensor_hal.cpp @@ -0,0 +1,286 @@ +/* + * gyro_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define DPS_TO_MDPS 1000 +#define MIN_RANGE(RES) (-((1 << (RES))/2)) +#define MAX_RANGE(RES) (((1 << (RES))/2)-1) +#define RAW_DATA_TO_DPS_UNIT(X) ((float)(X)/((float)DPS_TO_MDPS)) + +#define SENSOR_TYPE_GYRO "GYRO" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_RESOLUTION "RESOLUTION" + +#define ATTR_VALUE "value" + +gyro_sensor_hal::gyro_sensor_hal() +: m_x(-1) +, m_y(-1) +, m_z(-1) +, m_node_handle(-1) +, m_polling_interval(POLL_1HZ_MS) +, m_fired_time(0) +{ + const string sensorhub_interval_node_name = "gyro_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_GYRO, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_GYRO; + query.key = "gyro_sensor"; + query.iio_enable_node_name = "gyro_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + long resolution; + + if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_RESOLUTION, resolution)) { + ERR("[RESOLUTION] is empty\n"); + throw ENXIO; + } + + m_resolution = (int)resolution; + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + + if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) { + ERR("gyro handle open fail for gyro processor, error:%s\n", strerror(errno)); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("m_raw_data_unit = %f\n",m_raw_data_unit); + INFO("RAW_DATA_TO_DPS_UNIT(m_raw_data_unit) = [%f]",RAW_DATA_TO_DPS_UNIT(m_raw_data_unit)); + INFO("gyro_sensor is created!\n"); +} + +gyro_sensor_hal::~gyro_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("gyro_sensor is destroyed!\n"); +} + +string gyro_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t gyro_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_GYROSCOPE; +} + +bool gyro_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_GYROSCOPE_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Gyro sensor real starting"); + return true; +} + +bool gyro_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_GYROSCOPE_ENABLE_BIT); + + INFO("Gyro sensor real stopping"); + return true; + +} + +bool gyro_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool gyro_sensor_hal::update_value(void) +{ + int gyro_raw[3] = {0,}; + bool x,y,z; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + x = y = z = false; + + struct input_event gyro_input; + DBG("gyro event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &gyro_input, sizeof(gyro_input)); + if (len != sizeof(gyro_input)) { + ERR("gyro_file read fail, read_len = %d\n, %s",len, strerror(errno)); + return false; + } + + ++read_input_cnt; + + if (gyro_input.type == EV_REL) { + switch (gyro_input.code) { + case REL_RX: + gyro_raw[0] = (int)gyro_input.value; + x = true; + break; + case REL_RY: + gyro_raw[1] = (int)gyro_input.value; + y = true; + break; + case REL_RZ: + gyro_raw[2] = (int)gyro_input.value; + z = true; + break; + default: + ERR("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code); + return false; + break; + } + } else if (gyro_input.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&gyro_input.time); + } else { + ERR("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (x) + m_x = gyro_raw[0]; + if (y) + m_y = gyro_raw[1]; + if (z) + m_z = gyro_raw[2]; + + m_fired_time = fired_time; + + DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time); + + return true; +} + +bool gyro_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int gyro_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time ; + data.value_count = 3; + data.values[0] = m_x; + data.values[1] = m_y; + data.values[2] = m_z; + + return 0; +} + +bool gyro_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = MIN_RANGE(m_resolution)* RAW_DATA_TO_DPS_UNIT(m_raw_data_unit); + properties.max_range = MAX_RANGE(m_resolution)* RAW_DATA_TO_DPS_UNIT(m_raw_data_unit); + properties.min_interval = 1; + properties.resolution = RAW_DATA_TO_DPS_UNIT(m_raw_data_unit); + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; + +} diff --git a/src/plugins/gyro/gyro_sensor_hal.h b/src/plugins/gyro/gyro_sensor_hal.h new file mode 100755 index 0000000..aedd640 --- /dev/null +++ b/src/plugins/gyro/gyro_sensor_hal.h @@ -0,0 +1,66 @@ +/* + * gyro_sensor_hal + * + * 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 _GYRO_SENSOR_HAL_H_ +#define _GYRO_SENSOR_HAL_H_ + +#include + +class gyro_sensor_hal : public sensor_hal_base +{ +public: + gyro_sensor_hal(); + virtual ~gyro_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long ms_interval); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + virtual bool get_properties(sensor_properties_s &properties); + +private: + int m_x; + int m_y; + int m_z; + int m_node_handle; + unsigned long m_polling_interval; + unsigned long long m_fired_time; + + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + float m_min_range; + float m_max_range; + int m_resolution; + float m_raw_data_unit; + + std::string m_data_node; + std::string m_enable_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_GYRO_SENSOR_HAL_CLASS_H_*/ diff --git a/src/plugins/light/light_sensor_hal.cpp b/src/plugins/light/light_sensor_hal.cpp new file mode 100755 index 0000000..4f96c55 --- /dev/null +++ b/src/plugins/light/light_sensor_hal.cpp @@ -0,0 +1,227 @@ +/* + * light_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_LIGHT "LIGHT" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_RESOLUTION "RESOLUTION" +#define ATTR_VALUE "value" +#define INITIAL_TIME -1 +#define BIAS 1 +#define INVALID_VALUE -1 +#define INITIAL_VALUE -1 + +light_sensor_hal::light_sensor_hal() +: m_polling_interval(POLL_1HZ_MS) +, m_adc(INVALID_VALUE) +, m_fired_time(INITIAL_TIME) +, m_node_handle(INITIAL_VALUE) +{ + const string sensorhub_interval_node_name = "light_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_LIGHT, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_LIGHT; + query.key = "light_sensor"; + query.iio_enable_node_name = "light_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("light_sensor_hal is created!\n"); +} + +light_sensor_hal::~light_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("light_sensor_hal is destroyed!\n"); +} + +string light_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + + +sensor_hal_type_t light_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_LIGHT; +} + +bool light_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_LIGHT_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Light sensor real starting"); + return true; +} + +bool light_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_LIGHT_ENABLE_BIT); + + INFO("Light sensor real stopping"); + return true; +} + +bool light_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool light_sensor_hal::update_value(void) +{ + unsigned short int adc = INITIAL_VALUE; + + struct input_event light_event; + DBG("light event detection!"); + + int len = read(m_node_handle, &light_event, sizeof(light_event)); + if (len == -1) { + DBG("read(m_node_handle) is error:%s.\n", strerror(errno)); + return false; + } + + if (light_event.type == EV_ABS && light_event.code == ABS_MISC) { + adc = light_event.value; + } else if (light_event.type == EV_REL && light_event.code == REL_MISC) { + adc = light_event.value - BIAS; + } else if (light_event.type == EV_REL && light_event.code == REL_RX) { + adc = light_event.value - BIAS; + } else { + DBG("light input event[type = %d, code = %d] is unknown.", light_event.type, light_event.code); + return false; + } + + DBG("read event, len : %d, type : %x, code : %x, value : %x", + len, light_event.type, light_event.code, light_event.value); + + DBG("update_value, adc : %d", adc); + + AUTOLOCK(m_value_mutex); + m_adc = adc; + m_fired_time = sensor_hal_base::get_timestamp(&light_event.time); + + return true; +} + +bool light_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int light_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time; + data.value_count = 1; + data.values[0] = (float) m_adc; + + return 0; +} + +bool light_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = 0; + properties.max_range = 65535; + properties.min_interval = 1; + properties.resolution = 1; + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/light/light_sensor_hal.h b/src/plugins/light/light_sensor_hal.h new file mode 100755 index 0000000..ff98264 --- /dev/null +++ b/src/plugins/light/light_sensor_hal.h @@ -0,0 +1,60 @@ +/* + * light_sensor_hal + * + * 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 _LIGHT_SENSOR_HAL_H_ +#define _LIGHT_SENSOR_HAL_H_ + +#include + +class light_sensor_hal : public sensor_hal_base +{ +public: + light_sensor_hal(); + virtual ~light_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + unsigned long m_polling_interval; + + int m_adc; + + unsigned long long m_fired_time; + int m_node_handle; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_GYRO_SENSOR_HAL_CLASS_H_*/ diff --git a/src/plugins/pressure/pressure_sensor_hal.cpp b/src/plugins/pressure/pressure_sensor_hal.cpp new file mode 100755 index 0000000..badd9bd --- /dev/null +++ b/src/plugins/pressure/pressure_sensor_hal.cpp @@ -0,0 +1,351 @@ +/* + * pressure_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_PRESSURE "PRESSURE" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_RESOLUTION "RESOLUTION" +#define ELEMENT_MIN_RANGE "MIN_RANGE" +#define ELEMENT_MAX_RANGE "MAX_RANGE" +#define ELEMENT_TEMPERATURE_RESOLUTION "TEMPERATURE_RESOLUTION" +#define ELEMENT_TEMPERATURE_OFFSET "TEMPERATURE_OFFSET" +#define ATTR_VALUE "value" + +#define SEA_LEVEL_PRESSURE 101325.0 +#define SEA_LEVEL_RESOLUTION 0.01 + +pressure_sensor_hal::pressure_sensor_hal() +: m_pressure(0) +, m_sea_level_pressure(SEA_LEVEL_PRESSURE) +, m_temperature(0) +, m_polling_interval(POLL_1HZ_MS) +, m_fired_time(0) +, m_node_handle(-1) +{ + const string sensorhub_interval_node_name = "pressure_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_PRESSURE, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_PRESSURE; + query.key = "pressure_sensor"; + query.iio_enable_node_name = "pressure_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + bool error = get_node_info(query, info); + + query.key = "barometer_sensor"; + error |= get_node_info(query, info); + + if (!error) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s", m_chip_name.c_str()); + + double min_range; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_MIN_RANGE, min_range)) { + ERR("[MIN_RANGE] is empty\n"); + throw ENXIO; + } + + m_min_range = (float)min_range; + INFO("m_min_range = %f\n",m_min_range); + + double max_range; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_MAX_RANGE, max_range)) { + ERR("[MAX_RANGE] is empty\n"); + throw ENXIO; + } + + m_max_range = (float)max_range; + INFO("m_max_range = %f\n",m_max_range); + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + INFO("m_raw_data_unit = %f\n", m_raw_data_unit); + + double resolution; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_RESOLUTION, resolution)) { + ERR("[RESOLUTION] is empty\n"); + throw ENXIO; + } + + m_resolution = (float)resolution; + INFO("m_resolution = %f\n", m_resolution); + + double temperature_resolution; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_TEMPERATURE_RESOLUTION, temperature_resolution)) { + ERR("[TEMPERATURE_RESOLUTION] is empty\n"); + throw ENXIO; + } + + m_temperature_resolution = (float)temperature_resolution; + INFO("m_temperature_resolution = %f\n", m_temperature_resolution); + + double temperature_offset; + + if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_TEMPERATURE_OFFSET, temperature_offset)) { + ERR("[TEMPERATURE_OFFSET] is empty\n"); + throw ENXIO; + } + + m_temperature_offset = (float)temperature_offset; + INFO("m_temperature_offset = %f\n", m_temperature_offset); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("pressure_sensor_hal is created!\n"); +} + +pressure_sensor_hal::~pressure_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("pressure_sensor_hal is destroyed!\n"); +} + +string pressure_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t pressure_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_PRESSURE; +} + +bool pressure_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_PRESSURE_ENABLE_BIT); + + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Pressure sensor real starting"); + return true; +} + +bool pressure_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_PRESSURE_ENABLE_BIT); + + INFO("Pressure sensor real stopping"); + return true; +} + +bool pressure_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool pressure_sensor_hal::update_value(void) +{ + int pressure_raw[3] = {0,}; + bool pressure = false; + bool sea_level = false; + bool temperature = false; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + struct input_event pressure_event; + DBG("pressure event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &pressure_event, sizeof(pressure_event)); + if (len != sizeof(pressure_event)) { + ERR("pressure_file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (pressure_event.type == EV_REL) { + switch (pressure_event.code) { + case REL_X: + case REL_HWHEEL: + pressure_raw[0] = (int)pressure_event.value; + pressure = true; + break; + case REL_Y: + case REL_DIAL: + pressure_raw[1] = (int)pressure_event.value; + sea_level = true; + break; + case REL_Z: + case REL_WHEEL: + pressure_raw[2] = (int)pressure_event.value; + temperature = true; + break; + default: + ERR("pressure_event event[type = %d, code = %d] is unknown.", pressure_event.type, pressure_event.code); + return false; + break; + } + } else if (pressure_event.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&pressure_event.time); + } else { + ERR("pressure_event event[type = %d, code = %d] is unknown.", pressure_event.type, pressure_event.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (pressure) + m_pressure = pressure_raw[0]; + if (sea_level) + m_sea_level_pressure = pressure_raw[1]; + if (temperature) + m_temperature = pressure_raw[2]; + + m_fired_time = fired_time; + + DBG("m_pressure = %d, sea_level = %d, temperature = %d, time = %lluus", m_pressure, m_sea_level_pressure, m_temperature, m_fired_time); + + return true; +} + +bool pressure_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + + +float pressure_sensor_hal::pressure_to_altitude(float pressure) +{ + return 44330.0f * (1.0f - pow(pressure/m_sea_level_pressure, 1.0f/5.255f)); +} + +void pressure_sensor_hal::raw_to_base(sensor_data_t &data) +{ + data.values[0] = data.values[0] * m_resolution; + m_sea_level_pressure = data.values[1] * SEA_LEVEL_RESOLUTION; + data.values[1] = pressure_to_altitude(data.values[0]); + data.values[2] = data.values[2] * m_temperature_resolution + m_temperature_offset; + data.value_count = 3; +} + +int pressure_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time ; + data.value_count = 3; + data.values[0] = m_pressure; + data.values[1] = m_sea_level_pressure; + data.values[2] = m_temperature; + + raw_to_base(data); + + return 0; +} + +bool pressure_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = m_min_range; + properties.max_range = m_max_range; + properties.min_interval = 1; + properties.resolution = m_raw_data_unit; + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/pressure/pressure_sensor_hal.h b/src/plugins/pressure/pressure_sensor_hal.h new file mode 100755 index 0000000..677b15d --- /dev/null +++ b/src/plugins/pressure/pressure_sensor_hal.h @@ -0,0 +1,74 @@ +/* + * pressure_sensor_hal + * + * 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 _PRESSURE_SENSOR_HAL_H_ +#define _PRESSURE_SENSOR_HAL_H_ + +#include + +class pressure_sensor_hal : public sensor_hal_base +{ +public: + pressure_sensor_hal(); + virtual ~pressure_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + virtual bool get_properties(sensor_properties_s &properties); +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + float m_pressure; + float m_sea_level_pressure; + float m_temperature; + float m_temperature_offset; + float m_temperature_resolution; + + int m_resolution; + + float m_min_range; + float m_max_range; + float m_raw_data_unit; + float m_temp_resolution; + float m_temp_offset; + unsigned long m_polling_interval; + + unsigned long long m_fired_time; + int m_node_handle; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); + float pressure_to_altitude(float pressure); + void raw_to_base(sensor_data_t &data); +}; +#endif /*_PRESSURE_SENSOR_HAL_CLASS_H_*/ diff --git a/src/plugins/proxi/proxi_sensor_hal.cpp b/src/plugins/proxi/proxi_sensor_hal.cpp new file mode 100644 index 0000000..4b7f948 --- /dev/null +++ b/src/plugins/proxi/proxi_sensor_hal.cpp @@ -0,0 +1,190 @@ +/* + * proxi_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::string; +using std::ifstream; + +#define SENSOR_TYPE_PROXI "PROXI" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ATTR_VALUE "value" + +proxi_sensor_hal::proxi_sensor_hal() +: m_state(-1) +, m_fired_time(0) +, m_node_handle(-1) +{ + const string sensorhub_interval_node_name = "prox_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_PROXI, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_PROXI; + query.key = "proximity_sensor"; + query.iio_enable_node_name = "proximity_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + + if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) { + ERR("Proxi handle(%d) open fail", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("Proxi_sensor_hal is created!\n"); +} + +proxi_sensor_hal::~proxi_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("Proxi_sensor_hal is destroyed!\n"); +} + +string proxi_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t proxi_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_PROXIMITY; +} + +bool proxi_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_PROXIMITY_ENABLE_BIT); + + m_fired_time = 0; + INFO("Proxi sensor real starting"); + return true; +} + +bool proxi_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_PROXIMITY_ENABLE_BIT); + + INFO("Proxi sensor real stopping"); + return true; +} + +bool proxi_sensor_hal::set_interval(unsigned long val) +{ + return true; +} + +bool proxi_sensor_hal::update_value(void) +{ + struct input_event proxi_event; + INFO("proxi event detection!"); + + int len = read(m_node_handle, &proxi_event, sizeof(proxi_event)); + + if (len == -1) { + DBG("read(m_node_handle) is error:%s.\n", strerror(errno)); + return false; + } + + DBG("read event, len : %d , type : %x , code : %x , value : %x", len, proxi_event.type, proxi_event.code, proxi_event.value); + if ((proxi_event.type == EV_ABS) && (proxi_event.code == ABS_DISTANCE)) { + AUTOLOCK(m_value_mutex); + m_state = proxi_event.value; + m_fired_time = sensor_hal_base::get_timestamp(&proxi_event.time); + } else { + return false; + } + return true; +} + +bool proxi_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int proxi_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_UNDEFINED; + data.timestamp = m_fired_time; + data.value_count = 1; + data.values[0] = m_state; + + return 0; +} + +bool proxi_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = 0; + properties.max_range = 1; + properties.min_interval = 1; + properties.resolution = 1; + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/proxi/proxi_sensor_hal.h b/src/plugins/proxi/proxi_sensor_hal.h new file mode 100755 index 0000000..27c4684 --- /dev/null +++ b/src/plugins/proxi/proxi_sensor_hal.h @@ -0,0 +1,56 @@ +/* + * proxi_sensor_hal + * + * 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 _PROXI_SENSOR_HAL_H_ +#define _PROXI_SENSOR_HAL_H_ + +#include + +class proxi_sensor_hal : public sensor_hal_base +{ +public: + proxi_sensor_hal(); + virtual ~proxi_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long ms_interval); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + virtual bool get_properties(sensor_properties_s &properties); +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + std::string m_enable_node; + std::string m_data_node; + + unsigned int m_state; + + unsigned long long m_fired_time; + + int m_node_handle; + bool m_sensorhub_controlled; + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_PROXI_SENSOR_HAL_H_*/ diff --git a/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.cpp b/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.cpp new file mode 100755 index 0000000..216e04d --- /dev/null +++ b/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.cpp @@ -0,0 +1,268 @@ +/* + * rv_raw_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_RV_RAW "ROTATION_VECTOR" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ATTR_VALUE "value" + +rv_raw_sensor_hal::rv_raw_sensor_hal() +: m_quat_a(0) +, m_quat_b(0) +, m_quat_c(0) +, m_quat_d(0) +, m_polling_interval(POLL_1HZ_MS) +{ + const string sensorhub_interval_node_name = "rot_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_RV_RAW, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_RV_RAW; + query.key = "rot_sensor"; + query.iio_enable_node_name = "rot_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s", m_chip_name.c_str()); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("rv_raw_sensor_hal is created!\n"); +} + +rv_raw_sensor_hal::~rv_raw_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("rv_raw_sensor_hal is destroyed!\n"); +} + +string rv_raw_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t rv_raw_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_RV_RAW; +} + +bool rv_raw_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Rotation vector raw sensor real starting"); + return true; +} + +bool rv_raw_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT); + + INFO("Rotation vector raw sensor real stopping"); + return true; +} + +bool rv_raw_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool rv_raw_sensor_hal::update_value(void) +{ + int rot_raw[5] = {0,}; + bool quat_a,quat_b,quat_c,quat_d,acc_rot; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + quat_a = quat_b = quat_c = quat_d = acc_rot = false; + + struct input_event rot_input; + DBG("geo event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &rot_input, sizeof(rot_input)); + if (len != sizeof(rot_input)) { + ERR("rot_file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (rot_input.type == EV_REL) { + switch (rot_input.code) { + case REL_X: + rot_raw[0] = (int)rot_input.value; + quat_a = true; + break; + case REL_Y: + rot_raw[1] = (int)rot_input.value; + quat_b = true; + break; + case REL_Z: + rot_raw[2] = (int)rot_input.value; + quat_c = true; + break; + case REL_RX: + rot_raw[3] = (int)rot_input.value; + quat_d = true; + break; + case REL_RY: + rot_raw[4] = (int)rot_input.value; + acc_rot = true; + break; + default: + ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code); + return false; + break; + } + } else if (rot_input.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&rot_input.time); + } else { + ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (quat_a) + m_quat_a = rot_raw[0]; + if (quat_b) + m_quat_b = rot_raw[1]; + if (quat_c) + m_quat_c = rot_raw[2]; + if (quat_d) + m_quat_d = rot_raw[3]; + if (acc_rot) + m_accuracy = rot_raw[4] - 1; /* accuracy bias: -1 */ + + m_fired_time = fired_time; + + DBG("m_quat_a = %d, m_quat_a = %d, m_quat_a = %d, m_quat_d = %d, m_accuracy = %d, time = %lluus", + m_quat_a, m_quat_a, m_quat_a, m_quat_d, m_accuracy, m_fired_time); + + return true; +} + +bool rv_raw_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int rv_raw_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + const float QUAT_SIG_FIGS = 1000000.0f; + + data.accuracy = (m_accuracy == 1) ? 0 : m_accuracy; /* hdst 0 and 1 are needed to calibrate */ + data.timestamp = m_fired_time; + data.value_count = 4; + data.values[0] = (float)m_quat_a / QUAT_SIG_FIGS; + data.values[1] = (float)m_quat_b / QUAT_SIG_FIGS; + data.values[2] = (float)m_quat_c / QUAT_SIG_FIGS; + data.values[3] = (float)m_quat_d / QUAT_SIG_FIGS; + return 0; +} + +bool rv_raw_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = 0; + properties.max_range = 1200; + properties.min_interval = 1; + properties.resolution = 1; + properties.fifo_count = 0; + properties.max_batch_count = 0; + return true; +} diff --git a/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.h b/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.h new file mode 100755 index 0000000..3a2b0ef --- /dev/null +++ b/src/plugins/rotation_vector/rv_raw/rv_raw_sensor_hal.h @@ -0,0 +1,65 @@ +/* + * rv_raw_sensor_hal + * + * 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 _RV_RAW_SENSOR_HAL_H_ +#define _RV_RAW_SENSOR_HAL_H_ + +#include + +class rv_raw_sensor_hal : public sensor_hal_base +{ +public: + rv_raw_sensor_hal(); + virtual ~rv_raw_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + virtual bool get_properties(sensor_properties_s &properties); +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + unsigned long m_polling_interval; + + int m_quat_a; + int m_quat_b; + int m_quat_c; + int m_quat_d; + int m_accuracy; + + unsigned long long m_fired_time; + int m_node_handle; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_RV_RAW_SENSOR_HAL_H_*/ + diff --git a/src/plugins/temperature/temperature_sensor_hal.cpp b/src/plugins/temperature/temperature_sensor_hal.cpp new file mode 100755 index 0000000..e491c6d --- /dev/null +++ b/src/plugins/temperature/temperature_sensor_hal.cpp @@ -0,0 +1,255 @@ +/* + * temperature_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +using std::string; + +#define SENSOR_TYPE_TEMPERATURE "TEMPERATURE" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" + +#define TEMP_INPUT_NAME "temperature_sensor" +#define TEMP_IIO_ENABLE_NODE_NAME "temp_enable" +#define TEMP_SENSORHUB_POLL_NODE_NAME "temp_poll_delay" +#define INITIAL_TIME -1 + +temperature_sensor_hal::temperature_sensor_hal() +: m_temperature(0) +, m_node_handle(-1) +, m_polling_interval(POLL_1HZ_MS) +, m_fired_time(INITIAL_TIME) +{ + const string sensorhub_interval_node_name = TEMP_SENSORHUB_POLL_NODE_NAME; + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_TEMPERATURE, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + } + + query.sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_TEMPERATURE; + query.key = TEMP_INPUT_NAME; + query.iio_enable_node_name = TEMP_IIO_ENABLE_NODE_NAME; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + csensor_config &config = csensor_config::get_instance(); + + if (!config.get(SENSOR_TYPE_TEMPERATURE, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + if (!config.get(SENSOR_TYPE_TEMPERATURE, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_TEMPERATURE, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("m_vendor = %s", m_vendor.c_str()); + INFO("m_chip_name = %s", m_chip_name.c_str()); + INFO("m_raw_data_unit = %f\n", m_raw_data_unit); + INFO("temperature_sensor_hal is created!\n"); +} + +temperature_sensor_hal::~temperature_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("temperature_sensor_hal is destroyed!\n"); +} + +string temperature_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + +sensor_hal_type_t temperature_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_TEMPERATURE; +} + +bool temperature_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, + SENSORHUB_TEMPERATURE_HUMIDITY_ENABLE_BIT); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("Temperature sensor real starting"); + return true; +} + +bool temperature_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, + SENSORHUB_TEMPERATURE_HUMIDITY_ENABLE_BIT); + + INFO("Temperature sensor real stopping"); + return true; +} + +bool temperature_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling node: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool temperature_sensor_hal::update_value(void) +{ + int temperature_raw = 0; + bool temperature = false; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + struct input_event temperature_event; + DBG("temperature event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &temperature_event, sizeof(temperature_event)); + if (len != sizeof(temperature_event)) { + ERR("temperature_file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (temperature_event.type == EV_REL) { + switch (temperature_event.code) { + case REL_HWHEEL: + temperature_raw = (int)temperature_event.value; + temperature = true; + break; + default: + ERR("temperature_event event[type = %d, code = %d] is unknown.", temperature_event.type, temperature_event.code); + return false; + break; + } + } else if (temperature_event.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&temperature_event.time); + } else { + ERR("temperature_event event[type = %d, code = %d] is unknown.", temperature_event.type, temperature_event.code); + return false; + } + } + + if (syn == false) { + ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt); + return false; + } + + AUTOLOCK(m_value_mutex); + + if (temperature) + m_temperature = temperature_raw; + + m_fired_time = fired_time; + + DBG("m_temperature = %d, time = %lluus", m_temperature, m_fired_time); + + return true; +} + +bool temperature_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int temperature_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time ; + data.value_count = 1; + data.values[0] = (float) m_temperature; + + return 0; +} + +bool temperature_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = -45; + properties.max_range = 130; + properties.min_interval = 1; + properties.resolution = 1; + properties.fifo_count = 0; + properties.max_batch_count = 0; + + return true; +} diff --git a/src/plugins/temperature/temperature_sensor_hal.h b/src/plugins/temperature/temperature_sensor_hal.h new file mode 100755 index 0000000..7dd06d6 --- /dev/null +++ b/src/plugins/temperature/temperature_sensor_hal.h @@ -0,0 +1,60 @@ +/* + * temperature_sensor_hal + * + * 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 _TEMPERATURE_SENSOR_HAL_H_ +#define _TEMPERATURE_SENSOR_HAL_H_ + +#include + +class temperature_sensor_hal : public sensor_hal_base +{ +public: + temperature_sensor_hal(); + virtual ~temperature_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); +private: + float m_temperature; + int m_node_handle; + unsigned long m_polling_interval; + unsigned long long m_fired_time; + + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + float m_raw_data_unit; + + std::string m_data_node; + std::string m_enable_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_TEMPERATURE_SENSOR_HAL_CLASS_H_*/ diff --git a/src/plugins/ultraviolet/ultraviolet_sensor_hal.cpp b/src/plugins/ultraviolet/ultraviolet_sensor_hal.cpp new file mode 100755 index 0000000..6723e3f --- /dev/null +++ b/src/plugins/ultraviolet/ultraviolet_sensor_hal.cpp @@ -0,0 +1,271 @@ +/* + * ultraviolet_sensor_hal + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ifstream; +using std::string; + +#define SENSOR_TYPE_ULTRAVIOLET "ULTRAVIOLET" +#define ELEMENT_NAME "NAME" +#define ELEMENT_VENDOR "VENDOR" +#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT" +#define ELEMENT_MIN_RANGE "MIN_RANGE" +#define ELEMENT_MAX_RANGE "MAX_RANGE" +#define ATTR_VALUE "value" + +#define BIAS 1 + +ultraviolet_sensor_hal::ultraviolet_sensor_hal() +: m_polling_interval(POLL_1HZ_MS) +, m_ultraviolet(0) +, m_fired_time(0) +, m_node_handle(-1) +{ + const string sensorhub_interval_node_name = "uv_poll_delay"; + csensor_config &config = csensor_config::get_instance(); + + node_info_query query; + node_info info; + + if (!find_model_id(SENSOR_TYPE_ULTRAVIOLET, m_model_id)) { + ERR("Failed to find model id"); + throw ENXIO; + + } + + query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name); + query.sensor_type = SENSOR_TYPE_ULTRAVIOLET; + query.key = "uv_sensor"; + query.iio_enable_node_name = "uv_enable"; + query.sensorhub_interval_node_name = sensorhub_interval_node_name; + + if (!get_node_info(query, info)) { + ERR("Failed to get node info"); + throw ENXIO; + } + + show_node_info(info); + + m_data_node = info.data_node_path; + m_enable_node = info.enable_node_path; + m_interval_node = info.interval_node_path; + + if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_VENDOR, m_vendor)) { + ERR("[VENDOR] is empty\n"); + throw ENXIO; + } + + INFO("m_vendor = %s", m_vendor.c_str()); + + if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_NAME, m_chip_name)) { + ERR("[NAME] is empty\n"); + throw ENXIO; + } + + INFO("m_chip_name = %s\n",m_chip_name.c_str()); + + double min_range; + + if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_MIN_RANGE, min_range)) { + ERR("[MIN_RANGE] is empty\n"); + throw ENXIO; + } + + m_min_range = (float)min_range; + INFO("m_min_range = %f\n",m_min_range); + + double max_range; + + if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_MAX_RANGE, max_range)) { + ERR("[MAX_RANGE] is empty\n"); + throw ENXIO; + } + + m_max_range = (float)max_range; + INFO("m_max_range = %f\n",m_max_range); + + double raw_data_unit; + + if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) { + ERR("[RAW_DATA_UNIT] is empty\n"); + throw ENXIO; + } + + m_raw_data_unit = (float)(raw_data_unit); + + if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) { + ERR("Failed to open handle(%d)", m_node_handle); + throw ENXIO; + } + + int clockId = CLOCK_MONOTONIC; + if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) + ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str()); + + INFO("m_raw_data_unit = %f\n", m_raw_data_unit); + INFO("ultraviolet_sensor_hal is created!\n"); +} + +ultraviolet_sensor_hal::~ultraviolet_sensor_hal() +{ + close(m_node_handle); + m_node_handle = -1; + + INFO("ultraviolet_sensor_hal is destroyed!\n"); +} + +string ultraviolet_sensor_hal::get_model_id(void) +{ + return m_model_id; +} + + +sensor_hal_type_t ultraviolet_sensor_hal::get_type(void) +{ + return SENSOR_HAL_TYPE_ULTRAVIOLET; +} + +bool ultraviolet_sensor_hal::enable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_UV_SENSOR); + set_interval(m_polling_interval); + + m_fired_time = 0; + INFO("ultraviolet sensor real starting"); + return true; +} + +bool ultraviolet_sensor_hal::disable(void) +{ + AUTOLOCK(m_mutex); + + set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_UV_SENSOR); + + INFO("ultraviolet sensor real stopping"); + return true; +} + +bool ultraviolet_sensor_hal::set_interval(unsigned long val) +{ + unsigned long long polling_interval_ns; + + AUTOLOCK(m_mutex); + + polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu); + + if (!set_node_value(m_interval_node, polling_interval_ns)) { + ERR("Failed to set polling resource: %s\n", m_interval_node.c_str()); + return false; + } + + INFO("Interval is changed from %dms to %dms]", m_polling_interval, val); + m_polling_interval = val; + return true; +} + +bool ultraviolet_sensor_hal::update_value(void) +{ + int ultraviolet_raw = -1; + bool ultraviolet_sign = false; + bool ultraviolet = false; + int read_input_cnt = 0; + const int INPUT_MAX_BEFORE_SYN = 10; + unsigned long long fired_time = 0; + bool syn = false; + + struct input_event ultraviolet_event; + DBG("ultraviolet event detection!"); + + while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) { + int len = read(m_node_handle, &ultraviolet_event, sizeof(ultraviolet_event)); + if (len != sizeof(ultraviolet_event)) { + ERR("ultraviolet file read fail, read_len = %d\n",len); + return false; + } + + ++read_input_cnt; + + if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_X) { + ultraviolet_raw = (int)ultraviolet_event.value; + ultraviolet = true; + } else if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_Y) { + ultraviolet_sign = ((int)ultraviolet_event.value < 0) ? false : true; + } else if (ultraviolet_event.type == EV_SYN) { + syn = true; + fired_time = sensor_hal_base::get_timestamp(&ultraviolet_event.time); + } else { + ERR("ultraviolet event[type = %d, code = %d] is unknown.", ultraviolet_event.type, ultraviolet_event.code); + return false; + } + } + + AUTOLOCK(m_value_mutex); + + if (ultraviolet && ultraviolet_sign) + m_ultraviolet = ultraviolet_raw - BIAS; + else + return false; + + m_fired_time = fired_time; + + DBG("m_ultraviolet = %d, time = %lluus", m_ultraviolet, m_fired_time); + + return true; +} + +bool ultraviolet_sensor_hal::is_data_ready(void) +{ + bool ret; + ret = update_value(); + return ret; +} + +int ultraviolet_sensor_hal::get_sensor_data(sensor_data_t &data) +{ + AUTOLOCK(m_value_mutex); + data.accuracy = SENSOR_ACCURACY_GOOD; + data.timestamp = m_fired_time; + data.value_count = 1; + data.values[0] = (float) m_ultraviolet; + + return 0; +} + +bool ultraviolet_sensor_hal::get_properties(sensor_properties_s &properties) +{ + properties.name = m_chip_name; + properties.vendor = m_vendor; + properties.min_range = m_min_range; + properties.max_range = m_max_range; + properties.min_interval = 1; + properties.resolution = m_raw_data_unit; + properties.fifo_count = 0; + properties.max_batch_count = 0; + + return true; +} diff --git a/src/plugins/ultraviolet/ultraviolet_sensor_hal.h b/src/plugins/ultraviolet/ultraviolet_sensor_hal.h new file mode 100755 index 0000000..dfe684c --- /dev/null +++ b/src/plugins/ultraviolet/ultraviolet_sensor_hal.h @@ -0,0 +1,66 @@ +/* + * ultraviolet_sensor_hal + * + * 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 _ULTRAVIOLET_SENSOR_HAL_H_ +#define _ULTRAVIOLET_SENSOR_HAL_H_ + +#include + +class ultraviolet_sensor_hal : public sensor_hal_base +{ +public: + ultraviolet_sensor_hal(); + virtual ~ultraviolet_sensor_hal(); + std::string get_model_id(void); + sensor_hal_type_t get_type(void); + bool enable(void); + bool disable(void); + bool set_interval(unsigned long val); + bool is_data_ready(void); + virtual int get_sensor_data(sensor_data_t &data); + bool get_properties(sensor_properties_s &properties); + +private: + std::string m_model_id; + std::string m_vendor; + std::string m_chip_name; + + float m_min_range; + float m_max_range; + float m_raw_data_unit; + + unsigned long m_polling_interval; + + int m_ultraviolet; + + unsigned long long m_fired_time; + int m_node_handle; + + std::string m_enable_node; + std::string m_data_node; + std::string m_interval_node; + + bool m_sensorhub_controlled; + + cmutex m_value_mutex; + + bool update_value(void); +}; +#endif /*_ULTRAVIOLET_SENSOR_HAL_CLASS_H_*/ + -- 2.7.4