--- /dev/null
+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
--- /dev/null
+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.
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+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
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<SENSOR>
+ <ACCEL>
+ <MODEL id="lsm330dlc-accel">
+ <NAME value="LSM330DLC"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="1" />
+ <RESOLUTION value="12" />
+ </MODEL>
+
+ <MODEL id="LSM330">
+ <NAME value="LSM330"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="1" />
+ <RESOLUTION value="12" />
+ </MODEL>
+
+ <MODEL id="K2HH">
+ <NAME value="K2HH" />
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6500">
+ <NAME value="MPU6500"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT SM-Z910F="0.061" SM-Z9005="0.061" value="0.244"/>
+ <RESOLUTION value="16" />
+ </MODEL>
+
+ <MODEL id="MPU6515">
+ <NAME value="MPU6515"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6050">
+ <NAME value="MPU6050"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6051">
+ <NAME value="MPU6051"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU9250">
+ <NAME value="MPU9250"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.244"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="ICM20628">
+ <NAME value="ICM20628"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.244" />
+ <RESOLUTION value="16" />
+ </MODEL>
+
+ <MODEL id="bma222e">
+ <NAME value="BMA222E"/>
+ <VENDOR value="BOSCH"/>
+ <RAW_DATA_UNIT value="15.63"/>
+ <RESOLUTION value="8"/>
+ </MODEL>
+
+ <MODEL id="BMI160">
+ <NAME value="BMI160"/>
+ <VENDOR value="Bosch"/>
+ <RAW_DATA_UNIT value="0.244"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_accel_1">
+ <NAME value="maru_sensor_accel_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+ </ACCEL>
+
+ <GYRO>
+ <MODEL id="lsm330dlc-gyro">
+ <NAME value="LSM330DLC"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="17.50"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="LSM330">
+ <NAME value="LSM330"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="17.50" />
+ <RESOLUTION value="16" />
+ </MODEL>
+
+ <MODEL id="MPU6500">
+ <NAME value="MPU6500"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="15.26"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6515">
+ <NAME value="MPU6515"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="15.26"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6050">
+ <NAME value="MPU6050"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="15.26"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU6051">
+ <NAME value="MPU6051"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="15.26"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="MPU9250">
+ <NAME value="MPU9250"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="15.26"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="ICM20628">
+ <NAME value="ICM20628"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="61.04"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="BMI160">
+ <NAME value="BMI160"/>
+ <VENDOR value="Bosch"/>
+ <RAW_DATA_UNIT value="61.04"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_gyro_1">
+ <NAME value="maru_sensor_gyro_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="1000"/>
+ <RESOLUTION value="16"/>
+ <MIN_RANGE value="-573"/>
+ <MAX_RANGE value="573"/>
+ </MODEL>
+ </GYRO>
+
+ <PROXI>
+ <MODEL id="taos">
+ <NAME value="TMD27723"/>
+ <VENDOR value="TAOS"/>
+ </MODEL>
+
+ <MODEL id="TMD3782">
+ <NAME value="TMD3782"/>
+ <VENDOR value="TAOS"/>
+ </MODEL>
+
+ <MODEL id="gp2a">
+ <NAME value="GP2AP020"/>
+ <VENDOR value="Sharp"/>
+ </MODEL>
+
+ <MODEL id="gp2ap002s">
+ <NAME value="GP2AP002S"/>
+ <VENDOR value="Sharp"/>
+ </MODEL>
+
+ <MODEL id="CM36651">
+ <NAME value="CM36651"/>
+ <VENDOR value="Capella"/>
+ </MODEL>
+
+ <MODEL id="MAX88922">
+ <NAME value="MAX88922"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+
+ <MODEL id="IMS1911">
+ <NAME value="IMS1911"/>
+ <VENDOR value="ITM"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_proxi_1">
+ <NAME value="maru_sensor_proxi_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ </MODEL>
+ </PROXI>
+
+ <LIGHT>
+ <MODEL id="taos">
+ <NAME value="TMD27723"/>
+ <VENDOR value="TAOS"/>
+ </MODEL>
+
+ <MODEL id="TMD3782">
+ <NAME value="TMD3782"/>
+ <VENDOR value="TAOS"/>
+ </MODEL>
+
+ <MODEL id="gp2a">
+ <NAME value="GP2AP020"/>
+ <VENDOR value="Sharp"/>
+ </MODEL>
+
+ <MODEL id="CM36651">
+ <NAME value="CM36651"/>
+ <VENDOR value="Capella"/>
+ </MODEL>
+
+ <MODEL id="MAX88922">
+ <NAME value="MAX88922"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+
+ <MODEL id="AL3320">
+ <NAME value="AL3320"/>
+ <VENDOR value="LITEON"/>
+ </MODEL>
+
+ <MODEL id="BH1733">
+ <NAME value="BH1733"/>
+ <VENDOR value="ROHM"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_light_1">
+ <NAME value="maru_sensor_light_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ </MODEL>
+ </LIGHT>
+
+ <MAGNETIC>
+ <MODEL id="AK8975C">
+ <NAME value="AK8975C" />
+ <VENDOR value="AKM"/>
+ <RAW_DATA_UNIT value="0.06"/>
+ <MIN_RANGE value="-1200"/>
+ <MAX_RANGE value="1200"/>
+ </MODEL>
+
+ <MODEL id="AK09911C">
+ <NAME value="AK09911C"/>
+ <VENDOR value="AKM"/>
+ <RAW_DATA_UNIT value="0.06"/>
+ <MIN_RANGE value="-4900"/>
+ <MAX_RANGE value="4900"/>
+ </MODEL>
+
+ <MODEL id="ak8975">
+ <NAME value="AK8975"/>
+ <VENDOR value="AKM"/>
+ <RAW_DATA_UNIT value="0.03"/>
+ <MIN_RANGE value="-1200"/>
+ <MAX_RANGE value="1200"/>
+ </MODEL>
+
+ <MODEL id="MPU9250">
+ <NAME value="MPU9250"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="1.0"/>
+ <MIN_RANGE value="-4800"/>
+ <MAX_RANGE value="4800"/>
+ </MODEL>
+
+ <MODEL id="YAS537">
+ <NAME value="YAS537"/>
+ <VENDOR value="Yamaha"/>
+ <RAW_DATA_UNIT value="0.1"/>
+ <MIN_RANGE value="-4800"/>
+ <MAX_RANGE value="4800"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_geo_1">
+ <NAME value="maru_sensor_geo_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.6"/>
+ <RESOLUTION value="14"/>
+ <MIN_RANGE value="-2000"/>
+ <MAX_RANGE value="2000"/>
+ </MODEL>
+ </MAGNETIC>
+
+ <PRESSURE>
+ <MODEL id="LPS25H">
+ <NAME value="LPS25H"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="0.000244"/>
+ <MIN_RANGE value="260"/>
+ <MAX_RANGE value="1260"/>
+ <RESOLUTION value="1"/>
+ <TEMPERATURE_RESOLUTION value="0.002083"/>
+ <TEMPERATURE_OFFSET value="42.5"/>
+ </MODEL>
+
+ <MODEL id="LPS331">
+ <NAME value="LPS331"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="0.000244"/>
+ <MIN_RANGE value="260"/>
+ <MAX_RANGE value="1260"/>
+ <RESOLUTION value="1"/>
+ <TEMPERATURE_RESOLUTION value="0.002083"/>
+ <TEMPERATURE_OFFSET value="42.5"/>
+ </MODEL>
+ <MODEL id="maru_sensor_pressure_1">
+ <NAME value="maru_sensor_pressure_1" />
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.0193"/>
+ <MIN_RANGE value="260"/>
+ <MAX_RANGE value="1260"/>
+ <RESOLUTION value="1"/>
+ <TEMPERATURE_RESOLUTION value="0.05"/>
+ <TEMPERATURE_OFFSET value="0"/>
+ </MODEL>
+ </PRESSURE>
+
+ <TEMPERATURE>
+ <MODEL id="LPS331">
+ <NAME value="LPS331" />
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="0.01"/>
+ <RESOLUTION value="1"/>
+ </MODEL>
+
+ <MODEL id="SHTC1">
+ <NAME value="SHTC1" />
+ <VENDOR value="SENSIRION"/>
+ <RAW_DATA_UNIT value="0.01"/>
+ <RESOLUTION value="1"/>
+ </MODEL>
+ </TEMPERATURE>
+
+ <HUMIDITY>
+ <MODEL id="SHTC1">
+ <NAME value="SHTC1" />
+ <VENDOR value="SENSIRION"/>
+ <RAW_DATA_UNIT value="0.01"/>
+ <MIN_RANGE value="-10"/>
+ <MAX_RANGE value="110"/>
+ <RESOLUTION value="1"/>
+ </MODEL>
+ </HUMIDITY>
+
+ <ULTRAVIOLET>
+ <MODEL id="UVIS25">
+ <NAME value="UVIS25" />
+ <VENDOR value="STM"/>
+ <RAW_DATA_UNIT value="0.0625"/>
+ <MIN_RANGE value="0"/>
+ <MAX_RANGE value="15"/>
+ </MODEL>
+ <MODEL id="maru_sensor_uv_1">
+ <NAME value="maru_sensor_uv_1" />
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.1"/>
+ <MIN_RANGE value="0"/>
+ <MAX_RANGE value="15"/>
+ </MODEL>
+ <MODEL id="MAX86902_UV">
+ <NAME value="MAX86902_UV" />
+ <VENDOR value="MAXIM"/>
+ <RAW_DATA_UNIT value="0.1"/>
+ <MIN_RANGE value="0"/>
+ <MAX_RANGE value="15"/>
+ </MODEL>
+ </ULTRAVIOLET>
+
+ <BIO_LED_RED>
+ <MODEL id="MAX86902">
+ <NAME value="MAX86902" />
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+ </BIO_LED_RED>
+</SENSOR>
--- /dev/null
+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)
--- /dev/null
+#ifdef ENABLE_ACCEL
+#include <accel_sensor_hal.h>
+#endif
+#ifdef ENABLE_BIO_LED_RED
+#include <bio_led_red_sensor_hal.h>
+#endif
+#ifdef ENABLE_GEO
+#include <geo_sensor_hal.h>
+#endif
+#ifdef ENABLE_GYRO
+#include <gyro_sensor_hal.h>
+#endif
+#ifdef ENABLE_LIGHT
+#include <light_sensor_hal.h>
+#endif
+#ifdef ENABLE_PRESSURE
+#include <pressure_sensor_hal.h>
+#endif
+#ifdef ENABLE_PROXI
+#include <proxi_sensor_hal.h>
+#endif
+#ifdef ENABLE_RV_RAW
+#include <rv_raw_sensor_hal.h>
+#endif
+#ifdef ENABLE_TEMPERATURE
+#include <temperature_sensor_hal.h>
+#endif
+#ifdef ENABLE_ULTRAVIOLET
+#include <ultraviolet_sensor_hal.h>
+#endif
+
+#include <sensor_common.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+#include <dirent.h>
+#include <string.h>
+#include <fstream>
+#include <csensor_config.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sys/time.h>
+#include <sensor_common.h>
+#include <cmutex.h>
+#include <sensor_logs.h>
+#include <string>
+#include <sensor_hal.h>
+
+/*
+* 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_*/
--- /dev/null
+/*
+ * 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 <pthread.h>
+#include <cbase_lock.h>
+#include <stdio.h>
+#include <sensor_logs.h>
+#include <errno.h>
+#include <sys/time.h>
+
+
+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();
+}
--- /dev/null
+/*
+ * 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 <pthread.h>
+
+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
--- /dev/null
+/*
+ * 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 <cconfig.h>
+#include <fstream>
+#include <string>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <string>
+#include <unordered_map>
+#include <sensor_logs.h>
+
+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_ */
--- /dev/null
+/*
+ * 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 <cmutex.h>
+#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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 <csensor_config.h>
+#include "sensor_logs.h"
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <string>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <cconfig.h>
+
+#define SENSOR_CONFIG_FILE_PATH "/usr/etc/sensors.xml"
+
+typedef std::unordered_map<std::string,std::string> Element;
+/*
+* an Element is a group of attributes
+* <Element value1 = "10.0", value2 = "20.0"/>
+*
+* "value" -> "LSM330DLC"
+*
+*/
+
+typedef std::unordered_map<std::string,Element> Model;
+/*
+* a Model is a group of elements to consist of specific vendor's one sensor configuration
+* <NAME value = "LSM330DLC" />
+* <VENDOR value = "ST Microelectronics"/>
+* <RAW_DATA_UNIT value = "1" />
+* <RESOLUTION value = "12" />
+*
+* <NAME> -> <value = "LSM330DLC"/>
+*
+*/
+
+typedef std::unordered_map<std::string,Model> Model_list;
+/*
+* a Model_list is a group of Model
+* <MODEL id = "lsm330dlc_accel">
+* </MODEL>
+* <MODEL id = "mpu6500">
+* </MODEL>
+*
+* "lsm330dlc_accel" -> <Model>
+*
+*/
+
+typedef std::unordered_map<std::string,Model_list> Sensor_config;
+/*
+* a SensorConfig represents sensors.xml
+* <ACCEL/>
+* <GYRO/>
+* <PROXIMITY/>
+*
+* "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
--- /dev/null
+/*
+ * 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 <unistd.h>
+#include <sensor_logs.h>
+#include <string>
+#include <vector>
+
+#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<void*> sensors;
+} sensor_module;
+
+typedef sensor_module* (*create_t)(void);
+
+typedef void *(*cmd_func_t)(void *data, void *cb_data);
+
+typedef std::vector<unsigned int> 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
--- /dev/null
+/*
+ * 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 <syslog.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include "sensor_logs.h"
+#include <dlog.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sensor_common.h>
+
+#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));
+}
--- /dev/null
+/*
+ * 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 <stdbool.h>
+#endif /* !__cplusplus */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#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 <string.h>
+#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
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <accel_sensor_hal.h>
+#include <sys/poll.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+#include <functional>
+
+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<bool ()> 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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <bio_led_red_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
+
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <geo_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <gyro_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <light_sensor_hal.h>
+#include <sys/ioctl.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <pressure_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+#include <algorithm>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <proxi_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <rv_raw_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
+
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <temperature_sensor_hal.h>
+#include <sys/ioctl.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
--- /dev/null
+/*
+ * 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <ultraviolet_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <sensor_hal_base.h>
+
+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_*/
+