Sensor Framework on Tizen 3.
There have been main features added.
Architecture Design:
- git repositories have been merged into platform/core/system/sensord
- new event driven architecture(before:polling based architecture)
- UNIX based sockets for IPC(before:VCONF)
- Server tracks the information of the clients
- data structure based STL, including map, multimap, list and more
Plugin Design:
- redefine interfaces related to sensor plugin(sensor_base, sensor_hal)
- for every sensor type, only one common plugin is required
- redesign architecture simply, removing redundent layers and data structures
- sensor device information is expressed with XML
- supports both physical and virtual sensor types
Other Features:
- support sensor hub
- proprietary libraries moved to sensord-proprietary git
- clean logs/enum types/structures
- define interface related to sensor fusion
- sensor fusion code to be added in the future
Sensor Type:
Accelerometer / Gyro / Geomagnetic / Proximity / Light
Gravity / Linear Accelerometer / Orientation
- they are not supported yet
- they should be changed based on iio sub-system
Contributed by:
Jae Hyun Jo <jaehyun7.jo@samsung.com>
Hyun-sung <hs81.go@samsung.com>
Ramasamy Kannan <ram.kannan@samsung.com>
Amit Vithalrao Dharmapurikar <amit.vd@samsung.com>
Kibak Yoon <kibak.yoon@samsung.com>
Signed-off-by: Kibak Yoon <kibak.yoon@samsung.com>
Change-Id: Ieb622be5db3cd2a0aeb4e5b442ba51dd785616ce
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensord_main CXX)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED glib-2.0 gio-2.0 vconf dlog libxml-2.0 libsystemd-daemon capi-system-info)
+add_definitions(${rpkgs_CFLAGS})
+
+# to install pkgconfig setup file.
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "2")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+add_definitions(-DUSE_DLOG_LOG)
+#add_definitions(-Wall -g -D_DEBUG)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+IF("${ARCH}" MATCHES "^arm.*")
+ CONFIGURE_FILE(sensor_plugins.xml.in sensor_plugins.xml @ONLY)
+ CONFIGURE_FILE(sensors.xml.in sensors.xml @ONLY)
+ install(FILES
+ sensor_plugins.xml
+ sensors.xml
+ DESTINATION etc)
+ELSE("${ARCH}" MATCHES "^arm.*")
+ CONFIGURE_FILE(sensor_plugins_sim.xml.in sensor_plugins.xml @ONLY)
+ CONFIGURE_FILE(sensors.xml.in sensors.xml @ONLY)
+ install(FILES
+ sensor_plugins.xml
+ sensors.xml
+ DESTINATION etc)
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.APLv2 DESTINATION share/license RENAME sensord)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.APLv2 DESTINATION share/license RENAME libsensord)
+
+add_subdirectory(src)
--- /dev/null
+Copyright (c) 2000 - 2014 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
+[Unit]
+Description=Sensor Daemon
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/sensord
+Restart=always
+RestartSec=0
+MemoryLimit=10M
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+[Unit]
+Description=Sensor daemon socket
+
+[Socket]
+ListenStream=/tmp/sf_command_socket
+SocketMode=0777
+PassCredentials=yes
+Accept=false
+SmackLabelIPIn=*
+SmackLabelIPOut=@
--- /dev/null
+Name: sensord
+Summary: Sensor daemon
+Version: 1.0.0
+Release: 0
+Group: System/Sensor Framework
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Source1: sensord.service
+Source2: sensord.socket
+
+%define accel_state ON
+%define gyro_state OFF
+%define proxi_state OFF
+%define light_state OFF
+%define geo_state OFF
+%define gravity_state OFF
+%define linear_accel_state OFF
+%define motion_state OFF
+
+BuildRequires: cmake
+BuildRequires: vconf-keys-devel
+BuildRequires: libattr-devel
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(libsystemd-daemon)
+BuildRequires: pkgconfig(capi-system-info)
+
+%description
+Sensor daemon
+
+%package sensord
+Summary: Sensor daemon
+Group: System/Sensor Framework
+Requires: %{name} = %{version}-%{release}
+
+%description sensord
+Sensor daemon
+
+%package -n libsensord
+Summary: Sensord library
+Group: System/Sensor Framework
+Requires: %{name} = %{version}-%{release}
+
+%description -n libsensord
+Sensord library
+
+%package -n libsensord-devel
+Summary: Sensord library (devel)
+Group: System/Sensor Framework
+Requires: %{name} = %{version}-%{release}
+
+%description -n libsensord-devel
+Sensord library (devel)
+
+%prep
+%setup -q
+
+%build
+#CFLAGS+=" -fvisibility=hidden "; export CFLAGS
+#CXXFLAGS+=" -fvisibility=hidden -fvisibility-inlines-hidden ";export CXXFLAGS
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DACCEL=%{accel_state} \
+ -DGYRO=%{gyro_state} -DPROXI=%{proxi_state} -DLIGHT=%{light_state} \
+ -DGEO=%{geo_state} -DGRAVITY=%{gravity_state} \
+ -DLINEAR_ACCEL=%{linear_accel_state} -DMOTION=%{motion_state}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/usr/share/license
+mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+install -m 0644 %SOURCE1 %{buildroot}%{_libdir}/systemd/system/
+install -m 0644 %SOURCE2 %{buildroot}%{_libdir}/systemd/system/
+ln -s ../sensord.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/sensord.socket
+ln -s ../sensord.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/sensord.service
+
+%post -p /sbin/ldconfig
+systemctl daemon-reload
+
+%postun -p /sbin/ldconfig
+systemctl daemon-reload
+
+%files -n sensord
+%manifest sensord.manifest
+%{_bindir}/sensord
+%attr(0644,root,root)/usr/etc/sensor_plugins.xml
+%attr(0644,root,root)/usr/etc/sensors.xml
+%{_libdir}/systemd/system/sensord.service
+%{_libdir}/systemd/system/sensord.socket
+%{_libdir}/systemd/system/multi-user.target.wants/sensord.service
+%{_libdir}/systemd/system/sockets.target.wants/sensord.socket
+%license LICENSE.APLv2
+%{_datadir}/license/sensord
+
+%files -n libsensord
+%manifest libsensord.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libsensor.so.*
+%{_libdir}/sensord/*.so*
+%{_libdir}/libsensord-share.so
+%{_libdir}/libsensord-server.so
+%license LICENSE.APLv2
+%{_datadir}/license/libsensord
+
+%files -n libsensord-devel
+%defattr(-,root,root,-)
+%{_includedir}/sensor/*.h
+%{_includedir}/sf_common/*.h
+%{_libdir}/libsensor.so
+%{_libdir}/pkgconfig/sensor.pc
+%{_libdir}/pkgconfig/sf_common.pc
+%{_libdir}/pkgconfig/sensord-server.pc
--- /dev/null
+<PLUGIN>
+ <HAL>
+ <MODULE path = "/usr/lib/sensord/libaccel_sensor_hal.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sensor_hal.so"/>
+ <MODULE path = "/usr/lib/sensord/libgeo_sensor_hal.so"/>
+ <MODULE path = "/usr/lib/sensord/libproxi_sensor_hal.so"/>
+ <MODULE path = "/usr/lib/sensord/liblight_sensor_hal.so"/>
+ </HAL>
+
+ <SENSOR>
+ <MODULE path = "/usr/lib/sensord/libaccel_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/libgeo_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/libproxi_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/liblight_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/libmotion_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/libsensor_fusion.so"/>
+ <MODULE path = "/usr/lib/sensord/libgravity_sensor.so"/>
+ <MODULE path = "/usr/lib/sensord/liblinear_accel_sensor.so"/>
+ </SENSOR>
+</PLUGIN>
--- /dev/null
+<PLUGIN>
+ <SENSOR_PLUGIN>
+ <MODULE path = "/usr/lib/sensord/libaccel_sim.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sim.so"/>
+ <MODULE path = "/usr/lib/sensord/liblight_sim.so"/>
+ <MODULE path = "/usr/lib/sensord/libproxi_sim.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sim.so"/>
+ </SENSOR_PLUGIN>
+
+ <PROCESSOR_PLUGIN>
+ <MODULE path = "/usr/lib/sensord/libaccel_sim_processor.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sim_processor.so"/>
+ <MODULE path = "/usr/lib/sensord/liblight_sim_processor.so"/>
+ <MODULE path = "/usr/lib/sensord/libproxi_sim_processor.so"/>
+ <MODULE path = "/usr/lib/sensord/libgyro_sim_processor.so"/>
+ </PROCESSOR_PLUGIN>
+</PLUGIN>
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /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="MPU6500">
+ <NAME value="MPU6500"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT SM-Z910F="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="bma222e">
+ <NAME value="BMA222E"/>
+ <VENDOR value="BOSCH"/>
+ <RAW_DATA_UNIT value="15.63"/>
+ <RESOLUTION value="8"/>
+ </MODEL>
+ </ACCEL>
+
+ <GYRO>
+ <MODEL id="lsm330dlc-gyro">
+ <NAME value="LSM330DLC"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="17.50"/>
+ <RESOLUTION value="12"/>
+ </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>
+ </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>
+ </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>
+ </LIGHT>
+
+ <MAGNETIC>
+ <MODEL id="AK09911C">
+ <NAME value="AK09911C"/>
+ <VENDOR value="AKM"/>
+ </MODEL>
+
+ <MODEL id="MPU9250">
+ <NAME value="MPU9250"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+ </MAGNETIC>
+
+ <PEDO>
+ <MODEL id="MPU6051">
+ <NAME value="MPU6051"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+
+ <MODEL id="MPU6500">
+ <NAME value="MPU6500"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+
+ <MODEL id="MPU6515">
+ <NAME value="MPU6515"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+ </PEDO>
+
+ <FLAT>
+ <MODEL id="MPU6051">
+ <NAME value="MPU6051"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+
+ <MODEL id="MPU6500">
+ <NAME value="MPU6500"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+
+ <MODEL id="MPU6515">
+ <NAME value="MPU6515"/>
+ <VENDOR value="Invensense"/>
+ </MODEL>
+ </FLAT>
+
+ <BIO>
+ <MODEL id="ADPD142">
+ <NAME value="ADPD142"/>
+ <VENDOR value="ANALOG DEVICES"/>
+ </MODEL>
+
+ <MODEL id="MAX86900">
+ <NAME value="MAX86900"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+ </BIO>
+
+ <BIO_HRM>
+ <MODEL id="ADPD142">
+ <NAME value="ADPD142"/>
+ <VENDOR value="ANALOG DEVICES"/>
+ </MODEL>
+
+ <MODEL id="MAX86900">
+ <NAME value="MAX86900"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+ </BIO_HRM>
+
+ <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>
+ </PRESSURE>
+</SENSOR>
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensord_src CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+include_directories(${CMAKE_SOURCE_DIR}/src/shared)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED glib-2.0 gio-2.0 vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+add_definitions(-Wall -std=gnu++0x)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+IF("${ACCEL}" STREQUAL "ON")
+add_subdirectory(accel)
+ENDIF()
+IF("${GYRO}" STREQUAL "ON")
+add_subdirectory(gyro)
+ENDIF()
+IF("${PROXI}" STREQUAL "ON")
+add_subdirectory(proxi)
+ENDIF()
+IF("${LIGHT}" STREQUAL "ON")
+add_subdirectory(light)
+ENDIF()
+IF("${GEO}" STREQUAL "ON")
+add_subdirectory(geo)
+ENDIF()
+IF("${GRAVITY}" STREQUAL "ON")
+add_subdirectory(gravity)
+ENDIF()
+IF("${LINEAR_ACCEL}" STREQUAL "ON")
+add_subdirectory(linear_accel)
+ENDIF()
+IF("${MOTION}" STREQUAL "ON")
+add_subdirectory(motion)
+ENDIF()
+IF("${SENSOR_FUSION}" STREQUAL "ON")
+add_subdirectory(sensor_fusion)
+ENDIF()
+
+add_subdirectory(server)
+add_subdirectory(libsensord)
+add_subdirectory(shared)
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(accel CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME accel_sensor)
+SET(SENSOR_HAL_NAME accel_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ accel_sensor.cpp
+ )
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ accel_sensor_hal.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <common.h>
+#include <sf_common.h>
+#include <accel_sensor.h>
+#include <sensor_plugin_loader.h>
+#include <algorithm>
+
+using std::bind1st;
+using std::mem_fun;
+
+#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 SENSOR_NAME "ACCELEROMETER_SENSOR"
+
+#define ROTATION_CHECK_INTERVAL 200
+#define ROTATION_RULE_CNT 4
+#define TILT_MIN 30
+
+#define ROTATION_0 0
+#define ROTATION_90 90
+#define ROTATION_180 180
+#define ROTATION_270 270
+#define ROTATION_360 360
+
+#define DEGREE_90 90
+#define DEGREE_180 180
+#define DEGREE_360 360
+
+struct rotation_rule {
+ int tilt;
+ int angle;
+};
+
+struct rotation_rule rot_rule[ROTATION_RULE_CNT] = {
+ {40, 80},
+ {50, 70},
+ {60, 65},
+ {90, 60},
+};
+
+accel_sensor::accel_sensor()
+: m_sensor_hal(NULL)
+, m_interval(POLL_1HZ_MS)
+{
+ m_name = string(SENSOR_NAME);
+
+ vector<unsigned int> supported_events = {
+ ACCELEROMETER_EVENT_ROTATION_CHECK,
+ ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME,
+ ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME,
+ };
+
+ for_each(supported_events.begin(), supported_events.end(),
+ bind1st(mem_fun(&sensor_base::register_supported_event), this));
+
+ physical_sensor::set_poller(accel_sensor::working, this);
+}
+
+accel_sensor::~accel_sensor()
+{
+ INFO("accel_sensor is destroyed!");
+}
+
+bool accel_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(ACCELEROMETER_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ sensor_properties_t properties;
+
+ if (m_sensor_hal->get_properties(properties) == false) {
+ ERR("sensor->get_properties() is failed!");
+ return false;
+ }
+
+ m_raw_data_unit = properties.sensor_resolution / GRAVITY * G_TO_MG;
+
+ INFO("m_raw_data_unit accel : [%f]", m_raw_data_unit);
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t accel_sensor::get_type(void)
+{
+ return ACCELEROMETER_SENSOR;
+}
+
+bool accel_sensor::working(void *inst)
+{
+ accel_sensor *sensor = (accel_sensor *)inst;
+ return sensor->process_event();
+}
+
+bool accel_sensor::process_event(void)
+{
+ sensor_data_t raw_data;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(raw_data);
+
+ AUTOLOCK(m_mutex);
+ AUTOLOCK(m_client_info_mutex);
+
+ if (get_client_cnt(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ sensor_event_t base_event;
+
+ copy_sensor_data(&raw_data, &(base_event.data));
+
+ base_event.event_type = ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME;
+ raw_to_base(base_event.data);
+ push(base_event);
+ }
+
+ if (get_client_cnt(ACCELEROMETER_EVENT_ROTATION_CHECK)) {
+ if (is_rotation_time()) {
+ sensor_data_t base_data;
+ float x, y, z;
+ int rotation;
+
+ copy_sensor_data(&raw_data, &base_data);
+ raw_to_base(base_data);
+
+ x = base_data.values[0];
+ y = base_data.values[1];
+ z = base_data.values[2];
+
+ rotation = get_rotation_event(x, y, z);
+
+ if (rotation != -1) {
+ AUTOLOCK(m_value_mutex);
+
+ sensor_event_t rotation_event;
+ rotation_event.event_type = ACCELEROMETER_EVENT_ROTATION_CHECK;
+ rotation_event.data.timestamp = raw_data.timestamp;
+ rotation_event.data.values_num = 1;
+ rotation_event.data.values[0] = rotation;
+ push(rotation_event);
+
+ INFO("Rotation event occurred, rotation value = %d", rotation);
+ }
+ }
+ }
+
+ if (get_client_cnt(ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME)) {
+ sensor_event_t orientation_event;
+
+ copy_sensor_data(&raw_data, &(orientation_event.data));
+
+ orientation_event.event_type = ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME;
+ raw_to_orientation(raw_data, orientation_event.data);
+ push(orientation_event);
+ }
+
+ return true;
+}
+
+bool accel_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail");
+ return false;
+ }
+
+ reset_rotation();
+
+ return start_poll();
+}
+
+bool accel_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool accel_sensor::add_client(unsigned int event_type)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!sensor_base::add_client(event_type))
+ return false;
+
+ switch (event_type) {
+ case ACCELEROMETER_EVENT_ROTATION_CHECK:
+ if (get_client_cnt(ACCELEROMETER_EVENT_ROTATION_CHECK) == 1)
+ reset_rotation();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+long accel_sensor::set_command(const unsigned int cmd, long value)
+{
+ if (m_sensor_hal->set_command(cmd, value) < 0) {
+ ERR("m_sensor_hal set_cmd fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool accel_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int accel_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ if (type == ACCELEROMETER_ROTATION_DATA_SET) {
+ AUTOLOCK(m_value_mutex);
+
+ data.data_accuracy = SENSOR_ACCURACY_NORMAL;
+ data.data_unit_idx = SENSOR_UNDEFINED_UNIT;
+ data.values_num = 1;
+ data.values[0] = m_rotation;
+ data.timestamp = m_rotation_time;
+ return 0;
+ }
+
+ if (m_sensor_hal->get_sensor_data(data) < 0) {
+ ERR("Failed to get sensor data");
+ return -1;
+ }
+
+ if (type == ACCELEROMETER_BASE_DATA_SET)
+ raw_to_base(data);
+ else if (type == ACCELEROMETER_ORIENTATION_DATA_SET) {
+ sensor_data_t raw;
+
+ copy_sensor_data(&data, &raw);
+ raw_to_orientation(raw, data);
+ } else {
+ ERR("Does not support type: 0x%x", type);
+ return -1;
+ }
+
+ return 0;
+}
+
+int accel_sensor::get_rotation_event(float x, float y, float z)
+{
+ int cur_rotation = ROTATION_UNKNOWN;
+
+ double atan_value;
+ int acc_theta, acc_pitch;
+ double realg;
+ bool is_stable = false;
+ bool rotation_on = false;
+ int tilt, angle;
+ int i;
+
+ atan_value = atan2(x, y);
+ acc_theta = (int)(atan_value * (RADIAN_VALUE) + DEGREE_360) % DEGREE_360;
+ realg = (double)sqrt((x * x) + (y * y) + (z * z));
+ acc_pitch = ROTATION_90 - abs((int) (asin(z / realg) * RADIAN_VALUE));
+
+ for (i = 0; i < ROTATION_RULE_CNT; ++i) {
+ tilt = rot_rule[i].tilt;
+
+ if ((acc_pitch >= TILT_MIN) && (acc_pitch <= tilt)) {
+ if ((m_rotation == ROTATION_EVENT_0) || (m_rotation == ROTATION_EVENT_180))
+ angle = rot_rule[i].angle;
+ else
+ angle = ROTATION_90 - rot_rule[i].angle;
+
+ if ((acc_theta >= ROTATION_360 - angle && acc_theta <= ROTATION_360 - 1) ||
+ (acc_theta >= ROTATION_0 && acc_theta <= ROTATION_0 + angle)) {
+ cur_rotation = ROTATION_EVENT_0;
+ } else if (acc_theta >= ROTATION_0 + angle && acc_theta <= ROTATION_180 - angle) {
+ cur_rotation = ROTATION_EVENT_90;
+ } else if (acc_theta >= ROTATION_180 - angle && acc_theta <= ROTATION_180 + angle) {
+ cur_rotation = ROTATION_EVENT_180;
+ } else if (acc_theta >= ROTATION_180 + angle && acc_theta <= ROTATION_360 - angle) {
+ cur_rotation = ROTATION_EVENT_270;
+ }
+ break;
+ }
+ }
+
+ m_windowing[m_curr_window_count++] = cur_rotation;
+
+ if (m_curr_window_count == MAX_WINDOW_NUM)
+ m_curr_window_count = 0;
+
+ for (i = 0; i < MAX_WINDOW_NUM ; i++) {
+ if (m_windowing[i] == cur_rotation)
+ is_stable = true;
+ else {
+ is_stable = false;
+ break;
+ }
+ }
+
+ rotation_on = (m_rotation != cur_rotation);
+
+ if (rotation_on && is_stable) {
+ m_rotation = cur_rotation;
+ m_rotation_time = get_timestamp();
+ return m_rotation;
+ }
+
+ return -1;
+}
+
+void accel_sensor::reset_rotation(void)
+{
+ int i;
+
+ for (i = 0 ; i < MAX_WINDOW_NUM ; i++)
+ m_windowing[i] = 0;
+
+ m_curr_window_count = 0;
+ m_rotation = ROTATION_UNKNOWN;
+ m_rotation_time = 0;
+ m_rotation_check_remained_time = ROTATION_CHECK_INTERVAL;
+}
+
+bool accel_sensor::is_rotation_time(void)
+{
+ AUTOLOCK(m_mutex);
+ m_rotation_check_remained_time -= m_interval;
+
+ if (m_rotation_check_remained_time <= 0) {
+ m_rotation_check_remained_time = ROTATION_CHECK_INTERVAL;
+ return true;
+ }
+
+ return false;
+}
+
+bool accel_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ m_interval = interval;
+ INFO("Polling interval is set to %dms", interval);
+ return m_sensor_hal->set_interval(interval);
+}
+
+void accel_sensor::raw_to_base(sensor_data_t &data)
+{
+ data.data_unit_idx = SENSOR_UNIT_METRE_PER_SECOND_SQUARED;
+ data.values_num = 3;
+ data.values[0] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data.values[0] * m_raw_data_unit);
+ data.values[1] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data.values[1] * m_raw_data_unit);
+ data.values[2] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data.values[2] * m_raw_data_unit);
+}
+
+void accel_sensor::raw_to_orientation(sensor_data_t &raw, sensor_data_t &orientation)
+{
+ orientation.timestamp = raw.time_stamp;
+ orientation.data_accuracy = raw.data_accuracy;
+ orientation.data_unit_idx = SENSOR_UNIT_DEGREE;
+ orientation.values_num = 3;
+ orientation.values[0] = fmodf((atan2(raw.values[0], raw.values[1]) * RADIAN_VALUE + DEGREE_360), DEGREE_360);
+ orientation.values[1] = fmodf((atan2(raw.values[1], raw.values[2]) * RADIAN_VALUE), DEGREE_180);
+ orientation.values[2] = fmodf((atan2(raw.values[0], raw.values[2]) * RADIAN_VALUE), DEGREE_180);
+
+ if (orientation.values[2] > DEGREE_90)
+ orientation.values[2] = DEGREE_180 - orientation.values[2];
+ else if (orientation.values[2] < -DEGREE_90)
+ orientation.values[2] = -DEGREE_180 - orientation.values[2];
+}
+
+extern "C" void *create(void)
+{
+ accel_sensor *inst;
+
+ try {
+ inst = new accel_sensor();
+ } catch (int err) {
+ ERR("Failed to create accel_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (accel_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _ACCEL_SENSOR_H_
+#define _ACCEL_SENSOR_H_
+
+#include <sensor_common.h>
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class accel_sensor : public physical_sensor
+{
+public:
+ accel_sensor();
+ virtual ~accel_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ bool add_client(unsigned int event_type);
+
+ virtual bool set_interval(unsigned long interval);
+ virtual long set_command(const unsigned int cmd, long value);
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ int get_sensor_data(const unsigned int type, sensor_data_t &data);
+private:
+ sensor_hal *m_sensor_hal;
+ cmutex m_value_mutex;
+
+ float m_raw_data_unit;
+
+ int m_rotation;
+ unsigned long long m_rotation_time;
+ unsigned long m_interval;
+ int m_curr_window_count;
+
+ static const int RADIAN_VALUE = 57.29747;
+ static const int MAX_WINDOW_NUM = 2;
+ long m_windowing[MAX_WINDOW_NUM];
+
+ int m_rotation_check_remained_time;
+
+ int get_rotation_event(float x, float y, float z);
+ void reset_rotation(void);
+ bool is_rotation_time(void);
+
+ void raw_to_base(sensor_data_t &data);
+ void raw_to_orientation(sensor_data_t &raw, sensor_data_t &orientation);
+ bool process_event(void);
+};
+#endif /*_ACCEL_SENSOR_H_*/
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <cconfig.h>
+#include <accel_sensor_hal.h>
+
+using std::ifstream;
+using config::CConfig;
+
+#define NODE_NAME "name"
+#define NODE_INPUT "input"
+#define NODE_ENABLE "enable"
+#define NODE_POLL_DELAY "poll_delay"
+#define NODE_ACCEL_POLL_DELAY "accel_poll_delay"
+#define SENSOR_NODE "/sys/class/sensors/"
+#define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
+#define INPUT_DEVICE_NODE "/sys/class/input/"
+#define DEV_INPUT_NODE "/dev/input/event/"
+#define CALIBRATION_NODE "/sys/class/sensors/accelerometer_sensor/calibration"
+#define CALIBRATION_FILE "/csa/sensor/accel_cal_data"
+#define CALIBRATION_DIR "/csa/sensor"
+
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+#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) (-((2 << (RES))/2))
+#define MAX_RANGE(RES) (((2 << (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"
+
+accel_sensor_hal::accel_sensor_hal()
+: m_x(INITIAL_VALUE)
+, m_y(INITIAL_VALUE)
+, m_z(INITIAL_VALUE)
+, m_node_handle(INITIAL_VALUE)
+, m_polling_interval(POLL_1HZ_MS)
+, m_fired_time(INITIAL_TIME)
+, m_sensorhub_supported(false)
+{
+ if (!check_hw_node()) {
+ ERR("check_hw_node() fail");
+ throw ENXIO;
+ }
+
+ CConfig &config = CConfig::get_instance();
+
+ if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty");
+ 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");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ long resolution;
+
+ if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RESOLUTION, resolution)) {
+ ERR("[RESOLUTION] is empty");
+ throw ENXIO;
+ }
+
+ m_resolution = (int)resolution;
+ INFO("m_resolution = %d", 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");
+ throw ENXIO;
+ }
+
+ m_raw_data_unit = (float)(raw_data_unit);
+ INFO("m_raw_data_unit = %f", m_raw_data_unit);
+
+ if ((m_node_handle = open(m_resource.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_resource.c_str());
+ throw ENXIO;
+ }
+
+ INFO("accel_sensor_hal is created!");
+}
+
+accel_sensor_hal::~accel_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = INITIAL_VALUE;
+
+ INFO("accel_sensor_hal is destroyed!");
+}
+
+string accel_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t accel_sensor_hal::get_type(void)
+{
+ return ACCELEROMETER_SENSOR;
+}
+
+long accel_sensor_hal::set_command(const unsigned int cmd, long value)
+{
+ FILE *fp;
+
+ AUTOLOCK(m_mutex);
+
+ switch (cmd) {
+ case ACCELEROMETER_PROPERTY_SET_CALIBRATION :
+ if (calibration(CAL_SET)) {
+ INFO("acc_sensor_calibration OK");
+ return 0;
+ }
+
+ ERR("acc_sensor_calibration FAIL");
+ return -1;
+ case ACCELEROMETER_PROPERTY_CHECK_CALIBRATION_STATUS :
+ if (calibration(CAL_CHECK)) {
+ INFO("acc_sensor_calibration check OK");
+ return 0;
+ }
+
+ ERR("acc_sensor_calibration check FAIL");
+ return -1;
+ default:
+ ERR("Invalid property_cmd");
+ break;
+ }
+
+ return -1;
+}
+
+bool accel_sensor_hal::enable_resource(string &resource_node, bool enable)
+{
+ int prev_status, status;
+ FILE *fp = NULL;
+ fp = fopen(resource_node.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fscanf(fp, "%d", &prev_status) < 0) {
+ ERR("Failed to get data from %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+
+ if (enable) {
+ if (m_sensorhub_supported)
+ status = prev_status | (1 << SENSORHUB_ACCELEROMETER_ENABLE_BIT);
+ else
+ status = 1;
+ } else {
+ if (m_sensorhub_supported)
+ status = prev_status ^ (1 << SENSORHUB_ACCELEROMETER_ENABLE_BIT);
+ else
+ status = 0;
+ }
+
+ fp = fopen(resource_node.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%d", status) < 0) {
+ ERR("Failed to enable a resource file: %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return true;
+}
+
+bool accel_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, true);
+ 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);
+
+ enable_resource(m_enable_resource, false);
+ INFO("Accel sensor real stopping");
+ return true;
+}
+
+bool accel_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+ FILE *fp = NULL;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * MS_TO_SEC * MS_TO_SEC);
+ fp = fopen(m_polling_resource.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", m_polling_resource.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%llu", polling_interval_ns) < 0) {
+ ERR("Failed to set data %llu", polling_interval_ns);
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
+
+bool accel_sensor_hal::update_value(bool wait)
+{
+ const int TIMEOUT = 1;
+ 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 timeval tv;
+ fd_set readfds, exceptfds;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&exceptfds);
+ FD_SET(m_node_handle, &readfds);
+ FD_SET(m_node_handle, &exceptfds);
+
+ if (wait) {
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+
+ int ret;
+ ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
+
+ if (ret == -1) {
+ ERR("select error:%s m_node_handle:%d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ DBG("select timeout: %d seconds elapsed", tv.tv_sec);
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &exceptfds)) {
+ ERR("select exception occurred!");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &readfds)) {
+ 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", 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::get_timestamp(&accel_input.time);
+ } else {
+ ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
+ return false;
+ }
+ }
+ } else {
+ ERR("select nothing to read!!!");
+ 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::is_data_ready(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int accel_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ const int chance = 3;
+ int retry = 0;
+
+ while ((m_fired_time == 0) && (retry++ < chance)) {
+ INFO("Try usleep for getting a valid BASE DATA value");
+ usleep(m_polling_interval * MS_TO_SEC);
+ }
+
+ if (m_fired_time == 0) {
+ ERR("get_sensor_data failed");
+ return -1;
+ }
+
+ data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ data.data_unit_idx = SENSOR_UNIT_VENDOR_UNIT;
+ data.timestamp = m_fired_time ;
+ data.values_num = 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_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNIT_METRE_PER_SECOND_SQUARED;
+ properties.sensor_min_range = MIN_RANGE(m_resolution) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
+ properties.sensor_max_range = MAX_RANGE(m_resolution) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
+ snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
+ snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
+ properties.sensor_resolution = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
+ return true;
+}
+
+bool accel_sensor_hal::calibration(int cmd)
+{
+ if (cmd == CAL_CHECK) {
+ struct calibration_data {
+ short x;
+ short y;
+ short z;
+ };
+ struct calibration_data cal_data;
+
+ if (access(CALIBRATION_FILE, F_OK) == 0) {
+ FILE *fp = NULL;
+ fp = fopen(CALIBRATION_FILE, "r");
+
+ if (!fp) {
+ ERR("cannot open calibration file");
+ return false;
+ }
+
+ size_t read_cnt;
+ read_cnt = fread(&cal_data, sizeof(cal_data), 1, fp);
+
+ if (read_cnt != 1) {
+ ERR("cal_data read fail, read_cnt = %d", read_cnt);
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+ INFO("x = [%d] y = [%d] z = [%d]", cal_data.x, cal_data.y, cal_data.z);
+
+ if (cal_data.x == 0 && cal_data.y == 0 && cal_data.z == 0) {
+ DBG("cal_data values is zero");
+ return false;
+ } else
+ return true;
+ } else {
+ INFO("cannot access calibration file");
+ return false;
+ }
+ } else if (cmd == CAL_SET) {
+ if (mkdir(CALIBRATION_DIR, 0755) != 0)
+ INFO("mkdir fail");
+
+ FILE *fp;
+ fp = fopen(CALIBRATION_NODE, "w");
+
+ if (!fp) {
+ ERR("Failed to open a calibration file");
+ return false;
+ }
+
+ if (fprintf(fp, "%d", cmd) < 0) {
+ ERR("Failed to set calibration");
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+ return true;
+ } else if (cmd == CAL_MKDIR) {
+ if (mkdir(CALIBRATION_DIR, 0755) != 0) {
+ ERR("mkdir fail");
+ return false;
+ }
+
+ return true;
+ }
+
+ ERR("Non supported calibration cmd = %d", cmd);
+ return false;
+}
+
+bool accel_sensor_hal::is_sensorhub_supported(void)
+{
+ DIR *main_dir = NULL;
+ main_dir = opendir(SENSORHUB_NODE);
+
+ if (!main_dir) {
+ INFO("Sensor Hub is not supported");
+ return false;
+ }
+
+ INFO("It supports sensor hub");
+ closedir(main_dir);
+ return true;
+}
+
+bool accel_sensor_hal::check_hw_node(void)
+{
+ string name_node;
+ string hw_name;
+ DIR *main_dir = NULL;
+ struct dirent *dir_entry = NULL;
+ bool find_node = false;
+
+ INFO("======================start check_hw_node=============================");
+
+ m_sensorhub_supported = is_sensorhub_supported();
+ main_dir = opendir(SENSOR_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
+ name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (CConfig::get_instance().is_supported(SENSOR_TYPE_ACCEL, hw_name) == true) {
+ m_name = m_model_id = hw_name;
+ INFO("m_model_id = %s", m_model_id.c_str());
+ find_node = true;
+ calibration(CAL_MKDIR);
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+
+ if (find_node) {
+ main_dir = opendir(INPUT_DEVICE_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ find_node = false;
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
+ name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (hw_name == string(INPUT_NAME)) {
+ INFO("name_node = %s", name_node.c_str());
+ DBG("Find H/W for accel_sensor");
+
+ find_node = true;
+ string dir_name;
+ dir_name = string(dir_entry->d_name);
+ unsigned found = dir_name.find_first_not_of(NODE_INPUT);
+ m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
+
+ if (m_sensorhub_supported) {
+ m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
+ m_polling_resource = string(SENSORHUB_NODE) + string(NODE_ACCEL_POLL_DELAY);
+ } else {
+ m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
+ m_polling_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_POLL_DELAY);
+ }
+
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+ }
+
+ if (find_node) {
+ INFO("m_resource = %s", m_resource.c_str());
+ INFO("m_enable_resource = %s", m_enable_resource.c_str());
+ INFO("m_polling_resource = %s", m_polling_resource.c_str());
+ }
+
+ return find_node;
+}
+
+extern "C" void *create(void)
+{
+ accel_sensor_hal *inst;
+
+ try {
+ inst = new accel_sensor_hal();
+ } catch (int err) {
+ ERR("Failed to create accel_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (accel_sensor_hal *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _ACCEL_SENSOR_HAL_H_
+#define _ACCEL_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class accel_sensor_hal : public sensor_hal
+{
+ enum accel_cmd_cal_t {
+ CAL_CHECK = 0,
+ CAL_SET,
+ CAL_MKDIR,
+ };
+
+public:
+ accel_sensor_hal();
+ virtual ~accel_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ bool get_properties(sensor_properties_t &properties);
+ bool check_hw_node(void);
+ long set_command(const unsigned int cmd, long value);
+
+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;
+ bool m_sensorhub_supported;
+
+ string m_model_id;
+ string m_name;
+ string m_vendor;
+ string m_chip_name;
+
+ int m_resolution;
+ float m_raw_data_unit;
+
+ string m_resource;
+ string m_enable_resource;
+ string m_polling_resource;
+
+ cmutex m_value_mutex;
+
+ bool enable_resource(string &resource_node, bool enable);
+ bool update_value(bool wait);
+ bool calibration(int cmd);
+ bool is_sensorhub_supported(void);
+};
+#endif /*_ACCEL_SENSOR_HAL_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(geo CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME geo_sensor)
+SET(SENSOR_HAL_NAME geo_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+add_definitions(-DUSE_DLOG_LOG)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ geo_sensor.cpp
+)
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ geo_sensor_hal.cpp
+)
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <common.h>
+#include <sf_common.h>
+#include <geo_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define SENSOR_NAME "GEOMAGNETIC_SENSOR"
+
+geo_sensor::geo_sensor()
+: m_sensor_hal(NULL)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
+ register_supported_event(GEOMAGNETIC_EVENT_CALIBRATION_NEEDED);
+
+ physical_sensor::set_poller(geo_sensor::working, this);
+}
+
+geo_sensor::~geo_sensor()
+{
+ INFO("geo_sensor is destroyed!");
+}
+
+bool geo_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(GEOMAGNETIC_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t geo_sensor::get_type(void)
+{
+ return GEOMAGNETIC_SENSOR;
+}
+
+bool geo_sensor::working(void *inst)
+{
+ geo_sensor *sensor = (geo_sensor *)inst;
+ return sensor->process_event();
+}
+
+bool geo_sensor::process_event(void)
+{
+ sensor_event_t event;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+
+ AUTOLOCK(m_client_info_mutex);
+ AUTOLOCK(m_mutex);
+
+ if (get_client_cnt(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ event.event_type = GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME;
+
+ push(event);
+ }
+
+ return true;
+}
+
+bool geo_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool geo_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+long geo_sensor::set_command(const unsigned int cmd, long value)
+{
+ if (m_sensor_hal->set_command(cmd, value) < 0) {
+ ERR("m_sensor_hal set_cmd fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool geo_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int geo_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ int state;
+
+ if (type != GEOMAGNETIC_BASE_DATA_SET)
+ return -1;
+
+ state = m_sensor_hal->get_sensor_data(data);
+
+ if (state < 0) {
+ ERR("m_sensor_hal get struct_data fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool geo_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ INFO("Polling interval is set to %dms", interval);
+ return m_sensor_hal->set_interval(interval);
+}
+
+extern "C" void *create(void)
+{
+ geo_sensor *inst;
+
+ try {
+ inst = new geo_sensor();
+ } catch (int err) {
+ ERR("Failed to create geo_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (geo_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _GEO_SENSOR_H_
+#define _GEO_SENSOR_H_
+
+#include <sensor_common.h>
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class geo_sensor : public physical_sensor
+{
+public:
+ geo_sensor();
+ virtual ~geo_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ virtual bool set_interval(unsigned long interval);
+ virtual long set_command(const unsigned int cmd, long value);
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ int get_sensor_data(const unsigned int type, sensor_data_t &data);
+private:
+ sensor_hal *m_sensor_hal;
+ cmutex m_mutex;
+
+ bool process_event(void);
+};
+#endif /*_GEO_SENSOR_H_*/
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <cconfig.h>
+#include <geo_sensor_hal.h>
+
+using std::ifstream;
+using config::CConfig;
+
+#define NODE_NAME "name"
+#define NODE_INPUT "input"
+#define NODE_ENABLE "enable"
+#define NODE_POLL_DELAY "poll_delay"
+#define NODE_MAG_POLL_DELAY "mag_poll_delay"
+#define SENSOR_NODE "/sys/class/sensors/"
+#define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
+#define INPUT_DEVICE_NODE "/sys/class/input/"
+#define DEV_INPUT_NODE "/dev/input/event/"
+
+#define LBS_TO_UTESLA 0.06f
+
+#define SENSOR_TYPE_MAGNETIC "MAGNETIC"
+#define ELEMENT_NAME "NAME"
+#define ELEMENT_VENDOR "VENDOR"
+#define ATTR_VALUE "value"
+
+#define INPUT_NAME "geomagnetic_sensor"
+
+geo_sensor_hal::geo_sensor_hal()
+: m_x(INITIAL_VALUE)
+, m_y(INITIAL_VALUE)
+, m_z(INITIAL_VALUE)
+, m_node_handle(INITIAL_VALUE)
+, m_polling_interval(POLL_1HZ_MS)
+, m_fired_time(INITIAL_TIME)
+, m_sensorhub_supported(false)
+{
+ if (!check_hw_node()) {
+ ERR("check_hw_node() fail");
+ throw ENXIO;
+ }
+
+ CConfig &config = CConfig::get_instance();
+
+ if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty");
+ 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");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ if ((m_node_handle = open(m_resource.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_resource.c_str());
+ throw ENXIO;
+ }
+
+ INFO("geo_sensor_hal is created!");
+}
+
+geo_sensor_hal::~geo_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = INITIAL_VALUE;
+
+ INFO("geo_sensor_hal is destroyed!");
+}
+
+string geo_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t geo_sensor_hal::get_type(void)
+{
+ return GEOMAGNETIC_SENSOR;
+}
+
+bool geo_sensor_hal::enable_resource(string &resource_node, bool enable)
+{
+ int prev_status, status;
+ FILE *fp = NULL;
+ fp = fopen(resource_node.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fscanf(fp, "%d", &prev_status) < 0) {
+ ERR("Failed to get data from %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+
+ if (enable) {
+ if (m_sensorhub_supported)
+ status = prev_status | (1 << SENSORHUB_GEOMAGNETIC_ENABLE_BIT);
+ else
+ status = 1;
+ } else {
+ if (m_sensorhub_supported)
+ status = prev_status ^ (1 << SENSORHUB_GEOMAGNETIC_ENABLE_BIT);
+ else
+ status = 0;
+ }
+
+ fp = fopen(resource_node.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%d", status) < 0) {
+ ERR("Failed to enable a resource file: %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return true;
+}
+
+bool geo_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, true);
+ 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);
+
+ enable_resource(m_enable_resource, false);
+ INFO("Geo sensor real stopping");
+ return true;
+}
+
+bool geo_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+ FILE *fp = NULL;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * MS_TO_SEC * MS_TO_SEC);
+ fp = fopen(m_polling_resource.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", m_polling_resource.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%llu", polling_interval_ns) < 0) {
+ ERR("Failed to set data %llu", polling_interval_ns);
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
+
+bool geo_sensor_hal::update_value(bool wait)
+{
+ const int TIMEOUT = 1;
+ 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 timeval tv;
+ fd_set readfds, exceptfds;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&exceptfds);
+ FD_SET(m_node_handle, &readfds);
+ FD_SET(m_node_handle, &exceptfds);
+
+ if (wait) {
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+
+ int ret;
+ ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
+
+ if (ret == -1) {
+ ERR("select error:%s m_node_handle:%d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ DBG("select timeout: %d seconds elapsed", tv.tv_sec);
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &exceptfds)) {
+ ERR("select exception occurred!");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &readfds)) {
+ 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", 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 = get_timestamp(&geo_input.time);
+ } else {
+ ERR("geo_input event[type = %d, code = %d] is unknown.", geo_input.type, geo_input.code);
+ return false;
+ }
+ }
+ } else {
+ ERR("select nothing to read!!!");
+ 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 = 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(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int geo_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ const int chance = 3;
+ int retry = 0;
+
+ while ((m_fired_time == 0) && (retry++ < chance)) {
+ INFO("Try usleep for getting a valid BASE DATA value");
+ usleep(m_polling_interval * MS_TO_SEC);
+ }
+
+ if (m_fired_time == 0) {
+ ERR("get_sensor_data failed");
+ return -1;
+ }
+
+ data.data_accuracy = (m_hdst == 1) ? 0 : m_hdst; /* hdst 0 and 1 are needed to calibrate */
+ data.data_unit_idx = SENSOR_UNIT_MICRO_TESLA;
+ data.timestamp = m_fired_time;
+ data.values_num = 3;
+ data.values[0] = (float)m_x * LBS_TO_UTESLA;
+ data.values[1] = (float)m_y * LBS_TO_UTESLA;
+ data.values[2] = (float)m_z * LBS_TO_UTESLA;
+
+ return 0;
+}
+
+bool geo_sensor_hal::get_properties(sensor_properties_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNIT_MICRO_TESLA;
+ properties.sensor_min_range = -1200;
+ properties.sensor_max_range = 1200;
+ snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
+ snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
+ properties.sensor_resolution = 1;
+ return true;
+}
+
+bool geo_sensor_hal::is_sensorhub_supported(void)
+{
+ FILE *fp = NULL;
+ string mag_polling_resource = string(SENSORHUB_NODE) + string(MAG_POLL_DELAY);
+ fp = fopen(mag_polling_resource.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file");
+ return false;
+ }
+
+ INFO("Supported by Sensor-Hub");
+ fclose(fp);
+ return true;
+}
+
+bool geo_sensor_hal::check_hw_node(void)
+{
+ string name_node;
+ string hw_name;
+ DIR *main_dir = NULL;
+ struct dirent *dir_entry = NULL;
+ bool find_node = false;
+
+ INFO("======================start check_hw_node=============================");
+
+ m_sensorhub_supported = is_sensorhub_supported();
+ main_dir = opendir(SENSOR_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
+ name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (CConfig::get_instance().is_supported(SENSOR_TYPE_MAGNETIC, hw_name) == true) {
+ m_name = m_model_id = hw_name;
+ INFO("m_model_id = %s", m_model_id.c_str());
+ find_node = true;
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+
+ if (find_node) {
+ main_dir = opendir(INPUT_DEVICE_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ find_node = false;
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
+ name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (hw_name == string(INPUT_NAME)) {
+ INFO("name_node = %s", name_node.c_str());
+ DBG("Find H/W for mag_sensor");
+
+ find_node = true;
+ string dir_name;
+ dir_name = string(dir_entry->d_name);
+ unsigned found = dir_name.find_first_not_of(NODE_INPUT);
+ m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
+
+ if (m_sensorhub_supported) {
+ m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
+ m_polling_resource = string(SENSORHUB_NODE) + string(NODE_MAG_POLL_DELAY);
+ } else {
+ m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
+ m_polling_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_POLL_DELAY);
+ }
+
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+ }
+
+ if (find_node) {
+ INFO("m_resource = %s", m_resource.c_str());
+ INFO("m_enable_resource = %s", m_enable_resource.c_str());
+ INFO("m_polling_resource = %s", m_polling_resource.c_str());
+ }
+
+ return find_node;
+}
+
+extern "C" void *create(void)
+{
+ geo_sensor_hal *inst;
+
+ try {
+ inst = new geo_sensor_hal();
+ } catch (int err) {
+ ERR("Failed to create geo_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (geo_sensor_hal *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _GEO_SENSOR_HAL_H_
+#define _GEO_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class geo_sensor_hal : public sensor_hal
+{
+public:
+ geo_sensor_hal();
+ virtual ~geo_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ bool get_properties(sensor_properties_t &properties);
+ bool check_hw_node(void);
+
+private:
+ long a_x;
+ long a_y;
+ long a_z;
+ double m_x;
+ double m_y;
+ double m_z;
+ int m_hdst;
+ int m_node_handle;
+ unsigned long m_polling_interval;
+ unsigned long long m_fired_time;
+ bool m_sensorhub_supported;
+
+ string m_model_id;
+ string m_name;
+ string m_vendor;
+ string m_chip_name;
+
+ string m_resource;
+ string m_enable_resource;
+ string m_polling_resource;
+
+ cmutex m_value_mutex;
+
+ bool enable_resource(string &resource_node, bool enable);
+ bool update_value(bool wait);
+ bool is_sensorhub_supported(void);
+};
+#endif /*_GEO_SENSOR_HAL_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(gravity CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME gravity_sensor)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ gravity_sensor.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <common.h>
+#include <sf_common.h>
+#include <sensor_base.h>
+#include <virtual_sensor.h>
+#include <gravity_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+#define TIME_CONSTANT 0.18
+#define GRAVITY 9.80665
+
+#define SENSOR_NAME "GRAVITY_SENSOR"
+
+gravity_sensor::gravity_sensor()
+: m_accel_sensor(NULL)
+, m_x(INITIAL_VALUE)
+, m_y(INITIAL_VALUE)
+, m_z(INITIAL_VALUE)
+, m_time(INITIAL_TIME)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
+}
+
+gravity_sensor::~gravity_sensor()
+{
+ INFO("gravity_sensor is destroyed!");
+}
+
+bool gravity_sensor::init()
+{
+ m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR);
+
+ if (!m_accel_sensor) {
+ ERR("cannot load accel sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t gravity_sensor::get_type(void)
+{
+ return GRAVITY_SENSOR;
+}
+
+bool gravity_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->start();
+
+ activate();
+ return true;
+}
+
+bool gravity_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->stop();
+
+ deactivate();
+ return true;
+}
+
+bool gravity_sensor::add_interval(int client_id, unsigned int interval, bool is_processor)
+{
+ m_accel_sensor->add_interval(client_id, interval, true);
+ return sensor_base::add_interval(client_id, interval, true);
+}
+
+bool gravity_sensor::delete_interval(int client_id, bool is_processor)
+{
+ m_accel_sensor->delete_interval(client_id, true);
+ return sensor_base::delete_interval(client_id, true);
+}
+
+void gravity_sensor::synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs)
+{
+ if (event.event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME) {
+ float x, y, z;
+ calibrate_gravity(event, x, y, z);
+
+ sensor_event_t event;
+ event.event_type = GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME;
+ event.data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ event.data.data_unit_idx = SENSOR_UNIT_METRE_PER_SECOND_SQUARED;
+ event.data.timestamp = m_time;
+ event.data.values_num = 3;
+ event.data.values[0] = x;
+ event.data.values[1] = y;
+ event.data.values[2] = z;
+ outs.push_back(event);
+
+ AUTOLOCK(m_value_mutex);
+ m_x = x;
+ m_y = y;
+ m_z = z;
+
+ return;
+ }
+}
+
+int gravity_sensor::get_sensor_data(const unsigned int data_id, sensor_data_t &data)
+{
+ if (data_id != GRAVITY_BASE_DATA_SET)
+ return -1;
+
+ AUTOLOCK(m_value_mutex);
+
+ data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ data.data_unit_idx = SENSOR_UNIT_METRE_PER_SECOND_SQUARED;
+ data.time_stamp = m_time;
+ data.values_num = 3;
+ data.values[0] = m_x;
+ data.values[1] = m_y;
+ data.values[2] = m_z;
+
+ return 0;
+}
+
+bool gravity_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ m_accel_sensor->get_properties(type, properties);
+
+ if (type != GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME)
+ return true;
+
+ properties.sensor_min_range = properties.sensor_min_range / GRAVITY;
+ properties.sensor_max_range = properties.sensor_max_range / GRAVITY;
+ properties.sensor_resolution = properties.sensor_resolution / GRAVITY;
+ strncpy(properties.sensor_name, "Gravity Sensor", MAX_KEY_LENGTH);
+
+ return true;
+}
+
+void gravity_sensor::calibrate_gravity(const sensor_event_t &raw, float &x, float &y, float &z)
+{
+ unsigned long long timestamp;
+ float dt;
+ float alpha;
+ float last_x = 0, last_y = 0, last_z = 0;
+
+ {
+ AUTOLOCK(m_value_mutex);
+ last_x = m_x;
+ last_y = m_y;
+ last_z = m_z;
+ }
+
+ timestamp = get_timestamp();
+ dt = (timestamp - m_time) / US_TO_SEC;
+ m_time = timestamp;
+ alpha = TIME_CONSTANT / (TIME_CONSTANT + dt);
+
+ if (dt > 1.0)
+ alpha = 0.0;
+
+ x = (alpha * last_x) + ((1 - alpha) * raw.data.values[0] / GRAVITY);
+ y = (alpha * last_y) + ((1 - alpha) * raw.data.values[1] / GRAVITY);
+ z = (alpha * last_z) + ((1 - alpha) * raw.data.values[2] / GRAVITY);
+}
+
+extern "C" void *create(void)
+{
+ gravity_sensor *inst;
+
+ try {
+ inst = new gravity_sensor();
+ } catch (int ErrNo) {
+ ERR("Failed to create gravity_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (gravity_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _GRAVITY_SENSOR_H_
+#define _GRAVITY_SENSOR_H_
+
+#include <sensor.h>
+#include <virtual_sensor.h>
+#include <string>
+
+using std::string;
+
+class gravity_sensor : public virtual_sensor
+{
+public:
+ gravity_sensor();
+ virtual ~gravity_sensor();
+
+ bool init();
+ sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ bool on_start(void);
+ bool on_stop(void);
+
+ void synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs);
+
+ virtual bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
+ virtual bool delete_interval(int client_id, bool is_processor = false);
+
+ int get_sensor_data(const unsigned int data_id, sensor_data_t &data);
+ bool get_properties(const unsigned int type, sensor_properties_t &properties);
+private:
+ sensor_base *m_accel_sensor;
+ cmutex m_value_mutex;
+
+ float m_x;
+ float m_y;
+ float m_z;
+ unsigned long long m_time;
+
+ void calibrate_gravity(const sensor_event_t &raw, float &x, float &y, float &z);
+};
+
+#endif /*_GRAVITY_SENSOR_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(gyro CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME gyro_sensor)
+SET(SENSOR_HAL_NAME gyro_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ gyro_sensor.cpp
+ )
+add_library(${SENSOR_HAL_NAME} SHARED
+ gyro_sensor_hal.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <common.h>
+#include <sf_common.h>
+#include <gyro_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define INTIAL_VALUE -1
+#define MS_TO_US 1000
+#define DPS_TO_MDPS 1000
+#define RAW_DATA_TO_DPS_UNIT(X) ((float)(X)/((float)DPS_TO_MDPS))
+
+#define SENSOR_NAME "GYROSCOPE_SENSOR"
+
+gyro_sensor::gyro_sensor()
+: m_sensor_hal(NULL)
+, m_resolution(INITIAL_VALUE)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
+
+ physical_sensor::set_poller(gyro_sensor::working, this);
+}
+
+gyro_sensor::~gyro_sensor()
+{
+ INFO("gyro_sensor is destroyed!");
+}
+
+bool gyro_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(GYROSCOPE_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ sensor_properties_t properties;
+
+ if (m_sensor_hal->get_properties(properties) == false) {
+ ERR("sensor->get_properties() is failed!");
+ return false;
+ }
+
+ m_resolution = properties.sensor_resolution;
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t gyro_sensor::get_type(void)
+{
+ return GYROSCOPE_SENSOR;
+}
+
+bool gyro_sensor::working(void *inst)
+{
+ gyro_sensor *sensor = (gyro_sensor *)inst;
+ return sensor->process_event();
+}
+
+bool gyro_sensor::process_event(void)
+{
+ sensor_event_t event;
+
+ if (m_sensor_hal->is_data_ready(true) == false)
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+
+ AUTOLOCK(m_client_info_mutex);
+
+ if (get_client_cnt(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ event.event_type = GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME;
+ raw_to_base(event.data);
+ push(event);
+ }
+
+ return true;
+}
+
+bool gyro_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool gyro_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool gyro_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int gyro_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ int state;
+
+ if (type != GYRO_BASE_DATA_SET)
+ return -1;
+
+ state = m_sensor_hal->get_sensor_data(data);
+
+ if (state < 0) {
+ ERR("m_sensor_hal get struct_data fail");
+ return -1;
+ }
+
+ raw_to_base(data);
+
+ return 0;
+}
+
+bool gyro_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ INFO("Polling interval is set to %dms", interval);
+ return m_sensor_hal->set_interval(interval);
+}
+
+void gyro_sensor::raw_to_base(sensor_data_t &data)
+{
+ data.data_unit_idx = SENSOR_UNIT_DEGREE_PER_SECOND;
+ data.values_num = 3;
+ data.values[0] = data.values[0] * m_resolution;
+ data.values[1] = data.values[1] * m_resolution;
+ data.values[2] = data.values[2] * m_resolution;
+}
+
+extern "C" void *create(void)
+{
+ gyro_sensor *inst;
+
+ try {
+ inst = new gyro_sensor();
+ } catch (int err) {
+ ERR("Failed to create gyro_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (gyro_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _GYRO_SENSOR_H_
+#define _GYRO_SENSOR_H_
+
+#include <sensor_common.h>
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class gyro_sensor : public physical_sensor
+{
+public:
+ gyro_sensor();
+ virtual ~gyro_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ virtual bool set_interval(unsigned long interval);
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ int get_sensor_data(const unsigned int type, sensor_data_t &data);
+private:
+ sensor_hal *m_sensor_hal;
+ float m_resolution;
+
+ void raw_to_base(sensor_data_t &data);
+ bool process_event(void);
+};
+
+#endif /*_GYRO_SENSOR_H_*/
\ No newline at end of file
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <cconfig.h>
+#include <gyro_sensor_hal.h>
+
+using std::ifstream;
+using config::CConfig;
+
+#define NODE_NAME "name"
+#define NODE_INPUT "input"
+#define NODE_ENABLE "enable"
+#define NODE_POLL_DELAY "poll_delay"
+#define NODE_ACCEL_POLL_DELAY "gyro_poll_delay"
+#define SENSOR_NODE "/sys/class/sensors/"
+#define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
+#define INPUT_DEVICE_NODE "/sys/class/input/"
+#define DEV_INPUT_NODE "/dev/input/event/"
+
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+#define DPS_TO_MDPS 1000
+#define MIN_RANGE(RES) (-((2 << (RES))/2))
+#define MAX_RANGE(RES) (((2 << (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"
+
+#define INPUT_NAME "gyro_sensor"
+
+gyro_sensor_hal::gyro_sensor_hal()
+: m_x(INITIAL_VALUE)
+, m_y(INITIAL_VALUE)
+, m_z(INITIAL_VALUE)
+, m_node_handle(INITIAL_VALUE)
+, m_polling_interval(POLL_1HZ_MS)
+, m_fired_time(INITIAL_TIME)
+, m_sensorhub_supported(false)
+{
+ if (!check_hw_node()) {
+ ERR("check_hw_node() fail");
+ throw ENXIO;
+ }
+
+ CConfig &config = CConfig::get_instance();
+
+ if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty");
+ 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");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ long resolution;
+
+ if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_RESOLUTION, resolution)) {
+ ERR("[RESOLUTION] is empty");
+ throw ENXIO;
+ }
+
+ m_resolution = (int)resolution;
+ INFO("m_resolution = %d", m_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");
+ throw ENXIO;
+ }
+
+ m_raw_data_unit = (float)(raw_data_unit);
+ INFO("m_raw_data_unit = %f", m_raw_data_unit);
+ INFO("RAW_DATA_TO_DPS_UNIT(m_raw_data_unit) = [%f]", RAW_DATA_TO_DPS_UNIT(m_raw_data_unit));
+
+ if ((m_node_handle = open(m_resource.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_resource.c_str());
+ throw ENXIO;
+ }
+
+ INFO("gyro_sensor_hal is created!");
+}
+
+gyro_sensor_hal::~gyro_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = INITIAL_VALUE;
+
+ INFO("gyro_sensor_hal is destroyed!");
+}
+
+string gyro_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t gyro_sensor_hal::get_type(void)
+{
+ return GYROSCOPE_SENSOR;
+}
+
+bool gyro_sensor_hal::enable_resource(string &resource_node, bool enable)
+{
+ int prev_status, status;
+ FILE *fp = NULL;
+ fp = fopen(resource_node.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fscanf(fp, "%d", &prev_status) < 0) {
+ ERR("Failed to get data from %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+
+ if (enable) {
+ if (m_sensorhub_supported)
+ status = prev_status | (1 << SENSORHUB_GYROSCOPE_ENABLE_BIT);
+ else
+ status = 1;
+ } else {
+ if (m_sensorhub_supported)
+ status = prev_status ^ (1 << SENSORHUB_GYROSCOPE_ENABLE_BIT);
+ else
+ status = 0;
+ }
+
+ fp = fopen(resource_node.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%d", status) < 0) {
+ ERR("Failed to enable a resource file: %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return true;
+}
+
+bool gyro_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, true);
+ 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);
+
+ enable_resource(m_enable_resource, false);
+ INFO("Gyro sensor real stopping");
+ return true;
+}
+
+bool gyro_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+ FILE *fp = NULL;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * MS_TO_SEC * MS_TO_SEC);
+ fp = fopen(m_polling_resource.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", m_polling_resource.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%llu", polling_interval_ns) < 0) {
+ ERR("Failed to set data %llu", polling_interval_ns);
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
+
+bool gyro_sensor_hal::update_value(bool wait)
+{
+ const int TIMEOUT = 1;
+ 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 timeval tv;
+ fd_set readfds, exceptfds;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&exceptfds);
+ FD_SET(m_node_handle, &readfds);
+ FD_SET(m_node_handle, &exceptfds);
+
+ if (wait) {
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+
+ int ret;
+ ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
+
+ if (ret == -1) {
+ ERR("select error:%s m_node_handle:d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ DBG("select timeout: %d seconds elapsed", tv.tv_sec);
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &exceptfds)) {
+ ERR("select exception occurred!");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &readfds)) {
+ 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", len);
+ 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::get_timestamp(&gyro_input.time);
+ } else {
+ ERR("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code);
+ return false;
+ }
+ }
+ } else {
+ ERR("select nothing to read!!!");
+ 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 = 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(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int gyro_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ const int chance = 3;
+ int retry = 0;
+
+ while ((m_fired_time == 0) && (retry++ < chance)) {
+ INFO("Try usleep for getting a valid BASE DATA value");
+ usleep(m_polling_interval * MS_TO_SEC);
+ }
+
+ if (m_fired_time == 0) {
+ ERR("get_sensor_data failed");
+ return -1;
+ }
+
+ data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ data.data_unit_idx = SENSOR_UNIT_VENDOR_UNIT;
+ data.timestamp = m_fired_time ;
+ data.values_num = 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_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNIT_DEGREE_PER_SECOND;
+ properties.sensor_min_range = MIN_RANGE(m_resolution) * RAW_DATA_TO_DPS_UNIT(m_raw_data_unit);
+ properties.sensor_max_range = MAX_RANGE(m_resolution) * RAW_DATA_TO_DPS_UNIT(m_raw_data_unit);
+ snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
+ snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
+ properties.sensor_resolution = RAW_DATA_TO_DPS_UNIT(m_raw_data_unit);
+ return true;
+}
+
+bool gyro_sensor_hal::is_sensorhub_supported(void)
+{
+ DIR *main_dir = NULL;
+ main_dir = opendir(SENSORHUB_NODE);
+
+ if (!main_dir) {
+ INFO("Sensor Hub is not supported");
+ return false;
+ }
+
+ INFO("It supports sensor hub");
+ closedir(main_dir);
+ return true;
+}
+
+bool gyro_sensor_hal::check_hw_node(void)
+{
+ string name_node;
+ string hw_name;
+ DIR *main_dir = NULL;
+ struct dirent *dir_entry = NULL;
+ bool find_node = false;
+
+ INFO("======================start check_hw_node=============================");
+
+ m_sensorhub_supported = is_sensorhub_supported();
+ main_dir = opendir(SENSOR_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
+ name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (CConfig::get_instance().is_supported(SENSOR_TYPE_GYRO, hw_name) == true) {
+ m_name = m_model_id = hw_name;
+ INFO("m_model_id = %s", m_model_id.c_str());
+ find_node = true;
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+
+ if (find_node) {
+ main_dir = opendir(INPUT_DEVICE_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ find_node = false;
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
+ name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (hw_name == string(INPUT_NAME)) {
+ INFO("name_node = %s", name_node.c_str());
+ DBG("Find H/W for gyro_sensor");
+
+ find_node = true;
+ string dir_name;
+ dir_name = string(dir_entry->d_name);
+ unsigned found = dir_name.find_first_not_of(NODE_INPUT);
+ m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
+
+ if (m_sensorhub_supported) {
+ m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
+ m_polling_resource = string(SENSORHUB_NODE) + string(NODE_GYRO_POLL_DELAY);
+ } else {
+ m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
+ m_polling_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_POLL_DELAY);
+ }
+
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+ }
+
+ if (find_node) {
+ INFO("m_resource = %s", m_resource.c_str());
+ INFO("m_enable_resource = %s", m_enable_resource.c_str());
+ INFO("m_polling_resource = %s", m_polling_resource.c_str());
+ }
+
+ return find_node;
+}
+
+extern "C" void *create(void)
+{
+ gyro_sensor_hal *inst;
+
+ try {
+ inst = new gyro_sensor_hal();
+ } catch (int err) {
+ ERR("Failed to create gyro_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (gyro_sensor_hal *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _GYRO_SENSOR_HAL_H_
+#define _GYRO_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class gyro_sensor_hal : public sensor_hal
+{
+public:
+ gyro_sensor_hal();
+ virtual ~gyro_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ bool get_properties(sensor_properties_t &properties);
+ bool check_hw_node(void);
+
+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;
+ bool m_sensorhub_supported;
+
+ string m_model_id;
+ string m_name;
+ string m_vendor;
+ string m_chip_name;
+
+ int m_resolution;
+ float m_raw_data_unit;
+
+ string m_resource;
+ string m_enable_resource;
+ string m_polling_resource;
+
+ cmutex m_value_mutex;
+
+ bool enable_resource(string &resource_node, bool enable);
+ bool update_value(bool wait);
+ bool is_sensorhub_supported(void);
+};
+#endif /*_GYRO_SENSOR_HAL_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensor CXX)
+
+# to install pkgconfig setup file.
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION_MAJOR 1)
+SET(VERSION "${VERSION_MAJOR}.1.0")
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf glib-2.0)
+add_definitions(${rpkgs_CFLAGS})
+
+#add_definitions(-Wall -O3 -omit-frame-pointer -lm)
+#add_definitions(-Wall -g -lma -DUSE_FILE_DEBUG)
+#add_definitions(-D_DEBUG)
+add_definitions(-Wall -g -lma -DUSE_DLOG_LOG -std=c++0x)
+#add_definitions(-fvisibility=hidden -lm -DUSE_DLOG_LOG)
+#add_definitions(-fvisibility=hidden -lm)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+#ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK -DUSE_MPU3050_GYRO")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET")
+ELSE("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(${PROJECT_NAME} SHARED
+ client.cpp
+ csensor_event_listener.cpp
+ csensor_handle_info.cpp
+ client_common.cpp
+ command_channel.cpp
+ poller.cpp
+)
+
+target_link_libraries(${PROJECT_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "sensord-share")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+
+configure_file(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
+
+#install(DIRECTORY include/ DESTINATION include/ FILES_MATCHING PATTERN "*.h")
+install(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries)
+
+install(FILES sensor.h DESTINATION include/sensor/)
+install(FILES poller.h DESTINATION include/sensor/)
+install(FILES creg_event_info.h DESTINATION include/sensor/)
+install(FILES csensor_event_listener.h DESTINATION include/sensor/)
+install(FILES csensor_handle_info.h DESTINATION include/sensor/)
+install(FILES client_common.h DESTINATION include/sensor/)
+install(FILES sensor_accel.h DESTINATION include/sensor/)
+install(FILES sensor_geomag.h DESTINATION include/sensor/)
+install(FILES sensor_light.h DESTINATION include/sensor/)
+install(FILES sensor_proxi.h DESTINATION include/sensor/)
+install(FILES sensor_gyro.h DESTINATION include/sensor/)
+install(FILES sensor_gravity.h DESTINATION include/sensor/)
+install(FILES sensor_linear_accel.h DESTINATION include/sensor/)
+install(FILES sensor_orientation.h DESTINATION include/sensor/)
+install(FILES sensor_context.h DESTINATION include/sensor/)
+install(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 <sf_common.h>
+#include <sensor.h>
+#include <csensor_event_listener.h>
+#include <client_common.h>
+#include <vconf.h>
+#include <cmutex.h>
+#include <common.h>
+
+#ifndef EXTAPI
+#define EXTAPI __attribute__((visibility("default")))
+#endif
+
+static const int OP_SUCCESS = 0;
+static const int OP_ERROR = -1;
+static const int CMD_ERROR = -2;
+
+static csensor_event_listener &event_listener = csensor_event_listener::get_instance();
+static cmutex lock;
+
+static bool g_power_save_state = false;
+
+static bool get_power_save_state(void);
+static void power_save_state_cb(keynode_t *node, void *data);
+static void clean_up(void);
+static void good_bye(void);
+static int change_sensor_rep(sensor_type_t sensor, sensor_rep &prev_rep, sensor_rep &cur_rep);
+
+void init_client(void)
+{
+ atexit(good_bye);
+}
+
+static void good_bye(void)
+{
+ _D("Good bye! %s", get_client_name());
+ clean_up();
+}
+
+static int g_power_save_state_cb_cnt = 0;
+
+static void set_power_save_state_cb(void)
+{
+ if (g_power_save_state_cb_cnt < 0)
+ _E("g_power_save_state_cb_cnt(%d) is wrong", g_power_save_state_cb_cnt);
+
+ ++g_power_save_state_cb_cnt;
+
+ if (g_power_save_state_cb_cnt == 1) {
+ _D("Power save callback is registered");
+ g_power_save_state = get_power_save_state();
+ _D("power_save_state = [%s]", g_power_save_state ? "on" : "off");
+ vconf_notify_key_changed(VCONFKEY_PM_STATE, power_save_state_cb, NULL);
+ }
+}
+
+static void unset_power_save_state_cb(void)
+{
+ --g_power_save_state_cb_cnt;
+
+ if (g_power_save_state_cb_cnt < 0)
+ _E("g_power_save_state_cb_cnt(%d) is wrong", g_power_save_state_cb_cnt);
+
+ if (g_power_save_state_cb_cnt == 0) {
+ _D("Power save callback is unregistered");
+ vconf_ignore_key_changed(VCONFKEY_PM_STATE, power_save_state_cb);
+ }
+}
+
+static void clean_up(void)
+{
+ handle_vector handles;
+ handle_vector::iterator it_handle;
+
+ event_listener.get_all_handles(handles);
+ it_handle = handles.begin();
+
+ while (it_handle != handles.end()) {
+ sf_disconnect(*it_handle);
+ ++it_handle;
+ }
+}
+
+static bool get_power_save_state (void)
+{
+ int pm_state, ps_state;
+
+ vconf_get_int(VCONFKEY_PM_STATE, &pm_state);
+
+ if ((pm_state == VCONFKEY_PM_STATE_LCDOFF))
+ return true;
+
+ return false;
+}
+
+static void power_save_state_cb(keynode_t *node, void *data)
+{
+ bool cur_power_save_state;
+ sensor_type_vector sensors;
+ sensor_rep prev_rep, cur_rep;
+
+ AUTOLOCK(lock);
+ cur_power_save_state = get_power_save_state();
+
+ if (cur_power_save_state == g_power_save_state) {
+ _T("g_power_save_state NOT changed : [%d]", cur_power_save_state);
+ return;
+ }
+
+ g_power_save_state = cur_power_save_state;
+ _D("power_save_state %s noti to %s", g_power_save_state ? "on" : "off", get_client_name());
+
+ event_listener.get_listening_sensors(sensors);
+ sensor_type_vector::iterator it_sensor;
+ it_sensor = sensors.begin();
+
+ while (it_sensor != sensors.end()) {
+ event_listener.get_sensor_rep(*it_sensor, prev_rep);
+
+ if (cur_power_save_state)
+ event_listener.pause_sensor(*it_sensor);
+ else
+ event_listener.resume_sensor(*it_sensor);
+
+ event_listener.get_sensor_rep(*it_sensor, cur_rep);
+ change_sensor_rep(*it_sensor, prev_rep, cur_rep);
+ ++it_sensor;
+ }
+}
+
+static bool get_events_diff(event_type_vector &a_vec, event_type_vector &b_vec, event_type_vector &add_vec, event_type_vector &del_vec)
+{
+ sort(a_vec.begin(), a_vec.end());
+ sort(b_vec.begin(), b_vec.end());
+
+ set_difference(a_vec.begin(), a_vec.end(), b_vec.begin(), b_vec.end(), back_inserter(del_vec));
+ set_difference(b_vec.begin(), b_vec.end(), a_vec.begin(), a_vec.end(), back_inserter(add_vec));
+
+ return !(add_vec.empty() && del_vec.empty());
+}
+
+static int change_sensor_rep(sensor_type_t sensor, sensor_rep &prev_rep, sensor_rep &cur_rep)
+{
+ int client_id;
+ command_channel *cmd_channel;
+ event_type_vector add_event_types, del_event_types;
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, %s, %s", client_id, get_sensor_name(sensor), get_client_name());
+
+ get_events_diff(prev_rep.event_types, cur_rep.event_types, add_event_types, del_event_types);
+
+ if (cur_rep.active) {
+ if (prev_rep.option != cur_rep.option) {
+ if (!cmd_channel->cmd_set_option(cur_rep.option)) {
+ ERR("Sending cmd_set_option(%d, %s, %d) failed for %s", client_id, get_sensor_name(sensor), cur_rep.option, get_client_name());
+ return CMD_ERROR;
+ }
+ }
+
+ if (prev_rep.interval != cur_rep.interval) {
+ unsigned int min_interval;
+
+ if (cur_rep.interval == 0)
+ min_interval = POLL_MAX_HZ_MS;
+ else
+ min_interval = cur_rep.interval;
+
+ if (!cmd_channel->cmd_set_interval(min_interval)) {
+ ERR("Sending cmd_set_interval(%d, %s, %d) failed for %s", client_id, get_sensor_name(sensor), min_interval, get_client_name());
+ return CMD_ERROR;
+ }
+ }
+
+ if (!add_event_types.empty()) {
+ if (!cmd_channel->cmd_register_events(add_event_types)) {
+ ERR("Sending cmd_register_events(%d, add_event_types) failed for %s", client_id, get_client_name());
+ return CMD_ERROR;
+ }
+ }
+ }
+
+ if (prev_rep.active && !del_event_types.empty()) {
+ if (!cmd_channel->cmd_unregister_events(del_event_types)) {
+ ERR("Sending cmd_unregister_events(%d, del_event_types) failed for %s", client_id, get_client_name());
+ return CMD_ERROR;
+ }
+ }
+
+ if (prev_rep.active != cur_rep.active) {
+ if (cur_rep.active) {
+ if (!cmd_channel->cmd_start()) {
+ ERR("Sending cmd_start(%d, %s) failed for %s", client_id, get_sensor_name(sensor), get_client_name());
+ return CMD_ERROR;
+ }
+ } else {
+ if (!cmd_channel->cmd_unset_interval()) {
+ ERR("Sending cmd_unset_interval(%d, %s) failed for %s", client_id, get_sensor_name(sensor), get_client_name());
+ return CMD_ERROR;
+ }
+
+ if (!cmd_channel->cmd_stop()) {
+ ERR("Sending cmd_stop(%d, %s) failed for %s", client_id, get_sensor_name(sensor), get_client_name());
+ return CMD_ERROR;
+ }
+ }
+ }
+
+ return OP_SUCCESS;
+}
+
+EXTAPI int sf_connect(sensor_type_t sensor)
+{
+ command_channel *cmd_channel = NULL;
+ int handle;
+ int client_id;
+ bool sensor_registered;
+ bool first_connection = false;
+
+ AUTOLOCK(lock);
+
+ sensor_registered = event_listener.is_sensor_registered(sensor);
+ handle = event_listener.create_handle(sensor);
+
+ if (handle == MAX_HANDLE) {
+ ERR("Maximum number of handles reached, sensor: %s in client %s", get_sensor_name(sensor), get_client_name());
+ return OP_ERROR;
+ }
+
+ if (!sensor_registered) {
+ cmd_channel = new command_channel();
+
+ if (!cmd_channel->create_channel()) {
+ ERR("%s failed to create command channel for %s", get_client_name(), get_sensor_name(sensor));
+ event_listener.delete_handle(handle);
+ delete cmd_channel;
+ return OP_ERROR;
+ }
+
+ event_listener.set_command_channel(sensor, cmd_channel);
+ }
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("%s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ event_listener.delete_handle(handle);
+ return OP_ERROR;
+ }
+
+ if (!event_listener.has_client_id()) {
+ first_connection = true;
+
+ if (!cmd_channel->cmd_get_id(client_id)) {
+ ERR("Sending cmd_get_id() failed for %s", get_sensor_name(sensor));
+ event_listener.close_command_channel(sensor);
+ event_listener.delete_handle(handle);
+ return CMD_ERROR;
+ }
+
+ event_listener.set_client_id(client_id);
+ INFO("%s gets client_id [%d]", get_client_name(), client_id);
+ event_listener.start_event_listener();
+ INFO("%s starts listening events with client_id [%d]", get_client_name(), client_id);
+ }
+
+ client_id = event_listener.get_client_id();
+ cmd_channel->set_client_id(client_id);
+
+ INFO("%s[%d] connects with %s[%d]", get_client_name(), client_id, get_sensor_name(sensor), handle);
+ event_listener.set_sensor_params(handle, SENSOR_STATE_STOPPED, SENSOR_OPTION_DEFAULT);
+
+ if (!sensor_registered) {
+ if (!cmd_channel->cmd_hello(sensor)) {
+ ERR("Sending cmd_hello(%s, %d) failed for %s", get_sensor_name(sensor), client_id, get_client_name());
+ event_listener.close_command_channel(sensor);
+ event_listener.delete_handle(handle);
+
+ if (first_connection)
+ event_listener.stop_event_listener();
+
+ return CMD_ERROR;
+ }
+ }
+
+ set_power_save_state_cb();
+ return handle;
+}
+
+EXTAPI int sf_disconnect(int handle)
+{
+ command_channel *cmd_channel;
+ sensor_type_t sensor;
+ int client_id;
+ int sensor_state;
+
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_state(handle, sensor_state) ||
+ !event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+ INFO("%s disconnects with %s[%d]", get_client_name(), get_sensor_name(sensor), handle);
+
+ if (sensor_state != SENSOR_STATE_STOPPED) {
+ WARN("Before disconnecting, sensor %s[%d] is forced to stop in client %s",
+ get_sensor_name(sensor), handle, get_client_name());
+ sf_stop(handle);
+ }
+
+ if (!event_listener.delete_handle(handle))
+ return OP_ERROR;
+
+ if (!event_listener.is_sensor_registered(sensor)) {
+ if (!cmd_channel->cmd_byebye()) {
+ ERR("Sending cmd_byebye(%d, %s) failed for %s", client_id, get_sensor_name(sensor), get_client_name());
+ return CMD_ERROR;
+ }
+
+ event_listener.close_command_channel(sensor);
+ }
+
+ if (!event_listener.is_active()) {
+ INFO("Stop listening events for client %s with client id [%d]", get_client_name(), event_listener.get_client_id());
+ event_listener.stop_event_listener();
+ }
+
+ unset_power_save_state_cb();
+
+ return OP_SUCCESS;
+}
+
+EXTAPI int sf_start(int handle, int option)
+{
+ sensor_type_t sensor;
+ sensor_rep prev_rep, cur_rep;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ retvm_if ((option < 0) || (option >= SENSOR_OPTION_END), OP_ERROR, "Invalid option value : %d, handle: %d, %s, %s",
+ option, handle, get_sensor_name(sensor), get_client_name());
+ INFO("%s starts %s[%d], with option: %d%s", get_client_name(), get_sensor_name(sensor),
+ handle, option, g_power_save_state ? " in power save state" : "");
+
+ if (g_power_save_state && (option != SENSOR_OPTION_ALWAYS_ON)) {
+ event_listener.set_sensor_params(handle, SENSOR_STATE_PAUSED, option);
+ return OP_SUCCESS;
+ }
+
+ event_listener.get_sensor_rep(sensor, prev_rep);
+ event_listener.set_sensor_params(handle, SENSOR_STATE_STARTED, option);
+ event_listener.get_sensor_rep(sensor, cur_rep);
+
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+EXTAPI int sf_stop(int handle)
+{
+ sensor_type_t sensor;
+ int sensor_state;
+ sensor_rep prev_rep, cur_rep;
+
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_state(handle, sensor_state) ||
+ !event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ retvm_if ((sensor_state == SENSOR_STATE_STOPPED), OP_SUCCESS, "%s already stopped with %s[%d]",
+ get_client_name(), get_sensor_name(sensor), handle);
+
+ INFO("%s stops sensor %s[%d]", get_client_name(), get_sensor_name(sensor), handle);
+
+ event_listener.get_sensor_rep(sensor, prev_rep);
+ event_listener.set_sensor_state(handle, SENSOR_STATE_STOPPED);
+ event_listener.get_sensor_rep(sensor, cur_rep);
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+EXTAPI int sf_register_event(int handle, unsigned int event_type, event_condition_t *event_condition, sensor_callback_func_t cb, void *cb_data )
+{
+ sensor_type_t sensor;
+ unsigned int interval = BASE_GATHERING_INTERVAL;
+ sensor_rep prev_rep, cur_rep;
+ retvm_if ((cb == NULL), OP_ERROR, "callback is NULL");
+
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (event_condition != NULL) {
+ if ((event_condition->cond_op == CONDITION_EQUAL) && (event_condition->cond_value1 > 0))
+ interval = event_condition->cond_value1;
+ }
+
+ INFO("%s registers event %s[0x%x] for sensor %s[%d] with interval: %d, cb: 0x%x, cb_data: 0x%x", get_client_name(), get_event_name(event_type),
+ event_type, get_sensor_name(sensor), handle, interval, cb, cb_data);
+
+ event_listener.get_sensor_rep(sensor, prev_rep);
+ event_listener.register_event(handle, event_type, interval, cb, cb_data);
+ event_listener.get_sensor_rep(sensor, cur_rep);
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+EXTAPI int sf_unregister_event(int handle, unsigned int event_type)
+{
+ sensor_type_t sensor;
+ sensor_rep prev_rep, cur_rep;
+
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ INFO("%s unregisters event %s[0x%x] for sensor %s[%d]", get_client_name(), get_event_name(event_type),
+ event_type, get_sensor_name(sensor), handle);
+
+ event_listener.get_sensor_rep(sensor, prev_rep);
+
+ if (!event_listener.unregister_event(handle, event_type)) {
+ ERR("%s try to unregister non registered event %s[0x%x] for sensor %s[%d]",
+ get_client_name(), get_event_name(event_type), event_type, get_sensor_name(sensor), handle);
+ return OP_ERROR;
+ }
+
+ event_listener.get_sensor_rep(sensor, cur_rep);
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+EXTAPI int sf_change_event_condition(int handle, unsigned int event_type, event_condition_t *event_condition)
+{
+ sensor_type_t sensor;
+ sensor_rep prev_rep, cur_rep;
+ unsigned int interval = BASE_GATHERING_INTERVAL;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (event_condition != NULL) {
+ if ((event_condition->cond_op == CONDITION_EQUAL) && (event_condition->cond_value1 > 0))
+ interval = event_condition->cond_value1;
+ }
+
+ INFO("%s changes interval of event %s[0x%x] for %s[%d] to interval %d", get_client_name(), get_event_name(event_type),
+ event_type, get_sensor_name(sensor), handle, interval);
+ event_listener.get_sensor_rep(sensor, prev_rep);
+ event_listener.set_event_interval(handle, event_type, interval);
+ event_listener.get_sensor_rep(sensor, cur_rep);
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+int sf_change_sensor_option(int handle, int option)
+{
+ sensor_type_t sensor;
+ sensor_rep prev_rep, cur_rep;
+ int sensor_state;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_state(handle, sensor_state) ||
+ !event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ retvm_if ((option < 0) || (option >= SENSOR_OPTION_END), OP_ERROR, "Invalid option value : %d, handle: %d, %s, %s",
+ option, handle, get_sensor_name(sensor), get_client_name());
+ event_listener.get_sensor_rep(sensor, prev_rep);
+
+ if (g_power_save_state) {
+ if ((option == SENSOR_OPTION_ALWAYS_ON) && (sensor_state == SENSOR_STATE_PAUSED))
+ event_listener.set_sensor_state(handle, SENSOR_STATE_STARTED);
+ else if ((option == SENSOR_OPTION_DEFAULT) && (sensor_state == SENSOR_STATE_STARTED))
+ event_listener.set_sensor_state(handle, SENSOR_STATE_PAUSED);
+ }
+
+ event_listener.set_sensor_option(handle, option);
+ event_listener.get_sensor_rep(sensor, cur_rep);
+ return change_sensor_rep(sensor, prev_rep, cur_rep);
+}
+
+EXTAPI int sf_send_sensorhub_data(int handle, const char *data, int data_len)
+{
+ sensor_type_t sensor;
+ command_channel *cmd_channel;
+ int client_id;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ retvm_if (sensor != CONTEXT_SENSOR, OP_ERROR, "%s use this API wrongly, only for CONTEXT_SENSOR not for %s",
+ get_client_name(), get_sensor_name(sensor));
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ retvm_if((data_len < 0) || (data == NULL), OP_ERROR, "Invalid data_len: %d, data: 0x%x, handle: %d, %s, %s",
+ data_len, data, handle, get_sensor_name(sensor), get_client_name());
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+ retvm_if (!event_listener.is_sensor_active(sensor), OP_ERROR, "%s with client_id:%d is not active state for %s with handle: %d",
+ get_sensor_name(sensor), client_id, get_client_name(), handle);
+
+ if (!cmd_channel->cmd_send_sensorhub_data(data_len, data)) {
+ ERR("Sending cmd_send_sensorhub_data(%d, %d, 0x%x) failed for %s",
+ client_id, data_len, data, get_client_name);
+ return CMD_ERROR;
+ }
+
+ return OP_SUCCESS;
+}
+
+EXTAPI int sf_is_sensor_event_available (sensor_type_t sensor, unsigned int event)
+{
+ command_channel *cmd_channel;
+ int handle;
+ int client_id;
+ handle = sf_connect(sensor);
+
+ if (handle < 0) {
+ return OP_ERROR;
+ }
+
+ if (event != 0) {
+ AUTOLOCK(lock);
+ INFO("%s checks if event %s[0x%x] is registered", get_client_name(), get_event_name(event), event);
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+
+ if (!cmd_channel->cmd_check_event(event)) {
+ INFO("Sensor event %s is not supported in sensor %s", get_event_name(event), get_sensor_name(sensor));
+ return CMD_ERROR;
+ }
+ }
+
+ sf_disconnect(handle);
+ return OP_SUCCESS;
+}
+
+static int server_get_properties(int handle, unsigned int type, void *properties)
+{
+ command_channel *cmd_channel;
+ sensor_type_t sensor;
+ int client_id;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+ INFO("%s gets property with %s[%d], property_id: %d", get_client_name(), get_sensor_name(sensor), handle, type);
+
+ if (!cmd_channel->cmd_get_properties(type, properties)) {
+ ERR("Sending cmd_get_properties(%d, %s, %d, 0x%x) failed for %s", client_id, get_sensor_name(sensor), type, properties, get_client_name());
+ return CMD_ERROR;
+ }
+
+ return OP_SUCCESS;
+}
+
+static int server_set_property(int handle, unsigned int property_id, long value)
+{
+ command_channel *cmd_channel;
+ sensor_type_t sensor;
+ int client_id;
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+ INFO("%s gets property with %s[%d], property_id: %d", get_client_name(), get_sensor_name(sensor), handle, property_id);
+
+ if (!cmd_channel->cmd_set_command(property_id, value)) {
+ ERR("Cmd_set_value(%d, %s, %d, %d) failed for %s", client_id, get_sensor_name(sensor), property_id, value, get_client_name());
+ return CMD_ERROR;
+ }
+
+ return OP_SUCCESS;
+}
+
+EXTAPI int sf_get_data_properties(unsigned int data_id, sensor_data_properties_t *return_data_properties)
+{
+ int handle;
+ int state = -1;
+ retvm_if ((!return_data_properties ), -1, "Invalid return properties pointer : %p from %s",
+ return_data_properties, get_client_name());
+ handle = sf_connect((sensor_type_t)(data_id >> 16));
+
+ if (handle < 0) {
+ ERR("Sensor connect fail !! for : %x", (data_id >> 16));
+ return OP_ERROR;
+ } else {
+ state = server_get_properties(handle, data_id, return_data_properties );
+
+ if (state < 0)
+ ERR("server_get_properties fail, state : %d", state);
+
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+static unsigned int get_sensor_property_level(sensor_type_t sensor)
+{
+ return (sensor << SENSOR_TYPE_SHIFT) | 0x0001;
+}
+
+EXTAPI int sf_get_properties(sensor_type_t sensor, sensor_properties_t *return_properties)
+{
+ int handle;
+ int state = -1;
+ retvm_if ((!return_properties ), -1, "Invalid return properties pointer : %p from %s",
+ return_properties, get_client_name());
+ handle = sf_connect(sensor);
+
+ if (handle < 0) {
+ ERR("Sensor connect fail !! for : %x", sensor);
+ return OP_ERROR;
+ } else {
+ state = server_get_properties(handle, get_sensor_property_level(sensor), return_properties );
+
+ if (state < 0)
+ ERR("server_get_properties fail, state : %d", state);
+
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+EXTAPI int sf_set_property(sensor_type_t sensor, unsigned int property_id, long value)
+{
+ int handle;
+ int state = -1;
+ handle = sf_connect(sensor);
+
+ if (handle < 0) {
+ ERR("Sensor connect fail !! for : %x", sensor);
+ return OP_ERROR;
+ } else {
+ state = server_set_property(handle, property_id, value );
+
+ if (state < 0)
+ ERR("server_set_property fail, state : %d", state);
+
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+EXTAPI int sf_get_data(int handle, unsigned int data_id, sensor_data_t *sensor_data)
+{
+ sensor_type_t sensor;
+ command_channel *cmd_channel;
+ int sensor_state;
+ int client_id;
+ retvm_if ((!sensor_data), OP_ERROR, "sf_get_data fail, invalid get_values pointer %p", sensor_data);
+ AUTOLOCK(lock);
+
+ if (!event_listener.get_sensor_state(handle, sensor_state) ||
+ !event_listener.get_sensor_type(handle, sensor)) {
+ ERR("client %s failed to get handle information", get_client_name());
+ return OP_ERROR;
+ }
+
+ if (!event_listener.get_command_channel(sensor, &cmd_channel)) {
+ ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor));
+ return OP_ERROR;
+ }
+
+ client_id = event_listener.get_client_id();
+ retvm_if ((client_id < 0), OP_ERROR, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor), get_client_name());
+
+ if (sensor_state != SENSOR_STATE_STARTED) {
+ ERR("Sensor %s is not started for client %s with handle: %d, sensor_state: %d", get_sensor_name(sensor), get_client_name(), handle, sensor_state);
+ return OP_ERROR;
+ }
+
+ if (!cmd_channel->cmd_get_data(data_id, sensor_data)) {
+ ERR("Cmd_get_struct(%d, %d, 0x%x) failed for %s", client_id, data_id, sensor_data, get_client_name());
+ return CMD_ERROR;
+ }
+
+ return OP_SUCCESS;
+}
+
+EXTAPI int sf_check_rotation(unsigned long *curr_state)
+{
+ int state = -1;
+ int handle = 0;
+ sensor_data_t sensor_data;
+ retvm_if (curr_state == NULL, -1, "sf_check_rotation fail, invalid curr_state");
+ *curr_state = ROTATION_UNKNOWN;
+
+ handle = sf_connect(ACCELEROMETER_SENSOR);
+
+ if (handle < 0) {
+ ERR("sensor attach fail");
+ return OP_ERROR;
+ }
+
+ state = sf_start(handle, 1);
+
+ if (state < 0) {
+ ERR("sf_start fail");
+ return OP_ERROR;
+ }
+
+ state = sf_get_data(handle, ACCELEROMETER_ROTATION_DATA_SET, &sensor_data);
+
+ if (state < 0) {
+ ERR("sf_get_data fail");
+ return OP_ERROR;
+ }
+
+ state = sf_stop(handle);
+
+ if (state < 0) {
+ ERR("sf_stop fail");
+ return OP_ERROR;
+ }
+
+ state = sf_disconnect(handle);
+
+ if (state < 0) {
+ ERR("sf_disconnect fail");
+ return OP_ERROR;
+ }
+
+ *curr_state = sensor_data.values[0];
+
+ INFO("%s gets %s by checking rotation", get_client_name(), get_rotate_name(*curr_state));
+ return OP_SUCCESS;
+}
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 <client_common.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <map>
+
+using std::map;
+
+#define FILL_LOG_ELEMENT(ID, TYPE, CNT, PRINT_PER_CNT) {ID, TYPE, {#TYPE, CNT, PRINT_PER_CNT} }
+
+log_element g_log_elements[] = {
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, UNKNOWN_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, ACCELEROMETER_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GEOMAGNETIC_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, LIGHT_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, PROXIMITY_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GYROSCOPE_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, MOTION_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GRAVITY_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, LINEAR_ACCEL_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, ORIENTATION_SENSOR, 0, 1),
+
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_ROTATION_CHECK, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_CALIBRATION_NEEDED, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_SET_WAKEUP, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_EVENT_CALIBRATION_NEEDED, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_CHANGE_STATE, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, LIGHT_EVENT_CHANGE_LEVEL, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, MOTION_ENGINE_EVENT_SNAP, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, MOTION_ENGINE_EVENT_SHAKE, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, MOTION_ENGINE_EVENT_DOUBLETAP, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, MOTION_ENGINE_EVENT_DIRECT_CALL, 0, 1),
+
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_STATE_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
+
+ FILL_LOG_ELEMENT(LOG_ID_DATA, ACCELEROMETER_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, ACCELEROMETER_ORIENTATION_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, ACCELEROMETER_ROTATION_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, GYRO_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, PROXIMITY_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, PROXIMITY_DISTANCE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, GEOMAGNETIC_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, GEOMAGNETIC_RAW_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, GEOMAGNETIC_ATTITUDE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, LIGHT_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, LIGHT_LUX_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, GRAVITY_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, LINEAR_ACCEL_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, ORIENTATION_BASE_DATA_SET, 0, 25),
+
+ FILL_LOG_ELEMENT(LOG_ID_ROTATE, ROTATION_EVENT_0, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_ROTATE, ROTATION_EVENT_90, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_ROTATE, ROTATION_EVENT_180, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_ROTATE, ROTATION_EVENT_270, 0, 1),
+};
+
+typedef map<unsigned int, log_attr *> log_map;
+log_map g_log_maps[LOG_ID_END];
+
+extern void init_client(void);
+static void init_log_maps(void);
+
+class initiator
+{
+public:
+ initiator()
+ {
+ init_log_maps();
+ init_client();
+ }
+} g_initiatior;
+
+static void init_log_maps(void)
+{
+ int cnt;
+ cnt = sizeof(g_log_elements) / sizeof(g_log_elements[0]);
+
+ for (int i = 0; i < cnt; ++i) {
+ g_log_maps[g_log_elements[i].id][g_log_elements[i].type] = &g_log_elements[i].log_attr;
+ }
+}
+
+const char *get_log_element_name(log_id id, unsigned int type)
+{
+ const char *p_unknown = "UNKNOWN";
+ log_map::iterator iter;
+ iter = g_log_maps[id].find(type);
+
+ if (iter == g_log_maps[id].end()) {
+ INFO("Unknown type value: 0x%x", type);
+ return p_unknown;
+ }
+
+ return iter->second->name;
+}
+
+const char *get_sensor_name(sensor_type_t sensor_type)
+{
+ return get_log_element_name(LOG_ID_SENSOR_TYPE, sensor_type);
+}
+
+const char *get_event_name(unsigned int event_type)
+{
+ return get_log_element_name(LOG_ID_EVENT, event_type);
+}
+
+const char *get_data_name(unsigned int data_id)
+{
+ return get_log_element_name(LOG_ID_DATA, data_id);
+}
+
+const char *get_rotate_name(unsigned int rotate_type)
+{
+ return get_log_element_name(LOG_ID_ROTATE, rotate_type);
+}
+
+bool is_one_shot_event(unsigned int event_type)
+{
+ switch (event_type) {
+ case ACCELEROMETER_EVENT_SET_WAKEUP:
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+bool is_ontime_event(unsigned int event_type)
+{
+ switch (event_type ) {
+ case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
+ case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME:
+ case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME:
+ case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME:
+ case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME:
+ case LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME:
+ case PROXIMITY_EVENT_STATE_REPORT_ON_TIME:
+ case PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME:
+ case GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME:
+ case LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME:
+ case ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME:
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+bool is_panning_event(unsigned int event_type)
+{
+ return false;
+}
+
+bool is_single_state_event(unsigned int event_type)
+{
+ switch (event_type) {
+ case ACCELEROMETER_EVENT_SET_WAKEUP:
+ case ACCELEROMETER_EVENT_ROTATION_CHECK:
+ case GEOMAGNETIC_EVENT_CALIBRATION_NEEDED:
+ case LIGHT_EVENT_CHANGE_LEVEL:
+ case PROXIMITY_EVENT_CHANGE_STATE:
+ case MOTION_ENGINE_EVENT_SNAP:
+ case MOTION_ENGINE_EVENT_SHAKE:
+ case MOTION_ENGINE_EVENT_DOUBLETAP:
+ case MOTION_ENGINE_EVENT_DIRECT_CALL:
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+unsigned int get_calibration_event_type(unsigned int event_type)
+{
+ sensor_type_t sensor;
+ sensor = (sensor_type_t)(event_type >> SENSOR_TYPE_SHIFT);
+
+ switch (sensor) {
+ case GEOMAGNETIC_SENSOR:
+ return GEOMAGNETIC_EVENT_CALIBRATION_NEEDED;
+ case ORIENTATION_SENSOR:
+ return ORIENTATION_EVENT_CALIBRATION_NEEDED;
+ default:
+ return 0;
+ }
+}
+
+unsigned long long get_timestamp(void)
+{
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return ((unsigned long long)(t.tv_sec) * NS_TO_SEC + t.tv_nsec) / MS_TO_SEC;
+}
+
+void sensor_event_to_data(sensor_event_t &event, sensor_data_t &data)
+{
+ data.data_accuracy = event.data.data_accuracy;
+ data.data_unit_idx = event.data.data_unit_idx;
+ data.timestamp = event.data.timestamp;
+ data.values_num = event.data.values_num;
+ memcpy(data.values, event.data.values, sizeof(event.data.values));
+}
+
+void sensorhub_event_to_hub_data(sensorhub_event_t &event, sensorhub_data_t &data)
+{
+ data.version = event.data.version;
+ data.sensorhub = event.data.sensorhub;
+ data.type = event.data.type;
+ data.hub_data_size = event.data.hub_data_size;
+ data.timestamp = event.data.timestamp;
+ memcpy(data.hub_data, event.data.hub_data, event.data.hub_data_size);
+ memcpy(data.data, event.data.data, sizeof(event.data.data));
+}
+
+void print_event_occurrence_log(csensor_handle_info &sensor_handle_info, creg_event_info &event_info,
+ sensor_event_data_t &sensor_event_data)
+{
+ log_attr *log_attr;
+ log_map::iterator iter;
+ iter = g_log_maps[LOG_ID_EVENT].find(event_info.m_event_type);
+
+ if (iter == g_log_maps[LOG_ID_EVENT].end()) {
+ ERR("wrong event_type: 0x%x, handle %d", event_info.m_event_type, sensor_handle_info.m_handle);
+ return;
+ }
+
+ log_attr = iter->second;
+ log_attr->cnt++;
+
+ if ((log_attr->cnt != 1) && ((log_attr->cnt % log_attr->print_per_cnt) != 0)) {
+ return;
+ }
+
+ INFO("%s receives %s with %s[%d][state: %d, option: %d count: %d]", get_client_name(), log_attr->name,
+ get_sensor_name(sensor_handle_info.m_sensor_type), sensor_handle_info.m_handle, sensor_handle_info.m_sensor_state,
+ sensor_handle_info.m_sensor_option, log_attr->cnt);
+
+ if (event_info.m_event_type == ACCELEROMETER_EVENT_ROTATION_CHECK) {
+ INFO("%s", get_rotate_name(*(unsigned int *)(sensor_event_data.event_data)));
+ }
+
+ INFO("0x%x(cb_event_type = %s, &cb_data, client_data = 0x%x)", event_info.m_event_callback,
+ log_attr->name, event_info.m_cb_data);
+}
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 CLIENT_COMMON_H_
+#define CLIENT_COMMON_H_
+
+#include <sensor.h>
+#include <csensor_handle_info.h>
+#include <creg_event_info.h>
+#include <common.h>
+
+#define BASE_GATHERING_INTERVAL 100
+#define CLIENT_NAME_SIZE NAME_MAX+10
+
+enum log_id {
+ LOG_ID_START = 0,
+ LOG_ID_SENSOR_TYPE = 0,
+ LOG_ID_EVENT,
+ LOG_ID_DATA,
+ LOG_ID_PROPERTY,
+ LOG_ID_ROTATE,
+ LOG_ID_END,
+};
+
+struct log_attr {
+ const char *name;
+ unsigned long cnt;
+ const unsigned int print_per_cnt;
+};
+
+struct log_element {
+ log_id id;
+ unsigned int type;
+ struct log_attr log_attr;
+};
+
+typedef struct {
+ int handle;
+ unsigned int event_type;
+ sensor_event_data_t ev_data;
+ int sensor_state;
+ int sensor_option;
+ sensor_type_t sensor;
+ creg_event_info event_info;
+} log_info;
+
+bool is_sensorhub_event(unsigned int event_type);
+bool is_one_shot_event(unsigned int event_type);
+bool is_ontime_event(unsigned int event_type);
+bool is_panning_event(unsigned int event_type);
+bool is_single_state_event(unsigned int event_type);
+unsigned int get_calibration_event_type(unsigned int event_type);
+unsigned long long get_timestamp(void);
+void sensor_event_to_data(sensor_event_t &event, sensor_data_t &data);
+void sensorhub_event_to_hub_data(sensorhub_event_t &event, sensorhub_data_t &data);
+
+const char *get_log_element_name(log_id id, unsigned int type);
+const char *get_sensor_name(sensor_type_t sensor_type);
+const char *get_event_name(unsigned int event_type);
+const char *get_data_name(unsigned int data_id);
+const char *get_rotate_name(unsigned int rotate_type);
+void print_event_occurrence_log(csensor_handle_info &sensor_handle_info,
+ creg_event_info &event_info,
+ sensor_event_data_t &event_data);
+
+#endif /* CLIENT_COMMON_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 <command_channel.h>
+#include <client_common.h>
+#include <sf_common.h>
+
+command_channel::command_channel()
+: m_client_id(CLIENT_ID_INVALID)
+, m_sensor_type(UNKNOWN_SENSOR)
+{
+}
+
+command_channel::~command_channel()
+{
+ if (m_command_socket.is_valid())
+ m_command_socket.close();
+}
+
+bool command_channel::command_handler(cpacket *packet, void **return_payload)
+{
+ if (!m_command_socket.is_valid()) {
+ ERR("Command socket(%d) is not valid for client %s", m_command_socket.get_socket_fd(), get_client_name());
+ return false;
+ }
+
+ if (packet->size() < 0) {
+ ERR("Packet is not valid for client %s", get_client_name());
+ return false;
+ }
+
+ if (m_command_socket.send(packet->packet(), packet->size()) <= 0) {
+ ERR("Failed to send command in client %s", get_client_name());
+ return false;
+ }
+
+ packet_header header;
+
+ if (m_command_socket.recv(&header, sizeof(header)) <= 0) {
+ ERR("Failed to receive header for reply packet in client %s", get_client_name());
+ return false;
+ }
+
+ char *buffer = new char[header.size];
+
+ if (m_command_socket.recv(buffer, header.size) <= 0) {
+ ERR("Failed to receive reply packet in client %s", get_client_name());
+ delete[] buffer;
+ return false;
+ }
+
+ *return_payload = buffer;
+ return true;
+}
+
+bool command_channel::create_channel(void)
+{
+ if (!m_command_socket.create(SOCK_STREAM))
+ return false;
+
+ if (!m_command_socket.connect(COMMAND_CHANNEL_PATH)) {
+ ERR("Failed to connect command channel for client %s, command socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd());
+ return false;
+ }
+
+ m_command_socket.set_connection_mode();
+ return true;
+}
+
+void command_channel::set_client_id(int client_id)
+{
+ m_client_id = client_id;
+}
+
+bool command_channel::cmd_get_id(int &client_id)
+{
+ cpacket *packet;
+ cmd_get_id_t *cmd_get_id;
+ cmd_get_id_done_t *cmd_get_id_done;
+
+ packet = new cpacket(sizeof(cmd_get_id_t));
+ packet->set_cmd(CMD_GET_ID);
+ packet->set_payload_size(sizeof(cmd_get_id_t));
+ cmd_get_id = (cmd_get_id_t *)packet->data();
+ cmd_get_id->pid = getpid();
+
+ INFO("%s send cmd_get_id()", get_client_name());
+
+ if (!command_handler(packet, (void **)&cmd_get_id_done)) {
+ ERR("Client %s failed to send/receive command", get_client_name());
+ delete packet;
+ return false;
+ }
+
+ if (cmd_get_id_done->client_id < 0) {
+ ERR("Client %s failed to get client_id[%d] from server",
+ get_client_name(), cmd_get_id_done->client_id);
+ delete[] (char *)cmd_get_id_done;
+ delete packet;
+ return false;
+ }
+
+ client_id = cmd_get_id_done->client_id;
+
+ delete[] (char *)cmd_get_id_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_hello(sensor_type_t sensor)
+{
+ cpacket *packet;
+ cmd_hello_t *cmd_hello;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_hello_t));
+ packet->set_cmd(CMD_HELLO);
+ packet->set_payload_size(sizeof(cmd_hello_t));
+ cmd_hello = (cmd_hello_t *)packet->data();
+ cmd_hello->client_id = m_client_id;
+ cmd_hello->sensor = sensor;
+
+ INFO("%s send cmd_hello(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_sensor_name(sensor));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s]",
+ get_client_name(), get_sensor_name(sensor));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("client %s got error[%d] from server with sensor [%s]",
+ get_client_name(), cmd_done->value, get_sensor_name(sensor));
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ m_sensor_type = sensor;
+ return true;
+}
+
+bool command_channel::cmd_byebye(void)
+{
+ cpacket *packet;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_byebye_t));
+ packet->set_cmd(CMD_BYEBYE);
+ packet->set_payload_size(sizeof(cmd_byebye_t));
+
+ INFO("%s send cmd_byebye(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+
+ if (m_command_socket.is_valid())
+ m_command_socket.close();
+
+ m_client_id = CLIENT_ID_INVALID;
+ m_sensor_type = UNKNOWN_SENSOR;
+ return true;
+}
+
+bool command_channel::cmd_start(void)
+{
+ cpacket *packet;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_start_t));
+ packet->set_cmd(CMD_START);
+ packet->set_payload_size(sizeof(cmd_start_t));
+
+ INFO("%s send cmd_start(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_stop(void)
+{
+ cpacket *packet;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_stop_t));
+ packet->set_cmd(CMD_STOP);
+ packet->set_payload_size(sizeof(cmd_stop_t));
+
+ INFO("%s send cmd_stop(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_set_option(int option)
+{
+ cpacket *packet;
+ cmd_set_option_t *cmd_set_option;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_set_option_t));
+ packet->set_cmd(CMD_SET_OPTION);
+ packet->set_payload_size(sizeof(cmd_set_option_t));
+ cmd_set_option = (cmd_set_option_t *)packet->data();
+ cmd_set_option->option = option;
+
+ INFO("%s send cmd_set_option(client_id=%d, %s, option=%d)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type), option);
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d], option[%]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id, option);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d], option[%]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id, option);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_register_event(unsigned int event_type)
+{
+ cpacket *packet;
+ cmd_reg_t *cmd_reg;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_reg_t));
+ packet->set_cmd(CMD_REG);
+ packet->set_payload_size(sizeof(cmd_reg_t));
+ cmd_reg = (cmd_reg_t *)packet->data();
+ cmd_reg->event_type = event_type;
+
+ INFO("%s send cmd_register_event(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_event_name(event_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command with client_id [%d], event_type[%s]",
+ get_client_name(), m_client_id, get_event_name(event_type));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server with client_id [%d], event_type[%s]",
+ get_client_name(), cmd_done->value, m_client_id, get_event_name(event_type));
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_register_events(event_type_vector &event_vec)
+{
+ event_type_vector::iterator it_event;
+ it_event = event_vec.begin();
+
+ while (it_event != event_vec.end()) {
+ if (!cmd_register_event(*it_event))
+ return false;
+
+ ++it_event;
+ }
+
+ return true;
+}
+
+bool command_channel::cmd_unregister_event(unsigned int event_type)
+{
+ cpacket *packet;
+ cmd_unreg_t *cmd_unreg;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_unreg_t));
+ packet->set_cmd(CMD_UNREG);
+ packet->set_payload_size(sizeof(cmd_unreg_t));
+ cmd_unreg = (cmd_unreg_t *)packet->data();
+ cmd_unreg->event_type = event_type;
+
+ INFO("%s send cmd_unregister_event(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_event_name(event_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command with client_id [%d], event_type[%s]",
+ get_client_name(), m_client_id, get_event_name(event_type));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server with client_id [%d], event_type[%s]",
+ get_client_name(), cmd_done->value, m_client_id, get_event_name(event_type));
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_unregister_events(event_type_vector &event_vec)
+{
+ event_type_vector::iterator it_event;
+ it_event = event_vec.begin();
+
+ while (it_event != event_vec.end()) {
+ if (!cmd_unregister_event(*it_event))
+ return false;
+
+ ++it_event;
+ }
+
+ return true;
+}
+
+bool command_channel::cmd_check_event(unsigned int event_type)
+{
+ cpacket *packet;
+ cmd_check_event_t *cmd_check_event;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_check_event_t));
+ packet->set_cmd(CMD_CHECK_EVENT);
+ packet->set_payload_size(sizeof(cmd_check_event_t));
+ cmd_check_event = (cmd_check_event_t *)packet->data();
+ cmd_check_event->event_type = event_type;
+
+ INFO("%s send cmd_check_event(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_event_name(event_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command with client_id [%d], event_type[%s]",
+ get_client_name(), m_client_id, get_event_name(event_type));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_set_interval(unsigned int interval)
+{
+ cpacket *packet;
+ cmd_set_interval_t *cmd_set_interval;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_set_interval_t));
+ packet->set_cmd(CMD_SET_INTERVAL);
+ packet->set_payload_size(sizeof(cmd_set_interval_t));
+ cmd_set_interval = (cmd_set_interval_t *)packet->data();
+ cmd_set_interval->interval = interval;
+
+ INFO("%s send cmd_set_interval(client_id=%d, %s, interval=%d)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type), interval);
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("%s failed to send/receive command for sensor[%s] with client_id [%d], interval[%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id, interval);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("%s got error[%d] from server for sensor[%s] with client_id [%d], interval[%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id, interval);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_unset_interval(void)
+{
+ cpacket *packet;
+ cmd_done_t *cmd_done;
+ packet = new cpacket(sizeof(cmd_unset_interval_t));
+ packet->set_cmd(CMD_UNSET_INTERVAL);
+ packet->set_payload_size(sizeof(cmd_unset_interval_t));
+
+ INFO("%s send cmd_unset_interval(client_id=%d, %s)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type));
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), m_client_id);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+static bool is_sensor_property(unsigned int type)
+{
+ return ((type & 0xFFFF) == 1);
+}
+
+bool command_channel::cmd_get_properties(unsigned int type, void *properties)
+{
+ cpacket *packet;
+ cmd_get_properties_t *cmd_get_properties;
+ cmd_properties_done_t *cmd_properties_done;
+
+ packet = new cpacket(sizeof(cmd_get_properties_t));
+ packet->set_cmd(CMD_GET_PROPERTIES);
+ packet->set_payload_size(sizeof(cmd_get_properties_t));
+ cmd_get_properties = (cmd_get_properties_t *)packet->data();
+ cmd_get_properties->type = type;
+
+ INFO("%s send cmd_get_properties(client_id=%d, %s, %s)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type), get_data_name(type));
+
+ if (!command_handler(packet, (void **)&cmd_properties_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d], data_id[%s]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id, get_data_name(type));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_properties_done->state < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with client_id [%d], data_id[%s]",
+ get_client_name(), cmd_properties_done->state, get_sensor_name(m_sensor_type), m_client_id, get_data_name(type));
+ delete[] (char *)cmd_properties_done;
+ delete packet;
+ return false;
+ }
+
+ sensor_properties_t *ret_properties;
+ ret_properties = &cmd_properties_done->properties;
+
+ if (is_sensor_property(type)) {
+ sensor_properties_t *sensor_properties;
+ sensor_properties = (sensor_properties_t *)properties;
+ sensor_properties->sensor_unit_idx = ret_properties->sensor_unit_idx;
+ sensor_properties->sensor_min_range = ret_properties->sensor_min_range;
+ sensor_properties->sensor_max_range = ret_properties->sensor_max_range;
+ sensor_properties->sensor_resolution = ret_properties->sensor_resolution;
+ strncpy(sensor_properties->sensor_name, ret_properties->sensor_name, strlen(ret_properties->sensor_name));
+ strncpy(sensor_properties->sensor_vendor, ret_properties->sensor_vendor, strlen(ret_properties->sensor_vendor));
+ } else {
+ sensor_data_properties_t *data_properies;
+ data_properies = (sensor_data_properties_t *)properties;
+ data_properies->sensor_unit_idx = ret_properties->sensor_unit_idx ;
+ data_properies->sensor_min_range = ret_properties->sensor_min_range;
+ data_properies->sensor_max_range = ret_properties->sensor_max_range;
+ data_properies->sensor_resolution = ret_properties->sensor_resolution;
+ }
+
+ delete[] (char *)cmd_properties_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_set_command(unsigned int cmd, long value)
+{
+ cpacket *packet;
+ cmd_set_command_t *cmd_set_command;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_set_command_t));
+ packet->set_cmd(CMD_SET_COMMAND);
+ packet->set_payload_size(sizeof(cmd_set_command_t));
+ cmd_set_command = (cmd_set_command_t *)packet->data();
+ cmd_set_command->cmd = cmd;
+ cmd_set_command->value = value;
+
+ INFO("%s send cmd_set_command(client_id=%d, %s, 0x%x, %ld)",
+ get_client_name(), m_client_id, get_sensor_name(m_sensor_type), cmd, value);
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("Client %s failed to send/receive command for sensor[%s] with client_id [%d], property[0x%x], value[%d]",
+ get_client_name(), get_sensor_name(m_sensor_type), m_client_id, cmd, value);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("Client %s got error[%d] from server for sensor[%s] with property[0x%x], value[%d]",
+ get_client_name(), cmd_done->value, get_sensor_name(m_sensor_type), cmd, value);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_get_data(unsigned int type, sensor_data_t *sensor_data)
+{
+ cpacket *packet;
+ cmd_get_data_t *cmd_get_data;
+ cmd_get_data_done_t *cmd_get_data_done;
+
+ packet = new cpacket(sizeof(cmd_get_data_done_t));
+ packet->set_cmd(CMD_GET_DATA);
+ packet->set_payload_size(sizeof(cmd_get_data_t));
+ cmd_get_data = (cmd_get_data_t *)packet->data();
+ cmd_get_data->type = type;
+
+ if (!command_handler(packet, (void **)&cmd_get_data_done)) {
+ ERR("Client %s failed to send/receive command with client_id [%d], data_id[%s]",
+ get_client_name(), m_client_id, get_data_name(type));
+ delete packet;
+ return false;
+ }
+
+ if (cmd_get_data_done->state < 0) {
+ ERR("Client %s got error[%d] from server with client_id [%d], data_id[%s]",
+ get_client_name(), cmd_get_data_done->state, m_client_id, get_data_name(type));
+ sensor_data->data_accuracy = SENSOR_ACCURACY_UNDEFINED;
+ sensor_data->data_unit_idx = SENSOR_UNDEFINED_UNIT;
+ sensor_data->timestamp = 0;
+ sensor_data->values_num = 0;
+
+ delete[] (char *)cmd_get_data_done;
+ delete packet;
+ return false;
+ }
+
+ sensor_data_t *base_data;
+ base_data = &cmd_get_data_done->base_data;
+ sensor_data->timestamp = base_data->timestamp;
+ sensor_data->data_accuracy = base_data->data_accuracy;
+ sensor_data->data_unit_idx = base_data->data_unit_idx;
+ sensor_data->values_num = base_data->values_num;
+ memcpy(sensor_data->values, base_data->values,
+ sizeof(sensor_data->values[0]) * base_data->values_num);
+
+ delete[] (char *)cmd_get_data_done;
+ delete packet;
+ return true;
+}
+
+bool command_channel::cmd_send_sensorhub_data(int data_len, const char *buffer)
+{
+ cpacket *packet;
+ cmd_send_sensorhub_data_t *cmd_send_sensorhub_data;
+ cmd_done_t *cmd_done;
+
+ packet = new cpacket(sizeof(cmd_send_sensorhub_data_t) + data_len);
+ packet->set_cmd(CMD_SEND_SENSORHUB_DATA);
+ cmd_send_sensorhub_data = (cmd_send_sensorhub_data_t *)packet->data();
+ cmd_send_sensorhub_data->data_len = data_len;
+ memcpy(cmd_send_sensorhub_data->data, buffer, data_len);
+
+ INFO("%s send cmd_send_sensorhub_data(client_id=%d, data_len = %d, buffer = 0x%x)",
+ get_client_name(), m_client_id, data_len, buffer);
+
+ if (!command_handler(packet, (void **)&cmd_done)) {
+ ERR("%s failed to send/receive command with client_id [%d]",
+ get_client_name(), m_client_id);
+ delete packet;
+ return false;
+ }
+
+ if (cmd_done->value < 0) {
+ ERR("%s got error[%d] from server with client_id [%d]",
+ get_client_name(), cmd_done->value, m_client_id);
+ delete[] (char *)cmd_done;
+ delete packet;
+ return false;
+ }
+
+ delete[] (char *)cmd_done;
+ delete packet;
+ return true;
+}
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 _COMMAND_CHANNEL_H_
+#define _COMMAND_CHANNEL_H_
+#include <sf_common.h>
+#include <sensor.h>
+#include <cpacket.h>
+#include <csocket.h>
+#include <vector>
+
+using std::vector;
+
+class command_channel
+{
+public:
+
+ command_channel();
+ ~command_channel();
+
+ bool create_channel(void);
+ void set_client_id(int client_id);
+
+ bool cmd_get_id(int &client_id);
+ bool cmd_hello(sensor_type_t sensor);
+ bool cmd_byebye(void);
+ bool cmd_start(void);
+ bool cmd_stop(void);
+ bool cmd_set_option(int option);
+ bool cmd_register_event(unsigned int event_type);
+ bool cmd_register_events(event_type_vector &event_vec);
+ bool cmd_unregister_event(unsigned int event_type);
+ bool cmd_unregister_events(event_type_vector &event_vec);
+ bool cmd_check_event(unsigned int event_type);
+ bool cmd_set_interval(unsigned int interval);
+ bool cmd_unset_interval(void);
+ bool cmd_get_properties(unsigned int type, void *properties);
+ bool cmd_set_command(unsigned int cmd, long value);
+ bool cmd_get_data(unsigned int type, sensor_data_t *values);
+ bool cmd_send_sensorhub_data(int data_len, const char *buffer);
+private:
+ csocket m_command_socket;
+ int m_client_id;
+ sensor_type_t m_sensor_type;
+ bool command_handler(cpacket *packet, void **return_payload);
+};
+
+#endif /* COMMAND_CHANNEL_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 CREG_EVENT_INFO_H_
+#define CREG_EVENT_INFO_H_
+
+#include <sensor.h>
+#include <sf_common.h>
+
+class creg_event_info
+{
+public:
+ unsigned long long m_id;
+ int m_handle;
+ unsigned int m_event_type;
+ unsigned int m_event_interval;
+ sensor_callback_func_t m_event_callback;
+ void *m_cb_data;
+ unsigned long long m_previous_event_time;
+ bool m_fired;
+
+ creg_event_info(): m_id(0), m_handle(-1),
+ m_event_type(0), m_event_interval(POLL_1HZ_MS),
+ m_event_callback(NULL), m_cb_data(NULL),
+ m_previous_event_time(0), m_fired(false) {}
+
+ ~creg_event_info() {}
+};
+
+#endif /* CREG_EVENT_INFO_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_event_listener.h>
+#include <client_common.h>
+#include <sf_common.h>
+#include <thread>
+#include <chrono>
+
+using std::thread;
+using std::pair;
+
+csensor_event_listener::csensor_event_listener()
+: m_client_id(CLIENT_ID_INVALID)
+, m_thread_state(THREAD_STATE_TERMINATE)
+, m_poller(NULL)
+{
+}
+
+csensor_event_listener::~csensor_event_listener()
+{
+ stop_event_listener();
+}
+
+int csensor_event_listener::create_handle(const sensor_type_t sensor)
+{
+ csensor_handle_info handle_info;
+ int handle = 0;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ while (m_sensor_handle_infos.count(handle) > 0)
+ handle++;
+
+ if (handle == MAX_HANDLE) {
+ ERR("Handles of client %s are full", get_client_name());
+ return MAX_HANDLE_REACHED;
+ }
+
+ handle_info.m_sensor_type = sensor;
+ handle_info.m_sensor_state = SENSOR_STATE_STOPPED;
+ handle_info.m_sensor_option = SENSOR_OPTION_DEFAULT;
+ handle_info.m_handle = handle;
+ m_sensor_handle_infos.insert(pair<int, csensor_handle_info> (handle, handle_info));
+ return handle;
+}
+
+bool csensor_event_listener::delete_handle(const int handle)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ m_sensor_handle_infos.erase(it_handle);
+ return true;
+}
+
+bool csensor_event_listener::is_active()
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ return !m_sensor_handle_infos.empty();
+}
+
+bool csensor_event_listener::start_handle(const int handle)
+{
+ return set_sensor_state(handle, SENSOR_STATE_STARTED);
+}
+
+bool csensor_event_listener::stop_handle(const int handle)
+{
+ return set_sensor_state(handle, SENSOR_STATE_STOPPED);
+}
+
+bool csensor_event_listener::register_event(const int handle, const unsigned int event_type,
+ const unsigned int interval, const sensor_callback_func_t callback, void *cb_data)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.add_reg_event_info(event_type, interval, callback, cb_data))
+ return false;
+
+ return true;
+}
+
+bool csensor_event_listener::unregister_event(const int handle, const unsigned int event_type)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.delete_reg_event_info(event_type))
+ return false;
+
+ return true;
+}
+
+bool csensor_event_listener::change_event_interval(const int handle, const unsigned int event_type,
+ const unsigned int interval)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.change_reg_event_interval(event_type, interval))
+ return false;
+
+ return true;
+}
+
+bool csensor_event_listener::set_sensor_params(const int handle, int sensor_state, int sensor_option)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_state = sensor_state;
+ it_handle->second.m_sensor_option = sensor_option;
+
+ return true;
+}
+
+bool csensor_event_listener::set_sensor_state(const int handle, const int sensor_state)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_state = sensor_state;
+
+ return true;
+}
+
+bool csensor_event_listener::set_sensor_option(const int handle, const int sensor_option)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_option = sensor_option;
+
+ return true;
+}
+
+bool csensor_event_listener::set_event_interval(const int handle, const unsigned int event_type, const unsigned int interval)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.change_reg_event_interval(event_type, interval))
+ return false;
+
+ return true;
+}
+
+void csensor_event_listener::get_listening_sensors(sensor_type_vector &sensors)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ sensors.push_back(it_handle->second.m_sensor_type);
+ ++it_handle;
+ }
+
+ sort(sensors.begin(), sensors.end());
+ unique(sensors.begin(), sensors.end());
+}
+
+void csensor_event_listener::get_sensor_rep(sensor_type_t sensor, sensor_rep &rep)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ rep.active = is_sensor_active(sensor);
+ rep.option = get_active_option(sensor);
+ rep.interval = get_active_min_interval(sensor);
+ get_active_event_types(sensor, rep.event_types);
+}
+
+void csensor_event_listener::pause_sensor(const sensor_type_t sensor)
+{
+ sensor_handle_info_map::iterator it_handle;
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED) &&
+ (it_handle->second.m_sensor_option != SENSOR_OPTION_ALWAYS_ON)) {
+ it_handle->second.m_sensor_state = SENSOR_STATE_PAUSED;
+ INFO("%s's %s[%d] is paused", get_client_name(), get_sensor_name(sensor), it_handle->first);
+ }
+
+ ++it_handle;
+ }
+}
+
+void csensor_event_listener::resume_sensor(const sensor_type_t sensor)
+{
+ sensor_handle_info_map::iterator it_handle;
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_PAUSED)) {
+ it_handle->second.m_sensor_state = SENSOR_STATE_STARTED;
+ INFO("%s's %s[%d] is resumed", get_client_name(), get_sensor_name(sensor), it_handle->first);
+ }
+
+ ++it_handle;
+ }
+}
+
+bool csensor_event_listener::set_command_channel(sensor_type_t sensor, command_channel *cmd_channel)
+{
+ sensor_command_channel_map::iterator it_channel;
+ it_channel = m_command_channels.find(sensor);
+
+ if (it_channel != m_command_channels.end()) {
+ ERR("%s alreay has command_channel for %s", get_client_name(), get_sensor_name(sensor));
+ return false;
+ }
+
+ m_command_channels.insert(pair<sensor_type_t, command_channel *> (sensor, cmd_channel));
+ return true;
+}
+
+bool csensor_event_listener::get_command_channel(sensor_type_t sensor, command_channel **cmd_channel)
+{
+ sensor_command_channel_map::iterator it_channel;
+ it_channel = m_command_channels.find(sensor);
+
+ if (it_channel == m_command_channels.end()) {
+ ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor));
+ return false;
+ }
+
+ *cmd_channel = it_channel->second;
+ return true;
+}
+
+bool csensor_event_listener::close_command_channel(sensor_type_t sensor)
+{
+ sensor_command_channel_map::iterator it_channel;
+ it_channel = m_command_channels.find(sensor);
+
+ if (it_channel == m_command_channels.end()) {
+ ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor));
+ return false;
+ }
+
+ delete it_channel->second;
+ m_command_channels.erase(it_channel);
+ return true;
+}
+
+bool csensor_event_listener::has_client_id(void)
+{
+ return (m_client_id != CLIENT_ID_INVALID);
+}
+
+int csensor_event_listener::get_client_id(void)
+{
+ return m_client_id;
+}
+
+void csensor_event_listener::set_client_id(const int client_id)
+{
+ m_client_id = client_id;
+}
+
+unsigned int csensor_event_listener::get_active_min_interval(const sensor_type_t sensor)
+{
+ unsigned int min_interval = POLL_MAX_HZ_MS;
+ bool active_sensor_found = false;
+ unsigned int interval;
+
+ AUTOLOCK(m_handle_info_lock);
+ sensor_handle_info_map::iterator it_handle;
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
+ active_sensor_found = true;
+ interval = it_handle->second.get_min_interval();
+ min_interval = (interval < min_interval) ? interval : min_interval;
+ }
+
+ ++it_handle;
+ }
+
+ if (!active_sensor_found)
+ DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
+
+ return (active_sensor_found) ? min_interval : 0;
+}
+
+unsigned int csensor_event_listener::get_active_option(const sensor_type_t sensor)
+{
+ int active_option = SENSOR_OPTION_DEFAULT;
+ bool active_sensor_found = false;
+ int option;
+ AUTOLOCK(m_handle_info_lock);
+ sensor_handle_info_map::iterator it_handle;
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
+ active_sensor_found = true;
+ option = it_handle->second.m_sensor_option;
+ active_option = (option > active_option) ? option : active_option;
+ }
+
+ ++it_handle;
+ }
+
+ if (!active_sensor_found)
+ DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
+
+ return active_option;
+}
+
+bool csensor_event_listener::get_sensor_type(const int handle, sensor_type_t &sensor)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor = it_handle->second.m_sensor_type;
+ return true;
+}
+
+bool csensor_event_listener::get_sensor_state(const int handle, int &sensor_state)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor_state = it_handle->second.m_sensor_state;
+ return true;
+}
+
+void csensor_event_listener::get_active_event_types(const sensor_type_t sensor,
+ event_type_vector &active_event_types)
+{
+ event_type_vector event_types;
+
+ AUTOLOCK(m_handle_info_lock);
+ sensor_handle_info_map::iterator it_handle;
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
+ it_handle->second.get_reg_event_types(event_types);
+
+ ++it_handle;
+ }
+
+ if (event_types.empty())
+ return;
+
+ sort(event_types.begin(), event_types.end());
+ unique_copy(event_types.begin(), event_types.end(), back_inserter(active_event_types));
+}
+
+void csensor_event_listener::get_all_handles(handle_vector &handles)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ handles.push_back(it_handle->first);
+ ++it_handle;
+ }
+}
+
+bool csensor_event_listener::is_sensor_registered(const sensor_type_t sensor)
+{
+ sensor_handle_info_map::iterator it_handle;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if (it_handle->second.m_sensor_type == sensor)
+ return true;
+
+ ++it_handle;
+ }
+
+ return false;
+}
+
+bool csensor_event_listener::is_sensor_active(const sensor_type_t sensor)
+{
+ sensor_handle_info_map::iterator it_handle;
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_type == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
+ return true;
+
+ ++it_handle;
+ }
+
+ return false;
+}
+
+void csensor_event_listener::handle_events(void *event)
+{
+ const unsigned int MS_TO_US = 1000;
+ const float MIN_DELIVERY_DIFF_FACTOR = 0.75f;
+
+ unsigned long long cur_time;
+ long long diff_time;
+ creg_event_info event_info;
+ sensor_event_data_t event_data;
+ int situation;
+
+ sensor_data_t sensor_data;
+ sensorhub_data_t sensorhub_data;
+ sensor_panning_data_t panning_data;
+ int single_state_event_data = 0;
+ int data_accuracy = SENSOR_ACCURACY_GOOD;
+
+ unsigned int event_type = *((unsigned int *)(event));
+ bool is_hub_event = is_sensorhub_event(event_type);
+
+ client_callback_info *callback_info;
+ vector<client_callback_info *> client_callback_infos;
+ sensor_handle_info_map::iterator it_handle;
+
+ if (is_hub_event) {
+ sensorhub_event_t *sensor_hub_event = (sensorhub_event_t *)event;
+ sensorhub_event_to_hub_data(*sensor_hub_event, sensorhub_data);
+ event_data.event_data = &sensorhub_data;
+ event_data.event_data_size = sizeof(sensorhub_data);
+ situation = sensor_hub_event->situation;
+ cur_time = sensor_hub_event->data.timestamp;
+ } else {
+ sensor_event_t *sensor_event = (sensor_event_t *)event;
+ situation = sensor_event->situation;
+ cur_time = sensor_event->data.timestamp;
+
+ if (is_single_state_event(event_type)) {
+ single_state_event_data = (int) sensor_event->data.values[0];
+ event_data.event_data = (void *) & (single_state_event_data);
+ event_data.event_data_size = sizeof(single_state_event_data);
+ } else if (is_panning_event(event_type)) {
+ panning_data.x = (int)sensor_event->data.values[0];
+ panning_data.y = (int)sensor_event->data.values[1];
+ event_data.event_data = (void *)&panning_data;
+ event_data.event_data_size = sizeof(panning_data);
+ } else {
+ sensor_event_to_data(*sensor_event, sensor_data);
+ event_data.event_data = (void *)&sensor_data;
+ event_data.event_data_size = sizeof(sensor_data);
+ data_accuracy = sensor_event->data.data_accuracy;
+ }
+ }
+
+ { /* scope for the lock */
+ AUTOLOCK(m_handle_info_lock);
+
+ for (it_handle = m_sensor_handle_infos.begin(); it_handle != m_sensor_handle_infos.end(); ++it_handle) {
+ csensor_handle_info &sensor_handle_info = it_handle->second;
+
+ if ((sensor_handle_info.m_sensor_state != SENSOR_STATE_STARTED) || !sensor_handle_info.get_reg_event_info(event_type, event_info))
+ continue;
+
+ if ((sensor_handle_info.m_sensor_option != SENSOR_OPTION_ALWAYS_ON) &&
+ ((situation == SITUATION_LCD_OFF) || (situation == SITUATION_SURVIVAL_MODE)))
+ continue;
+
+ if (event_info.m_fired)
+ continue;
+
+ diff_time = cur_time - event_info.m_previous_event_time;
+
+ if ((diff_time >= event_info.m_event_interval * MS_TO_US * MIN_DELIVERY_DIFF_FACTOR) || ((diff_time > 0) && !is_ontime_event(event_type))) {
+ unsigned int cal_event_type;
+ creg_event_info cal_event_info;
+ event_info.m_previous_event_time = cur_time;
+ cal_event_type = get_calibration_event_type(event_type);
+
+ if (cal_event_type) {
+ if ((data_accuracy == SENSOR_ACCURACY_BAD) && !sensor_handle_info.bad_accuracy &&
+ sensor_handle_info.get_reg_event_info(cal_event_type, cal_event_info)) {
+ sensor_event_data_t cal_event_data;
+ client_callback_info *cal_callback_info;
+
+ cal_event_info.m_previous_event_time = cur_time;
+ cal_event_data.event_data = (void *) & (data_accuracy);
+ cal_event_data.event_data_size = sizeof(data_accuracy);
+ cal_callback_info = get_callback_info(cal_event_info, cal_event_data);
+ client_callback_infos.push_back(cal_callback_info);
+ sensor_handle_info.bad_accuracy = true;
+
+ print_event_occurrence_log(sensor_handle_info, cal_event_info, cal_event_data);
+ }
+
+ if ((data_accuracy != SENSOR_ACCURACY_BAD) && sensor_handle_info.bad_accuracy)
+ sensor_handle_info.bad_accuracy = false;
+ }
+
+ callback_info = get_callback_info(event_info, event_data);
+ client_callback_infos.push_back(callback_info);
+
+ if (is_one_shot_event(event_type))
+ event_info.m_fired = true;
+
+ print_event_occurrence_log(sensor_handle_info, event_info, event_data);
+ }
+ }
+ }
+
+ vector<client_callback_info *>::iterator it_calback_info;
+ it_calback_info = client_callback_infos.begin();
+
+ while (it_calback_info != client_callback_infos.end()) {
+ post_callback_to_main_loop(*it_calback_info);
+ ++it_calback_info;
+ }
+}
+
+client_callback_info *csensor_event_listener::get_callback_info(creg_event_info &event_info, sensor_event_data_t &event_data)
+{
+ client_callback_info *callback_info;
+ callback_info = new client_callback_info;
+ callback_info->event_id = event_info.m_id;
+ callback_info->handle = event_info.m_handle;
+ callback_info->callback = event_info.m_event_callback;
+ callback_info->event_type = event_info.m_event_type;
+ callback_info->event_data.event_data_size = event_data.event_data_size;
+ callback_info->event_data.event_data = new char[event_data.event_data_size];
+ memcpy(callback_info->event_data.event_data, event_data.event_data, event_data.event_data_size);
+ callback_info->data = event_info.m_cb_data;
+ return callback_info;
+}
+
+void csensor_event_listener::post_callback_to_main_loop(client_callback_info *cb_info)
+{
+ g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
+}
+
+bool csensor_event_listener::is_event_active(int handle, unsigned int event_type, unsigned long long event_id)
+{
+ sensor_handle_info_map::iterator it_handle;
+ creg_event_info event_info;
+
+ AUTOLOCK(m_handle_info_lock);
+ it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end())
+ return false;
+
+ if (!it_handle->second.get_reg_event_info(event_type, event_info))
+ return false;
+
+ if (event_info.m_id != event_id)
+ return false;
+
+ return true;
+}
+
+bool csensor_event_listener::is_valid_callback(client_callback_info *cb_info)
+{
+ return is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
+}
+
+gboolean csensor_event_listener::callback_dispatcher(gpointer data)
+{
+ client_callback_info *cb_info = (client_callback_info *) data;
+
+ if (csensor_event_listener::get_instance().is_valid_callback(cb_info))
+ cb_info->callback(cb_info->event_type, &cb_info->event_data, cb_info->data);
+ else
+ WARN("Discard invalid callback cb(0x%x)(%s, 0x%x, 0x%x) with id: %llu",
+ cb_info->callback, get_event_name(cb_info->event_type), &cb_info->event_data,
+ cb_info->data, cb_info->event_id);
+
+ delete[] (char *)(cb_info->event_data.event_data);
+ delete cb_info;
+
+ /*
+ * To be called only once, it returns false
+ */
+ return false;
+}
+
+bool csensor_event_listener::sensor_event_poll(void *buffer, int buffer_len)
+{
+ ssize_t len;
+ len = m_event_socket.recv(buffer, buffer_len);
+
+ if (!len) {
+ if (!m_poller->poll())
+ return false;
+
+ len = m_event_socket.recv(buffer, buffer_len);
+
+ if (!len) {
+ INFO("%s failed to read after poll!", get_client_name());
+ return false;
+ }
+ }
+
+ if (len < 0) {
+ INFO("%s failed to recv event from event socket", get_client_name());
+ return false;
+ }
+
+ return true;
+}
+
+void csensor_event_listener::listen_events(void)
+{
+ sensorhub_event_t buffer;
+
+ do {
+ lock l(m_thread_mutex);
+
+ if (m_thread_state == THREAD_STATE_START) {
+ if (!sensor_event_poll(&buffer, sizeof(buffer))) {
+ INFO("sensor_event_poll failed");
+ break;
+ }
+
+ handle_events(&buffer);
+ } else {
+ break;
+ }
+
+ } while (true);
+
+ if (m_poller != NULL) {
+ delete m_poller;
+ m_poller = NULL;
+ }
+
+ close_event_channel();
+ set_client_id(CLIENT_ID_INVALID);
+
+ lock l(m_thread_mutex);
+ m_thread_state = THREAD_STATE_TERMINATE;
+ m_thread_cond.notify_one();
+ INFO("Event listener thread is terminated.");
+}
+
+bool csensor_event_listener::create_event_channel(void)
+{
+ int client_id;
+ event_channel_ready_t event_channel_ready;
+
+ if (!m_event_socket.create(SOCK_SEQPACKET))
+ return false;
+
+ if (!m_event_socket.connect(EVENT_CHANNEL_PATH)) {
+ ERR("Failed to connect event channel for client %s, event socket fd[%d]", get_client_name(), m_event_socket.get_socket_fd());
+ return false;
+ }
+
+ m_event_socket.set_connection_mode();
+ client_id = get_client_id();
+
+ if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) {
+ ERR("Failed to send client id for client %s on event socket[%d]", get_client_name(), m_event_socket.get_socket_fd());
+ return false;
+ }
+
+ if (m_event_socket.recv(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
+ ERR("%s failed to recv event_channel_ready packet on event socket[%d] with client id [%d]",
+ get_client_name(), m_event_socket.get_socket_fd(), client_id);
+ return false;
+ }
+
+ if ((event_channel_ready.magic != EVENT_CHANNEL_MAGIC) || (event_channel_ready.client_id != client_id)) {
+ ERR("Event_channel_ready packet is wrong, magic = 0x%x, client id = %d",
+ event_channel_ready.magic, event_channel_ready.client_id);
+ return false;
+ }
+
+ INFO("Event channel is established for client %s on socket[%d] with client id : %d",
+ get_client_name(), m_event_socket.get_socket_fd(), client_id);
+ return true;
+}
+
+void csensor_event_listener::close_event_channel(void)
+{
+ m_event_socket.close();
+}
+
+void csensor_event_listener::stop_event_listener(void)
+{
+ const int THREAD_TERMINATING_TIMEOUT = 2;
+ ulock u(m_thread_mutex);
+
+ if (m_thread_state != THREAD_STATE_TERMINATE) {
+ m_thread_state = THREAD_STATE_STOP;
+ _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
+
+ if (m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT)) == std::cv_status::timeout)
+ _E("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT);
+ else
+ _D("Listener thread for %s is terminated", get_client_name());
+ }
+}
+
+void csensor_event_listener::set_thread_state(thread_state state)
+{
+ lock l(m_thread_mutex);
+ m_thread_state = state;
+}
+
+bool csensor_event_listener::start_event_listener(void)
+{
+ if (!create_event_channel()) {
+ ERR("Event channel is not established for %s", get_client_name());
+ return false;
+ }
+
+ m_event_socket.set_transfer_mode();
+ m_poller = new poller(m_event_socket.get_socket_fd());
+
+ set_thread_state(THREAD_STATE_START);
+ thread listener(&csensor_event_listener::listen_events, this);
+ listener.detach();
+ return true;
+}
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 CSENSOR_EVENT_LISTENER_H_
+#define CSENSOR_EVENT_LISTENER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include <csensor_handle_info.h>
+#include <unistd.h>
+#include <csocket.h>
+#include <string.h>
+#include <sf_common.h>
+#include <algorithm>
+#include <sstream>
+#include <map>
+#include <vector>
+#include <string>
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+#include <cmutex.h>
+#include <poller.h>
+
+using std::map;
+using std::vector;
+using std::string;
+using std::queue;
+using std::mutex;
+using std::lock_guard;
+using std::unique_lock;
+using std::condition_variable;
+
+typedef vector<unsigned int> handle_vector;
+typedef vector<sensor_type_t> sensor_type_vector;
+typedef map<int, vector<unsigned int>> handle_events_map;
+typedef map<int, csensor_handle_info> sensor_handle_info_map;
+typedef map<sensor_type_t, command_channel *> sensor_command_channel_map;
+
+typedef struct {
+ unsigned long long event_id;
+ int handle;
+ sensor_callback_func_t callback;
+ unsigned int event_type;
+ sensor_event_data_t event_data;
+ void *data;
+} client_callback_info;
+
+typedef struct sensor_rep {
+ bool active;
+ int option;
+ unsigned int interval;
+ event_type_vector event_types;
+} sensor_rep;
+
+class csensor_event_listener
+{
+public:
+ int create_handle(const sensor_type_t sensor);
+ bool delete_handle(const int handle);
+ bool start_handle(const int handle);
+ bool stop_handle(const int handle);
+ bool register_event(const int handle, const unsigned int event_type,
+ const unsigned int interval,
+ const sensor_callback_func_t callback, void *cb_data);
+ bool unregister_event(const int handle, const unsigned int event_type);
+ bool change_event_interval(const int handle, const unsigned int event_type,
+ const unsigned int interval);
+
+ bool set_sensor_params(const int handle, int sensor_state, int sensor_option);
+ bool set_sensor_state(const int handle, const int sensor_state);
+ bool set_sensor_option(const int handle, const int sensor_option);
+ bool set_event_interval(const int handle, const unsigned int event_type,
+ const unsigned int interval);
+
+ void get_listening_sensors(sensor_type_vector &sensors);
+
+ void pause_sensor(const sensor_type_t sensor);
+ void resume_sensor(const sensor_type_t sensor);
+
+ unsigned int get_active_min_interval(const sensor_type_t sensor);
+ unsigned int get_active_option(const sensor_type_t sensor);
+ void get_active_event_types(const sensor_type_t sensor,
+ event_type_vector &active_event_types);
+
+ bool get_sensor_type(const int handle, sensor_type_t &sensor);
+ bool get_sensor_state(const int handle, int &state);
+
+ void get_sensor_rep(sensor_type_t sensor, sensor_rep &rep);
+
+ bool has_client_id(void);
+ int get_client_id(void);
+ void set_client_id(const int client_id);
+
+ bool is_active(void);
+ bool is_sensor_registered(const sensor_type_t sensor);
+ bool is_sensor_active(const sensor_type_t sensor);
+
+ bool set_command_channel(sensor_type_t sensor, command_channel *cmd_channel);
+ bool get_command_channel(sensor_type_t sensor, command_channel **cmd_channel);
+ bool close_command_channel(sensor_type_t sensor);
+
+ void get_all_handles(handle_vector &handles);
+
+ int get_single_event_count(const unsigned int event_type);
+ bool start_event_listener(void);
+ void stop_event_listener(void);
+
+ static csensor_event_listener &get_instance(void) {
+ static csensor_event_listener inst;
+ return inst;
+ }
+
+private:
+ enum thread_state {
+ THREAD_STATE_START,
+ THREAD_STATE_STOP,
+ THREAD_STATE_TERMINATE,
+ };
+ typedef lock_guard<mutex> lock;
+ typedef unique_lock<mutex> ulock;
+
+ sensor_handle_info_map m_sensor_handle_infos;
+ sensor_command_channel_map m_command_channels;
+
+ int m_client_id;
+
+ csocket m_event_socket;
+ poller *m_poller;
+
+ cmutex m_handle_info_lock;
+
+ thread_state m_thread_state;
+ mutex m_thread_mutex;
+ condition_variable m_thread_cond;
+
+ csensor_event_listener();
+ ~csensor_event_listener();
+
+ csensor_event_listener(const csensor_event_listener &) {};
+ csensor_event_listener &operator=(const csensor_event_listener &);
+
+ bool create_event_channel(void);
+ void close_event_channel(void);
+
+ bool sensor_event_poll(void *buffer, int buffer_len);
+
+ void listen_events(void);
+ void handle_events(void *event);
+
+ client_callback_info *get_callback_info(creg_event_info &event_info,
+ sensor_event_data_t &event_data);
+
+ unsigned long long renew_event_id(void);
+
+ void post_callback_to_main_loop(client_callback_info *cb_info);
+
+ bool is_event_active(int handle, unsigned int event_type, unsigned long long event_id);
+ bool is_valid_callback(client_callback_info *cb_info);
+ static gboolean callback_dispatcher(gpointer data);
+
+ void set_thread_state(thread_state state);
+};
+#endif /* CSENSOR_EVENT_LISTENER_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 <client_common.h>
+#include <csensor_handle_info.h>
+
+using std::pair;
+
+unsigned long long csensor_handle_info::m_event_id = 0;
+
+csensor_handle_info::csensor_handle_info()
+: m_handle(0)
+, m_sensor_type(UNKNOWN_SENSOR)
+, m_sensor_state(SENSOR_STATE_UNKNOWN)
+, m_sensor_option(SENSOR_OPTION_DEFAULT)
+, bad_accuracy(false)
+{
+}
+
+csensor_handle_info::~csensor_handle_info()
+{
+ clear_all_events();
+}
+
+bool csensor_handle_info::get_reg_event_info(unsigned int event_type, creg_event_info &event_info)
+{
+ event_info_map::iterator it_event;
+ it_event = m_reg_event_infos.find(event_type);
+
+ if (it_event == m_reg_event_infos.end()) {
+ DBG("Event %s[0x%x] is not registered for client %s", get_event_name(event_type), event_type, get_client_name());
+ return false;
+ }
+
+ event_info = it_event->second;
+ return true;
+}
+
+void csensor_handle_info::get_reg_event_types(event_type_vector &event_types)
+{
+ event_info_map::iterator it_event;
+ it_event = m_reg_event_infos.begin();
+
+ while (it_event != m_reg_event_infos.end()) {
+ event_types.push_back(it_event->first);
+ ++it_event;
+ }
+}
+
+bool csensor_handle_info::add_reg_event_info(const unsigned int event_type, const unsigned int interval,
+ const sensor_callback_func_t callback, void *cb_data)
+{
+ event_info_map::iterator it_event;
+ creg_event_info event_info;
+ it_event = m_reg_event_infos.find(event_type);
+
+ if (it_event != m_reg_event_infos.end()) {
+ ERR("Event %s[0x%x] is already registered for client %s", get_event_name(event_type), event_type, get_client_name());
+ return false;
+ }
+
+ event_info.m_id = renew_event_id();
+ event_info.m_handle = m_handle;
+ event_info.m_event_type = event_type;
+ event_info.m_event_interval = interval;
+ event_info.m_event_callback = callback;
+ event_info.m_cb_data = cb_data;
+ m_reg_event_infos.insert(pair<unsigned int, creg_event_info> (event_type, event_info));
+ return true;
+}
+
+bool csensor_handle_info::delete_reg_event_info(const unsigned int event_type)
+{
+ event_info_map::iterator it_event;
+ it_event = m_reg_event_infos.find(event_type);
+
+ if (it_event == m_reg_event_infos.end()) {
+ ERR("Event %s[0x%x] is not registered for client %s", get_event_name(event_type), event_type, get_client_name());
+ return false;
+ }
+
+ m_reg_event_infos.erase(it_event);
+ return true;
+}
+
+void csensor_handle_info::clear_all_events(void)
+{
+ m_reg_event_infos.clear();
+}
+
+unsigned long long csensor_handle_info::renew_event_id(void)
+{
+ return m_event_id++;
+}
+
+bool csensor_handle_info::change_reg_event_interval(const unsigned int event_type, const unsigned int interval)
+{
+ event_info_map::iterator it_event;
+ it_event = m_reg_event_infos.find(event_type);
+
+ if (it_event == m_reg_event_infos.end()) {
+ ERR("Event %s[0x%x] is not registered for client %s", get_event_name(event_type), event_type, get_client_name());
+ return false;
+ }
+
+ it_event->second.m_id = renew_event_id();
+ it_event->second.m_event_interval = interval;
+ return true;
+}
+
+unsigned int csensor_handle_info::get_min_interval(void)
+{
+ unsigned int min_interval = POLL_MAX_HZ_MS;
+ unsigned int interval;
+
+ if (m_reg_event_infos.empty()) {
+ DBG("No events are registered for client %s", get_client_name());
+ return min_interval;
+ }
+
+ event_info_map::iterator it_event;
+ it_event = m_reg_event_infos.begin();
+
+ while (it_event != m_reg_event_infos.end()) {
+ interval = it_event->second.m_event_interval;
+ min_interval = (interval < min_interval) ? interval : min_interval;
+ ++it_event;
+ }
+
+ return min_interval;
+}
+
+unsigned int csensor_handle_info::get_reg_event_count(void)
+{
+ return m_reg_event_infos.size();
+}
+
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 CSENSOR_HANDLE_INFO_H_
+#define CSENSOR_HANDLE_INFO_H_
+
+#include <creg_event_info.h>
+#include <command_channel.h>
+#include <common.h>
+#include <string.h>
+#include <map>
+#include <vector>
+
+using std::map;
+using std::vector;
+
+typedef map<unsigned int, creg_event_info> event_info_map;
+
+class csensor_handle_info
+{
+public:
+ int m_handle;
+ sensor_type_t m_sensor_type;
+ int m_sensor_state;
+ int m_sensor_option;
+ int bad_accuracy;
+
+ csensor_handle_info();
+ ~csensor_handle_info();
+
+ bool add_reg_event_info(const unsigned int event_type, const unsigned int interval,
+ const sensor_callback_func_t callback, void *cb_data);
+ bool delete_reg_event_info(const unsigned int event_type);
+
+ bool change_reg_event_interval(const unsigned int event_type, const unsigned int interval);
+
+ bool get_reg_event_info(const unsigned int event_type, creg_event_info &event_info);
+ void get_reg_event_types(event_type_vector &event_types);
+ unsigned int get_min_interval(void);
+ unsigned int get_reg_event_count(void);
+
+ void clear_all_events(void);
+ static unsigned long long renew_event_id(void);
+private:
+ event_info_map m_reg_event_infos;
+ static unsigned long long m_event_id;
+};
+
+#endif /* CSENSOR_HANDLE_INFO_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 <common.h>
+#include <poller.h>
+#include <sf_common.h>
+
+poller::poller(int fd)
+: m_epfd(-1)
+{
+ create(fd);
+}
+
+bool poller::create(int fd)
+{
+ m_epfd = epoll_create(1);
+
+ struct epoll_event event;
+ event.data.fd = fd;
+ event.events = EPOLLIN | EPOLLERR | EPOLLHUP;
+
+ if (epoll_ctl(m_epfd, EPOLL_CTL_ADD, fd, &event)) {
+ ERR("errno : %d , errstr : %s", errno, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+bool poller::fill_event_queue(void)
+{
+ const int EPOLL_MAX_EVENT = 16;
+ struct epoll_event event_items[EPOLL_MAX_EVENT];
+ int nr_events = epoll_wait(m_epfd, event_items, EPOLL_MAX_EVENT, -1);
+
+ if (nr_events < 0) {
+ if (errno == EINTR) {
+ return true;
+ }
+
+ ERR("Epoll failed errrno : %d , errstr : %s", errno, strerror(errno));
+ return false;
+ }
+
+ if (nr_events == 0) {
+ ERR("Epoll timeout!");
+ return false;
+ }
+
+ for (int i = 0; i < nr_events; i++)
+ m_event_queue.push(event_items[i].events);
+
+ return true;
+}
+
+bool poller::poll(void)
+{
+ while (true) {
+ if (m_event_queue.empty()) {
+ if (!fill_event_queue())
+ return false;
+ }
+
+ if (!m_event_queue.empty()) {
+ int event = m_event_queue.front();
+ m_event_queue.pop();
+
+ if (event & EPOLLERR) {
+ ERR("Poll error!");
+ return false;
+ }
+
+ if (event & EPOLLHUP) {
+ INFO("Poll: Connetion is closed from the other side");
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
+
+poller::~poller()
+{
+ if (m_epfd)
+ close(m_epfd);
+}
+
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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 _POLLER_H_
+#define _POLLER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/epoll.h>
+#include <poller.h>
+#include <unistd.h>
+#include <sf_common.h>
+#include <algorithm>
+#include <queue>
+
+using std::queue;
+
+class poller
+{
+public:
+ poller(int fd);
+ ~poller();
+
+ bool poll(void);
+private:
+ int m_epfd;
+ queue<int> m_event_queue;
+
+ bool create(int fd);
+ bool fill_event_queue(void);
+};
+
+#endif /* _POLLER_H_ */
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_H_
+#define _SENSOR_H_
+
+#ifndef DEPRECATED
+#define DEPRECATED __attribute__((deprecated))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <sys/types.h>
+
+/*header for common sensor type*/
+#include <sensor_common.h>
+
+/*header for each sensor type*/
+#include <sensor_accel.h>
+#include <sensor_geomag.h>
+#include <sensor_light.h>
+#include <sensor_proxi.h>
+#include <sensor_motion.h>
+#include <sensor_gyro.h>
+#include <sensor_gravity.h>
+#include <sensor_linear_accel.h>
+#include <sensor_orientation.h>
+#include <sensor_context.h>
+
+typedef struct {
+ condition_op_t cond_op;
+ float cond_value1;
+} event_condition_t;
+
+typedef struct {
+ size_t event_data_size;
+ void *event_data;
+} sensor_event_data_t;
+
+typedef void (*sensor_callback_func_t)(unsigned int, sensor_event_data_t *, void *);
+
+typedef struct {
+ int x;
+ int y;
+ int z;
+} sensor_panning_data_t;
+
+typedef struct {
+ int sensor_unit_idx;
+ float sensor_min_range;
+ float sensor_max_range;
+ float sensor_resolution;
+} sensor_data_properties_t;
+
+/**
+ * @fn int sf_is_sensor_event_available(sensor_type_t desired_sensor_type, unsigned int desired_event_type)
+ * @brief This API loads the in parameter available list with the type of sensor available for operation . Some of the supported types are ACCELEROMETER_SENSOR_TYPE, GEOMAGNETIC_SENSOR_TYPE etc. This API will return 0 when it is available and negative value when it does not available.
+ * @param[in] desired_sensor_type your desired sensor type to check
+ * @param[in] desired_event_type your desired event type to check, if you want to check only sensor-available , set "0" value
+ * @return if it succeed, it return zero value(available), otherwise negative value return (not available)
+ */
+int sf_is_sensor_event_available(sensor_type_t desired_sensor_type, unsigned int desired_event_type);
+
+/**
+ * @fn int sf_get_data_properties(unsigned data_id, sensor_dada_properties_t *return_data_properties)
+ * @brief This API loads the properties of data ID like unit of sensor data, max/min range of sensor data etc to the output parameter sensor_data_properties.
+ * @param[in] data_id your desired data ID
+ * @param[out] return_data_properties property information of your desired data ID
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_get_data_properties(unsigned int data_id, sensor_data_properties_t *return_data_properties);
+
+/**
+ * @fn int sf_get_properties(sensor_type_t sensor, sensor_properties_t *return_properties)
+ * @brief This API loads the properties of sensor type like unit of sensor data, max/min range of sensor data etc to the output parameter sensor_properties.
+ * @param[in] sensor your desired sensor type
+ * @param[out] return_properties property information of your desired sensor
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_get_properties(sensor_type_t sensor, sensor_properties_t *return_properties);
+
+/**
+ * @fn int sf_set_property(sensor_type_t sensor, unsigned int property_id, long value)
+ * @brief This API set the property of sensor type like calibration, enable wakeup event, etc
+ * @param[in] sensor your desired sensor type, property_id your desired property ID, value for property input
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_set_property(sensor_type_t sensor, unsigned int property_id, long value);
+
+/**
+ * @fn int sf_connect(sensor_type_t sensor)
+ * @brief This API connects a sensor type to respective sensor. The application calls with the type of the sensor (ex. ACCELEROMETER_SENSOR) and on basis of that server takes decision of which plug-in to be connected. Once sensor connected application can proceed for data processing. This API returns a positive handle which should be used by application to communicate on sensor type.
+ * @param[in] sensor your desired sensor type
+ * @return if it succeed, it return handle value( >=0 ), otherwise negative value return
+ */
+int sf_connect(sensor_type_t sensor);
+
+/**
+ * @fn int sf_disconnect(int handle)
+ * @brief This API disconnects an attached sensor from an application. Application must use the handle retuned after attaching the sensor. After detaching, the corresponding handle will be released.
+ * @param[in] handle received handle value by sf_connect()
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_disconnect(int handle);
+
+/**
+ * @fn int sf_start(int handle, int option)
+ * @brief This API sends a start command to sensor server. This intimates server that the client side is ready to handle data and start processing. The parameter option should be '0' for current usages.
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] option With SENSOR_OPTION_DEFAULT, it stops to sense when LCD is off, and with SENSOR_OPTION_ALWAYS_ON, it continues to sense even when LCD is off
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_start(int handle, int option);
+
+/**
+ * @fn int sf_stop(int handle)
+ * @brief This API sends a stop command to the Sensor server indicating that the data processing is stopped from application side for this time.
+ * @param[in] handle received handle value by sf_connect()
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_stop(int handle);
+
+/**
+ * @fn int sf_register_event(int handle, unsigned int event_type, event_conditon_t *event_condition, sensor_callback_func_t cb, void *cb_data)
+ * @brief This API registers a user defined callback function with a connected sensor for a particular event. This callback function will be called when there is a change in the state of respective sensor. cb_data will be the parameter used during the callback call. Callback interval can be adjusted using even_contion_t argument.
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] event_type your desired event_type to register it
+ * @param[in] event_condition input event_condition for special event. if you want to register without event_condition, just use a NULL value
+ * @param[in] cb your define callback function
+ * @param[in] cb_data your option data that will be send when your define callback function called. if you don't have any option data, just use a NULL value
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_register_event(int handle, unsigned int event_type, event_condition_t *event_condition, sensor_callback_func_t cb, void *cb_data);
+
+/**
+ * @fn int sf_unregister_event(int handle, unsigned int event_type)
+ * @brief This API de-registers a user defined callback function with a sensor registered with the specified handle. After unsubscribe, no event will be sent to the application.
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] event_type your desired event_type that you want to unregister event
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_unregister_event(int handle, unsigned int event_type);
+
+/**
+ * @fn int sf_get_data(int handle, unsigned int data_id, sensor_data_t* values)
+ * @brief This API gets raw data from a sensor with connecting the sensor-server. The type of sensor is supplied and return data is stored in the output parameter values [].
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] data_id predefined data_ID as every sensor in own header - sensor_xxx.h, enum xxx_data_id {}
+ * @param[out] values return values
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_get_data(int handle, unsigned int data_id, sensor_data_t *values);
+
+/**
+ * @fn int sf_check_rotation( unsigned long *curr_state)
+ * @brief This API used to get the current rotation state. (i.e. ROTATION_EVENT_0, ROTATION_EVENT_90, ROTATION_EVENT_180 & ROTATION_EVENT_270 ). This API will directly access the sensor without connection process with the sensor-server. Result will be stored in the output parameter state.
+ * @param[out] curr_state it will return enum accelerometer_rotate_state value
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_check_rotation(unsigned long *curr_state);
+
+/**
+ * @fn int sf_change_event_condition(int handle, unsigned int event_type, event_condition_t *event_condition)
+ * @brief This API change a user defined callback function condition with a sensor registered with the specified handle.
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] event_type your desired event_type that you want to unregister event
+ * @param[in] event_condition your desired event condition that you want to change event
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_change_event_condition(int handle, unsigned int event_type, event_condition_t *event_condition);
+
+/**
+ * @fn int sf_change_sensor_option(int handle, int option)
+ * @brief This API change sensor option .
+ * @param[in] handle received handle value by sf_connect()
+ * @param[in] option your desired option that you want to turn on sensor during LCD OFF
+ * @return if it succeed, it return zero value, otherwise negative value return
+ */
+int sf_change_sensor_option(int handle, int option);
+
+/**
+ * @fn int sf_send_sensorhub_data(int handle, const char* buffer, int data_len)
+ * @brief This API sends data to sensorhub.
+ * @param[in] handle received handle by sf_connect()
+ * @param[in] data it holds data to send to sensorhub
+ * @param[in] data_len the length of data
+ * @return if it succeed, it returns zero, otherwise negative value
+ */
+int sf_send_sensorhub_data(int handle, const char *data, int data_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_SENSOR_H_*/
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@/sensor
+
+Name: libsensord
+Description: Sensord library
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -lsensor
+Cflags: -I${includedir}
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_ACCEL_H_
+#define _SENSOR_ACCEL_H_
+
+//! Pre-defined events for the accelometer sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_ACCEL Accelerometer Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Accelerometer sensor.
+ * @{
+ */
+
+enum accelerometer_data_id {
+ ACCELEROMETER_BASE_DATA_SET = (ACCELEROMETER_SENSOR << 16) | 0x0001,
+ ACCELEROMETER_ORIENTATION_DATA_SET = (ACCELEROMETER_SENSOR << 16) | 0x0002,
+ ACCELEROMETER_LINEAR_ACCELERATION_DATA_SET = (ACCELEROMETER_SENSOR << 16) | 0x0004,
+ ACCELEROMETER_GRAVITY_DATA_SET = (ACCELEROMETER_SENSOR << 16) | 0x0008,
+ ACCELEROMETER_ROTATION_DATA_SET = (ACCELEROMETER_SENSOR << 16) | 0x0010,
+};
+
+enum accelerometer_event_type {
+ ACCELEROMETER_EVENT_ROTATION_CHECK = (ACCELEROMETER_SENSOR << 16) | 0x0001,
+ ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0002,
+ ACCELEROMETER_EVENT_CALIBRATION_NEEDED = (ACCELEROMETER_SENSOR << 16) | 0x0004,
+ ACCELEROMETER_EVENT_SET_HORIZON = (ACCELEROMETER_SENSOR << 16) | 0x0008,
+ ACCELEROMETER_EVENT_SET_WAKEUP = (ACCELEROMETER_SENSOR << 16) | 0x0010,
+ ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0020,
+ ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0040,
+ ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0080,
+};
+
+enum accelerometer_rotate_state {
+ ROTATION_UNKNOWN = 0,
+ ROTATION_PORTRAIT_TOP = 1,
+ ROTATION_LANDSCAPE_LEFT = 2,
+ ROTATION_PORTRAIT_BTM = 3,
+ ROTATION_LANDSCAPE_RIGHT = 4,
+ ROTATION_EVENT_0 = 1, /*CCW base*/
+ ROTATION_EVENT_90 = 2, /*CCW base*/
+ ROTATION_EVENT_180 = 3, /*CCW base*/
+ ROTATION_EVENT_270 = 4, /*CCW base*/
+};
+
+enum accelerometer_property_id {
+ ACCELEROMETER_PROPERTY_UNKNOWN = 0,
+ ACCELEROMETER_PROPERTY_SET_CALIBRATION,
+ ACCELEROMETER_PROPERTY_CHECK_CALIBRATION_STATUS,
+ ACCELEROMETER_PROPERTY_SET_WAKEUP,
+ ACCELEROMETER_PROPERTY_CHECK_WAKEUP_STATUS,
+ ACCELEROMETER_PROPERTY_CHECK_WAKEUP_SUPPORTED,
+ ACCELEROMETER_PROPERTY_GET_WAKEUP,
+};
+
+enum accelerometer_wakeup_state {
+ WAKEUP_UNSET = 0,
+ WAKEUP_SET = 1,
+};
+
+struct rotation_event {
+ enum accelerometer_rotate_state rotation;
+ enum accelerometer_rotate_state rm[2];
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_ACCEL_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_CONTEXT_H_
+#define _SENSOR_CONTEXT_H_
+
+//! Pre-defined events for the context sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_CONTEXT Context Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Context sensor.
+ * @{
+ */
+
+enum context_data_id {
+ CONTEXT_BASE_DATA_SET = (CONTEXT_SENSOR << 16) | 0x0001,
+};
+
+enum context_event_type {
+ CONTEXT_EVENT_REPORT = (CONTEXT_SENSOR << 16) | 0x0001,
+};
+
+enum context_property_id {
+ CONTEXT_PROPERTY_UNKNOWN = 0,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_CONTEXT_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_GEOMAG_H_
+#define _SENSOR_GEOMAG_H_
+
+//! Pre-defined events for the geomagnetic sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_GEOMAG Geomagnetic Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Geomagnatic sensor.
+ * @{
+ */
+
+enum geomag_data_id {
+ GEOMAGNETIC_BASE_DATA_SET = (GEOMAGNETIC_SENSOR << 16) | 0x0001,
+ GEOMAGNETIC_RAW_DATA_SET = (GEOMAGNETIC_SENSOR << 16) | 0x0001,
+ GEOMAGNETIC_ATTITUDE_DATA_SET = (GEOMAGNETIC_SENSOR << 16) | 0x0002,
+};
+
+enum geomag_evet_type {
+ GEOMAGNETIC_EVENT_CALIBRATION_NEEDED = (GEOMAGNETIC_SENSOR << 16) | 0x0001,
+ GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME = (GEOMAGNETIC_SENSOR << 16) | 0x0002,
+ GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME = (GEOMAGNETIC_SENSOR << 16) | 0x0004,
+};
+
+enum geomag_property_id {
+ GEOMAGNETIC_PROPERTY_UNKNOWN = 0,
+ GEOMAGNETIC_PROPERTY_SET_ACCEL_CALIBRATION,
+ GEOMAGNETIC_PROPERTY_CHECK_ACCEL_CALIBRATION,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_GEOMAG_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_GRAVITY_H_
+#define _SENSOR_GRAVITY_H_
+
+//! Pre-defined events for the gravity sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_GRAVITY Gravity Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Gravity sensor.
+ * @{
+ */
+
+enum gravity_data_id {
+ GRAVITY_BASE_DATA_SET = (GRAVITY_SENSOR << 16) | 0x0001,
+};
+
+enum gravity_event_type {
+ GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME = (GRAVITY_SENSOR << 16) | 0x0002,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_GRAVITY_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_GYRO_H_
+#define _SENSOR_GYRO_H_
+
+//! Pre-defined events for the gyroscope sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_GYRO Gyro Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the gyro sensor.
+ * @{
+ */
+
+enum gyro_data_id {
+ GYRO_BASE_DATA_SET = (GYROSCOPE_SENSOR << 16) | 0x0001,
+};
+
+enum gyro_event_type {
+ GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME = (GYROSCOPE_SENSOR << 16) | 0x0001,
+};
+
+enum gyro_property_id {
+ GYROSCOPE_PROPERTY_UNKNOWN = 0,
+ GYROSCOPE_PROPERTY_SET_CALIBRATION,
+ GYROSCOPE_PROPERTY_CHECK_CALIBRATION,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_GYRO_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_LIGHT_H_
+#define _SENSOR_LIGHT_H_
+
+//! Pre-defined events for the light sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_LIGHT Light Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the light sensor.
+ * @{
+ */
+
+enum light_data_id {
+ LIGHT_BASE_DATA_SET = (LIGHT_SENSOR << 16) | 0x0001,
+ LIGHT_LUX_DATA_SET = (LIGHT_SENSOR << 16) | 0x0002,
+};
+
+enum light_evet_type {
+ LIGHT_EVENT_CHANGE_LEVEL = (LIGHT_SENSOR << 16) | 0x0001,
+ LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME = (LIGHT_SENSOR << 16) | 0x0002,
+ LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME = (LIGHT_SENSOR << 16) | 0x0004,
+};
+
+enum light_property_id {
+ LIGHT_PROPERTY_UNKNOWN = 0,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_LIGHT_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_LINEAR_ACCEL_H_
+#define _SENSOR_LINEAR_ACCEL_H_
+
+//! Pre-defined events for the linear accelerometer sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_LINEAR_ACCEL Linear Accelerometer Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Linear Accelerometer sensor.
+ * @{
+ */
+
+enum linear_accel_data_id {
+ LINEAR_ACCEL_BASE_DATA_SET = (LINEAR_ACCEL_SENSOR << 16) | 0x0001,
+};
+
+enum linear_accel_event_type {
+ LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME = (LINEAR_ACCEL_SENSOR << 16) | 0x0001,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_LINEAR_ACCEL_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_MOTION_H_
+#define _SENSOR_MOTION_H_
+
+//! Pre-defined events for the motion sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+enum motion_event_type {
+ MOTION_ENGINE_EVENT_SNAP = (MOTION_SENSOR << 16) | 0x0001,
+ MOTION_ENGINE_EVENT_SHAKE = (MOTION_SENSOR << 16) | 0x0002,
+ MOTION_ENGINE_EVENT_DOUBLETAP = (MOTION_SENSOR << 16) | 0x0004,
+ MOTION_ENGINE_EVENT_DIRECT_CALL = (MOTION_SENSOR << 16) | 0x0020,
+ MOTION_ENGINE_EVENT_TILT_TO_UNLOCK = (MOTION_SENSOR << 16) | 0x0040,
+ MOTION_ENGINE_EVENT_LOCK_EXECUTE_CAMERA = (MOTION_SENSOR << 16) | 0x0080,
+ MOTION_ENGINE_EVENT_SMART_ALERT = (MOTION_SENSOR << 16) | 0x0100,
+ MOTION_ENGINE_EVENT_TILT = (MOTION_SENSOR << 16) | 0x0200,
+ MOTION_ENGINE_EVENT_PANNING_BROWSE = (MOTION_SENSOR << 16) | 0x0400,
+ MOTION_ENGINE_EVENT_NO_MOVE = (MOTION_SENSOR << 16) | 0x0800,
+ MOTION_ENGINE_EVENT_SHAKE_ALWAYS_ON = (MOTION_SENSOR << 16) | 0x1000,
+};
+
+enum motion_snap_event {
+ MOTION_ENGIEN_SNAP_NONE = 0,
+ MOTION_ENGIEN_NEGATIVE_SNAP_X = 1,
+ MOTION_ENGIEN_POSITIVE_SNAP_X = 2,
+ MOTION_ENGIEN_NEGATIVE_SNAP_Y = 3,
+ MOTION_ENGIEN_POSITIVE_SNAP_Y = 4,
+ MOTION_ENGIEN_NEGATIVE_SNAP_Z = 5,
+ MOTION_ENGIEN_POSITIVE_SNAP_Z = 6,
+ MOTION_ENGIEN_SNAP_LEFT = MOTION_ENGIEN_NEGATIVE_SNAP_X,
+ MOTION_ENGIEN_SNAP_RIGHT = MOTION_ENGIEN_POSITIVE_SNAP_X,
+ MOTION_ENGINE_SNAP_NONE = 0,
+ MOTION_ENGINE_NEGATIVE_SNAP_X = 1,
+ MOTION_ENGINE_POSITIVE_SNAP_X = 2,
+ MOTION_ENGINE_NEGATIVE_SNAP_Y = 3,
+ MOTION_ENGINE_POSITIVE_SNAP_Y = 4,
+ MOTION_ENGINE_NEGATIVE_SNAP_Z = 5,
+ MOTION_ENGINE_POSITIVE_SNAP_Z = 6,
+ MOTION_ENGINE_SNAP_LEFT = MOTION_ENGINE_NEGATIVE_SNAP_X,
+ MOTION_ENGINE_SNAP_RIGHT = MOTION_ENGINE_POSITIVE_SNAP_X,
+};
+
+enum motion_shake_event {
+ MOTION_ENGIEN_SHAKE_NONE = 0,
+ MOTION_ENGIEN_SHAKE_DETECTION = 1,
+ MOTION_ENGIEN_SHAKE_CONTINUING = 2,
+ MOTION_ENGIEN_SHAKE_FINISH = 3,
+ MOTION_ENGINE_SHAKE_BREAK = 4,
+ MOTION_ENGINE_SHAKE_NONE = 0,
+ MOTION_ENGINE_SHAKE_DETECTION = 1,
+ MOTION_ENGINE_SHAKE_CONTINUING = 2,
+ MOTION_ENGINE_SHAKE_FINISH = 3,
+};
+
+enum motion_doubletap_event {
+ MOTION_ENGIEN_DOUBLTAP_NONE = 0,
+ MOTION_ENGIEN_DOUBLTAP_DETECTION = 1,
+ MOTION_ENGINE_DOUBLTAP_NONE = 0,
+ MOTION_ENGINE_DOUBLTAP_DETECTION = 1,
+};
+
+enum motion_top_to_bottom_event {
+ MOTION_ENGIEN_TOP_TO_BOTTOM_NONE = 0,
+ MOTION_ENGIEN_TOP_TO_BOTTOM_WAIT = 1,
+ MOTION_ENGIEN_TOP_TO_BOTTOM_DETECTION = 2,
+ MOTION_ENGINE_TOP_TO_BOTTOM_NONE = 0,
+ MOTION_ENGINE_TOP_TO_BOTTOM_WAIT = 1,
+ MOTION_ENGINE_TOP_TO_BOTTOM_DETECTION = 2,
+};
+
+enum motion_direct_call_event_t {
+ MOTION_ENGINE_DIRECT_CALL_NONE,
+ MOTION_ENGINE_DIRECT_CALL_DETECTION,
+};
+
+enum motion_tilt_to_unlock_event_t {
+ MOTION_ENGINE_TILT_TO_UNLOCK_NONE,
+ MOTION_ENGINE_TILT_TO_UNLOCK_DETECTION,
+};
+
+enum motion_lock_execute_camera_event_t {
+ MOTION_ENGINE_LOCK_EXECUTE_CAMERA_NONE,
+ MOTION_ENGINE_LOCK_EXECUTE_CAMERA_L_DETECTION,
+ MOTION_ENGINE_LOCK_EXECUTE_CAMERA_R_DETECTION,
+};
+
+enum motion_smart_alert_t {
+ MOTION_ENGINE_SMART_ALERT_NONE,
+ MOTION_ENGINE_SMART_ALERT_DETECTION,
+};
+
+enum motion_no_move_t {
+ MOTION_ENGINE_NO_MOVE_NONE,
+ MOTION_ENGINE_NO_MOVE_DETECTION,
+};
+
+enum motion_property_id {
+ MOTION_PROPERTY_UNKNOWN = 0,
+ MOTION_PROPERTY_CHECK_ACCEL_SENSOR,
+ MOTION_PROPERTY_CHECK_GYRO_SENSOR,
+ MOTION_PROPERTY_CHECK_GEO_SENSOR,
+ MOTION_PROPERTY_CHECK_PRIXI_SENSOR,
+ MOTION_PROPERTY_CHECK_LIGHT_SENSOR,
+ MOTION_PROPERTY_CHECK_BARO_SENSOR,
+ MOTION_PROPERTY_LCD_TOUCH_ON,
+ MOTION_PROPERTY_LCD_TOUCH_OFF,
+ MOTION_PROPERTY_CHECK_GYRO_CAL_STATUS,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_MOTION_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * 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_ORIENTATION_H_
+#define _SENSOR_ORIENTATION_H_
+
+//! Pre-defined events for the orientation sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_ORIENTATION Orientation Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Orientation sensor.
+ * @{
+ */
+
+enum orientation_data_id {
+ ORIENTATION_BASE_DATA_SET = (ORIENTATION_SENSOR << 16) | 0x0001,
+};
+
+enum orientation_event_type {
+ ORIENTATION_EVENT_CALIBRATION_NEEDED = (ORIENTATION_SENSOR << 16) | 0x0001,
+ ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME = (ORIENTATION_SENSOR << 16) | 0x0002,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_ORIENTATION_H_*/
--- /dev/null
+/*
+ * libsensord
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __SENSOR_PROXI_H__
+#define __SENSOR_PROXI_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+/**
+ * @defgroup SENSOR_PROXY Proximity Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Proxymaty sensor.
+ * @{
+ */
+
+enum proxi_data_id {
+ PROXIMITY_BASE_DATA_SET = (PROXIMITY_SENSOR << 16) | 0x0001,
+ PROXIMITY_DISTANCE_DATA_SET = (PROXIMITY_SENSOR << 16) | 0x0002,
+};
+
+enum proxi_evet_type {
+ PROXIMITY_EVENT_CHANGE_STATE = (PROXIMITY_SENSOR << 16) | 0x0001,
+ PROXIMITY_EVENT_STATE_REPORT_ON_TIME = (PROXIMITY_SENSOR << 16) | 0x0002,
+ PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME = (PROXIMITY_SENSOR << 16) | 0x0004,
+};
+
+enum proxi_change_state {
+ PROXIMITY_STATE_FAR = 0,
+ PROXIMITY_STATE_NEAR = 1,
+};
+
+enum proxi_property_id {
+ PROXIMITY_PROPERTY_UNKNOWN = 0,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_PROXI_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(light CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME light_sensor)
+SET(SENSOR_HAL_NAME light_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ light_sensor.cpp
+ )
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ light_sensor_hal.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <common.h>
+#include <sf_common.h>
+#include <light_sensor.h>
+#include <sensor_plugin_loader.h>
+#include <algorithm>
+
+using std::bind1st;
+using std::mem_fun;
+
+#define SENSOR_NAME "LIGHT_SENSOR"
+
+#define INITIAL_VALUE -1
+const int light_sensor::m_light_level[] = {0, 1, 165, 288, 497, 869, 1532, 2692, 4692, 8280, 21428, 65535, 137852};
+
+light_sensor::light_sensor()
+: m_sensor_hal(NULL)
+, m_level(INITIAL_VALUE)
+{
+ m_name = string(SENSOR_NAME);
+
+ vector<unsigned int> supported_events = {
+ LIGHT_EVENT_CHANGE_LEVEL,
+ LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME,
+ LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME,
+ };
+
+ for_each(supported_events.begin(), supported_events.end(),
+ bind1st(mem_fun(&sensor_base::register_supported_event), this));
+
+ physical_sensor::set_poller(light_sensor::working, this);
+}
+
+light_sensor::~light_sensor()
+{
+ INFO("light_sensor is destroyed!");
+}
+
+bool light_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(LIGHT_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t light_sensor::get_type(void)
+{
+ return LIGHT_SENSOR;
+}
+
+bool light_sensor::working(void *inst)
+{
+ light_sensor *sensor = (light_sensor *)inst;
+ return sensor->process_event();
+}
+
+bool light_sensor::process_event(void)
+{
+ sensor_event_t event;
+ int level;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+ level = (int) adc_to_light_level((int)event.data.values[0]);
+
+ AUTOLOCK(m_client_info_mutex);
+
+ if (get_client_cnt(LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME)) {
+ event.event_type = LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME;
+ push(event);
+ }
+
+ if (get_client_cnt(LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME)) {
+ event.event_type = LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME;
+ raw_to_level(event.data);
+ push(event);
+ }
+
+ if (m_level != level) {
+ m_level = level;
+
+ if (get_client_cnt(LIGHT_EVENT_CHANGE_LEVEL)) {
+ event.event_type = LIGHT_EVENT_CHANGE_LEVEL;
+ raw_to_level(event.data);
+ push(event);
+ }
+ }
+
+ return true;
+}
+
+int light_sensor::adc_to_light_level(int adc)
+{
+ int level_cnt = sizeof(m_light_level) / sizeof(m_light_level[0]) - 1;
+
+ for (int i = 0; i < level_cnt; ++i) {
+ if (adc >= m_light_level[i] && adc < m_light_level[i + 1])
+ return i;
+ }
+
+ return -1;
+}
+
+bool light_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool light_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool light_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ m_sensor_hal->get_properties(properties);
+
+ if (type == LIGHT_LUX_DATA_SET)
+ return 0;
+
+ if (type == LIGHT_BASE_DATA_SET) {
+ properties.sensor_unit_idx = SENSOR_UNIT_LEVEL;
+ properties.sensor_min_range = 0;
+ properties.sensor_max_range = sizeof(m_light_level) / sizeof(m_light_level[0]) - 1;
+ properties.sensor_resolution = 1;
+ return 0;
+ }
+
+ return -1;
+}
+
+int light_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ int ret;
+ ret = m_sensor_hal->get_sensor_data(data);
+
+ if (ret < 0)
+ return -1;
+
+ if (type == LIGHT_LUX_DATA_SET)
+ return 0;
+
+ if (type == LIGHT_BASE_DATA_SET) {
+ raw_to_level(data);
+ return 0;
+ }
+
+ return -1;
+}
+
+bool light_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ INFO("Polling interval is set to %dms", interval);
+ return m_sensor_hal->set_interval(interval);
+}
+
+void light_sensor::raw_to_level(sensor_data_t &data)
+{
+ data.data_unit_idx = SENSOR_UNIT_LEVEL;
+ data.values[0] = (int) adc_to_light_level((int)data.values[0]);
+ data.values_num = 1;
+}
+
+extern "C" void *create(void)
+{
+ light_sensor *inst;
+
+ try {
+ inst = new light_sensor();
+ } catch (int err) {
+ ERR("Failed to create light_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (light_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _LIGHT_SENSOR_H_
+#define _LIGHT_SENSOR_H_
+
+#include <sensor_common.h>
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class light_sensor : public physical_sensor
+{
+public:
+ light_sensor();
+ virtual ~light_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ virtual bool set_interval(unsigned long interval);
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ int get_sensor_data(const unsigned int type, sensor_data_t &data);
+
+private:
+ static const int m_light_level[];
+ sensor_hal *m_sensor_hal;
+ int m_level;
+
+ int adc_to_light_level(int adc);
+ void raw_to_level(sensor_data_t &data);
+ void raw_to_state(sensor_data_t &data);
+ bool process_event(void);
+};
+#endif /*_LIGHT_SENSOR_H_*/
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <cconfig.h>
+#include <light_sensor_hal.h>
+
+using std::ifstream;
+using config::CConfig;
+
+#define NODE_NAME "name"
+#define NODE_INPUT "input"
+#define NODE_ENABLE "enable"
+#define NODE_POLL_DELAY "poll_delay"
+#define NODE_LIGHT_POLL_DELAY "light_poll_delay"
+#define SENSOR_NODE "/sys/class/sensors/"
+#define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
+#define INPUT_DEVICE_NODE "/sys/class/input/"
+#define DEV_INPUT_NODE "/dev/input/event/"
+
+#define BIAS 1
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+
+#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 INPUT_NAME "light_sensor"
+
+light_sensor_hal::light_sensor_hal()
+: m_adc(INITIAL_VALUE)
+, m_node_handle(INITIAL_VALUE)
+, m_polling_interval(POLL_1HZ_MS)
+, m_fired_time(INITIAL_TIME)
+, m_sensorhub_supported(false)
+{
+ if (!check_hw_node()) {
+ ERR("check_hw_node() fail");
+ throw ENXIO;
+ }
+
+ CConfig &config = CConfig::get_instance();
+
+ if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty");
+ 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");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ if ((m_node_handle = open(m_resource.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_resource.c_str());
+ throw ENXIO;
+ }
+
+ INFO("light_sensor_hal is created!");
+}
+
+light_sensor_hal::~light_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = INITIAL_VALUE;
+
+ INFO("light_sensor_hal is destroyed!");
+}
+
+string light_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t light_sensor_hal::get_type(void)
+{
+ return LIGHT_SENSOR;
+}
+
+bool light_sensor_hal::enable_resource(string &resource_node, bool enable)
+{
+ int prev_status, status;
+ FILE *fp = NULL;
+ fp = fopen(resource_node.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fscanf(fp, "%d", &prev_status) < 0) {
+ ERR("Failed to get data from %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+
+ if (enable) {
+ if (m_sensorhub_supported)
+ status = prev_status | (1 << SENSORHUB_LIGHT_ENABLE_BIT);
+ else
+ status = 1;
+ } else {
+ if (m_sensorhub_supported)
+ status = prev_status ^ (1 << SENSORHUB_LIGHT_ENABLE_BIT);
+ else
+ status = 0;
+ }
+
+ fp = fopen(resource_node.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%d", status) < 0) {
+ ERR("Failed to enable a resource file: %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return true;
+}
+
+bool light_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, true);
+ 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);
+
+ enable_resource(m_enable_resource, false);
+ INFO("Light sensor real stopping");
+ return true;
+}
+
+bool light_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+ FILE *fp = NULL;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * MS_TO_SEC * MS_TO_SEC);
+ fp = fopen(m_polling_resource.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", m_polling_resource.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%llu", polling_interval_ns) < 0) {
+ ERR("Failed to set data %llu", polling_interval_ns);
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
+
+bool light_sensor_hal::update_value(bool wait)
+{
+ const int TIMEOUT = 1;
+ struct timeval tv;
+ fd_set readfds, exceptfds;
+ int adc = INITIAL_VALUE;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&exceptfds);
+ FD_SET(m_node_handle, &readfds);
+ FD_SET(m_node_handle, &exceptfds);
+
+ if (wait) {
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+
+ int ret;
+ ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
+
+ if (ret == -1) {
+ ERR("select error:%s m_node_handle:%d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ DBG("select timeout: %d seconds elapsed", tv.tv_sec);
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &exceptfds)) {
+ ERR("select exception occurred!");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &readfds)) {
+ struct input_event light_event;
+ DBG("light event detection!");
+
+ int len;
+ len = read(m_node_handle, &light_event, sizeof(light_event));
+
+ if (len == -1) {
+ DBG("read(m_node_handle) is error:%s.", 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_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 = get_timestamp(&light_event.time);
+ } else {
+ ERR("select nothing to read!!!");
+ return false;
+ }
+
+ return true;
+}
+
+bool light_sensor_hal::is_data_ready(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int light_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ const int chance = 3;
+ int retry = 0;
+
+ while ((m_fired_time == 0) && (retry++ < chance)) {
+ INFO("Try usleep for getting a valid BASE DATA value");
+ usleep(m_polling_interval * MS_TO_SEC);
+ }
+
+ if (m_fired_time == 0) {
+ ERR("get_sensor_data failed");
+ return -1;
+ }
+
+ AUTOLOCK(m_value_mutex);
+ data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ data.data_unit_idx = SENSOR_UNIT_LUX;
+ data.timestamp = m_fired_time ;
+ data.values_num = 1;
+ data.values[0] = (float) m_adc;
+
+ return 0;
+}
+
+bool light_sensor_hal::get_properties(sensor_properties_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNIT_LUX;
+ properties.sensor_min_range = 0;
+ properties.sensor_max_range = 65536;
+ snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
+ snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
+ properties.sensor_resolution = 1.0f;
+ return true;
+}
+
+bool light_sensor_hal::is_sensorhub_supported(void)
+{
+ DIR *main_dir = NULL;
+ main_dir = opendir(SENSORHUB_NODE);
+
+ if (!main_dir) {
+ INFO("Sensor Hub is not supported");
+ return false;
+ }
+
+ INFO("It supports sensor hub");
+ closedir(main_dir);
+ return true;
+}
+
+bool light_sensor_hal::check_hw_node(void)
+{
+ string name_node;
+ string hw_name;
+ DIR *main_dir = NULL;
+ struct dirent *dir_entry = NULL;
+ bool find_node = false;
+
+ INFO("======================start check_hw_node=============================");
+
+ m_sensorhub_supported = is_sensorhub_supported();
+ main_dir = opendir(SENSOR_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
+ name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (CConfig::get_instance().is_supported(SENSOR_TYPE_LIGHT, hw_name) == true) {
+ m_name = m_model_id = hw_name;
+ INFO("m_model_id = %s", m_model_id.c_str());
+ find_node = true;
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+
+ if (find_node) {
+ main_dir = opendir(INPUT_DEVICE_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ find_node = false;
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
+ name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (hw_name == string(INPUT_NAME)) {
+ INFO("name_node = %s", name_node.c_str());
+ DBG("Find H/W for light_sensor");
+
+ find_node = true;
+ string dir_name;
+ dir_name = string(dir_entry->d_name);
+ unsigned found = dir_name.find_first_not_of(NODE_INPUT);
+ m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
+
+ if (m_sensorhub_supported) {
+ m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
+ m_polling_resource = string(SENSORHUB_NODE) + string(NODE_LIGHT_POLL_DELAY);
+ } else {
+ m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
+ m_polling_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_POLL_DELAY);
+ }
+
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+ }
+
+ if (find_node) {
+ INFO("m_resource = %s", m_resource.c_str());
+ INFO("m_enable_resource = %s", m_enable_resource.c_str());
+ INFO("m_polling_resource = %s", m_polling_resource.c_str());
+ }
+
+ return find_node;
+}
+
+extern "C" void *create(void)
+{
+ light_sensor_hal *inst;
+
+ try {
+ inst = new light_sensor_hal();
+ } catch (int err) {
+ ERR("Failed to create light_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (light_sensor_hal *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _LIGHT_SENSOR_HAL_H_
+#define _LIGHT_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class light_sensor_hal : public sensor_hal
+{
+public:
+ light_sensor_hal();
+ virtual ~light_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ bool get_properties(sensor_properties_t &properties);
+ bool check_hw_node(void);
+
+private:
+ int m_adc;
+ int m_node_handle;
+ unsigned long m_polling_interval;
+ unsigned long long m_fired_time;
+ bool m_sensorhub_supported;
+
+ string m_model_id;
+ string m_name;
+ string m_vendor;
+ string m_chip_name;
+
+ string m_resource;
+ string m_enable_resource;
+ string m_polling_resource;
+
+ cmutex m_value_mutex;
+
+ bool enable_resource(string &resource_node, bool enable);
+ bool update_value(bool wait);
+ bool is_sensorhub_supported(void);
+};
+#endif /*_LIGHT_SENSOR_HAL_H_*/
\ No newline at end of file
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(linear_accel CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME linear_accel_sensor)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ linear_accel_sensor.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <common.h>
+#include <sf_common.h>
+#include <virtual_sensor.h>
+#include <linear_accel_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define SENSOR_NAME "LINEAR_ACCEL_SENSOR"
+
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+#define GRAVITY 9.80665
+
+linear_accel_sensor::linear_accel_sensor()
+: m_gravity_sensor(NULL)
+, m_x(INITIAL_VALUE)
+, m_y(INITIAL_VALUE)
+, m_z(INITIAL_VALUE)
+, m_time(INITIAL_TIME)
+{
+ m_name = string(SENSOR_NAME);
+ register_supported_event(LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME);
+}
+
+linear_accel_sensor::~linear_accel_sensor()
+{
+ INFO("linear_accel_sensor is destroyed!");
+}
+
+bool linear_accel_sensor::init()
+{
+ m_gravity_sensor = sensor_plugin_loader::get_instance().get_sensor(GRAVITY_SENSOR);
+
+ if (!m_gravity_sensor) {
+ ERR("cannot load gravity sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t linear_accel_sensor::get_type(void)
+{
+ return LINEAR_ACCEL_SENSOR;
+}
+
+bool linear_accel_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+ m_gravity_sensor->add_client(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_gravity_sensor->start();
+ activate();
+ return true;
+}
+
+bool linear_accel_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+ m_gravity_sensor->delete_client(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_gravity_sensor->stop();
+ deactivate();
+ return true;
+}
+
+bool linear_accel_sensor::add_interval(int client_id, unsigned int interval, bool is_processor)
+{
+ m_gravity_sensor->add_interval((int)this , interval, true);
+ return sensor_base::add_interval(client_id, interval, is_processor);
+}
+
+bool linear_accel_sensor::delete_interval(int client_id, bool is_processor)
+{
+ m_gravity_sensor->delete_interval((int)this , true);
+ return sensor_base::delete_interval(client_id, is_processor);
+}
+
+void linear_accel_sensor::synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs)
+{
+ vector<sensor_event_t> gravity_event;
+ ((virtual_sensor *)m_gravity_sensor)->synthesize(event, gravity_event);
+
+ if (!gravity_event.empty() && event.event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME) {
+ AUTOLOCK(m_value_mutex);
+
+ m_time = gravity_event[0].data.timestamp;
+ gravity_event[0].event_type = LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME;
+ m_x = event.data.values[0] - gravity_event[0].data.values[0] * GRAVITY;
+ m_y = event.data.values[1] - gravity_event[0].data.values[1] * GRAVITY;
+ m_z = event.data.values[2] - gravity_event[0].data.values[2] * GRAVITY;
+
+ gravity_event[0].data.values[0] = m_x;
+ gravity_event[0].data.values[1] = m_y;
+ gravity_event[0].data.values[2] = m_z;
+ outs.push_back(gravity_event[0]);
+ return;
+ }
+}
+
+int linear_accel_sensor::get_sensor_data(const unsigned int data_id, sensor_data_t &data)
+{
+ if (data_id != LINEAR_ACCEL_BASE_DATA_SET)
+ return -1;
+
+ AUTOLOCK(m_value_mutex);
+ data.data_accuracy = SENSOR_ACCURACY_GOOD;
+ data.data_unit_idx = SENSOR_UNIT_METRE_PER_SECOND_SQUARED;
+ data.time_stamp = m_time;
+ data.values[0] = m_x;
+ data.values[1] = m_y;
+ data.values[2] = m_z;
+ data.values_num = 3;
+ return 0;
+}
+
+bool linear_accel_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ m_gravity_sensor->get_properties(type, properties);
+
+ if (type != LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME)
+ return true;
+
+ strncpy(properties.sensor_name, "Linear Accelerometer Sensor", MAX_KEY_LENGTH);
+ return true;
+}
+
+extern "C" void *create(void)
+{
+ linear_accel_sensor *inst;
+
+ try {
+ inst = new linear_accel_sensor();
+ } catch (int ErrNo) {
+ ERR("Failed to create linear_accel_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (linear_accel_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _LINEAR_ACCEL_SENSOR_H_
+#define _LINEAR_ACCEL_SENSOR_H_
+
+#include <sensor.h>
+#include <vconf.h>
+#include <string>
+
+using std::string;
+
+class linear_accel_sensor : public virtual_sensor
+{
+public:
+ linear_accel_sensor();
+ virtual ~linear_accel_sensor();
+
+ bool init();
+ sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ bool on_start(void);
+ bool on_stop(void);
+
+ void synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs);
+
+ virtual bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
+ virtual bool delete_interval(int client_id, bool is_processor = false);
+
+ int get_sensor_data(const unsigned int data_id, sensor_data_t &data);
+ bool get_properties(const unsigned int type, sensor_properties_t &properties);
+private:
+ sensor_base *m_gravity_sensor;
+ cmutex m_value_mutex;
+
+ float m_x;
+ float m_y;
+ float m_z;
+ unsigned long long m_time;
+};
+
+#endif /*_LINEAR_ACCEL_SENSOR_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(proxi CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+SET(SENSOR_NAME proxi_sensor)
+SET(SENSOR_HAL_NAME proxi_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+add_definitions(${rpkgs_CFLAGS} -DUSE_ONLY_ONE_MODULE)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+add_library(${SENSOR_NAME} SHARED
+ proxi_sensor.cpp
+)
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ proxi_sensor_hal.cpp
+)
+
+target_link_libraries(${SENSOR_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <common.h>
+#include <sf_common.h>
+#include <proxi_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define SENSOR_NAME "PROXI_SENSOR"
+
+proxi_sensor::proxi_sensor()
+: m_sensor_hal(NULL)
+, m_state(PROXIMITY_STATE_FAR)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(PROXIMITY_EVENT_CHANGE_STATE);
+ register_supported_event(PROXIMITY_EVENT_STATE_REPORT_ON_TIME);
+ register_supported_event(PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME);
+
+ physical_sensor::set_poller(proxi_sensor::working, this);
+}
+
+proxi_sensor::~proxi_sensor()
+{
+ INFO("proxi_sensor is destroyed!");
+}
+
+bool proxi_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(PROXIMITY_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+sensor_type_t proxi_sensor::get_type(void)
+{
+ return PROXIMITY_SENSOR;
+}
+
+bool proxi_sensor::working(void *inst)
+{
+ proxi_sensor *sensor = (proxi_sensor *)inst;
+ return sensor->process_event();
+}
+
+bool proxi_sensor::process_event(void)
+{
+ sensor_event_t event;
+ int state;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+
+ AUTOLOCK(m_client_info_mutex);
+ AUTOLOCK(m_mutex);
+
+ if (get_client_cnt(PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME)) {
+ event.event_type = PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME;
+ raw_to_base(event.data);
+ push(event);
+ }
+
+ state = event.data.values[0];
+
+ if (m_state != state) {
+ AUTOLOCK(m_value_mutex);
+ m_state = state;
+
+ if (get_client_cnt(PROXIMITY_EVENT_CHANGE_STATE)) {
+ event.event_type = PROXIMITY_EVENT_CHANGE_STATE;
+ raw_to_state(event.data);
+ push(event);
+ }
+ }
+
+ return true;
+}
+
+bool proxi_sensor::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool proxi_sensor::on_stop(void)
+{
+ AUTOLOCK(m_mutex);
+
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool proxi_sensor::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int proxi_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ int state;
+
+ if ((type != PROXIMITY_BASE_DATA_SET) && (type != PROXIMITY_DISTANCE_DATA_SET))
+ return -1;
+
+ state = m_sensor_hal->get_sensor_data(data);
+
+ if (state < 0) {
+ ERR("m_sensor_hal get struct_data fail");
+ return -1;
+ }
+
+ if (type == PROXIMITY_DISTANCE_DATA_SET) {
+ raw_to_base(data);
+ return 0;
+ }
+
+ return 0;
+}
+
+void proxi_sensor::raw_to_base(sensor_data_t &data)
+{
+ data.values[0] = (float)((PROXIMITY_STATE_NEAR - data.values[0]) * 5);
+}
+
+void proxi_sensor::raw_to_state(sensor_data_t &data)
+{
+ data.values_num = 1;
+}
+
+extern "C" void *create(void)
+{
+ proxi_sensor *inst;
+
+ try {
+ inst = new proxi_sensor();
+ } catch (int err) {
+ ERR("Failed to create proxi_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (proxi_sensor *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _PROXI_SENSOR_H_
+#define _PROXI_SENSOR_H_
+
+#include <sensor_common.h>
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class proxi_sensor : public physical_sensor
+{
+public:
+ proxi_sensor();
+ virtual ~proxi_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ virtual int get_sensor_data(const unsigned int type, sensor_data_t &data);
+private:
+ sensor_hal *m_sensor_hal;
+ cmutex m_value_mutex;
+
+ int m_state;
+
+ void raw_to_base(sensor_data_t &data);
+ void raw_to_state(sensor_data_t &data);
+ bool process_event(void);
+};
+#endif /*_PROXI_SENSOR_H_*/
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <fstream>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <cconfig.h>
+#include <proxi_sensor_hal.h>
+
+using std::ifstream;
+using config::CConfig;
+
+#define NODE_NAME "name"
+#define NODE_INPUT "input"
+#define NODE_ENABLE "enable"
+#define SENSOR_NODE "/sys/class/sensors/"
+#define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
+#define INPUT_DEVICE_NODE "/sys/class/input/"
+#define DEV_INPUT_NODE "/dev/input/event/"
+
+#define INITIAL_VALUE -1
+#define INITIAL_TIME 0
+#define PROXI_CODE 0x0019
+
+#define SENSOR_TYPE_PROXI "PROXI"
+#define ELEMENT_NAME "NAME"
+#define ELEMENT_VENDOR "VENDOR"
+#define ATTR_VALUE "value"
+
+#define INPUT_NAME "proximity_sensor"
+
+proxi_sensor_hal::proxi_sensor_hal()
+: m_state(PROXIMITY_STATE_FAR)
+, m_node_handle(INITIAL_VALUE)
+, m_fired_time(INITIAL_TIME)
+, m_sensorhub_supported(false)
+{
+ if (!check_hw_node()) {
+ ERR("check_hw_node() fail");
+ throw ENXIO;
+ }
+
+ CConfig &config = CConfig::get_instance();
+
+ if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty");
+ 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");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ if ((m_node_handle = open(m_resource.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_resource.c_str());
+ throw ENXIO;
+ }
+
+ INFO("proxi_sensor_hal is created!");
+}
+
+proxi_sensor_hal::~proxi_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = INITIAL_VALUE;
+
+ INFO("proxi_sensor_hal is destroyed!");
+}
+
+string proxi_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t proxi_sensor_hal::get_type(void)
+{
+ return PROXIMITY_SENSOR;
+}
+
+bool proxi_sensor_hal::enable_resource(string &resource_node, bool enable)
+{
+ int prev_status, status;
+ FILE *fp = NULL;
+ fp = fopen(resource_node.c_str(), "r");
+
+ if (!fp) {
+ ERR("Fail to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fscanf(fp, "%d", &prev_status) < 0) {
+ ERR("Failed to get data from %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+
+ if (enable) {
+ if (m_sensorhub_supported)
+ status = prev_status | (1 << SENSORHUB_PROXIMITY_ENABLE_BIT);
+ else
+ status = 1;
+ } else {
+ if (m_sensorhub_supported)
+ status = prev_status ^ (1 << SENSORHUB_PROXIMITY_ENABLE_BIT);
+ else
+ status = 0;
+ }
+
+ fp = fopen(resource_node.c_str(), "w");
+
+ if (!fp) {
+ ERR("Failed to open a resource file: %s", resource_node.c_str());
+ return false;
+ }
+
+ if (fprintf(fp, "%d", status) < 0) {
+ ERR("Failed to enable a resource file: %s", resource_node.c_str());
+ fclose(fp);
+ return false;
+ }
+
+ if (fp)
+ fclose(fp);
+
+ return true;
+}
+
+bool proxi_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, true);
+
+ m_fired_time = 0;
+ INFO("Proxi sensor real starting");
+ return true;
+}
+
+bool proxi_sensor_hal::disable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ enable_resource(m_enable_resource, false);
+ INFO("Proxi sensor real stopping");
+ return true;
+}
+
+bool proxi_sensor_hal::update_value(bool wait)
+{
+ struct input_event proxi_event;
+ fd_set readfds, exceptfds;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&exceptfds);
+ FD_SET(m_node_handle, &readfds);
+ FD_SET(m_node_handle, &exceptfds);
+
+ int ret;
+ ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, NULL);
+
+ if (ret == -1) {
+ ERR("select error:%s m_node_handle:d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ DBG("select timeout");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &exceptfds)) {
+ ERR("select exception occurred!");
+ return false;
+ }
+
+ if (FD_ISSET(m_node_handle, &readfds)) {
+ 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.", 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 == PROXI_CODE)) {
+ AUTOLOCK(m_value_mutex);
+
+ if (proxi_event.value == PROXIMITY_NODE_STATE_FAR) {
+ INFO("PROXIMITY_STATE_FAR state occured");
+ m_state = PROXIMITY_STATE_FAR;
+ } else if (proxi_event.value == PROXIMITY_NODE_STATE_NEAR) {
+ INFO("PROXIMITY_STATE_NEAR state occured");
+ m_state = PROXIMITY_STATE_NEAR;
+ } else {
+ ERR("PROXIMITY_STATE Unknown: %d", proxi_event.value);
+ return false;
+ }
+
+ m_fired_time = sensor_hal::get_timestamp(&proxi_event.time);
+ } else {
+ return false;
+ }
+ } else {
+ ERR("select nothing to read!!!");
+ return false;
+ }
+
+ return true;
+}
+
+bool proxi_sensor_hal::is_data_ready(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int proxi_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ AUTOLOCK(m_value_mutex);
+ data.data_accuracy = SENSOR_ACCURACY_UNDEFINED;
+ data.data_unit_idx = SENSOR_UNIT_STATE_ON_OFF;
+ data.timestamp = m_fired_time;
+ data.values_num = 1;
+ data.values[0] = m_state;
+ return 0;
+}
+
+bool proxi_sensor_hal::get_properties(sensor_properties_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNIT_STATE_ON_OFF;
+ properties.sensor_min_range = 0;
+ properties.sensor_max_range = 1;
+ snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
+ snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
+ properties.sensor_resolution = 1;
+ return true;
+}
+
+bool proxi_sensor_hal::is_sensorhub_supported(void)
+{
+ DIR *main_dir = NULL;
+ main_dir = opendir(SENSORHUB_NODE);
+
+ if (!main_dir) {
+ INFO("Sensor Hub is not supported");
+ return false;
+ }
+
+ INFO("It supports sensor hub");
+ closedir(main_dir);
+ return true;
+}
+
+bool proxi_sensor_hal::check_hw_node(void)
+{
+ string name_node;
+ string hw_name;
+ DIR *main_dir = NULL;
+ struct dirent *dir_entry = NULL;
+ bool find_node = false;
+
+ INFO("======================start check_hw_node=============================");
+
+ m_sensorhub_supported = is_sensorhub_supported();
+ main_dir = opendir(SENSOR_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
+ name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (CConfig::get_instance().is_supported(SENSOR_TYPE_PROXI, hw_name) == true) {
+ m_name = m_model_id = hw_name;
+ INFO("m_model_id = %s", m_model_id.c_str());
+ find_node = true;
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+
+ if (find_node) {
+ main_dir = opendir(INPUT_DEVICE_NODE);
+
+ if (!main_dir) {
+ ERR("Directory open failed to collect data");
+ return false;
+ }
+
+ find_node = false;
+
+ while ((!find_node) && (dir_entry = readdir(main_dir))) {
+ if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
+ name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
+ ifstream infile(name_node.c_str());
+
+ if (!infile)
+ continue;
+
+ infile >> hw_name;
+
+ if (hw_name == string(INPUT_NAME)) {
+ INFO("name_node = %s", name_node.c_str());
+ DBG("Find H/W for proxi_sensor");
+
+ find_node = true;
+ string dir_name;
+ dir_name = string(dir_entry->d_name);
+ unsigned found = dir_name.find_first_not_of(NODE_INPUT);
+ m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
+
+ if (m_sensorhub_supported)
+ m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
+ else
+ m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
+
+ break;
+ }
+ }
+ }
+
+ closedir(main_dir);
+ }
+
+ if (find_node) {
+ INFO("m_resource = %s", m_resource.c_str());
+ INFO("m_enable_resource = %s", m_enable_resource.c_str());
+ }
+
+ return find_node;
+}
+
+extern "C" void *create(void)
+{
+ proxi_sensor_hal *inst;
+
+ try {
+ inst = new proxi_sensor_hal();
+ } catch (int err) {
+ ERR("Failed to create proxi_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (proxi_sensor_hal *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _PROXI_SENSOR_HAL_H_
+#define _PROXI_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class proxi_sensor_hal : public sensor_hal
+{
+public:
+ enum proxi_node_state_event_t {
+ PROXIMITY_NODE_STATE_NEAR = 0,
+ PROXIMITY_NODE_STATE_FAR = 1,
+ PROXIMITY_NODE_STATE_UNKNOWN = 2,
+ };
+
+ proxi_sensor_hal();
+ virtual ~proxi_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ bool get_properties(sensor_properties_t &properties);
+ bool check_hw_node(void);
+
+private:
+ unsigned int m_state;
+ int m_node_handle;
+ unsigned long long m_fired_time;
+ bool m_sensorhub_supported;
+
+ string m_model_id;
+ string m_name;
+ string m_vendor;
+ string m_chip_name;
+
+ string m_resource;
+ string m_enable_resource;
+
+ cmutex m_value_mutex;
+
+ bool enable_resource(string &resource_node, bool enable);
+ bool update_value(bool wait);
+ bool is_sensorhub_supported(void);
+};
+#endif /*_PROXI_SENSOR_HAL_H_*/
\ No newline at end of file
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensor_fusion CXX)
+
+# to install pkgconfig setup file.
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(VERSION 1.0)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED vconf)
+
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "0")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET -DHWREV_CHECK")
+ MESSAGE("add -DTARGET -DHWREV_CHECK")
+ELSE("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DSIMULATOR")
+ MESSAGE("add -DSIMULATOR")
+ENDIF("${ARCH}" MATCHES "^arm.*")
+
+add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-Wall -g -D_DEBUG)
+add_definitions(-DUSE_DLOG_LOG)
+add_definitions(-Iinclude)
+
+SET(SENSOR_FUSION_NAME sensor_fusion)
+
+add_library(${SENSOR_FUSION_NAME} SHARED
+ lib_sensor_fusion.cpp
+ )
+
+target_link_libraries(${SENSOR_FUSION_NAME} ${rpkgs_LDFLAGS} ${GLES_LDFLAGS} "-lm")
+
+install(TARGETS ${SENSOR_FUSION_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <sensor.h>
+#include <common.h>
+#include <sf_common.h>
+#include <lib_sensor_fusion.h>
+#include <sensor_plugin_loader.h>
+
+#define SENSOR_NAME "Sensor Fusion"
+
+lib_sensor_fusion::lib_sensor_fusion()
+{
+ m_name = string(SENSOR_NAME);
+}
+
+lib_sensor_fusion::~lib_sensor_fusion()
+{
+}
+
+bool lib_sensor_fusion::init(void)
+{
+ m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR);
+ m_gyro_sensor = sensor_plugin_loader::get_instance().get_sensor(GYROSCOPE_SENSOR);
+ m_magnetic_sensor = sensor_plugin_loader::get_instance().get_sensor(GEOMAGNETIC_SENSOR);
+
+ if (!m_accel_sensor || !m_gyro_sensor || !m_magnetic_sensor) {
+ ERR("Fail to load sensors, accel: 0x%x, gyro: 0x%x, mag: 0x%x",
+ m_accel_sensor, m_gyro_sensor, m_magnetic_sensor);
+ return false;
+ }
+
+ INFO("%s is created!", sensor_base::get_name());
+ return true;
+}
+
+bool lib_sensor_fusion::on_start(void)
+{
+ AUTOLOCK(m_mutex);
+
+ m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->start();
+ m_gyro_sensor->add_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_gyro_sensor->start();
+ m_magnetic_sensor->add_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_magnetic_sensor->start();
+ return true;
+}
+
+bool lib_sensor_fusion::on_stop(void)
+{
+ m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->stop();
+ m_gyro_sensor->delete_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_gyro_sensor->stop();
+ m_magnetic_sensor->delete_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_magnetic_sensor->stop();
+ return true;
+}
+
+bool lib_sensor_fusion::add_interval(int client_id, unsigned int interval)
+{
+ AUTOLOCK(m_mutex);
+
+ m_accel_sensor->add_interval(client_id, interval, true);
+ m_gyro_sensor->add_interval(client_id, interval, true);
+ m_magnetic_sensor->add_interval(client_id, interval, true);
+ return true;
+}
+
+bool lib_sensor_fusion::delete_interval(int client_id)
+{
+ AUTOLOCK(m_mutex);
+
+ m_accel_sensor->delete_interval(client_id, true);
+ m_gyro_sensor->delete_interval(client_id, true);
+ m_magnetic_sensor->delete_interval(client_id, true);
+ return true;
+}
+
+bool lib_sensor_fusion::get_properties(sensor_properties_t &properties)
+{
+ properties.sensor_unit_idx = SENSOR_UNDEFINED_UNIT;
+ properties.sensor_min_range = 0;
+ properties.sensor_max_range = 1;
+ properties.sensor_resolution = 1;
+ strncpy(properties.sensor_vendor, "Samsung", MAX_KEY_LENGTH);
+ strncpy(properties.sensor_name, SENSOR_NAME, MAX_KEY_LENGTH);
+ return true;
+}
+
+void lib_sensor_fusion::fuse(const sensor_event_t &event)
+{
+ return;
+}
+
+bool lib_sensor_fusion::get_rotation_matrix(arr33_t &rot)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_attitude(float &x, float &y, float &z, float &w)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_gyro_bias(float &x, float &y, float &z)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_rotation_vector(float &x, float &y, float &z, float &w, float &heading_accuracy)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_linear_acceleration(float &x, float &y, float &z)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_gravity(float &x, float &y, float &z)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_rotation_vector_6axis(float &x, float &y, float &z, float &w, float &heading_accuracy)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_geomagnetic_rotation_vector(float &x, float &y, float &z, float &w)
+{
+ return true;
+}
+
+bool lib_sensor_fusion::get_orientation(float &azimuth, float &pitch, float &roll)
+{
+ return true;
+}
+
+extern "C" void *create(void)
+{
+ lib_sensor_fusion *inst;
+
+ try {
+ inst = new lib_sensor_fusion();
+ } catch (int err) {
+ ERR("lib_sensor_fusion class create fail , errno : %d , errstr : %s", err, strerror(err));
+ return NULL;
+ }
+
+ return (void *)inst;
+}
+
+extern "C" void destroy(void *inst)
+{
+ delete (lib_sensor_fusion *)inst;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _LIB_SENSOR_FUSION_H_
+#define _LIB_SENSOR_FUSION_H_
+
+#include <sensor_fusion.h>
+
+class lib_sensor_fusion : public sensor_fusion
+{
+public:
+ lib_sensor_fusion();
+ ~lib_sensor_fusion();
+
+ bool init(void);
+ bool on_start(void);
+ bool on_stop(void);
+
+ bool add_interval(int client_id, unsigned int interval);
+ bool delete_interval(int client_id);
+ bool get_properties(sensor_properties_t &properties);
+
+ void fuse(const sensor_event_t &event);
+ bool get_rotation_matrix(arr33_t &rot);
+ bool get_attitude(float &x, float &y, float &z, float &w);
+ bool get_gyro_bias(float &x, float &y, float &z);
+ bool get_rotation_vector(float &x, float &y, float &z, float &w, float &heading_accuracy);
+ bool get_linear_acceleration(float &x, float &y, float &z);
+ bool get_gravity(float &x, float &y, float &z);
+ bool get_rotation_vector_6axis(float &x, float &y, float &z, float &w, float &heading_accuracy);
+ bool get_geomagnetic_rotation_vector(float &x, float &y, float &z, float &w);
+ bool get_orientation(float &azimuth, float &pitch, float &roll);
+private:
+ sensor_base *m_accel_sensor;
+ sensor_base *m_gyro_sensor;
+ sensor_base *m_magnetic_sensor;
+};
+
+#endif /*_LIB_SENSOR_FUSION_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensord CXX)
+
+#add_definitions(-Wall -g -DUSE_FILE_DEBUG)
+#add_definitions(-Wall -g -D_DEBUG)
+#add_definitions(-Wall -g -pg)
+add_definitions(-Wall -std=gnu++0x)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+SET(SERVER_SRCS
+ server.cpp
+ command_worker.cpp
+ main.cpp
+)
+
+add_executable(${PROJECT_NAME} ${SERVER_SRCS})
+
+target_link_libraries(${PROJECT_NAME} ${rpkgs_LDFLAGS} "sensord-server")
+set(CMAKE_CXX_FLAGS "-lrt -ldl -pthread ${CMAKE_CXX_FLAGS}")
+
+install(TARGETS ${PROJECT_NAME} DESTINATION bin)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <command_worker.h>
+#include <sensor_plugin_loader.h>
+#include <thread>
+#include <string>
+
+using std::string;
+
+command_worker::cmd_handler_t command_worker::m_cmd_handlers[];
+
+command_worker::command_worker(const csocket &socket)
+: m_client_id(CLIENT_ID_INVALID)
+, m_socket(socket)
+, m_module(NULL)
+, m_sensor_type(UNKNOWN_SENSOR)
+{
+ init_cmd_handlers();
+
+ m_worker.set_context(this);
+ m_worker.set_working(working);
+ m_worker.set_stopped(stopped);
+}
+
+command_worker::~command_worker()
+{
+ m_socket.close();
+}
+
+bool command_worker::start(void)
+{
+ return m_worker.start();
+}
+
+void command_worker::init_cmd_handlers(void)
+{
+ static bool init = false;
+
+ if (!init) {
+ m_cmd_handlers[CMD_GET_ID] = &command_worker::cmd_get_id;
+ m_cmd_handlers[CMD_HELLO] = &command_worker::cmd_hello;
+ m_cmd_handlers[CMD_BYEBYE] = &command_worker::cmd_byebye;
+ m_cmd_handlers[CMD_START] = &command_worker::cmd_start;
+ m_cmd_handlers[CMD_STOP] = &command_worker::cmd_stop;
+ m_cmd_handlers[CMD_REG] = &command_worker::cmd_register_event;
+ m_cmd_handlers[CMD_UNREG] = &command_worker::cmd_unregister_event;
+ m_cmd_handlers[CMD_CHECK_EVENT] = &command_worker::cmd_check_event;
+ m_cmd_handlers[CMD_SET_OPTION] = &command_worker::cmd_set_option;
+ m_cmd_handlers[CMD_SET_INTERVAL] = &command_worker::cmd_set_interval;
+ m_cmd_handlers[CMD_UNSET_INTERVAL] = &command_worker::cmd_unset_interval;
+ m_cmd_handlers[CMD_SET_COMMAND] = &command_worker::cmd_set_command;
+ m_cmd_handlers[CMD_GET_PROPERTIES] = &command_worker::cmd_get_properties;
+ m_cmd_handlers[CMD_GET_DATA] = &command_worker::cmd_get_data;
+ m_cmd_handlers[CMD_SEND_SENSORHUB_DATA] = &command_worker::cmd_send_sensorhub_data;
+ init = true;
+ }
+}
+
+bool command_worker::working(void *ctx)
+{
+ int ret;
+ command_worker *inst = (command_worker *)ctx;
+ packet_header header;
+ char *payload;
+
+ if (inst->m_socket.recv(&header, sizeof(header)) <= 0) {
+ DBG("%s failed to receive header", inst->get_info());
+ return false;
+ }
+
+ if (header.size > 0) {
+ payload = new char[header.size];
+
+ if (inst->m_socket.recv(payload, header.size) <= 0) {
+ DBG("%s failed to receive data of packet", inst->get_info());
+ delete[] payload;
+ return false;
+ }
+ } else {
+ payload = NULL;
+ }
+
+ ret = inst->dispatch_command(header.cmd, payload);
+
+ if (payload)
+ delete[] payload;
+
+ return ret;
+}
+
+bool command_worker::stopped(void *ctx)
+{
+ event_type_vector event_vec;
+ command_worker *inst = (command_worker *)ctx;
+
+ INFO("%s is stopped", inst->get_info());
+
+ if ((inst->m_module) && (inst->m_client_id != CLIENT_ID_INVALID)) {
+ get_client_info_manager().get_registered_events(inst->m_client_id, inst->m_sensor_type, event_vec);
+ event_type_vector::iterator it_event;
+ it_event = event_vec.begin();
+
+ while (it_event != event_vec.end()) {
+ WARN("Does not unregister event[0x%x] before connection broken for [%s]!!", *it_event, inst->m_module->get_name());
+
+ if (!inst->m_module->delete_client(*it_event))
+ ERR("Unregistering event[0x%x] failed", *it_event);
+
+ ++it_event;
+ }
+
+ if (get_client_info_manager().is_started(inst->m_client_id, inst->m_sensor_type)) {
+ WARN("Does not receive cmd_stop before connection broken for [%s]!!", inst->m_module->get_name());
+ inst->m_module->delete_interval(inst->m_client_id, false);
+ inst->m_module->stop();
+ }
+
+ if (inst->m_sensor_type) {
+ if (get_client_info_manager().has_sensor_record(inst->m_client_id, inst->m_sensor_type)) {
+ INFO("Removing sensor[0x%x] record for client_id[%d]", inst->m_sensor_type, inst->m_client_id);
+ get_client_info_manager().remove_sensor_record(inst->m_client_id, inst->m_sensor_type);
+ }
+ }
+ }
+
+ delete inst;
+ return true;
+}
+
+bool command_worker::dispatch_command(int cmd, void *payload)
+{
+ int ret = false;
+
+ if (!(cmd > 0 && cmd < CMD_CNT)) {
+ ERR("Unknown command: %d", cmd);
+ } else {
+ cmd_handler_t cmd_handler;
+ cmd_handler = command_worker::m_cmd_handlers[cmd];
+
+ if (cmd_handler)
+ ret = (this->*cmd_handler)(payload);
+ }
+
+ return ret;
+}
+
+bool command_worker::send_cmd_done(long value)
+{
+ cpacket *ret_packet;
+ cmd_done_t *cmd_done;
+
+ ret_packet = new cpacket(sizeof(cmd_done_t));
+ ret_packet->set_cmd(CMD_DONE);
+ cmd_done = (cmd_done_t *)ret_packet->data();
+ cmd_done->value = value;
+
+ if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
+ ERR("Failed to send a cmd_done to client_id [%d] with value [%ld]", m_client_id, value);
+ delete ret_packet;
+ return false;
+ }
+
+ delete ret_packet;
+ return true;
+}
+
+bool command_worker::send_cmd_get_id_done(int client_id)
+{
+ cpacket *ret_packet;
+ cmd_get_id_done_t *cmd_get_id_done;
+
+ ret_packet = new cpacket(sizeof(cmd_get_id_done_t));
+ ret_packet->set_cmd(CMD_GET_ID);
+ cmd_get_id_done = (cmd_get_id_done_t *)ret_packet->data();
+ cmd_get_id_done->client_id = client_id;
+
+ if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
+ ERR("Failed to send a cmd_get_id_done with client_id [%d]", client_id);
+ delete ret_packet;
+ return false;
+ }
+
+ delete ret_packet;
+ return true;
+}
+
+bool command_worker::send_cmd_properties_done(int state, sensor_properties_t *properties)
+{
+ cpacket *ret_packet;
+ cmd_properties_done_t *cmd_properties_done;
+
+ ret_packet = new cpacket(sizeof(cmd_properties_done_t));
+ ret_packet->set_cmd(CMD_GET_PROPERTIES);
+ cmd_properties_done = (cmd_properties_done_t *)ret_packet->data();
+ cmd_properties_done->state = state;
+ memcpy(&cmd_properties_done->properties, properties , sizeof(sensor_properties_t));
+
+ if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
+ ERR("Failed to send a cmd_get_properties");
+ delete ret_packet;
+ return false;
+ }
+
+ delete ret_packet;
+ return true;
+}
+
+bool command_worker::send_cmd_get_data_done(int state, sensor_data_t *data)
+{
+ cpacket *ret_packet;
+ cmd_get_data_done_t *cmd_get_data_done;
+
+ ret_packet = new cpacket(sizeof(cmd_get_data_done_t));
+ ret_packet->set_cmd(CMD_GET_DATA);
+ cmd_get_data_done = (cmd_get_data_done_t *)ret_packet->data();
+ cmd_get_data_done->state = state;
+ memcpy(&cmd_get_data_done->base_data , data, sizeof(sensor_data_t));
+
+ if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
+ ERR("Failed to send a cmd_get_data_done");
+ delete ret_packet;
+ return false;
+ }
+
+ delete ret_packet;
+ return true;
+}
+
+bool command_worker::cmd_get_id(void *payload)
+{
+ DBG("CMD_GET_ID Handler invoked");
+
+ cmd_get_id_t *cmd;
+ int client_id;
+
+ cmd = (cmd_get_id_t *)payload;
+ client_id = get_client_info_manager().create_client_record();
+ get_client_info_manager().set_client_info(client_id, cmd->pid);
+ INFO("New client id [%d] created", client_id);
+
+ if (!send_cmd_get_id_done(client_id))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_hello(void *payload)
+{
+ DBG("CMD_HELLO Handler invoked");
+
+ cmd_hello_t *cmd;
+ long ret_value = OP_ERROR;
+
+ cmd = (cmd_hello_t *)payload;
+ m_sensor_type = static_cast<sensor_type_t>(cmd->sensor);
+ m_client_id = cmd->client_id;
+ DBG("Hello sensor [0x%x], client id [%d]", m_sensor_type, m_client_id);
+ m_module = (sensor_base *)sensor_plugin_loader::get_instance().get_sensor(m_sensor_type);
+
+ if (m_module) {
+ get_client_info_manager().create_sensor_record(m_client_id, m_sensor_type);
+ INFO("New sensor record created for sensor [0x%x], sensor name [%s] on client id [%d]", m_sensor_type, m_module->get_name(), m_client_id);
+ ret_value = OP_SUCCESS;
+ } else {
+ ERR("Sensor type[0x%x] is not supported", m_sensor_type);
+
+ if (!get_client_info_manager().has_sensor_record(m_client_id))
+ get_client_info_manager().remove_client_record(m_client_id);
+ }
+
+ if (!send_cmd_done(ret_value))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_byebye(void *payload)
+{
+ long ret_value;
+ DBG("CMD_BYEBYE for client [%d], sensor [0x%x]", m_client_id, m_sensor_type);
+
+ if (!get_client_info_manager().remove_sensor_record(m_client_id, m_sensor_type)) {
+ ERR("Error removing sensor_record for client [%d]", m_client_id);
+ ret_value = OP_ERROR;
+ } else {
+ m_client_id = CLIENT_ID_INVALID;
+ ret_value = OP_SUCCESS;
+ }
+
+ if (!send_cmd_done(ret_value))
+ ERR("Failed to send cmd_done to a client");
+
+ if (ret_value == OP_SUCCESS)
+ return false;
+
+ return true;
+}
+
+bool command_worker::cmd_start(void *payload)
+{
+ long value = OP_SUCCESS;
+ DBG("START Sensor [0x%x], called from client [%d]", m_sensor_type, m_client_id);
+ DBG("Invoke Module start for []");
+
+ if (m_module->start()) {
+ get_client_info_manager().set_start(m_client_id, m_sensor_type, true);
+
+ /*
+ * Rotation could be changed even LCD is off by pop sync rotation
+ * and a client listening rotation event with always-on option.
+ * To reflect the last rotation state, request it to event dispatcher.
+ */
+ get_event_dispathcher().request_last_event(m_client_id, m_sensor_type);
+ } else {
+ value = OP_ERROR;
+ }
+
+ if (!send_cmd_done(value))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_stop(void *payload)
+{
+ long ret_val = OP_SUCCESS;
+ DBG("STOP Sensor [0x%x], called from client [%d]", m_sensor_type, m_client_id);
+
+ if (m_module->stop()) {
+ get_client_info_manager().set_start(m_client_id, m_sensor_type, false);
+ }
+
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_register_event(void *payload)
+{
+ cmd_reg_t *cmd;
+ long ret_val = OP_ERROR;
+
+ cmd = (cmd_reg_t *)payload;
+
+ if (!get_client_info_manager().register_event(m_client_id, cmd->event_type)) {
+ INFO("Failed to register event [0x%x] for client [%d] to client info manager",
+ cmd->event_type, m_client_id);
+ goto out;
+ }
+
+ m_module->add_client(cmd->event_type);
+ ret_val = OP_SUCCESS;
+ DBG("Registering Event [0x%x] is done for client [%d]", cmd->event_type, m_client_id);
+
+out:
+
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_unregister_event(void *payload)
+{
+ cmd_unreg_t *cmd;
+ long ret_val = OP_ERROR;
+ cmd = (cmd_unreg_t *)payload;
+
+ if (!get_client_info_manager().unregister_event(m_client_id, cmd->event_type)) {
+ ERR("Failed to unregister event [0x%x] for client [%d from client info manager",
+ cmd->event_type, m_client_id);
+ goto out;
+ }
+
+ if (!m_module->delete_client(cmd->event_type)) {
+ ERR("Failed to unregister event [0x%x] for client [%d]",
+ cmd->event_type, m_client_id);
+ goto out;
+ }
+
+ ret_val = OP_SUCCESS;
+ DBG("Unregistering Event [0x%x] is done for client [%d]",
+ cmd->event_type, m_client_id);
+
+out:
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_check_event(void *payload)
+{
+ cmd_check_event_t *cmd;
+ long ret_val = OP_ERROR;
+ cmd = (cmd_check_event_t *)payload;
+
+ if (m_module->is_supported(cmd->event_type)) {
+ ret_val = OP_SUCCESS;
+ DBG("Event[0x%x] is supported for client [%d], for sensor [0x%x]", cmd->event_type, m_client_id, (cmd->event_type >> 16));
+ }
+
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_set_interval(void *payload)
+{
+ cmd_set_interval_t *cmd;
+ long ret_val = OP_ERROR;
+ cmd = (cmd_set_interval_t *)payload;
+
+ if (!get_client_info_manager().set_interval(m_client_id, m_sensor_type, cmd->interval)) {
+ ERR("Failed to register interval for client [%d], for sensor [0x%x] with interval [%d] to client info manager",
+ m_client_id, m_sensor_type, cmd->interval);
+ goto out;
+ }
+
+ if (!m_module->add_interval(m_client_id, cmd->interval, false)) {
+ ERR("Failed to set interval for client [%d], for sensor [0x%x] with interval [%d]",
+ m_client_id, m_sensor_type, cmd->interval);
+ goto out;
+ }
+
+ ret_val = OP_SUCCESS;
+
+out:
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_unset_interval(void *payload)
+{
+ long ret_val = OP_ERROR;
+
+ if (!get_client_info_manager().set_interval(m_client_id, m_sensor_type, 0)) {
+ ERR("Failed to unregister interval for client [%d], for sensor [0x%x] to client info manager",
+ m_client_id, m_sensor_type);
+ goto out;
+ }
+
+ if (!m_module->delete_interval(m_client_id, false)) {
+ ERR("Failed to delete interval for client [%d]", m_client_id);
+ goto out;
+ }
+
+ ret_val = OP_SUCCESS;
+
+out:
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_set_option(void *payload)
+{
+ cmd_set_option_t *cmd;
+ long ret_val = OP_ERROR;
+ cmd = (cmd_set_option_t *)payload;
+
+ if (!get_client_info_manager().set_option(m_client_id, m_sensor_type, cmd->option)) {
+ ERR("Failed to register interval for client [%d], for sensor [0x%x] with option [%d] to client info manager",
+ m_client_id, m_sensor_type, cmd->option);
+ goto out;
+ }
+
+ ret_val = OP_SUCCESS;
+
+out:
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_set_command(void *payload)
+{
+ DBG("CMD_SET_COMMAND Handler invoked");
+
+ cmd_set_command_t *cmd;
+ long ret_val = OP_ERROR;
+ cmd = (cmd_set_command_t *)payload;
+ ret_val = m_module->set_command(cmd->cmd, cmd->value);
+
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_get_properties(void *payload)
+{
+ DBG("CMD_GET_PROPERTIES Handler invoked");
+ int state = OP_ERROR;
+ cmd_get_properties_t *cmd;
+ sensor_properties_t sensor_properties;
+
+ cmd = (cmd_get_properties_t *) payload;
+ memset(&sensor_properties, 0, sizeof(sensor_properties));
+ state = m_module->get_properties(cmd->type, sensor_properties);
+
+ if (state != 0)
+ ERR("processor_module get_property fail");
+
+ if (!send_cmd_properties_done(state, &sensor_properties))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+bool command_worker::cmd_get_data(void *payload)
+{
+ DBG("CMD_GET_VALUE Handler invoked");
+ cmd_get_data_t *cmd;
+ int state = OP_ERROR;
+ sensor_data_t base_data;
+
+ cmd = (cmd_get_data_t *)payload;
+ state = m_module->get_sensor_data(cmd->type, base_data);
+
+ if (state != 0)
+ ERR("processor_module cmd_get_data fail");
+
+ send_cmd_get_data_done(state, &base_data);
+ return true;
+}
+
+bool command_worker::cmd_send_sensorhub_data(void *payload)
+{
+ DBG("CMD_SEND_SENSORHUB_DATA Handler invoked");
+ cmd_send_sensorhub_data_t *cmd;
+ long ret_val = OP_ERROR;
+
+ cmd = (cmd_send_sensorhub_data_t *)payload;
+ ret_val = m_module->send_sensorhub_data(cmd->data, cmd->data_len);
+
+ if (!send_cmd_done(ret_val))
+ ERR("Failed to send cmd_done to a client");
+
+ return true;
+}
+
+const char *command_worker::get_info(void)
+{
+ static string info;
+ const char *client_info = NULL;
+ const char *sensor_info = NULL;
+
+ if (m_client_id != CLIENT_ID_INVALID)
+ client_info = get_client_info_manager().get_client_info(m_client_id);
+
+ if (m_module)
+ sensor_info = m_module->get_name();
+
+ info = string("Command worker for ") + (client_info ? client_info : "Unknown") + "'s "
+ + (sensor_info ? sensor_info : "Unknown");
+ return info.c_str();
+}
+
+cclient_info_manager &command_worker::get_client_info_manager(void)
+{
+ return cclient_info_manager::get_instance();
+}
+
+csensor_event_dispatcher &command_worker::get_event_dispathcher(void)
+{
+ return csensor_event_dispatcher::get_instance();
+}
+
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef COMMAND_WORKER_H_
+#define COMMAND_WORKER_H_
+
+#include <worker_thread.h>
+#include <cclient_info_manager.h>
+#include <csensor_event_dispatcher.h>
+#include <sensor_base.h>
+
+class command_worker
+{
+private:
+ typedef bool (command_worker::*cmd_handler_t)(void *payload);
+
+ static const int OP_ERROR = -1;
+ static const int OP_SUCCESS = 0;
+
+ int m_client_id;
+ csocket m_socket;
+ worker_thread m_worker;
+ sensor_base *m_module;
+ sensor_type_t m_sensor_type;
+
+ static cmd_handler_t m_cmd_handlers[CMD_CNT];
+
+ static void init_cmd_handlers(void);
+
+ static bool working(void *ctx);
+ static bool stopped(void *ctx);
+
+ bool dispatch_command(int cmd, void *payload);
+
+ bool send_cmd_done(long value);
+ bool send_cmd_get_id_done(int client_id);
+ bool send_cmd_properties_done(int state, sensor_properties_t *properties);
+ bool send_cmd_get_data_done(int state, sensor_data_t *data);
+
+ bool cmd_get_id(void *payload);
+ bool cmd_hello(void *payload);
+ bool cmd_byebye(void *payload);
+ bool cmd_get_value(void *payload);
+ bool cmd_start(void *payload);
+ bool cmd_stop(void *payload);
+ bool cmd_register_event(void *payload);
+ bool cmd_unregister_event(void *payload);
+ bool cmd_check_event(void *payload);
+ bool cmd_set_interval(void *payload);
+ bool cmd_unset_interval(void *payload);
+ bool cmd_set_option(void *payload);
+ bool cmd_set_command(void *payload);
+ bool cmd_get_properties(void *payload);
+ bool cmd_get_data(void *payload);
+ bool cmd_send_sensorhub_data(void *payload);
+
+ const char *get_info(void);
+
+ static cclient_info_manager &get_client_info_manager(void);
+ static csensor_event_dispatcher &get_event_dispathcher(void);
+public:
+ command_worker(const csocket &socket);
+ virtual ~command_worker();
+
+ bool start(void);
+};
+#endif /* COMMAND_WORKER_H_ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <signal.h>
+#include <common.h>
+#include <server.h>
+#include <sensor_plugin_loader.h>
+
+static void sig_term_handler(int signo, siginfo_t *info, void *data)
+{
+ char proc_name[NAME_MAX];
+
+ get_proc_name(info->si_pid, proc_name);
+
+ ERR("Received SIGTERM(%d) from %s(%d)", signo, proc_name, info->si_pid);
+ exit(EXIT_SUCCESS);
+}
+
+static void signal_init(void)
+{
+ struct sigaction sig_act;
+
+ sig_act.sa_handler = SIG_IGN;
+ sigemptyset(&sig_act.sa_mask);
+
+ sigaction(SIGCHLD, &sig_act, NULL);
+ sigaction(SIGPIPE, &sig_act, NULL);
+
+ sig_act.sa_handler = NULL;
+ sig_act.sa_sigaction = sig_term_handler;
+ sig_act.sa_flags = SA_SIGINFO;
+ sigaction(SIGTERM, &sig_act, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ signal_init();
+
+ INFO("Sensord started");
+
+ sensor_plugin_loader::get_instance().load_plugins();
+
+ server::get_instance().run();
+ server::get_instance().stop();
+
+ sensor_plugin_loader::get_instance().destroy();
+
+ INFO("Sensord terminated");
+ return 0;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <systemd/sd-daemon.h>
+#include <server.h>
+#include <sensor_plugin_loader.h>
+#include <command_worker.h>
+#include <thread>
+
+using std::thread;
+
+server::server()
+: m_mainloop(NULL)
+{
+}
+
+server::~server()
+{
+ stop();
+}
+
+int server::get_systemd_socket(const char *name)
+{
+ int type = SOCK_STREAM;
+ const int listening = 1;
+ size_t length = 0;
+ int fd = -1;
+
+ if (sd_listen_fds(1) != 1)
+ return -1;
+
+ fd = SD_LISTEN_FDS_START + 0;
+
+ if (sd_is_socket_unix(fd, type, listening, name, length) > 0)
+ return fd;
+
+ return -1;
+}
+
+void server::accept_client(void)
+{
+ command_worker *cmd_worker;
+ INFO("Client acceptor is started");
+
+ while (true) {
+ csocket client_command_socket;
+
+ if (!m_client_accep_socket.accept(client_command_socket)) {
+ ERR("Failed to accept connection request from a client");
+ continue;
+ }
+
+ DBG("New client (socket_fd : %d) connected", client_command_socket.get_socket_fd());
+ cmd_worker = new command_worker(client_command_socket);
+
+ if (!cmd_worker->start())
+ delete cmd_worker;
+ }
+}
+
+void server::run(void)
+{
+ int sock_fd = -1;
+ const int MAX_PENDING_CONNECTION = 5;
+
+ m_mainloop = g_main_loop_new(NULL, false);
+
+ sock_fd = get_systemd_socket(COMMAND_CHANNEL_PATH);
+
+ if (sock_fd >= 0) {
+ INFO("Succeeded to get systemd socket(%d)", sock_fd);
+ m_client_accep_socket = csocket(sock_fd);
+ } else {
+ ERR("Failed to get systemd socket, create it by myself!");
+
+ if (!m_client_accep_socket.create(SOCK_STREAM)) {
+ ERR("Failed to create command channel");
+ return;
+ }
+
+ if (!m_client_accep_socket.bind(COMMAND_CHANNEL_PATH)) {
+ ERR("Failed to bind command channel");
+ m_client_accep_socket.close();
+ return;
+ }
+
+ if (!m_client_accep_socket.listen(MAX_PENDING_CONNECTION)) {
+ ERR("Failed to listen command channel");
+ return;
+ }
+ }
+
+ csensor_event_dispatcher::get_instance().run();
+
+ thread client_accepter(&server::accept_client, this);
+ client_accepter.detach();
+
+ sd_notify(0, "READY=1");
+
+ g_main_loop_run(m_mainloop);
+ g_main_loop_unref(m_mainloop);
+ return;
+}
+
+void server::stop(void)
+{
+ if (m_mainloop)
+ g_main_loop_quit(m_mainloop);
+
+ m_client_accep_socket.close();
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _SERVER_H_
+#define _SERVER_H_
+
+#include <glib.h>
+#include <csocket.h>
+
+class server
+{
+private:
+ GMainLoop *m_mainloop;
+ csocket m_client_accep_socket;
+
+ server();
+ ~server();
+
+ void accept_client(void);
+ int get_systemd_socket(const char *name);
+public:
+ void run(void);
+ void stop(void);
+ static server &get_instance() {
+ static server inst;
+ return inst;
+ }
+};
+
+#endif /*_SERVER_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sf_common CXX)
+# to install pkgconfig setup file.
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+#set(CMAKE_INSTALL_PREFIX "$ENV{DATAFS}")
+set(PROJECT_MAJOR_VERSION "0")
+set(PROJECT_MINOR_VERSION "2")
+set(PROJECT_RELEASE_VERSION "1")
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+
+include(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED dlog libxml-2.0)
+add_definitions(${rpkgs_CFLAGS})
+
+add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
+add_definitions(-DLOCALEDIR="$ENV{DATAFS}/share/locale")
+add_definitions(-DFACTORYFS="$ENV{FACTORYFS}")
+add_definitions(-DDATAFS="$ENV{DATAFS}")
+add_definitions(-Wall -std=gnu++0x)
+add_definitions(-DUSE_DLOG_LOG)
+#add_definitions(-DX1_PROF)
+#add_definitions(-D_GETTEXT)
+#add_definitions(-Wall -O3 -omit-frame-pointer)
+#add_definitions(-D_DEFAULT_FONT_NAME="Vera")
+#add_definitions(-Wall -g -DUSE_FILE_DEBUG)
+#add_definitions(-Wall -g -D_DEBUG)
+#add_definitions(-Wl,--as-needed -Wl,-O1)
+#add_definitions(-finstrument-functions)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+add_library(sensord-server SHARED
+ crw_lock.cpp
+ worker_thread.cpp
+ cconfig.cpp
+ csensor_event_queue.cpp
+ csensor_event_dispatcher.cpp
+ csensor_usage.cpp
+ cclient_info_manager.cpp
+ cclient_sensor_record.cpp
+ cinterval_info_list.cpp
+ sensor_plugin_loader.cpp
+ sensor_hal.cpp
+ sensor_base.cpp
+ physical_sensor.cpp
+ virtual_sensor.cpp
+ sensor_fusion.cpp
+)
+
+add_library(sensord-share SHARED
+ cpacket.cpp
+ csocket.cpp
+ cbase_lock.cpp
+ cmutex.cpp
+ common.cpp
+)
+
+target_link_libraries(sensord-server ${rpkgs_LDFLAGS} "-lrt -ldl -pthread" "sensord-share")
+target_link_libraries(sensord-share ${rpkgs_LDFLAGS} "-lrt -ldl -pthread")
+configure_file(sensord-server.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/sensord-server.pc @ONLY)
+configure_file(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
+
+install(TARGETS sensord-server DESTINATION lib)
+install(TARGETS sensord-share DESTINATION lib)
+install(FILES sensord-server.pc DESTINATION lib/pkgconfig)
+install(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+install(FILES
+ sensor_fusion.h
+ crw_lock.h
+ worker_thread.h
+ cconfig.h
+ csensor_event_queue.h
+ cinterval_info_list.h
+ sensor_plugin_loader.h
+ sensor_hal.h
+ sensor_base.h
+ physical_sensor.h
+ virtual_sensor.h
+ sensor_fusion.h
+ sf_common.h
+ cpacket.h
+ csocket.h
+ cbase_lock.h
+ cmutex.h
+ common.h
+ DESTINATION include/${PROJECT_NAME}
+)
+
+install(FILES
+ sensor_common.h
+ DESTINATION include/sensor
+)
+
--- /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 <common.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::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;
+}
--- /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 _CBASE_LOCK_H_
+#define _CBASE_LOCK_H_
+
+#include <pthread.h>
+
+enum lock_type {
+ LOCK_TYPE_MUTEX,
+ LOCK_TYPE_READ,
+ LOCK_TYPE_WRITE,
+};
+
+#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()
+
+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 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) : m_lock(m) {
+ m_lock.lock(type, expr, module, func, line);
+ }
+
+ ~Autolock() {
+ m_lock.unlock();
+ }
+};
+
+#endif /*_CBASE_LOCK_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 <cclient_info_manager.h>
+#include <common.h>
+#include <csocket.h>
+
+using std::pair;
+
+cclient_info_manager::cclient_info_manager()
+{
+}
+
+cclient_info_manager::~cclient_info_manager()
+{
+ m_clients.clear();
+}
+
+unsigned int cclient_info_manager::get_interval(const int client_id, const sensor_type_t sensor)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return 0;
+ }
+
+ return it_record->second.get_interval(sensor);
+}
+
+bool cclient_info_manager::is_sensor_used(const sensor_type_t sensor, const event_situation mode)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.begin();
+
+ while (it_record != m_clients.end()) {
+ if (it_record->second.is_sensor_used(sensor, mode))
+ return true;
+
+ ++it_record;
+ }
+
+ return false;
+}
+
+bool cclient_info_manager::get_registered_events(const int client_id, const sensor_type_t sensor, event_type_vector &event_vec)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.get_registered_events(sensor, event_vec))
+ return false;
+
+ return true;
+}
+
+
+bool cclient_info_manager::register_event(const int client_id, const unsigned int event_type)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.register_event(event_type))
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::unregister_event(const int client_id, const unsigned int event_type)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.unregister_event(event_type))
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::set_interval(const int client_id, const sensor_type_t sensor, const unsigned int interval)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.set_interval(sensor, interval))
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::set_option(const int client_id, const sensor_type_t sensor, const int option)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.set_option(sensor, option))
+ return false;
+
+ return true;
+}
+
+
+bool cclient_info_manager::set_start(const int client_id, const sensor_type_t sensor, bool start)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.set_start(sensor, start))
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::is_started(const int client_id, const sensor_type_t sensor)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ return it_record->second.is_started(sensor);
+}
+
+int cclient_info_manager::create_client_record(void)
+{
+ AUTOLOCK(m_mutex);
+ int client_id = 0;
+ cclient_sensor_record client_record;
+
+ while (m_clients.count(client_id) > 0)
+ client_id++;
+
+ if (client_id == MAX_HANDLE) {
+ ERR("Sensor records of clients are full");
+ return MAX_HANDLE_REACHED;
+ }
+
+ client_record.set_client_id(client_id);
+ m_clients.insert(pair<int, cclient_sensor_record> (client_id, client_record));
+ return client_id;
+}
+
+
+bool cclient_info_manager::remove_client_record(const int client_id)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ m_clients.erase(it_record);
+ INFO("Client record for client[%d] is removed from client info manager", client_id);
+ return true;
+}
+
+
+bool cclient_info_manager::has_client_record(int client_id)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ return (it_record != m_clients.end());
+}
+
+
+void cclient_info_manager::set_client_info(int client_id, pid_t pid)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return;
+ }
+
+ it_record->second.set_client_info(pid);
+ return;
+}
+
+const char *cclient_info_manager::get_client_info(int client_id)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ DBG("Client[%d] is not found", client_id);
+ return NULL;
+ }
+
+ return it_record->second.get_client_info();
+}
+
+bool cclient_info_manager::create_sensor_record(int client_id, const sensor_type_t sensor)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client record[%d] is not registered", client_id);
+ return false;
+ }
+
+ it_record->second.add_sensor_usage(sensor);
+ return true;
+}
+
+bool cclient_info_manager::remove_sensor_record(const int client_id, const sensor_type_t sensor)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.remove_sensor_usage(sensor))
+ return false;
+
+ if (!it_record->second.has_sensor_usage())
+ remove_client_record(client_id);
+
+ return true;
+}
+
+
+bool cclient_info_manager::has_sensor_record(const int client_id, const sensor_type_t sensor)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ DBG("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.has_sensor_usage(sensor))
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::has_sensor_record(const int client_id)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ DBG("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ if (!it_record->second.has_sensor_usage())
+ return false;
+
+ return true;
+}
+
+bool cclient_info_manager::get_listener_ids(const unsigned int event_type, const event_situation mode, client_id_vec &id_vec)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.begin();
+
+ while (it_record != m_clients.end()) {
+ if (it_record->second.is_listening_event(event_type, mode))
+ id_vec.push_back(it_record->first);
+
+ ++it_record;
+ }
+
+ return true;
+}
+
+bool cclient_info_manager::get_event_socket(const int client_id, csocket &socket)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ it_record->second.get_event_socket(socket);
+ return true;
+}
+
+bool cclient_info_manager::set_event_socket(const int client_id, const csocket &socket)
+{
+ AUTOLOCK(m_mutex);
+ client_id_sensor_record_map::iterator it_record;
+ it_record = m_clients.find(client_id);
+
+ if (it_record == m_clients.end()) {
+ ERR("Client[%d] is not found", client_id);
+ return false;
+ }
+
+ it_record->second.set_event_socket(socket);
+ 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.
+ *
+ */
+
+#ifndef _CCLIENT_INFO_MANAGER_H_
+#define _CCLIENT_INFO_MANAGER_H_
+
+#include <cclient_sensor_record.h>
+#include <map>
+#include <common.h>
+#include <cmutex.h>
+
+using std::map;
+
+typedef map<int, cclient_sensor_record> client_id_sensor_record_map;
+typedef vector<int> client_id_vec;
+
+class cclient_info_manager
+{
+public:
+ static cclient_info_manager &get_instance() {
+ static cclient_info_manager inst;
+ return inst;
+ }
+
+ int create_client_record(void);
+ bool remove_client_record(const int client_id);
+ bool has_client_record(int client_id);
+
+ void set_client_info(int client_id, pid_t pid);
+ const char *get_client_info(int client_id);
+
+ bool create_sensor_record(int client_id, const sensor_type_t sensor);
+ bool remove_sensor_record(const int client_id, const sensor_type_t sensor);
+ bool has_sensor_record(const int client_id, const sensor_type_t sensor);
+ bool has_sensor_record(const int client_id);
+
+ bool register_event(const int client_id, const unsigned int event_type);
+ bool unregister_event(const int client_id, const unsigned int event_type);
+ bool is_sensor_event_registered(const int client_id, const unsigned int event_type);
+
+ bool set_interval(const int client_id, const sensor_type_t sensor, const unsigned int interval);
+ unsigned int get_interval(const int client_id, const sensor_type_t sensor);
+ bool set_option(const int client_id, const sensor_type_t sensor, const int option);
+
+ bool set_start(const int client_id, const sensor_type_t sensor, bool start);
+ bool is_started(const int client_id, const sensor_type_t sensor);
+
+ bool is_sensor_used(const sensor_type_t sensor, const event_situation mode);
+ bool get_registered_events(const int client_id, const sensor_type_t sensor, event_type_vector &event_vec);
+
+ bool get_listener_ids(const unsigned int event_type, const event_situation mode, client_id_vec &id_vec);
+ bool get_event_socket(const int client_id, csocket &sock);
+ bool set_event_socket(const int client_id, const csocket &sock);
+private:
+ client_id_sensor_record_map m_clients;
+ cmutex m_mutex;
+
+ cclient_info_manager();
+ ~cclient_info_manager();
+ cclient_info_manager(cclient_info_manager const &) {};
+ cclient_info_manager &operator=(cclient_info_manager const &);
+};
+
+#endif /*_CCLIENT_INFO_MANAGER_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 <cclient_sensor_record.h>
+#include <common.h>
+
+using std::pair;
+
+static sensor_type_t get_sensor_type(const unsigned int event_type)
+{
+ return (sensor_type_t) (event_type >> SENSOR_TYPE_SHIFT);
+}
+
+cclient_sensor_record::cclient_sensor_record()
+: m_client_id(0)
+, m_pid(-1)
+{
+}
+
+cclient_sensor_record::~cclient_sensor_record()
+{
+ m_sensor_usages.clear();
+ close_event_socket();
+}
+
+bool cclient_sensor_record::register_event(const unsigned int event_type)
+{
+ sensor_usage_map::iterator it_usage;
+ sensor_type_t sensor = get_sensor_type(event_type);
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ csensor_usage usage;
+ usage.register_event(event_type);
+ m_sensor_usages.insert(pair<sensor_type_t, csensor_usage>(sensor, usage));
+ return true;
+ }
+
+ if (!it_usage->second.register_event(event_type)) {
+ ERR("Event[0x%x] is already registered", event_type);
+ return false;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::unregister_event(const unsigned int event_type)
+{
+ sensor_usage_map::iterator it_usage;
+ sensor_type_t sensor = get_sensor_type(event_type);
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ ERR("Sensor[0x%x] is not registered", sensor);
+ return false;
+ }
+
+ if (!it_usage->second.unregister_event(event_type)) {
+ ERR("Event[0x%x] is already registered", event_type);
+ return false;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::set_interval(const sensor_type_t sensor, const unsigned int interval)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ csensor_usage usage;
+ usage.m_interval = interval;
+ m_sensor_usages.insert(pair<sensor_type_t, csensor_usage>(sensor, usage));
+ } else {
+ it_usage->second.m_interval = interval;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::set_option(const sensor_type_t sensor, const int option)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ csensor_usage usage;
+ usage.m_option = option;
+ m_sensor_usages.insert(pair<sensor_type_t, csensor_usage>(sensor, usage));
+ } else {
+ it_usage->second.m_option = option;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::set_start(const sensor_type_t sensor, bool start)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ csensor_usage usage;
+ usage.m_start = start;
+ m_sensor_usages.insert(pair<sensor_type_t, csensor_usage>(sensor, usage));
+ } else {
+ it_usage->second.m_start = start;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::is_started(const sensor_type_t sensor)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end())
+ return false;
+
+ return it_usage->second.m_start;
+}
+
+unsigned int cclient_sensor_record::get_interval(const sensor_type_t sensor)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ ERR("Sensor[0x%x] is not found", sensor);
+ return 0;
+ }
+
+ return it_usage->second.m_interval;
+}
+
+bool cclient_sensor_record::is_sensor_used(const sensor_type_t sensor, const event_situation mode)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end())
+ return false;
+
+ if ((mode == SITUATION_LCD_OFF || mode == SITUATION_SURVIVAL_MODE) &&
+ (it_usage->second.m_option != SENSOR_OPTION_ALWAYS_ON))
+ return false;
+
+ return true;
+}
+
+bool cclient_sensor_record::is_listening_event(const unsigned int event_type, const event_situation mode)
+{
+ sensor_usage_map::iterator it_usage;
+ sensor_type_t sensor = get_sensor_type(event_type);
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end())
+ return false;
+
+ if ((mode == SITUATION_LCD_OFF || mode == SITUATION_SURVIVAL_MODE) &&
+ (it_usage->second.m_option != SENSOR_OPTION_ALWAYS_ON))
+ return false;
+
+ if (it_usage->second.is_event_registered(event_type))
+ return true;
+
+ return false;
+}
+
+bool cclient_sensor_record::add_sensor_usage(const sensor_type_t sensor)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage != m_sensor_usages.end()) {
+ ERR("Sensor[0x%x] is already registered", sensor);
+ return false;
+ }
+
+ csensor_usage usage;
+ m_sensor_usages.insert(pair<sensor_type_t, csensor_usage> (sensor, usage));
+ return true;
+}
+
+bool cclient_sensor_record::remove_sensor_usage(const sensor_type_t sensor)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ ERR("Sensor[0x%x] is not found", sensor);
+ return false;
+ }
+
+ m_sensor_usages.erase(it_usage);
+ return true;
+}
+
+bool cclient_sensor_record::has_sensor_usage(void)
+{
+ if (m_sensor_usages.empty())
+ return false;
+
+ return true;
+}
+
+bool cclient_sensor_record::has_sensor_usage(const sensor_type_t sensor)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ DBG("Sensor[0x%x] is not found", sensor);
+ return false;
+ }
+
+ return true;
+}
+
+bool cclient_sensor_record::get_registered_events(const sensor_type_t sensor, event_type_vector &event_vec)
+{
+ sensor_usage_map::iterator it_usage;
+ it_usage = m_sensor_usages.find(sensor);
+
+ if (it_usage == m_sensor_usages.end()) {
+ DBG("Sensor[0x%x] is not found", sensor);
+ return false;
+ }
+
+ copy(it_usage->second.m_reg_events.begin(), it_usage->second.m_reg_events.end(), back_inserter(event_vec));
+ return true;
+}
+
+void cclient_sensor_record::set_client_id(int client_id)
+{
+ m_client_id = client_id;
+}
+
+void cclient_sensor_record::set_client_info(pid_t pid)
+{
+ char client_info[NAME_MAX + 32];
+ char proc_name[NAME_MAX];
+ m_pid = pid;
+ get_proc_name(pid, proc_name);
+ snprintf(client_info, sizeof(client_info), "%s[pid=%d, id=%d]", proc_name, m_pid, m_client_id);
+ m_client_info.assign(client_info);
+}
+
+const char *cclient_sensor_record::get_client_info(void)
+{
+ return m_client_info.c_str();
+}
+
+void cclient_sensor_record::set_event_socket(const csocket &socket)
+{
+ m_event_socket = socket;
+}
+
+void cclient_sensor_record::get_event_socket(csocket &socket)
+{
+ socket = m_event_socket;
+}
+
+bool cclient_sensor_record::close_event_socket(void)
+{
+ return m_event_socket.close();
+}
+
--- /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 _CCLIENT_SENSOR_RECORD_H_
+#define _CCLIENT_SENSOR_RECORD_H_
+
+#include <sensor.h>
+#include <sf_common.h>
+#include <csensor_usage.h>
+#include <csocket.h>
+#include <map>
+
+using std::map;
+
+typedef map<sensor_type_t, csensor_usage> sensor_usage_map;
+
+class cclient_sensor_record
+{
+public:
+ cclient_sensor_record();
+ ~cclient_sensor_record();
+
+ void set_client_id(int client_id);
+
+ void set_client_info(pid_t pid);
+ const char *get_client_info(void);
+
+ bool register_event(const unsigned int event_type);
+ bool unregister_event(const unsigned int event_type);
+
+ bool set_interval(const sensor_type_t sensor, const unsigned int interval);
+ unsigned int get_interval(const sensor_type_t sensor);
+ bool set_option(const sensor_type_t sensor, const int option);
+
+ bool set_start(const sensor_type_t sensor, bool start);
+ bool is_started(const sensor_type_t sensor);
+
+ bool is_sensor_used(const sensor_type_t sensor, const event_situation mode);
+ bool is_listening_event(const unsigned int event_type, const event_situation mode);
+ bool has_sensor_usage(void);
+ bool has_sensor_usage(const sensor_type_t sensor);
+
+ bool get_registered_events(const sensor_type_t sensor, event_type_vector &event_vec);
+
+ bool add_sensor_usage(const sensor_type_t sensor);
+ bool remove_sensor_usage(const sensor_type_t sensor);
+
+ void set_event_socket(const csocket &socket);
+ void get_event_socket(csocket &socket);
+ bool close_event_socket(void);
+
+private:
+ int m_client_id;
+ pid_t m_pid;
+ string m_client_info;
+ csocket m_event_socket;
+ sensor_usage_map m_sensor_usages;
+};
+
+#endif /*_CCLIENT_SENSOR_RECORD_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 <cconfig.h>
+#include "common.h"
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <system/system_info.h>
+#include <sstream>
+
+using namespace config;
+
+#define ROOT_ELEMENT "SENSOR"
+#define TEXT_ELEMENT "text"
+#define MODEL_ID_ATTR "id"
+#define DEFAULT_ATTR "value"
+
+CConfig::CConfig()
+{
+}
+
+bool CConfig::load_config(const string &config_path)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+
+ DBG("CConfig::load_config(\"%s\") is called!", config_path.c_str());
+ doc = xmlParseFile(config_path.c_str());
+
+ if (doc == NULL) {
+ ERR("There is no %s", config_path.c_str());
+ return false;
+ }
+
+ cur = xmlDocGetRootElement(doc);
+
+ if (cur == NULL) {
+ ERR("There is no root element in %s", 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", 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>", (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\">", (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>", (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\">", (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("");
+ model_node_ptr = model_node_ptr->next;
+ }
+
+ DBG("");
+ model_list_node_ptr = model_list_node_ptr->next;
+ }
+
+ xmlFreeDoc(doc);
+ return true;
+}
+
+bool CConfig::get(const string &sensor_type, const string &model_id, const string &element, const string &attr, string &value)
+{
+ Sensor_config::iterator it_model_list;
+ it_model_list = m_sensor_config.find(sensor_type);
+
+ if (it_model_list == m_sensor_config.end()) {
+ ERR("There is no <%s> element", sensor_type.c_str());
+ return false;
+ }
+
+ Model_list::iterator it_model;
+ 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", sensor_type.c_str(), model_id.c_str());
+ return false;
+ }
+
+ Model::iterator it_element;
+ it_element = it_model->second.find(element);
+
+ if (it_element == it_model->second.end()) {
+ ERR("There is no <%s id=\"%s\"><%s> element", sensor_type.c_str(), model_id.c_str(), element.c_str());
+ return false;
+ }
+
+ Element::iterator it_attr;
+ it_attr = it_element->second.find(attr);
+
+ if (it_attr == it_element->second.end()) {
+ DBG("There is no <%s id=\"%s\"><%s \"%s\">", sensor_type.c_str(), model_id.c_str(), element.c_str(), attr.c_str());
+ return false;
+ }
+
+ value = it_attr->second;
+ return true;
+}
+
+bool CConfig::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 CConfig::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 CConfig::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 CConfig::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 CConfig::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 CConfig::is_supported(const string &sensor_type, const string &model_id)
+{
+ Sensor_config::iterator it_model_list;
+ it_model_list = m_sensor_config.find(sensor_type);
+
+ if (it_model_list == m_sensor_config.end())
+ return false;
+
+ Model_list::iterator it_model;
+ it_model = it_model_list->second.find(model_id);
+
+ if (it_model == it_model_list->second.end())
+ return false;
+
+ return true;
+}
+
+bool CConfig::get_device_id(void)
+{
+ int ret;
+ char *device = NULL;
+
+ ret = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &device);
+
+ if (device)
+ m_device_id = device;
+
+ free(device);
+ return (ret == SYSTEM_INFO_ERROR_NONE);
+}
--- /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 <map>
+#include <common.h>
+
+using std::map;
+using std::string;
+using std::istringstream;
+
+#define CONFIG_FILE_PATH "/usr/etc/sensors.xml"
+
+typedef map<string, string> Element;
+/*
+* an Element is a group of attributes
+* <Element value1 = "10.0", value2 = "20.0"/>
+*
+* "value" -> "LSM330DLC"
+*
+*/
+
+typedef map<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 map<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 map<string, Model_list> Sensor_config;
+/*
+* a SensorConfig represents sensors.xml
+* <ACCEL/>
+* <GYRO/>
+* <PROXIMITY/>
+*
+* "ACCEL" -> Model_list
+*
+*/
+
+namespace config
+{
+ class CConfig
+ {
+ private:
+ CConfig();
+ CConfig(CConfig const &) {};
+ CConfig &operator=(CConfig const &);
+ bool load_config(const string &config_path = CONFIG_FILE_PATH);
+ Sensor_config m_sensor_config;
+ string m_device_id;
+ public:
+ static CConfig &get_instance(void) {
+ static bool load_done = false;
+ static CConfig inst;
+
+ if (!load_done) {
+ inst.load_config();
+ 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 get(const string &sensor_type, const string &model_id, const string &element, const string &attr, string &value);
+ bool get(const string &sensor_type, const string &model_id, const string &element, const string &attr, double &value);
+ bool get(const string &sensor_type, const string &model_id, const string &element, const string &attr, long &value);
+
+ bool get(const string &sensor_type, const string &model_id, const string &element, string &value);
+ bool get(const string &sensor_type, const string &model_id, const string &element, double &value);
+ bool get(const string &sensor_type, const string &model_id, const string &element, long &value);
+
+ bool is_supported(const string &sensor_type, const string &model_id);
+ 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 <cinterval_info_list.h>
+#include <algorithm>
+
+bool cinterval_info_list::comp_interval_info(cinterval_info a, cinterval_info b)
+{
+ return a.interval < b.interval;
+}
+
+cinterval_info_iterator cinterval_info_list::find_if(int client_id, bool is_processor)
+{
+ cinterval_info_iterator iter;
+ iter = m_list.begin();
+
+ while (iter != m_list.end()) {
+ if ((iter->client_id == client_id) && (iter->is_processor == is_processor))
+ break;
+
+ ++iter;
+ }
+
+ return iter;
+}
+
+bool cinterval_info_list::add_interval(int client_id, unsigned int interval, bool is_processor)
+{
+ cinterval_info_iterator iter;
+ iter = find_if(client_id, is_processor);
+
+ if (iter != m_list.end())
+ *iter = cinterval_info(client_id, is_processor, interval);
+ else
+ m_list.push_back(cinterval_info(client_id, is_processor, interval));
+
+ return true;
+}
+
+bool cinterval_info_list::delete_interval(int client_id, bool is_processor)
+{
+ cinterval_info_iterator iter;
+ iter = find_if(client_id, is_processor);
+
+ if (iter == m_list.end())
+ return false;
+
+ m_list.erase(iter);
+ return true;
+}
+
+unsigned int cinterval_info_list::get_interval(int client_id, bool is_processor)
+{
+ cinterval_info_iterator iter;
+ iter = find_if(client_id, is_processor);
+
+ if (iter == m_list.end())
+ return 0;
+
+ return iter->interval;
+}
+
+unsigned int cinterval_info_list::get_min(void)
+{
+ if (m_list.size() == 0)
+ return 0;
+
+ cinterval_info_iterator iter;
+
+ iter = min_element(m_list.begin(), m_list.end(), comp_interval_info);
+ return iter->interval;
+}
+
--- /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 _CINTERVAL_INFO_LIST_H_
+#define _CINTERVAL_INFO_LIST_H_
+
+#include <list>
+
+using std::list;
+
+class cinterval_info
+{
+public:
+ cinterval_info(int client_id, bool is_processor, unsigned int interval) {
+ this->client_id = client_id;
+ this->is_processor = is_processor;
+ this->interval = interval;
+ }
+
+ int client_id;
+ bool is_processor;
+ unsigned int interval;
+
+};
+
+typedef list<cinterval_info>::iterator cinterval_info_iterator;
+
+class cinterval_info_list
+{
+private:
+ static bool comp_interval_info(cinterval_info a, cinterval_info b);
+ cinterval_info_iterator find_if(int client_id, bool is_processor);
+
+ list<cinterval_info> m_list;
+
+public:
+ bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
+ bool delete_interval(int client_id, bool is_processor = false);
+ unsigned int get_interval(int client_id, bool is_processor = false);
+ unsigned int get_min(void);
+};
+#endif /*_CINTERVAL_INFO_LIST_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 "common.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()
+{
+ cbase_lock::lock(LOCK_TYPE_MUTEX, "mutex", __MODULE__, __func__, __LINE__);
+}
+
+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.
+ *
+ */
+
+#ifndef _CMUTEX_H_
+#define _CMUTEX_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 /*_CMUTEXT_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 <syslog.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include "common.h"
+#include <dlog.h>
+#include <stdarg.h>
+#include <sf_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 );
+ write(sf_debug_file_fd, sf_debug_file_buf, strlen(sf_debug_file_buf));
+ 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);
+}
+
+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);
+ fclose(fp);
+ return true;
+}
+
+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)
+{
+ return false;
+}
+
+void copy_sensor_data(sensor_data_t *src, sensor_data_t *dest)
+{
+ dest->data_accuracy = src->data_accuracy;
+ dest->data_unit_idx = src->data_unit_idx;
+ dest->timestamp = src->timestamp;
+ dest->values_num = src->values_num;
+ memcpy(dest->values, src->values, src->values_num * sizeof(src->values[0]));
+}
--- /dev/null
+/*
+ * libsensord-share
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif /* !__cplusplus */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+
+#ifndef 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;
+typedef struct sensor_data_t sensor_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 *src, sensor_data_t *dest);
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_COMMON_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 <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <new>
+#include <common.h>
+#include <cpacket.h>
+
+cpacket::cpacket(int size)
+{
+ char *ptr;
+ ptr = new(std::nothrow) char[size + sizeof(packet_header)];
+
+ m_packet = (packet_header *)ptr;
+ memset(m_packet, 0, size + sizeof(packet_header));
+ m_packet->size = size;
+ m_create = NEW;
+}
+
+cpacket::cpacket(void *data)
+{
+ m_packet = (packet_header *)data;
+ m_create = SET;
+}
+
+cpacket::~cpacket()
+{
+ if (m_create == NEW) {
+ delete[] (char *)m_packet;
+ m_packet = NULL;
+ }
+}
+
+void cpacket::set_payload_size(int size)
+{
+ if (!m_packet) {
+ ERR("error m_packet null!!");
+ } else {
+ m_packet->size = size;
+ }
+}
+
+void cpacket::set_cmd(int cmd)
+{
+ if (!m_packet) {
+ ERR("error m_packet null!!");
+ } else {
+ m_packet->cmd = cmd;
+ }
+}
+
+int cpacket::cmd(void)
+{
+ if (!m_packet) {
+ ERR("error m_packet null!!");
+ return -1;
+ } else {
+ return m_packet->cmd;
+ }
+}
+
+void *cpacket::data(void)
+{
+ if ( !m_packet ) {
+ ERR("error m_packet null!!");
+ return NULL;
+ }
+
+ return m_packet->data;
+}
+
+void *cpacket::packet(void)
+{
+ return (void *)m_packet;
+}
+
+int cpacket::header_size(void)
+{
+ return sizeof(packet_header);
+}
+
+int cpacket::size(void)
+{
+ if (!m_packet) {
+ ERR("error m_packet null!!");
+ return -1;
+ } else {
+ return m_packet->size + sizeof(packet_header);
+ }
+}
+
+int cpacket::payload_size(void)
+{
+ return m_packet->size;
+}
--- /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 _CPACKET_H_
+#define _CPACKET_H_
+
+typedef struct packet_header {
+ int cmd;
+ int size;
+ char data[0];
+} packet_header;
+
+class cpacket
+{
+public:
+ cpacket(int size);
+ cpacket(void *data);
+ virtual ~cpacket();
+
+ void set_cmd(int cmd);
+ int cmd(void);
+
+ void *data(void);
+ void *packet(void);
+
+ int size(void);
+ int payload_size(void);
+ void set_payload_size(int size);
+
+ static int header_size(void);
+
+private:
+ enum {
+ NEW = 0x01,
+ SET = 0x02,
+ };
+
+ packet_header *m_packet;
+
+ int m_create;
+};
+
+#endif /*_CPACKET_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 "crw_lock.h"
+#include "common.h"
+
+crw_lock::crw_lock()
+{
+ m_rw_lock = PTHREAD_RWLOCK_INITIALIZER;
+}
+
+crw_lock::~crw_lock()
+{
+ pthread_rwlock_destroy(&m_rw_lock);
+}
+
+void crw_lock::read_lock()
+{
+ cbase_lock::lock(LOCK_TYPE_READ, "read lock", __MODULE__, __func__, __LINE__);
+}
+
+void crw_lock::write_lock()
+{
+ cbase_lock::lock(LOCK_TYPE_WRITE, "write lock", __MODULE__, __func__, __LINE__);
+}
+
+int crw_lock::read_lock_impl(void)
+{
+ return pthread_rwlock_rdlock(&m_rw_lock);
+}
+int crw_lock::write_lock_impl(void)
+{
+ return pthread_rwlock_wrlock(&m_rw_lock);
+}
+
+int crw_lock::try_read_lock_impl(void)
+{
+ return pthread_rwlock_tryrdlock(&m_rw_lock);
+}
+
+int crw_lock::try_write_lock_impl(void)
+{
+ return pthread_rwlock_trywrlock(&m_rw_lock);
+}
+
+int crw_lock::unlock_impl()
+{
+ return pthread_rwlock_unlock(&m_rw_lock);
+}
--- /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 _CRW_LOCK_H_
+#define _CRW_LOCK_H_
+
+#include "cbase_lock.h"
+
+class crw_lock : public cbase_lock
+{
+public:
+ crw_lock();
+ virtual ~crw_lock();
+
+ void read_lock();
+ void write_lock();
+
+protected:
+ int read_lock_impl(void);
+ int write_lock_impl(void);
+
+ int try_read_lock_impl(void);
+ int try_write_lock_impl(void);
+ int unlock_impl();
+private:
+ pthread_rwlock_t m_rw_lock;
+};
+
+#endif /*_CRW_LOCK_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 <csensor_event_dispatcher.h>
+#include <sensor_plugin_loader.h>
+#include <common.h>
+#include <sf_common.h>
+#include <vconf.h>
+#include <thread>
+
+using std::thread;
+
+#define MAX_PENDING_CONNECTION 32
+
+csensor_event_dispatcher::csensor_event_dispatcher()
+: m_lcd_on(true)
+{
+ m_sensor_fusion = sensor_plugin_loader::get_instance().get_fusion();
+}
+
+csensor_event_dispatcher::~csensor_event_dispatcher() { }
+
+bool csensor_event_dispatcher::run(void)
+{
+ INFO("Starting Event Dispatcher");
+
+ if (!m_accept_socket.create(SOCK_SEQPACKET)) {
+ ERR("Listener Socket Creation failed in Server");
+ return false;
+ }
+
+ if (!m_accept_socket.bind(EVENT_CHANNEL_PATH)) {
+ ERR("Listener Socket Binding failed in Server");
+ m_accept_socket.close();
+ return false;
+ }
+
+ if (!m_accept_socket.listen(MAX_PENDING_CONNECTION)) {
+ ERR("Socket Listen failed in Server");
+ return false;
+ }
+
+ thread accepter(&csensor_event_dispatcher::accept_connections, this);
+ accepter.detach();
+
+ thread dispatcher(&csensor_event_dispatcher::dispatch_event, this);
+ dispatcher.detach();
+
+ return true;
+}
+
+void csensor_event_dispatcher::accept_event_channel(csocket client_socket)
+{
+ int client_id;
+ event_channel_ready_t event_channel_ready;
+ cclient_info_manager &client_info_manager = get_client_info_manager();
+ client_socket.set_connection_mode();
+
+ if (client_socket.recv(&client_id, sizeof(client_id)) <= 0) {
+ ERR("Failed to receive client id on socket fd[%d]", client_socket.get_socket_fd());
+ return;
+ }
+
+ client_socket.set_transfer_mode();
+ AUTOLOCK(m_mutex);
+
+ if (!get_client_info_manager().set_event_socket(client_id, client_socket)) {
+ ERR("Failed to store event socket[%d] for %s", client_socket.get_socket_fd(),
+ client_info_manager.get_client_info(client_id));
+ return;
+ }
+
+ event_channel_ready.magic = EVENT_CHANNEL_MAGIC;
+ event_channel_ready.client_id = client_id;
+
+ INFO("Event channel is accepted for %s on socket[%d]",
+ client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
+
+ if (client_socket.send(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
+ ERR("Failed to send event_channel_ready packet to %s on socket fd[%d]",
+ client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
+ return;
+ }
+}
+
+void csensor_event_dispatcher::accept_connections(void)
+{
+ INFO("Event channel acceptor is started.");
+
+ while (true) {
+ csocket client_socket;
+
+ if (!m_accept_socket.accept(client_socket)) {
+ ERR("Accepting socket failed in Server");
+ continue;
+ }
+
+ INFO("New client connected (socket_fd : %d)", client_socket.get_socket_fd());
+ thread event_channel_creator(&csensor_event_dispatcher::accept_event_channel, this, client_socket);
+ event_channel_creator.detach();
+ }
+}
+
+void csensor_event_dispatcher::dispatch_event(void)
+{
+ const int MAX_EVENT_PER_SENSOR = 16;
+ const int MAX_SENSOR_EVENT = 1 + (sensor_plugin_loader::get_instance().get_virtual_sensors().size()
+ * MAX_EVENT_PER_SENSOR);
+ const int MAX_SYNTH_PER_SENSOR = 5;
+ INFO("Event Dispatcher started");
+ m_lcd_on = is_lcd_on();
+
+ if (vconf_notify_key_changed(VCONFKEY_PM_STATE, situation_watcher, this) != 0)
+ ERR("Fail to set notify callback for %s", VCONFKEY_PM_STATE);
+
+ while (true) {
+ bool is_hub_event = false;
+ event_situation situation;
+ void *seed_event = get_event_queue().pop();
+ unsigned int event_type = *((unsigned int *)(seed_event));
+
+ if (is_sensorhub_event(event_type))
+ is_hub_event = true;
+
+ if (m_lcd_on)
+ situation = SITUATION_LCD_ON;
+ else
+ situation = SITUATION_LCD_OFF;
+
+ if (is_hub_event) {
+ sensorhub_event_t *sensorhub_event = (sensorhub_event_t *)seed_event;
+ sensorhub_event->situation = situation;
+ send_sensor_events(sensorhub_event, 1, true, situation);
+ } else {
+ sensor_event_t sensor_events[MAX_SENSOR_EVENT];
+ unsigned int event_cnt = 0;
+ sensor_events[event_cnt++] = *((sensor_event_t *)seed_event);
+
+ if (m_sensor_fusion) {
+ if (m_sensor_fusion->is_started())
+ m_sensor_fusion->fuse(*((sensor_event_t *)seed_event));
+ }
+
+ virtual_sensors v_sensors = get_active_virtual_sensors();
+ virtual_sensors::iterator it_v_sensor;
+ it_v_sensor = v_sensors.begin();
+ vector<sensor_event_t> v_sensor_events;
+ v_sensor_events.reserve(MAX_SYNTH_PER_SENSOR);
+
+ while (it_v_sensor != v_sensors.end()) {
+ int synthesized_cnt;
+ v_sensor_events.clear();
+ (*it_v_sensor)->synthesize(*((sensor_event_t *)seed_event), v_sensor_events);
+ synthesized_cnt = v_sensor_events.size();
+
+ for (int i = 0; i < synthesized_cnt; ++i)
+ sensor_events[event_cnt++] = v_sensor_events[i];
+
+ ++it_v_sensor;
+ }
+
+ sort_sensor_events(sensor_events, event_cnt);
+
+ for (int i = 0; i < event_cnt; ++i) {
+ sensor_events[i].situation = situation;
+
+ if (is_record_event(sensor_events[i].event_type))
+ put_last_event(sensor_events[i].event_type, sensor_events[i]);
+ }
+
+ send_sensor_events(sensor_events, event_cnt, false, situation);
+ }
+
+ if (is_hub_event)
+ delete (sensorhub_event_t *)seed_event;
+ else
+ delete (sensor_event_t *)seed_event;
+ }
+}
+
+void csensor_event_dispatcher::send_sensor_events(void *events, int event_cnt, bool is_hub_event, event_situation situation)
+{
+ sensor_event_t *sensor_events;
+ sensorhub_event_t *sensor_hub_events;
+ cclient_info_manager &client_info_manager = get_client_info_manager();
+
+ if (is_hub_event)
+ sensor_hub_events = (sensorhub_event_t *)events;
+ else
+ sensor_events = (sensor_event_t *)events;
+
+ for (int i = 0; i < event_cnt; ++i) {
+ client_id_vec id_vec;
+ unsigned int event_type;
+
+ if (is_hub_event)
+ event_type = sensor_hub_events[i].event_type;
+ else
+ event_type = sensor_events[i].event_type;
+
+ client_info_manager.get_listener_ids(event_type, situation, id_vec);
+ client_id_vec::iterator it_client_id;
+ it_client_id = id_vec.begin();
+
+ while (it_client_id != id_vec.end()) {
+ csocket client_socket;
+ client_info_manager.get_event_socket(*it_client_id, client_socket);
+ bool ret;
+
+ if (is_hub_event)
+ ret = (client_socket.send(sensor_hub_events + i, sizeof(sensorhub_event_t)) > 0);
+ else
+ ret = (client_socket.send(sensor_events + i, sizeof(sensor_event_t)) > 0);
+
+ if (ret)
+ DBG("Event[0x%x] sent to %s on socket[%d]", event_type, client_info_manager.get_client_info(*it_client_id), client_socket.get_socket_fd());
+ else
+ ERR("Failed to send event[0x%x] to %s on socket[%d]", event_type, client_info_manager.get_client_info(*it_client_id), client_socket.get_socket_fd());
+
+ ++it_client_id;
+ }
+ }
+}
+
+bool csensor_event_dispatcher::is_lcd_on(void)
+{
+ int lcd_state;
+
+ if (vconf_get_int(VCONFKEY_PM_STATE, &lcd_state) != 0) {
+ ERR("Can't get the value of VCONFKEY_PM_STATE");
+ return true;
+ }
+
+ if (lcd_state == VCONFKEY_PM_STATE_LCDOFF)
+ return false;
+
+ return true;
+}
+
+cclient_info_manager &csensor_event_dispatcher::get_client_info_manager(void)
+{
+ return cclient_info_manager::get_instance();
+}
+
+csensor_event_queue &csensor_event_dispatcher::get_event_queue(void)
+{
+ return csensor_event_queue::get_instance();
+}
+
+bool csensor_event_dispatcher::is_record_event(unsigned int event_type)
+{
+ switch (event_type) {
+ case ACCELEROMETER_EVENT_ROTATION_CHECK:
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void csensor_event_dispatcher::put_last_event(unsigned int event_type, const sensor_event_t &event)
+{
+ AUTOLOCK(m_last_events_mutex);
+ m_last_events[event_type] = event;
+}
+
+bool csensor_event_dispatcher::get_last_event(unsigned int event_type, sensor_event_t &event)
+{
+ AUTOLOCK(m_last_events_mutex);
+ event_type_last_event_map::iterator it_event;
+ it_event = m_last_events.find(event_type);
+
+ if (it_event == m_last_events.end())
+ return false;
+
+ event = it_event->second;
+ return true;
+}
+
+bool csensor_event_dispatcher::has_active_virtual_sensor(virtual_sensor *sensor)
+{
+ AUTOLOCK(m_active_virtual_sensors_mutex);
+ virtual_sensors::iterator it_v_sensor;
+ it_v_sensor = find(m_active_virtual_sensors.begin(), m_active_virtual_sensors.end(), sensor);
+ return (it_v_sensor != m_active_virtual_sensors.end());
+}
+
+virtual_sensors csensor_event_dispatcher::get_active_virtual_sensors(void)
+{
+ AUTOLOCK(m_active_virtual_sensors_mutex);
+ return m_active_virtual_sensors;
+}
+
+bool csensor_event_dispatcher::compare_by_timestamp(const sensor_event_t &a, const sensor_event_t &b)
+{
+ return a.data.timestamp < b.data.timestamp;
+}
+
+void csensor_event_dispatcher::sort_sensor_events(sensor_event_t *events, unsigned int cnt)
+{
+ std::sort(events, events + cnt, compare_by_timestamp);
+}
+
+void csensor_event_dispatcher::request_last_event(int client_id, const sensor_type_t sensor)
+{
+ cclient_info_manager &client_info_manager = get_client_info_manager();
+ event_type_vector event_vec;
+ csocket client_socket;
+
+ if (client_info_manager.get_registered_events(client_id, sensor, event_vec)) {
+ client_info_manager.get_event_socket(client_id, client_socket);
+ event_type_vector::iterator it_event;
+ it_event = event_vec.begin();
+
+ while (it_event != event_vec.end()) {
+ sensor_event_t event;
+
+ if (is_record_event(*it_event) && get_last_event(*it_event, event)) {
+ if (client_socket.send(&event, sizeof(event)) > 0)
+ INFO("Send the last event[0x%x] to %s on socket[%d]", event.event_type,
+ client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
+ else
+ ERR("Failed to send event[0x%x] to %s on socket[%d]", event.event_type,
+ client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
+ }
+
+ ++it_event;
+ }
+ }
+}
+
+bool csensor_event_dispatcher::add_active_virtual_sensor(virtual_sensor *sensor)
+{
+ AUTOLOCK(m_active_virtual_sensors_mutex);
+
+ if (has_active_virtual_sensor(sensor)) {
+ ERR("[%s] sensor is already added on active virtual sensors", sensor->get_name());
+ return false;
+ }
+
+ m_active_virtual_sensors.push_back(sensor);
+ return true;
+}
+
+bool csensor_event_dispatcher::delete_active_virtual_sensor(virtual_sensor *sensor)
+{
+ AUTOLOCK(m_active_virtual_sensors_mutex);
+ virtual_sensors::iterator it_v_sensor;
+ it_v_sensor = find(m_active_virtual_sensors.begin(), m_active_virtual_sensors.end(), sensor);
+
+ if (it_v_sensor == m_active_virtual_sensors.end()) {
+ ERR("Fail to delete non-existent [%s] sensor on active virtual sensors", sensor->get_name());
+ return false;
+ }
+
+ m_active_virtual_sensors.erase(it_v_sensor);
+ return true;
+}
+
+void csensor_event_dispatcher::situation_watcher(keynode_t *node, void *user_data)
+{
+ csensor_event_dispatcher *dispatcher = (csensor_event_dispatcher *) user_data;
+
+ if (!strcmp(vconf_keynode_get_name(node), VCONFKEY_PM_STATE))
+ dispatcher->m_lcd_on = dispatcher->is_lcd_on();
+}
--- /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_EVENT_DISPATCHER_H_
+#define _SENSOR_EVENT_DISPATCHER_H_
+
+#include <sf_common.h>
+#include <csensor_event_queue.h>
+#include <cclient_info_manager.h>
+#include <sensor_fusion.h>
+#include <csocket.h>
+#include <virtual_sensor.h>
+#include <vconf.h>
+
+typedef map<unsigned int, sensor_event_t> event_type_last_event_map;
+typedef list<virtual_sensor *> virtual_sensors;
+
+class csensor_event_dispatcher
+{
+private:
+ bool m_lcd_on;
+ csocket m_accept_socket;
+ cmutex m_mutex;
+ cmutex m_last_events_mutex;
+ event_type_last_event_map m_last_events;
+ virtual_sensors m_active_virtual_sensors;
+ cmutex m_active_virtual_sensors_mutex;
+ sensor_fusion *m_sensor_fusion;
+
+ csensor_event_dispatcher();
+ ~csensor_event_dispatcher();
+ csensor_event_dispatcher(csensor_event_dispatcher const &) {};
+ csensor_event_dispatcher &operator=(csensor_event_dispatcher const &);
+
+ void accept_connections(void);
+ void accept_event_channel(csocket client_socket);
+
+ void dispatch_event(void);
+ void send_sensor_events(void *events, int event_cnt, bool is_hub_event, event_situation situation);
+ static void situation_watcher(keynode_t *node, void *user_data);
+ bool is_lcd_on(void);
+ static cclient_info_manager &get_client_info_manager(void);
+ static csensor_event_queue &get_event_queue(void);
+
+ bool is_record_event(unsigned int event_type);
+ void put_last_event(unsigned int event_type, const sensor_event_t &event);
+ bool get_last_event(unsigned int event_type, sensor_event_t &event);
+
+ bool has_active_virtual_sensor(virtual_sensor *sensor);
+ virtual_sensors get_active_virtual_sensors(void);
+
+ static bool compare_by_timestamp(const sensor_event_t &a, const sensor_event_t &b);
+ void sort_sensor_events(sensor_event_t *events, unsigned int cnt);
+public:
+ static csensor_event_dispatcher &get_instance() {
+ static csensor_event_dispatcher inst;
+ return inst;
+ }
+
+ bool run(void);
+ void request_last_event(int client_id, const sensor_type_t sensor);
+
+ bool add_active_virtual_sensor(virtual_sensor *sensor);
+ bool delete_active_virtual_sensor(virtual_sensor *sensor);
+};
+
+#endif /*_CSENSOR_EVENT_DISPATCHER_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 <csensor_event_queue.h>
+#include "common.h"
+
+csensor_event_queue::csensor_event_queue()
+{
+}
+
+void csensor_event_queue::push(sensor_event_t const &event)
+{
+ sensor_event_t *new_event = new sensor_event_t;
+ *new_event = event;
+ push_internal(new_event);
+}
+
+void csensor_event_queue::push(sensorhub_event_t const &event)
+{
+ sensorhub_event_t *new_event = new sensorhub_event_t;
+ *new_event = event;
+ push_internal(new_event);
+}
+
+void csensor_event_queue::push_internal(void *event)
+{
+ lock l(m_mutex);
+ bool wake = m_queue.empty();
+
+ if (m_queue.size() >= QUEUE_FULL_SIZE) {
+ ERR("Queue is full");
+ } else
+ m_queue.push(event);
+
+ if (wake)
+ m_cond_var.notify_one();
+}
+
+void *csensor_event_queue::pop(void)
+{
+ ulock u(m_mutex);
+
+ while (m_queue.empty())
+ m_cond_var.wait(u);
+
+ void *event = m_queue.front();
+ m_queue.pop();
+ return event;
+}
+
--- /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 _CSENSOR_EVENT_QUEUE_H_
+#define _CSENSOR_EVENT_QUEUE_H_
+
+#include <sf_common.h>
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+
+using std::queue;
+using std::mutex;
+using std::lock_guard;
+using std::unique_lock;
+using std::condition_variable;
+
+class csensor_event_queue
+{
+private:
+ static const unsigned int QUEUE_FULL_SIZE = 1000;
+
+ queue<void * > m_queue;
+ mutex m_mutex;
+ condition_variable m_cond_var;
+
+ typedef lock_guard<mutex> lock;
+ typedef unique_lock<mutex> ulock;
+
+ csensor_event_queue();
+ csensor_event_queue(csensor_event_queue const &) {};
+ csensor_event_queue &operator=(csensor_event_queue const &);
+ void push_internal(void *event);
+
+public:
+ static csensor_event_queue &get_instance() {
+ static csensor_event_queue inst;
+ return inst;
+ }
+ void push(sensor_event_t const &event);
+ void push(sensorhub_event_t const &event);
+ void *pop(void);
+};
+
+#endif /*_CSENSOR_EVENT_QUEUE_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.h>
+#include <csensor_usage.h>
+#include <common.h>
+
+csensor_usage::csensor_usage()
+: m_interval(POLL_MAX_HZ_MS)
+, m_option(SENSOR_OPTION_DEFAULT)
+, m_start(false)
+{
+}
+
+csensor_usage::~csensor_usage()
+{
+ m_reg_events.clear();
+}
+
+bool csensor_usage::register_event(const unsigned int event_type)
+{
+ reg_event_vector::iterator it_event;
+ it_event = find(m_reg_events.begin(), m_reg_events.end(), event_type);
+
+ if (it_event != m_reg_events.end()) {
+ ERR("Event[0x%x] is already registered", event_type);
+ return false;
+ }
+
+ m_reg_events.push_back(event_type);
+ return true;
+}
+
+bool csensor_usage::unregister_event(const unsigned int event_type)
+{
+ reg_event_vector::iterator it_event;
+ it_event = find(m_reg_events.begin(), m_reg_events.end(), event_type);
+
+ if (it_event == m_reg_events.end()) {
+ ERR("Event[0x%x] is not found", event_type);
+ return false;
+ }
+
+ m_reg_events.erase(it_event);
+ return true;
+}
+
+bool csensor_usage::is_event_registered(const unsigned int event_type)
+{
+ reg_event_vector::iterator it_event;
+ it_event = find (m_reg_events.begin(), m_reg_events.end(), event_type);
+
+ if (it_event == m_reg_events.end()) {
+ DBG("Event[0x%x] is not registered", event_type);
+ 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.
+ *
+ */
+
+#ifndef CSENSOR_USAGE_H_
+#define CSENSOR_USAGE_H_
+
+#include <sf_common.h>
+#include <algorithm>
+#include <vector>
+
+using std::vector;
+
+typedef vector<unsigned int> reg_event_vector;
+
+class csensor_usage
+{
+public:
+ unsigned int m_interval;
+ int m_option;
+ reg_event_vector m_reg_events;
+ bool m_start;
+
+ csensor_usage();
+ ~csensor_usage();
+
+ bool register_event(const unsigned int event_type);
+ bool unregister_event(const unsigned int event_type);
+ bool is_event_registered(const unsigned int event_type);
+};
+
+#endif /* CSENSOR_USAGE_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 <csocket.h>
+#include <attr/xattr.h>
+#include <sys/stat.h>
+
+csocket::csocket()
+: m_sock_fd(-1)
+, m_sock_type(SOCK_STREAM)
+, m_send_flags(MSG_NOSIGNAL)
+, m_recv_flags(MSG_NOSIGNAL)
+{
+ memset(&m_addr, 0, sizeof(m_addr));
+}
+
+csocket::csocket(int sock_fd)
+: m_send_flags(MSG_NOSIGNAL)
+, m_recv_flags(MSG_NOSIGNAL)
+{
+ m_sock_fd = sock_fd;
+ set_sock_type();
+ memset(&m_addr, 0, sizeof(m_addr));
+}
+
+csocket::csocket(const csocket &sock)
+{
+ if (this == &sock)
+ return;
+
+ m_sock_fd = sock.m_sock_fd;
+ m_sock_type = sock.m_sock_type;
+ m_send_flags = sock.m_send_flags;
+ m_recv_flags = sock.m_recv_flags;
+
+ memcpy(&m_addr, &sock.m_addr, sizeof(sockaddr_un));
+}
+
+csocket::~csocket()
+{
+}
+
+bool csocket::create(int sock_type)
+{
+ m_sock_fd = socket(AF_UNIX, sock_type, 0);
+
+ if (!is_valid()) {
+ ERR("Failed to create socket for %s, errno : %d , errstr : %s ",
+ get_client_name(), errno, strerror(errno));
+ return false;
+ }
+
+ m_sock_type = sock_type;
+ return true;
+}
+
+bool csocket::bind (const char *sock_path)
+{
+ int length;
+ mode_t socket_mode;
+
+ if (!is_valid()) {
+ ERR("%s's socket is invalid", get_client_name());
+ return false;
+ }
+
+ if ((fsetxattr(m_sock_fd, "security.SMACK64IPOUT", "@", 2, 0)) < 0) {
+ if (errno != EOPNOTSUPP) {
+ close();
+ ERR("security.SMACK64IPOUT error = [%d][%s]", errno, strerror(errno) );
+ return false;
+ }
+ }
+
+ if ((fsetxattr(m_sock_fd, "security.SMACK64IPIN", "*", 2, 0)) < 0) {
+ if (errno != EOPNOTSUPP) {
+ close();
+ ERR("security.SMACK64IPIN error = [%d][%s]", errno, strerror(errno) );
+ return false;
+ }
+ }
+
+ if (!access(sock_path, F_OK)) {
+ unlink(sock_path);
+ }
+
+ m_addr.sun_family = AF_UNIX;
+ strcpy(m_addr.sun_path, sock_path);
+ length = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
+
+ if (::bind(m_sock_fd, (struct sockaddr *)&m_addr, length) < 0) {
+ ERR("Binding failed for socket(%d), errno : %d , errstr : %s", m_sock_fd, errno, strerror(errno));
+ close();
+ return false;
+ }
+
+ socket_mode = ( S_IRWXU | S_IRWXG | S_IRWXO );
+
+ if (chmod(sock_path, socket_mode) < 0) {
+ ERR("chmod failed for socket(%d), errno : %d , errstr : %s", m_sock_fd, errno, strerror(errno));
+ close();
+ return false;
+ }
+
+ return true;
+}
+
+bool csocket::listen(const int max_connections)
+{
+ if (!is_valid()) {
+ ERR("Socket(%d) is invalid", m_sock_fd);
+ return false;
+ }
+
+ if (::listen(m_sock_fd, max_connections) < 0) {
+ ERR("Listening failed for socket(%d), errno : %d , errstr : %s", m_sock_fd, errno, strerror(errno));
+ close();
+ return false;
+ }
+
+ return true;
+}
+
+bool csocket::accept(csocket &client_socket) const
+{
+ int addr_length = sizeof(m_addr);
+ client_socket.m_sock_fd = ::accept(m_sock_fd, (sockaddr *)&m_addr, (socklen_t *)&addr_length);
+
+ if (!client_socket.is_valid()) {
+ ERR("Accept failed for socket(%d), errno : %d , errstr : %s", m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+ssize_t csocket::send_for_seqpacket(void const *buffer, size_t size) const
+{
+ ssize_t err, len;
+
+ do {
+ len = ::send(m_sock_fd, buffer, size, m_send_flags);
+ err = len < 0 ? errno : 0;
+ } while (err == EINTR);
+
+ if (err) {
+ ERR("send(%d, 0x%x, %d, 0x%x) = %d cause = %s(%d)",
+ m_sock_fd, buffer, size, m_send_flags, len, strerror(errno), errno);
+ }
+
+ return err == 0 ? len : -err;
+}
+
+ssize_t csocket::recv_for_seqpacket(void *buffer, size_t size) const
+{
+ ssize_t err, len;
+
+ do {
+ len = ::recv(m_sock_fd, buffer, size, m_recv_flags);
+
+ if (len > 0) {
+ err = 0;
+ } else if (len == 0) {
+ ERR("recv(%d, 0x%p , %d) = %d, because the peer performed shutdown!",
+ m_sock_fd, buffer, size, len);
+ err = 1;
+ } else {
+ err = errno;
+ }
+ } while (err == EINTR);
+
+ if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+ DBG("recv(%d, 0x%x, %d, 0x%x) = %d cause = %s(%d)",
+ m_sock_fd, buffer, size, m_recv_flags, len, strerror(errno), errno);
+ return 0;
+ }
+
+ if (err) {
+ ERR("recv(%d, 0x%x, %d, 0x%x) = %d cause = %s(%d)",
+ m_sock_fd, buffer, size, m_recv_flags, len, strerror(errno), errno);
+ }
+
+ return err == 0 ? len : -err;
+}
+
+ssize_t csocket::send_for_stream(void const *buffer, size_t size) const
+{
+ ssize_t len;
+ ssize_t err = 0;
+ ssize_t total_sent_size = 0;
+
+ do {
+ len = ::send(m_sock_fd, buffer + total_sent_size, size - total_sent_size, m_send_flags);
+
+ if (len >= 0) {
+ total_sent_size += len;
+ err = 0;
+ } else {
+ ERR("send(%d, 0x%p + %d, %d - %d) = %d, error: %s(%d) for %s",
+ m_sock_fd, buffer, total_sent_size, size, total_sent_size,
+ len, strerror(errno), errno, get_client_name());
+
+ if (errno != EINTR) {
+ err = errno;
+ break;
+ }
+ }
+ } while (total_sent_size < size);
+
+ return err == 0 ? total_sent_size : -err;
+}
+
+ssize_t csocket::recv_for_stream(void *buffer, size_t size) const
+{
+ ssize_t len;
+ ssize_t err = 0;
+ ssize_t total_recv_size = 0;
+
+ do {
+ len = ::recv(m_sock_fd, buffer + total_recv_size, size - total_recv_size, m_recv_flags);
+
+ if (len > 0) {
+ total_recv_size += len;
+ } else if (len == 0) {
+ ERR("recv(%d, 0x%p + %d, %d - %d) = %d, because the peer of %s performed shutdown!",
+ m_sock_fd, buffer, total_recv_size, size, total_recv_size, len, get_client_name());
+ err = 1;
+ break;
+ } else {
+ ERR("recv(%d, 0x%p + %d, %d - %d) = %d, error: %s(%d) for %s",
+ m_sock_fd, buffer, total_recv_size, size, total_recv_size,
+ len, strerror(errno), errno, get_client_name());
+
+ if (errno != EINTR) {
+ err = errno;
+ break;
+ }
+ }
+ } while (total_recv_size < size);
+
+ return err == 0 ? total_recv_size : -err;
+}
+
+ssize_t csocket::send(void const *buffer, size_t size) const
+{
+ if (m_sock_type == SOCK_STREAM)
+ return send_for_stream(buffer, size);
+
+ return send_for_seqpacket(buffer, size);
+}
+
+ssize_t csocket::recv(void *buffer, size_t size) const
+{
+ if (m_sock_type == SOCK_STREAM)
+ return recv_for_stream(buffer, size);
+
+ return recv_for_seqpacket(buffer, size);
+}
+
+bool csocket::connect(const char *sock_path)
+{
+ const int TIMEOUT = 3;
+ fd_set write_fds;
+ struct timeval tv;
+ int addr_len;
+ bool prev_blocking_mode;
+
+ if (!is_valid()) {
+ ERR("%s's socket is invalid", get_client_name());
+ return false;
+ }
+
+ prev_blocking_mode = is_blocking_mode();
+ set_blocking_mode(false);
+
+ m_addr.sun_family = AF_UNIX;
+ strcpy(m_addr.sun_path, sock_path);
+ addr_len = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
+
+ if (::connect(m_sock_fd, (sockaddr *) &m_addr, addr_len) < 0) {
+ ERR("connect error: %s sock_fd: %d for %s", strerror(errno), m_sock_fd, get_client_name());
+ return false;
+ }
+
+ FD_ZERO(&write_fds);
+ FD_SET(m_sock_fd, &write_fds);
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+
+ int ret;
+ ret = select(m_sock_fd + 1, NULL, &write_fds, NULL, &tv);
+
+ if (ret == -1) {
+ ERR("select error: %s sock_fd: %d for %s", strerror(errno), m_sock_fd, get_client_name());
+ close();
+ return false;
+ } else if (!ret) {
+ ERR("select timeout: %d seconds elapsed for %s", tv.tv_sec, get_client_name());
+ close();
+ return true;
+ }
+
+ if (!FD_ISSET(m_sock_fd, &write_fds)) {
+ ERR("select failed for %s, nothing to write, m_sock_fd : %d", get_client_name(), m_sock_fd);
+ close();
+ return false;
+ }
+
+ int so_error;
+ socklen_t len = sizeof(so_error);
+
+ if (getsockopt(m_sock_fd, SOL_SOCKET, SO_ERROR, &so_error, &len) == -1) {
+ ERR("getsockopt failed for %s, m_sock_fd : %d, errno : %d , errstr : %s",
+ get_client_name(), m_sock_fd, errno, strerror(errno));
+ close();
+ return false;
+ }
+
+ if (so_error) {
+ ERR("SO_ERROR occurred for %s, m_sock_fd : %d, so_error : %d",
+ get_client_name(), m_sock_fd, so_error);
+ close();
+ return false;
+ }
+
+ if (prev_blocking_mode)
+ set_blocking_mode(true);
+
+ return true;
+}
+
+bool csocket::set_blocking_mode(bool blocking)
+{
+ int flags;
+ flags = fcntl(m_sock_fd, F_GETFL);
+
+ if (flags == -1) {
+ ERR("fcntl(F_GETFL) failed for %s, m_sock_fd: %d, errno : %d , errstr : %s", get_client_name(), m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
+ flags = fcntl(m_sock_fd, F_SETFL, flags);
+
+ if (flags == -1) {
+ ERR("fcntl(F_SETFL) failed for %s, m_sock_fd: %d, errno : %d , errstr : %s", get_client_name(), m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+bool csocket::set_sock_type(void)
+{
+ socklen_t opt_len;
+ int sock_type;
+ opt_len = sizeof(sock_type);
+
+ if (getsockopt(m_sock_fd, SOL_SOCKET, SO_TYPE, &sock_type, &opt_len) < 0) {
+ ERR("getsockopt(SOL_SOCKET, SO_TYPE) failed for %s, m_sock_fd: %d, errno : %d , errstr : %s", get_client_name(), m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ m_sock_type = sock_type;
+ return true;
+}
+
+bool csocket::set_connection_mode(void)
+{
+ struct timeval tv;
+ const int TIMEOUT = 3;
+ set_blocking_mode(true);
+ tv.tv_sec = TIMEOUT;
+ tv.tv_usec = 0;
+
+ if (setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
+ ERR("Set SO_RCVTIMEO failed for %s, m_sock_fd : %d, errno : %d , errstr : %s",
+ get_client_name(), m_sock_fd, errno, strerror(errno));
+ close();
+ return false;
+ }
+
+ m_send_flags = MSG_NOSIGNAL;
+ m_recv_flags = MSG_NOSIGNAL;
+ return true;
+}
+
+bool csocket::set_transfer_mode(void)
+{
+ set_blocking_mode(false);
+ m_send_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+ m_recv_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+ return true;
+}
+
+bool csocket::is_blocking_mode(void)
+{
+ int flags;
+ flags = fcntl(m_sock_fd, F_GETFL);
+
+ if (flags == -1) {
+ ERR("fcntl(F_GETFL) failed for %s, m_sock_fd: %d, errno : %d , errstr : %s", get_client_name(), m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ return !(flags & O_NONBLOCK);
+}
+
+bool csocket::close(void)
+{
+ if (m_sock_fd >= 0) {
+ if (::close(m_sock_fd) < 0) {
+ ERR("Socket(%d) close failed, errno : %d , errstr : %s", m_sock_fd, errno, strerror(errno));
+ return false;
+ }
+
+ m_sock_fd = -1;
+ }
+
+ 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.
+ *
+ */
+
+#ifndef CSOCKET_H_
+#define CSOCKET_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "common.h"
+#include <string>
+
+using std::string;
+
+class csocket
+{
+public:
+ csocket();
+ virtual ~csocket();
+ csocket(int sock_fd);
+ csocket(const csocket &sock);
+
+ //Server
+ bool create(int sock_type);
+ bool bind (const char *sock_path);
+ bool listen(const int max_connections);
+ bool accept(csocket &client_socket) const;
+
+ //Client
+ bool connect(const char *sock_path);
+
+ //Data Transfer
+ ssize_t send(void const *buffer, size_t size) const;
+ ssize_t recv(void *buffer, size_t size) const;
+
+ bool set_connection_mode(void);
+ bool set_transfer_mode(void);
+ bool is_blocking_mode(void);
+
+ //check if socket is created
+ bool is_valid(void) const {
+ return (m_sock_fd >= 0);
+ }
+ int get_socket_fd(void) const {
+ return m_sock_fd;
+ }
+
+ bool close(void);
+ bool is_block_mode(void);
+
+private:
+ bool set_blocking_mode(bool blocking);
+ bool set_sock_type(void);
+
+ ssize_t send_for_seqpacket(void const *buffer, size_t size) const;
+ ssize_t send_for_stream(void const *buffer, size_t size) const;
+ ssize_t recv_for_seqpacket(void *buffer, size_t size) const;
+ ssize_t recv_for_stream(void *buffer, size_t size) const;
+
+ int m_sock_fd;
+ int m_sock_type;
+ sockaddr_un m_addr;
+ int m_send_flags;
+ int m_recv_flags;
+};
+
+#endif /* CSOCKET_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 <physical_sensor.h>
+#include <csensor_event_queue.h>
+
+physical_sensor::physical_sensor()
+{
+}
+
+physical_sensor::~physical_sensor()
+{
+}
+
+bool physical_sensor::push(sensor_event_t const &event)
+{
+ csensor_event_queue::get_instance().push(event);
+ return true;
+}
+
+bool physical_sensor::push(sensorhub_event_t const &event)
+{
+ csensor_event_queue::get_instance().push(event);
+ return true;
+}
+
+void physical_sensor::set_poller(working_func_t func, void *arg)
+{
+ m_sensor_data_poller.set_context(arg);
+ m_sensor_data_poller.set_working(func);
+}
+
+bool physical_sensor::start_poll(void)
+{
+ return m_sensor_data_poller.start();
+}
+
+bool physical_sensor::stop_poll(void)
+{
+ return m_sensor_data_poller.pause();
+}
--- /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 _PHYSICAL_SENSOR_H_
+#define _PHYSICAL_SENSOR_H_
+
+#include <sensor_base.h>
+#include <sf_common.h>
+#include <worker_thread.h>
+
+class physical_sensor : public sensor_base
+{
+public:
+ typedef worker_thread::trans_func_t working_func_t;
+
+private:
+ worker_thread m_sensor_data_poller;
+
+protected:
+ physical_sensor();
+ virtual ~physical_sensor();
+
+ bool push(sensor_event_t const &event);
+ bool push(sensorhub_event_t const &event);
+
+ void set_poller(working_func_t func, void *arg);
+ bool start_poll(void);
+ bool stop_poll(void);
+};
+
+#endif /*_PHYSICAL_SENSOR_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_base.h>
+#include <algorithm>
+
+#define UNKNOWN_NAME "UNKNOWN_SENSOR"
+
+sensor_base::sensor_base()
+: m_client(0)
+, m_started(false)
+{
+}
+
+sensor_base::~sensor_base()
+{
+}
+
+bool sensor_base::init()
+{
+ return true;
+}
+
+bool sensor_base::is_virtual()
+{
+ return false;
+}
+
+bool sensor_base::is_fusion(void)
+{
+ return false;
+}
+
+sensor_type_t sensor_base::get_type()
+{
+ return UNKNOWN_SENSOR;
+}
+
+const char *sensor_base::get_name()
+{
+ if (m_name.empty())
+ return UNKNOWN_NAME;
+
+ return m_name.c_str();
+}
+
+bool sensor_base::on_start()
+{
+ return true;
+}
+
+bool sensor_base::on_stop()
+{
+ return true;
+}
+
+bool sensor_base::start()
+{
+ AUTOLOCK(m_mutex);
+ AUTOLOCK(m_client_mutex);
+ ++m_client;
+
+ if (m_client == 1) {
+ if (!on_start()) {
+ ERR("[%s] sensor failed to start", get_name());
+ return false;
+ }
+
+ m_started = true;
+ }
+
+ INFO("[%s] sensor started, #client = %d", get_name(), m_client);
+ return true;
+}
+
+bool sensor_base::stop(void)
+{
+ AUTOLOCK(m_mutex);
+ AUTOLOCK(m_client_mutex);
+ --m_client;
+
+ if (m_client == 0) {
+ if (!on_stop()) {
+ ERR("[%s] sensor faild to stop", get_name());
+ return false;
+ }
+
+ m_started = false;
+ }
+
+ INFO("[%s] sensor stopped, #client = %d", get_name(), m_client);
+ return true;
+}
+
+bool sensor_base::is_started(void)
+{
+ AUTOLOCK(m_mutex);
+ AUTOLOCK(m_client_mutex);
+ return m_started;
+}
+
+bool sensor_base::add_client(unsigned int event_type)
+{
+ if (!is_supported(event_type)) {
+ ERR("Invaild event type: 0x%x", event_type);
+ return false;
+ }
+
+ AUTOLOCK(m_client_info_mutex);
+ ++(m_client_info[event_type]);
+ return true;
+}
+
+bool sensor_base::delete_client(unsigned int event_type)
+{
+ if (!is_supported(event_type)) {
+ ERR("Invaild event type: 0x%x", event_type);
+ return false;
+ }
+
+ AUTOLOCK(m_client_info_mutex);
+ client_info::iterator iter;
+ iter = m_client_info.find(event_type);
+
+ if (iter == m_client_info.end())
+ return false;
+
+ if (iter->second == 0)
+ return false;
+
+ --(iter->second);
+ return true;
+}
+
+bool sensor_base::add_interval(int client_id, unsigned int interval, bool is_processor)
+{
+ unsigned int cur_min;
+ AUTOLOCK(m_interval_info_list_mutex);
+ cur_min = m_interval_info_list.get_min();
+
+ if (!m_interval_info_list.add_interval(client_id, interval, is_processor))
+ return false;
+
+ if ((interval < cur_min) || !cur_min) {
+ INFO("Min interval for sensor[0x%x] is changed from %dms to %dms"
+ " by%sclient[%d] adding interval",
+ get_type(), cur_min, interval,
+ is_processor ? " processor " : " ", client_id);
+ set_interval(interval);
+ }
+
+ return true;
+}
+
+bool sensor_base::delete_interval(int client_id, bool is_processor)
+{
+ unsigned int prev_min, cur_min;
+ AUTOLOCK(m_interval_info_list_mutex);
+ prev_min = m_interval_info_list.get_min();
+
+ if (!m_interval_info_list.delete_interval(client_id, is_processor))
+ return false;
+
+ cur_min = m_interval_info_list.get_min();
+
+ if (!cur_min) {
+ INFO("No interval for sensor[0x%x] by%sclient[%d] deleting interval, "
+ "so set to default %dms",
+ get_type(), is_processor ? " processor " : " ",
+ client_id, POLL_1HZ_MS);
+ set_interval(POLL_1HZ_MS);
+ } else if (cur_min != prev_min) {
+ INFO("Min interval for sensor[0x%x] is changed from %dms to %dms"
+ " by%sclient[%d] deleting interval",
+ get_type(), prev_min, cur_min,
+ is_processor ? " processor " : " ", client_id);
+ set_interval(cur_min);
+ }
+
+ return true;
+}
+
+unsigned int sensor_base::get_interval(int client_id, bool is_processor)
+{
+ AUTOLOCK(m_interval_info_list_mutex);
+ return m_interval_info_list.get_interval(client_id, is_processor);
+}
+
+bool sensor_base::get_properties(const unsigned int type, sensor_properties_t &properties)
+{
+ ERR("Invalid type: 0x%x", type);
+ return false;
+}
+
+bool sensor_base::is_supported(unsigned int event_type)
+{
+ vector<int>::iterator iter;
+ iter = find(m_supported_event_info.begin(), m_supported_event_info.end(), event_type);
+
+ if (iter == m_supported_event_info.end())
+ return false;
+
+ return true;
+}
+
+long sensor_base::set_command(const unsigned int cmd, long value)
+{
+ return -1;
+}
+
+int sensor_base::send_sensorhub_data(const char *data, int data_len)
+{
+ return -1;
+}
+
+int sensor_base::get_sensor_data(const unsigned int type, sensor_data_t &data)
+{
+ return -1;
+}
+
+void sensor_base::register_supported_event(unsigned int event_type)
+{
+ m_supported_event_info.push_back(event_type);
+}
+
+unsigned int sensor_base::get_client_cnt(unsigned int event_type)
+{
+ AUTOLOCK(m_client_info_mutex);
+ client_info::iterator iter;
+ iter = m_client_info.find(event_type);
+
+ if (iter == m_client_info.end())
+ return 0;
+
+ return iter->second;
+}
+
+bool sensor_base::set_interval(unsigned long val)
+{
+ return true;
+}
+
+unsigned long long sensor_base::get_timestamp(void)
+{
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return ((unsigned long long)(t.tv_sec) * NS_TO_SEC + t.tv_nsec) / MS_TO_SEC;
+}
+
+unsigned long long sensor_base::get_timestamp(timeval *t)
+{
+ if (!t) {
+ ERR("t is NULL");
+ return 0;
+ }
+
+ return ((unsigned long long)(t->tv_sec) * US_TO_SEC + t->tv_usec);
+}
--- /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_BASE_H_
+#define _SENSOR_BASE_H_
+
+#include <list>
+#include <map>
+#include <vector>
+#include <mutex>
+#include <condition_variable>
+#include <string>
+#include <cinterval_info_list.h>
+#include <cmutex.h>
+#include <common.h>
+#include <sensor_common.h>
+#include <worker_thread.h>
+
+using std::string;
+using std::mutex;
+using std::recursive_mutex;
+using std::lock_guard;
+using std::list;
+using std::map;
+using std::vector;
+using std::unique_lock;
+using std::condition_variable;
+
+class sensor_base
+{
+private:
+ typedef map<unsigned int, unsigned int> client_info;
+
+public:
+ sensor_base();
+ virtual ~sensor_base();
+
+ virtual bool init(void);
+ virtual sensor_type_t get_type(void);
+ virtual const char *get_name(void);
+ virtual bool is_virtual(void);
+ virtual bool is_fusion(void);
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ bool start(void);
+ bool stop(void);
+ bool is_started(void);
+
+ virtual bool add_client(unsigned int event_type);
+ virtual bool delete_client(unsigned int event_type);
+
+ virtual bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
+ virtual bool delete_interval(int client_id, bool is_processor = false);
+ unsigned int get_interval(int client_id, bool is_processor = false);
+
+ virtual bool get_properties(const unsigned int type, sensor_properties_t &properties);
+ bool is_supported(unsigned int event_type);
+
+ virtual long set_command(const unsigned int cmd, long value);
+ virtual int send_sensorhub_data(const char *data, int data_len);
+
+ virtual int get_sensor_data(const unsigned int type, sensor_data_t &data);
+
+ void register_supported_event(unsigned int event_type);
+protected:
+ typedef lock_guard<mutex> lock;
+ typedef lock_guard<recursive_mutex> rlock;
+ typedef unique_lock<mutex> ulock;
+
+ cinterval_info_list m_interval_info_list;
+ cmutex m_interval_info_list_mutex;
+
+ cmutex m_mutex;
+
+ unsigned int m_client;
+ cmutex m_client_mutex;
+
+ client_info m_client_info;
+ cmutex m_client_info_mutex;
+
+ vector<int> m_supported_event_info;
+
+ bool m_started;
+
+ string m_name;
+
+ unsigned int get_client_cnt(unsigned int event_type);
+ virtual bool set_interval(unsigned long val);
+
+ unsigned long long get_timestamp(void);
+ unsigned long long get_timestamp(timeval *t);
+};
+
+#endif /*_SENSOR_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.
+ *
+ */
+
+#ifndef _SENSOR_COMMON_H_
+#define _SENSOR_COMMON_H_
+
+#ifndef DEPRECATED
+#define DEPRECATED __attribute__((deprecated))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /*__cplusplus*/
+
+#define MAX_KEY_LENGTH 64
+#define MAX_VALUE_SIZE 12
+#define SENSORHUB_TYPE_CONTEXT 1
+#define SENSORHUB_TYPE_GESTURE 2
+#define MS_TO_SEC 1000
+#define US_TO_SEC 1000000
+#define NS_TO_SEC 1000000000
+
+/**
+ * @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 {
+ 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,
+ ORIENTATION_SENSOR,
+} sensor_type_t;
+
+typedef struct sensor_data_t {
+ int data_accuracy;
+ int data_unit_idx;
+/*
+ * Use "timestamp" instead of "time_stamp"
+ * which is going to be removed soon
+ */
+ union {
+ unsigned long long time_stamp;
+ unsigned long long timestamp;
+ };
+ int values_num;
+ float values[MAX_VALUE_SIZE];
+} sensor_data_t;
+
+typedef struct sensor_event_t {
+ unsigned int event_type;
+ int situation;
+ sensor_data_t data;
+} sensor_event_t;
+
+#define HUB_DATA_MAX_SIZE 4096
+
+typedef struct {
+ int version;
+ int sensorhub;
+ int type;
+ int hub_data_size;
+ long long timestamp;
+ char hub_data[HUB_DATA_MAX_SIZE];
+ float data[16];
+} sensorhub_data_t;
+
+typedef struct sensorhub_event_t {
+ unsigned int event_type;
+ int situation;
+ sensorhub_data_t data;
+} sensorhub_event_t;
+
+typedef struct {
+ int sensor_unit_idx;
+ float sensor_min_range;
+ float sensor_max_range;
+ float sensor_resolution;
+ char sensor_name[MAX_KEY_LENGTH];
+ char sensor_vendor[MAX_KEY_LENGTH];
+} sensor_properties_t;
+
+enum sensor_data_unit_idx {
+ SENSOR_UNDEFINED_UNIT,
+ SENSOR_UNIT_METRE_PER_SECOND_SQUARED,
+ SENSOR_UNIT_MICRO_TESLA,
+ SENSOR_UNIT_DEGREE,
+ SENSOR_UNIT_LUX,
+ SENSOR_UNIT_CENTIMETER,
+ SENSOR_UNIT_LEVEL,
+ SENSOR_UNIT_STATE_ON_OFF,
+ SENSOR_UNIT_DEGREE_PER_SECOND,
+ SENSOR_UNIT_HECTOPASCAL,
+ SENSOR_UNIT_CELSIUS,
+ SENSOR_UNIT_METER,
+ SENSOR_UNIT_STEP,
+ SENSOR_UNIT_VENDOR_UNIT = 100,
+ SENSOR_UNIT_FILTER_CONVERTED,
+ SENSOR_UNIT_SENSOR_END
+};
+
+enum sensor_data_accuracy {
+ SENSOR_ACCURACY_UNDEFINED = -1,
+ SENSOR_ACCURACY_BAD = 0,
+ SENSOR_ACCURACY_NORMAL =1,
+ SENSOR_ACCURACY_GOOD = 2,
+ SENSOR_ACCURACY_VERYGOOD = 3
+};
+
+enum sensor_start_option {
+ SENSOR_OPTION_DEFAULT = 0,
+ SENSOR_OPTION_ALWAYS_ON = 1,
+ SENSOR_OPTION_END
+};
+
+enum _sensor_current_state {
+ SENSOR_STATE_UNKNOWN = -1,
+ SENSOR_STATE_STOPPED = 0,
+ SENSOR_STATE_STARTED = 1,
+ SENSOR_STATE_PAUSED = 2
+};
+
+enum _sensor_wakeup_state {
+ SENSOR_WAKEUP_UNKNOWN = -1,
+ SENSOR_WAKEUP_UNSETTED = 0,
+ SENSOR_WAKEUP_SETTED = 1,
+};
+
+enum _sensor_poweroff_state {
+ SENSOR_POWEROFF_UNKNOWN = -1,
+ SENSOR_POWEROFF_AWAKEN = 1,
+};
+
+enum event_situation {
+ SITUATION_LCD_ON,
+ SITUATION_LCD_OFF,
+ SITUATION_SURVIVAL_MODE
+};
+
+enum poll_value_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 enum {
+ CONDITION_NO_OP,
+ CONDITION_EQUAL,
+ CONDITION_GREAT_THAN,
+ CONDITION_LESS_THAN,
+} condition_op_t;
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_SENSOR_COMMON_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_fusion.h>
+
+sensor_fusion::sensor_fusion()
+{
+}
+
+sensor_fusion::~sensor_fusion()
+{
+}
+
+bool sensor_fusion::is_data_ready(void)
+{
+ return true;
+}
+
+bool sensor_fusion::get_properties(sensor_properties_t &properties)
+{
+ return false;
+}
+
+bool sensor_fusion::add_interval(int client_id, unsigned int interval)
+{
+ return true;
+}
+
+bool sensor_fusion::delete_interval(int client_id)
+{
+ return true;
+}
+
+bool sensor_fusion::get_rotation_matrix(arr33_t &rot)
+{
+ return false;
+}
+
+bool sensor_fusion::get_attitude(float &x, float &y, float &z, float &w)
+{
+ return false;
+}
+
+bool sensor_fusion::get_gyro_bias(float &x, float &y, float &z)
+{
+ return false;
+}
+
+bool sensor_fusion::get_rotation_vector(float &x, float &y, float &z, float &w, float &heading_accuracy)
+{
+ return false;
+}
+
+bool sensor_fusion::get_linear_acceleration(float &x, float &y, float &z)
+{
+ return false;
+}
+
+bool sensor_fusion::get_gravity(float &x, float &y, float &z)
+{
+ return false;
+}
+
+bool sensor_fusion::get_rotation_vector_6axis(float &x, float &y, float &z, float &w, float &heading_accuracy)
+{
+ return false;
+}
+
+bool sensor_fusion::get_geomagnetic_rotation_vector(float &x, float &y, float &z, float &w)
+{
+ return false;
+}
+
+bool sensor_fusion::get_orientation(float &azimuth, float &pitch, float &roll)
+{
+ return false;
+}
+
+bool sensor_fusion::is_fusion(void)
+{
+ 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.
+ *
+ */
+
+#ifndef _SENSOR_FUSION_H_
+#define _SENSOR_FUSION_H_
+
+#include <array>
+#include <sensor_base.h>
+
+typedef std::array<std::array<float, 3> , 3> arr33_t;
+
+class sensor_fusion : public sensor_base
+{
+public:
+ sensor_fusion();
+ virtual ~sensor_fusion();
+
+ virtual void fuse(const sensor_event_t &event) = 0;
+ virtual bool is_data_ready(void);
+ virtual bool add_interval(int client_id, unsigned int interval);
+ virtual bool delete_interval(int client_id);
+ virtual bool get_properties(sensor_properties_t &properties);
+
+ virtual bool get_rotation_matrix(arr33_t &rot);
+ virtual bool get_attitude(float &x, float &y, float &z, float &w);
+ virtual bool get_gyro_bias(float &x, float &y, float &z);
+ virtual bool get_rotation_vector(float &x, float &y, float &z, float &w, float &heading_accuracy);
+ virtual bool get_linear_acceleration(float &x, float &y, float &z);
+ virtual bool get_gravity(float &x, float &y, float &z);
+ virtual bool get_rotation_vector_6axis(float &x, float &y, float &z, float &w, float &heading_accuracy);
+ virtual bool get_geomagnetic_rotation_vector(float &x, float &y, float &z, float &w);
+ virtual bool get_orientation(float &azimuth, float &pitch, float &roll);
+
+ bool is_fusion(void);
+};
+
+#endif /*_SENSOR_FUSION_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.h>
+
+bool sensor_hal::set_interval(unsigned long val)
+{
+ return true;
+}
+
+long sensor_hal::set_command(const unsigned int cmd, long val)
+{
+ return -1;
+}
+
+int sensor_hal::send_sensorhub_data(const char *data, int data_len)
+{
+ return -1;
+}
+
+int sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ return -1;
+}
+
+int sensor_hal::get_sensor_data(sensorhub_data_t &data)
+{
+ return -1;
+}
+
+unsigned long long sensor_hal::get_timestamp(void)
+{
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return ((unsigned long long)(t.tv_sec) * NS_TO_SEC + t.tv_nsec) / MS_TO_SEC;
+}
+
+unsigned long long sensor_hal::get_timestamp(timeval *t)
+{
+ if (!t) {
+ ERR("t is NULL");
+ return 0;
+ }
+
+ return ((unsigned long long)(t->tv_sec) * US_TO_SEC + t->tv_usec);
+}
--- /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_H_
+#define _SENSOR_HAL_H_
+
+#include <sys/time.h>
+#include <sf_common.h>
+#include <cmutex.h>
+#include <common.h>
+#include <sensor.h>
+#include <string>
+
+using std::string;
+
+/*
+* 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
+
+class sensor_hal
+{
+public:
+ sensor_hal() {}
+ virtual ~sensor_hal() {}
+
+ virtual bool init(void *data = NULL) {
+ return true;
+ }
+ virtual string get_model_id(void) = 0;
+ virtual sensor_type_t get_type(void) = 0;
+ virtual bool enable(void) = 0;
+ virtual bool disable(void) = 0;
+ virtual bool set_interval(unsigned long val);
+ virtual bool is_data_ready(bool wait) = 0;
+ virtual bool get_properties(sensor_properties_t &properties) = 0;
+ virtual int get_sensor_data(sensor_data_t &data);
+ virtual int get_sensor_data(sensorhub_data_t &data);
+ virtual long set_command(const unsigned int cmd, long val);
+ virtual int send_sensorhub_data(const char *data, int data_len);
+protected:
+ cmutex m_mutex;
+
+ unsigned long long get_timestamp(void);
+ unsigned long long get_timestamp(timeval *t);
+};
+#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_plugin_loader.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <sensor_hal.h>
+#include <sensor_base.h>
+#include <sensor_fusion.h>
+#include <dlfcn.h>
+#include <common.h>
+
+using std::make_pair;
+
+#define ROOT_ELEMENT "PLUGIN"
+#define TEXT_ELEMENT "text"
+#define PATH_ATTR "path"
+#define HAL_ELEMENT "HAL"
+#define SENSOR_ELEMENT "SENSOR"
+
+sensor_plugin_loader::sensor_plugin_loader()
+{
+}
+
+void *sensor_plugin_loader::load_module(const char *path)
+{
+ void *handle = dlopen(path, RTLD_NOW);
+
+ if (!handle) {
+ DBG("Target file is %s , dlerror : %s", path, dlerror());
+ return NULL;
+ }
+
+ dlerror();
+
+ typedef void *create_t(void);
+ typedef void destroy_t(void *);
+ create_t *init_module = (create_t *) dlsym(handle, "create");
+ const char *dlsym_error = dlerror();
+
+ if (dlsym_error) {
+ ERR("Failed to find \"create\" %s", dlsym_error);
+ dlclose(handle);
+ return NULL;
+ }
+
+ destroy_t *exit_module = (destroy_t *) dlsym(handle, "destroy");
+ dlsym_error = dlerror();
+
+ if (dlsym_error) {
+ ERR("Failed to find \"destroy\" %s", dlsym_error);
+ dlclose(handle);
+ return NULL;
+ }
+
+ void *module = init_module();
+
+ if (!module) {
+ ERR("Failed to init the module => dlerror : %s , Target file is %s", dlerror(), path);
+ dlclose(handle);
+ return NULL;
+ }
+
+ return module;
+}
+
+bool sensor_plugin_loader::insert_module(const char *node_name, const char *path)
+{
+ if (strcmp(node_name, HAL_ELEMENT) == 0) {
+ DBG("insert sensor plugin [%s]", path);
+ sensor_hal *module;
+ module = (sensor_hal *)load_module(path);
+
+ if (!module)
+ return false;
+
+ sensor_type_t sensor_type = module->get_type();
+ m_sensor_hals.insert(make_pair(sensor_type, module));
+ }
+
+ if (strcmp(node_name, SENSOR_ELEMENT) == 0) {
+ DBG("insert sensor plugin [%s]", path);
+ sensor_base *module;
+ module = (sensor_base *)load_module(path);
+
+ if (!module)
+ return false;
+
+ if (!module->init()) {
+ ERR("Failed to init [%s] module", module->get_name());
+ delete module;
+ return false;
+ }
+
+ DBG("init [%s] module", module->get_name());
+ sensor_type_t sensor_type = module->get_type();
+
+ if (module->is_fusion())
+ m_fusions.push_back((sensor_fusion *) module);
+ else
+ m_sensors.insert(make_pair(sensor_type, module));
+ }
+
+ return true;
+}
+
+bool sensor_plugin_loader::load_plugins(const string &plugins_path)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+
+ DBG("sensor_plugin_load::load_plugins(\"%s\") is called!", plugins_path.c_str());
+ doc = xmlParseFile(plugins_path.c_str());
+
+ if (doc == NULL) {
+ ERR("There is no %s", plugins_path.c_str());
+ return false;
+ }
+
+ cur = xmlDocGetRootElement(doc);
+
+ if (cur == NULL) {
+ ERR("There is no root element in %s", plugins_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", ROOT_ELEMENT, plugins_path.c_str());
+ xmlFreeDoc(doc);
+ return false;
+ }
+
+ xmlNodePtr plugin_list_node_ptr;
+ xmlNodePtr module_node_ptr;
+ char *prop = NULL;
+ plugin_list_node_ptr = cur->xmlChildrenNode;
+
+ while (plugin_list_node_ptr != NULL) {
+ //skip garbage element, [text]
+ if (!xmlStrcmp(plugin_list_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
+ plugin_list_node_ptr = plugin_list_node_ptr->next;
+ continue;
+ }
+
+ DBG("<%s>", (const char *)plugin_list_node_ptr->name);
+
+ module_node_ptr = plugin_list_node_ptr->xmlChildrenNode;
+
+ while (module_node_ptr != NULL) {
+ if (!xmlStrcmp(module_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
+ module_node_ptr = module_node_ptr->next;
+ continue;
+ }
+
+ string path;
+ prop = (char *)xmlGetProp(module_node_ptr, (const xmlChar *)PATH_ATTR);
+ path = prop;
+ free(prop);
+ DBG("<%s path=\"%s\">", (const char *) module_node_ptr->name, path.c_str());
+ bool error = insert_module((const char *) plugin_list_node_ptr->name, path.c_str());
+
+ if (!error) {
+ //ERR("Fail to insert module : [%s]", path.c_str()) ;
+ }
+
+ DBG("");
+ module_node_ptr = module_node_ptr->next;
+ }
+
+ DBG("");
+ plugin_list_node_ptr = plugin_list_node_ptr->next;
+ }
+
+ xmlFreeDoc(doc);
+ show_sensor_info();
+ return true;
+}
+
+void sensor_plugin_loader::show_sensor_info(void)
+{
+ int index = 0;
+ sensor_plugins::iterator it = m_sensors.begin();
+
+ INFO("========== Loaded sensor information ==========");
+
+ while (it != m_sensors.end()) {
+ sensor_base *sensor = it->second;
+ sensor_properties_t properties;
+ int default_type = sensor->get_type() << SENSOR_TYPE_SHIFT | 0x1;
+
+ if (sensor->get_properties(default_type, properties)) {
+ INFO("[%d] %s", ++index, sensor->get_name());
+ INFO("name : %s", properties.sensor_name);
+ INFO("vendor : %s", properties.sensor_vendor);
+ INFO("unit_idx : %d", properties.sensor_unit_idx);
+ INFO("min_range : %f", properties.sensor_min_range);
+ INFO("max_range : %f", properties.sensor_max_range);
+ INFO("resolution : %f", properties.sensor_resolution);
+ }
+
+ it++;
+ }
+
+ INFO("===============================================");
+}
+
+sensor_hal *sensor_plugin_loader::get_sensor_hal(sensor_type_t type)
+{
+ sensor_hal_plugins::iterator it_plugins;
+ it_plugins = m_sensor_hals.find(type);
+
+ if (it_plugins == m_sensor_hals.end())
+ return NULL;
+
+ return it_plugins->second;
+}
+
+vector<sensor_hal *> sensor_plugin_loader::get_sensor_hals(sensor_type_t type)
+{
+ vector<sensor_hal *> sensor_hal_list;
+ pair<sensor_hal_plugins::iterator, sensor_hal_plugins::iterator> ret;
+ ret = m_sensor_hals.equal_range(type);
+ sensor_hal_plugins::iterator it;
+
+ for (it = ret.first; it != ret.second; ++it) {
+ sensor_hal_list.push_back(it->second);
+ }
+
+ return sensor_hal_list;
+}
+
+sensor_base *sensor_plugin_loader::get_sensor(sensor_type_t type)
+{
+ sensor_plugins::iterator it_plugins;
+ it_plugins = m_sensors.find(type);
+
+ if (it_plugins == m_sensors.end())
+ return NULL;
+
+ return it_plugins->second;
+}
+
+vector<sensor_base *> sensor_plugin_loader::get_sensors(sensor_type_t type)
+{
+ vector<sensor_base *> sensor_list;
+ pair<sensor_plugins::iterator, sensor_plugins::iterator> ret;
+ ret = m_sensors.equal_range(type);
+ sensor_plugins::iterator it;
+
+ for (it = ret.first; it != ret.second; ++it) {
+ sensor_list.push_back(it->second);
+ }
+
+ return sensor_list;
+}
+
+vector<sensor_base *> sensor_plugin_loader::get_virtual_sensors(void)
+{
+ vector<sensor_base *> virtual_list;
+ sensor_plugins::iterator sensor_it;
+ sensor_base *module;
+
+ for (sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
+ module = sensor_it->second;
+
+ if (module && module->is_virtual() == true) {
+ virtual_list.push_back(module);
+ }
+ }
+
+ return virtual_list;
+}
+
+sensor_fusion *sensor_plugin_loader::get_fusion(void)
+{
+ if (m_fusions.empty())
+ return NULL;
+
+ return m_fusions.front();
+}
+
+vector<sensor_fusion *> sensor_plugin_loader::get_fusions(void)
+{
+ return m_fusions;
+}
+
+bool sensor_plugin_loader::destroy()
+{
+ sensor_base *sensor;
+ sensor_plugins::iterator sensor_it;
+
+ for (sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
+ sensor = sensor_it->second;
+ delete sensor;
+ }
+
+ sensor_hal *sensor_hal;
+ sensor_hal_plugins::iterator sensor_hal_it;
+
+ for (sensor_hal_it = m_sensor_hals.begin(); sensor_hal_it != m_sensor_hals.end(); ++sensor_hal_it) {
+ sensor_hal = sensor_hal_it->second;
+ delete sensor_hal;
+ }
+
+ m_sensors.clear();
+ m_sensor_hals.clear();
+ 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.
+ *
+ */
+
+#ifndef _SENSOR_PLUGIN_LOADER_H_
+#define _SENSOR_PLUGIN_LOADER_H_
+
+#include <sensor_common.h>
+#include <cmutex.h>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <map>
+
+class sensor_hal;
+class sensor_base;
+class sensor_fusion;
+
+using std::pair;
+using std::vector;
+using std::multimap;
+using std::string;
+using std::istringstream;
+
+#define PLUGINS_FILE_PATH "/usr/etc/sensor_plugins.xml"
+
+typedef multimap<sensor_type_t, sensor_hal *> sensor_hal_plugins;
+/*
+* a hal_plugins is a group of hal plugin
+* <HAL>
+* ...
+* </HAL>
+*
+*/
+
+typedef multimap<sensor_type_t, sensor_base *> sensor_plugins;
+/*
+* a sensor_plugins is a group of sensor plugin
+* <SENSOR>
+* ...
+* </SENSOR>
+*
+*/
+
+typedef vector<sensor_fusion *> fusion_plugins;
+/*
+* a fusion_plugins is a group of fusion plugin
+* <FUSION>
+* ...
+* </FUSION>
+*
+*/
+
+class sensor_plugin_loader
+{
+private:
+ sensor_plugin_loader();
+
+ void *load_module(const char *path);
+ bool insert_module(const char *node_name, const char *path);
+ void show_sensor_info(void);
+
+ sensor_hal_plugins m_sensor_hals;
+ sensor_plugins m_sensors;
+ fusion_plugins m_fusions;
+
+public:
+ static sensor_plugin_loader &get_instance() {
+ static sensor_plugin_loader inst;
+ return inst;
+ }
+ bool load_plugins(const string &plugins_path = PLUGINS_FILE_PATH);
+
+ sensor_hal *get_sensor_hal(sensor_type_t type);
+ vector<sensor_hal *> get_sensor_hals(sensor_type_t type);
+
+ sensor_base *get_sensor(sensor_type_t type);
+ vector<sensor_base *> get_sensors(sensor_type_t type);
+
+ vector<sensor_base *> get_virtual_sensors(void);
+
+ sensor_fusion *get_fusion(void);
+ vector<sensor_fusion *> get_fusions(void);
+
+ bool destroy();
+};
+#endif /*_SENSOR_PLUGIN_LOADER_H_*/
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@/sf_common
+
+Name: libsensord-server
+Description: Commonly used code and defintions for sensord and sensord-proprietary
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -lsensord-server
+Cflags: -I${includedir}
--- /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 _SF_COMMON_H_
+#define _SF_COMMON_H_
+
+#include <unistd.h>
+#include <cpacket.h>
+#include <vector>
+#include <sensor_common.h>
+
+#define COMMAND_CHANNEL_PATH "/tmp/sf_command_socket"
+#define EVENT_CHANNEL_PATH "/tmp/sf_event_socket"
+
+#define MAX_VALUE_SIZE 12
+#define MAX_HANDLE 64
+#define MAX_HANDLE_REACHED -2
+#define CLIENT_ID_INVALID -1
+
+enum packet_type_t {
+ CMD_NONE = 0,
+ CMD_GET_ID,
+ CMD_HELLO,
+ CMD_BYEBYE,
+ CMD_WAIT_EVENT,
+ CMD_DONE,
+ CMD_START,
+ CMD_STOP,
+ CMD_REG,
+ CMD_UNREG,
+ CMD_CHECK_EVENT,
+ CMD_SET_OPTION,
+ CMD_SET_INTERVAL,
+ CMD_UNSET_INTERVAL,
+ CMD_SET_COMMAND,
+ CMD_GET_PROPERTIES,
+ CMD_GET_DATA,
+ CMD_SEND_SENSORHUB_DATA,
+ CMD_CNT,
+};
+
+typedef struct {
+ pid_t pid;
+} cmd_get_id_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 {
+ unsigned int type;
+} cmd_get_properties_t;
+
+typedef struct {
+ long value;
+} cmd_done_t;
+
+typedef struct {
+ int client_id;
+} cmd_get_id_done_t;
+
+typedef struct {
+ int state;
+ sensor_properties_t properties;
+} cmd_properties_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 event_type;
+} cmd_check_event_t;
+
+typedef struct {
+ unsigned int interval;
+} cmd_set_interval_t;
+
+typedef struct {
+} cmd_unset_interval_t;
+
+typedef struct {
+ int option;
+} cmd_set_option_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 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_GESTURE_ENABLE_BIT,
+ SENSORHUB_PROXIMITY_ENABLE_BIT,
+ SENSORHUB_LIGHT_ENABLE_BIT,
+ SENSORHUB_PROXIMITY_RAW_ENABLE_BIT,
+ SENSORHUB_ORIENTATION_ENABLE_BIT,
+ SENSORHUB_GYRO_UNCALIB_ENABLE_BIT,
+ SENSORHUB_GAME_ROTATION_VECTOR_ENABLE_BIT = 15,
+ SENSORHUB_ENABLE_BIT_MAX,
+};
+
+#endif /*_SF_COMMON_H_*/
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@/sf_common
+
+Name: libsf_common
+Description: Commonly used code and defintions for the sensor framework.
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -lsensord-share
+Cflags: -I${includedir}
--- /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 <virtual_sensor.h>
+#include <csensor_event_dispatcher.h>
+
+virtual_sensor::virtual_sensor()
+{
+}
+
+virtual_sensor::~virtual_sensor()
+{
+}
+
+bool virtual_sensor::is_virtual(void)
+{
+ return true;
+}
+
+bool virtual_sensor::activate(void)
+{
+ return csensor_event_dispatcher::get_instance().add_active_virtual_sensor(this);
+}
+
+bool virtual_sensor::deactivate(void)
+{
+ return csensor_event_dispatcher::get_instance().delete_active_virtual_sensor(this);
+}
--- /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 _VIRTUAL_SENSOR_H_
+#define _VIRTUAL_SENSOR_H_
+
+#include <sensor_base.h>
+
+class virtual_sensor : public sensor_base
+{
+public:
+ virtual_sensor();
+ virtual ~virtual_sensor();
+
+ virtual void synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs) = 0;
+ bool is_virtual(void);
+
+protected:
+ bool activate(void);
+ bool deactivate(void);
+};
+
+#endif /*_VIRTUAL_SENSOR_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 <common.h>
+#include <worker_thread.h>
+#include <thread>
+
+using std::thread;
+
+worker_thread::worker_thread()
+: m_state(WORKER_STATE_INITIAL)
+, m_context(NULL)
+, m_thread_created(false)
+{
+ for (int i = 0; i < TRANS_FUNC_CNT; ++i)
+ m_trans_func[i] = NULL;
+}
+
+worker_thread::~worker_thread()
+{
+ stop();
+}
+
+bool worker_thread::transition_function(trans_func_index index)
+{
+ if (m_trans_func[index] != NULL) {
+ if (!m_trans_func[index](m_context)) {
+ _T("Transition[%d] function returning false", index);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+worker_thread::worker_state_t worker_thread::get_state(void)
+{
+ lock l(m_mutex);
+ return m_state;
+}
+
+bool worker_thread::start(void)
+{
+ lock l(m_mutex);
+
+ if (m_state == WORKER_STATE_WORKING) {
+ _T("Worker thread is already working");
+ return true;
+ }
+
+ if ((m_state == WORKER_STATE_INITIAL) || (m_state == WORKER_STATE_STOPPED)) {
+ m_state = WORKER_STATE_WORKING;
+
+ if (!m_thread_created) {
+ thread th(&worker_thread::main, this);
+ th.detach();
+ }
+
+ return true;
+ } else if (m_state == WORKER_STATE_PAUSED) {
+ m_state = WORKER_STATE_WORKING;
+ m_cond_working.notify_one();
+ return true;
+ }
+
+ _T("Failed to start, because current state(%d) is not for START", m_state);
+ return false;
+}
+
+bool worker_thread::stop(void)
+{
+ lock l(m_mutex);
+
+ if (m_state == WORKER_STATE_STOPPED) {
+ _T("Worker thread is already stopped");
+ return true;
+ }
+
+ if ((m_state == WORKER_STATE_WORKING) || (m_state == WORKER_STATE_PAUSED)) {
+ if (m_state == WORKER_STATE_PAUSED)
+ m_cond_working.notify_one();
+
+ m_state = WORKER_STATE_STOPPED;
+ return true;
+ }
+
+ _T("Failed to stop, because current state(%d) is not for STOP", m_state);
+ return false;
+}
+
+bool worker_thread::pause(void)
+{
+ lock l(m_mutex);
+
+ if (m_state == WORKER_STATE_PAUSED) {
+ _T("Worker thread is already paused");
+ return true;
+ }
+
+ if (m_state == WORKER_STATE_WORKING) {
+ m_state = WORKER_STATE_PAUSED;
+ return true;
+ }
+
+ _T("Failed to pause, because current state(%d) is not for PAUSE", m_state);
+ return false;
+}
+
+bool worker_thread::resume(void)
+{
+ lock l(m_mutex);
+
+ if (m_state == WORKER_STATE_WORKING) {
+ _T("Worker thread is already working");
+ return true;
+ }
+
+ if (m_state == WORKER_STATE_PAUSED) {
+ m_state = WORKER_STATE_WORKING;
+ m_cond_working.notify_one();
+ return true;
+ }
+
+ _T("Failed to resume, because current state(%d) is not for RESUME", m_state);
+ return false;
+}
+
+
+/*
+ * After state changed to STOPPED, it should not access member fields,
+ * because some transition funciton of STOPPED delete this pointer
+ */
+
+void worker_thread::main(void)
+{
+ _T("Worker thread(0x%x) is created", std::this_thread::get_id());
+ transition_function(STARTED);
+
+ while (true) {
+ worker_state_t state;
+ state = get_state();
+
+ if (state == WORKER_STATE_WORKING) {
+ if (!transition_function(WORKING)) {
+ m_state = WORKER_STATE_STOPPED;
+ _T("Worker thread(0x%x) exits from working state", std::this_thread::get_id());
+ m_thread_created = false;
+ transition_function(STOPPED);
+ break;
+ }
+
+ continue;
+ }
+
+ ulock u(m_mutex);
+
+ if (m_state == WORKER_STATE_PAUSED) {
+ transition_function(PAUSED);
+ _T("Worker thread(0x%x) is paused", std::this_thread::get_id());
+ m_cond_working.wait(u);
+
+ if (m_state == WORKER_STATE_WORKING) {
+ transition_function(RESUMED);
+ _T("Worker thread(0x%x) is resumed", std::this_thread::get_id());
+ } else if (m_state == WORKER_STATE_STOPPED) {
+ m_thread_created = false;
+ transition_function(STOPPED);
+ break;
+ }
+ } else if (m_state == WORKER_STATE_STOPPED) {
+ m_thread_created = false;
+ transition_function(STOPPED);
+ break;
+ }
+ }
+
+ _T("Worker thread(0x%x)'s main is terminated", std::this_thread::get_id());
+}
+
+void worker_thread::set_started(trans_func_t func)
+{
+ m_trans_func[STARTED] = func;
+}
+
+void worker_thread::set_stopped(trans_func_t func)
+{
+ m_trans_func[STOPPED] = func;
+}
+
+void worker_thread::set_paused(trans_func_t func)
+{
+ m_trans_func[PAUSED] = func;
+}
+
+void worker_thread::set_resumed(trans_func_t func)
+{
+ m_trans_func[RESUMED] = func;
+}
+
+void worker_thread::set_working(trans_func_t func)
+{
+ m_trans_func[WORKING] = func;
+}
+
+void worker_thread::set_context(void *ctx)
+{
+ m_context = ctx;
+}
--- /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 _WORKER_THREAD_H_
+#define _WORKER_THREAD_H_
+
+#include <mutex>
+#include <condition_variable>
+
+using std::mutex;
+using std::lock_guard;
+using std::unique_lock;
+using std::condition_variable;
+
+class worker_thread
+{
+public:
+ enum worker_state_t {
+ WORKER_STATE_INITIAL,
+ WORKER_STATE_WORKING,
+ WORKER_STATE_PAUSED,
+ WORKER_STATE_STOPPED,
+ };
+
+ typedef bool(*trans_func_t)(void *data);
+private:
+ enum trans_func_index {
+ STARTED = 0,
+ STOPPED,
+ PAUSED,
+ RESUMED,
+ WORKING,
+ TRANS_FUNC_CNT,
+ };
+
+ typedef lock_guard<mutex> lock;
+ typedef unique_lock<mutex> ulock;
+
+ worker_state_t m_state;
+ void *m_context;
+ mutex m_mutex;
+ condition_variable m_cond_working;
+ bool m_thread_created;
+
+ trans_func_t m_trans_func[TRANS_FUNC_CNT];
+
+ bool transition_function(trans_func_index index);
+ void main(void);
+public:
+ worker_thread();
+ virtual ~worker_thread();
+
+ bool start(void);
+ bool stop(void);
+ bool pause(void);
+ bool resume(void);
+
+ worker_state_t get_state(void);
+
+ void set_started(trans_func_t func);
+ void set_stopped(trans_func_t func);
+ void set_paused(trans_func_t func);
+ void set_resumed(trans_func_t func);
+ void set_working(trans_func_t func);
+
+ void set_context(void *ctx);
+};
+
+#endif /*_WORKER_THREAD_H_*/