sensor-framework : Initial commit 19/19819/3
authorkibak.yoon <kibak.yoon@samsung.com>
Mon, 21 Apr 2014 05:51:42 +0000 (14:51 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Thu, 24 Apr 2014 06:00:21 +0000 (15:00 +0900)
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

121 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE.APLv2 [new file with mode: 0644]
libsensord.manifest [new file with mode: 0644]
packaging/sensord.service [new file with mode: 0755]
packaging/sensord.socket [new file with mode: 0644]
packaging/sensord.spec [new file with mode: 0755]
sensor_plugins.xml.in [new file with mode: 0755]
sensor_plugins_sim.xml.in [new file with mode: 0755]
sensord.manifest [new file with mode: 0755]
sensors.xml.in [new file with mode: 0755]
src/CMakeLists.txt [new file with mode: 0755]
src/accel/CMakeLists.txt [new file with mode: 0755]
src/accel/accel_sensor.cpp [new file with mode: 0755]
src/accel/accel_sensor.h [new file with mode: 0755]
src/accel/accel_sensor_hal.cpp [new file with mode: 0755]
src/accel/accel_sensor_hal.h [new file with mode: 0755]
src/geo/CMakeLists.txt [new file with mode: 0755]
src/geo/geo_sensor.cpp [new file with mode: 0755]
src/geo/geo_sensor.h [new file with mode: 0755]
src/geo/geo_sensor_hal.cpp [new file with mode: 0755]
src/geo/geo_sensor_hal.h [new file with mode: 0755]
src/gravity/CMakeLists.txt [new file with mode: 0755]
src/gravity/gravity_sensor.cpp [new file with mode: 0755]
src/gravity/gravity_sensor.h [new file with mode: 0755]
src/gyro/CMakeLists.txt [new file with mode: 0755]
src/gyro/gyro_sensor.cpp [new file with mode: 0755]
src/gyro/gyro_sensor.h [new file with mode: 0755]
src/gyro/gyro_sensor_hal.cpp [new file with mode: 0755]
src/gyro/gyro_sensor_hal.h [new file with mode: 0755]
src/libsensord/CMakeLists.txt [new file with mode: 0755]
src/libsensord/client.cpp [new file with mode: 0755]
src/libsensord/client_common.cpp [new file with mode: 0755]
src/libsensord/client_common.h [new file with mode: 0755]
src/libsensord/command_channel.cpp [new file with mode: 0755]
src/libsensord/command_channel.h [new file with mode: 0755]
src/libsensord/creg_event_info.h [new file with mode: 0755]
src/libsensord/csensor_event_listener.cpp [new file with mode: 0755]
src/libsensord/csensor_event_listener.h [new file with mode: 0755]
src/libsensord/csensor_handle_info.cpp [new file with mode: 0755]
src/libsensord/csensor_handle_info.h [new file with mode: 0755]
src/libsensord/poller.cpp [new file with mode: 0755]
src/libsensord/poller.h [new file with mode: 0755]
src/libsensord/sensor.h [new file with mode: 0755]
src/libsensord/sensor.pc.in [new file with mode: 0755]
src/libsensord/sensor_accel.h [new file with mode: 0755]
src/libsensord/sensor_context.h [new file with mode: 0755]
src/libsensord/sensor_geomag.h [new file with mode: 0755]
src/libsensord/sensor_gravity.h [new file with mode: 0755]
src/libsensord/sensor_gyro.h [new file with mode: 0755]
src/libsensord/sensor_light.h [new file with mode: 0755]
src/libsensord/sensor_linear_accel.h [new file with mode: 0755]
src/libsensord/sensor_motion.h [new file with mode: 0755]
src/libsensord/sensor_orientation.h [new file with mode: 0755]
src/libsensord/sensor_proxi.h [new file with mode: 0755]
src/light/CMakeLists.txt [new file with mode: 0755]
src/light/light_sensor.cpp [new file with mode: 0755]
src/light/light_sensor.h [new file with mode: 0755]
src/light/light_sensor_hal.cpp [new file with mode: 0755]
src/light/light_sensor_hal.h [new file with mode: 0755]
src/linear_accel/CMakeLists.txt [new file with mode: 0755]
src/linear_accel/linear_accel_sensor.cpp [new file with mode: 0755]
src/linear_accel/linear_accel_sensor.h [new file with mode: 0755]
src/proxi/CMakeLists.txt [new file with mode: 0755]
src/proxi/proxi_sensor.cpp [new file with mode: 0755]
src/proxi/proxi_sensor.h [new file with mode: 0755]
src/proxi/proxi_sensor_hal.cpp [new file with mode: 0755]
src/proxi/proxi_sensor_hal.h [new file with mode: 0755]
src/sensor_fusion/CMakeLists.txt [new file with mode: 0755]
src/sensor_fusion/lib_sensor_fusion.cpp [new file with mode: 0755]
src/sensor_fusion/lib_sensor_fusion.h [new file with mode: 0755]
src/server/CMakeLists.txt [new file with mode: 0755]
src/server/command_worker.cpp [new file with mode: 0755]
src/server/command_worker.h [new file with mode: 0755]
src/server/main.cpp [new file with mode: 0755]
src/server/server.cpp [new file with mode: 0755]
src/server/server.h [new file with mode: 0755]
src/shared/CMakeLists.txt [new file with mode: 0755]
src/shared/cbase_lock.cpp [new file with mode: 0755]
src/shared/cbase_lock.h [new file with mode: 0755]
src/shared/cclient_info_manager.cpp [new file with mode: 0755]
src/shared/cclient_info_manager.h [new file with mode: 0755]
src/shared/cclient_sensor_record.cpp [new file with mode: 0755]
src/shared/cclient_sensor_record.h [new file with mode: 0755]
src/shared/cconfig.cpp [new file with mode: 0755]
src/shared/cconfig.h [new file with mode: 0755]
src/shared/cinterval_info_list.cpp [new file with mode: 0755]
src/shared/cinterval_info_list.h [new file with mode: 0755]
src/shared/cmutex.cpp [new file with mode: 0755]
src/shared/cmutex.h [new file with mode: 0755]
src/shared/common.cpp [new file with mode: 0755]
src/shared/common.h [new file with mode: 0755]
src/shared/cpacket.cpp [new file with mode: 0755]
src/shared/cpacket.h [new file with mode: 0755]
src/shared/crw_lock.cpp [new file with mode: 0755]
src/shared/crw_lock.h [new file with mode: 0755]
src/shared/csensor_event_dispatcher.cpp [new file with mode: 0755]
src/shared/csensor_event_dispatcher.h [new file with mode: 0755]
src/shared/csensor_event_queue.cpp [new file with mode: 0755]
src/shared/csensor_event_queue.h [new file with mode: 0755]
src/shared/csensor_usage.cpp [new file with mode: 0755]
src/shared/csensor_usage.h [new file with mode: 0755]
src/shared/csocket.cpp [new file with mode: 0755]
src/shared/csocket.h [new file with mode: 0755]
src/shared/physical_sensor.cpp [new file with mode: 0755]
src/shared/physical_sensor.h [new file with mode: 0755]
src/shared/sensor_base.cpp [new file with mode: 0755]
src/shared/sensor_base.h [new file with mode: 0755]
src/shared/sensor_common.h [new file with mode: 0755]
src/shared/sensor_fusion.cpp [new file with mode: 0755]
src/shared/sensor_fusion.h [new file with mode: 0755]
src/shared/sensor_hal.cpp [new file with mode: 0755]
src/shared/sensor_hal.h [new file with mode: 0755]
src/shared/sensor_plugin_loader.cpp [new file with mode: 0755]
src/shared/sensor_plugin_loader.h [new file with mode: 0755]
src/shared/sensord-server.pc.in [new file with mode: 0755]
src/shared/sf_common.h [new file with mode: 0755]
src/shared/sf_common.pc.in [new file with mode: 0755]
src/shared/virtual_sensor.cpp [new file with mode: 0755]
src/shared/virtual_sensor.h [new file with mode: 0755]
src/shared/worker_thread.cpp [new file with mode: 0755]
src/shared/worker_thread.h [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..fbcfe9a
--- /dev/null
@@ -0,0 +1,53 @@
+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)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..91cbe82
--- /dev/null
@@ -0,0 +1,203 @@
+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.
diff --git a/libsensord.manifest b/libsensord.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/packaging/sensord.service b/packaging/sensord.service
new file mode 100755 (executable)
index 0000000..d3ab961
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=Sensor Daemon
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/sensord
+Restart=always
+RestartSec=0
+MemoryLimit=10M
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/sensord.socket b/packaging/sensord.socket
new file mode 100644 (file)
index 0000000..5357ca5
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=Sensor daemon socket
+
+[Socket]
+ListenStream=/tmp/sf_command_socket
+SocketMode=0777
+PassCredentials=yes
+Accept=false
+SmackLabelIPIn=*
+SmackLabelIPOut=@
diff --git a/packaging/sensord.spec b/packaging/sensord.spec
new file mode 100755 (executable)
index 0000000..f5fb9fa
--- /dev/null
@@ -0,0 +1,117 @@
+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
diff --git a/sensor_plugins.xml.in b/sensor_plugins.xml.in
new file mode 100755 (executable)
index 0000000..2e844ff
--- /dev/null
@@ -0,0 +1,21 @@
+<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>
diff --git a/sensor_plugins_sim.xml.in b/sensor_plugins_sim.xml.in
new file mode 100755 (executable)
index 0000000..8f7b40b
--- /dev/null
@@ -0,0 +1,17 @@
+<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>
diff --git a/sensord.manifest b/sensord.manifest
new file mode 100755 (executable)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/sensors.xml.in b/sensors.xml.in
new file mode 100755 (executable)
index 0000000..b4dfa74
--- /dev/null
@@ -0,0 +1,229 @@
+<?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>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..f2872e1
--- /dev/null
@@ -0,0 +1,53 @@
+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)
diff --git a/src/accel/CMakeLists.txt b/src/accel/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..b4dcd9a
--- /dev/null
@@ -0,0 +1,52 @@
+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)
diff --git a/src/accel/accel_sensor.cpp b/src/accel/accel_sensor.cpp
new file mode 100755 (executable)
index 0000000..21d256d
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * 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;
+}
diff --git a/src/accel/accel_sensor.h b/src/accel/accel_sensor.h
new file mode 100755 (executable)
index 0000000..dedf8c2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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_*/
diff --git a/src/accel/accel_sensor_hal.cpp b/src/accel/accel_sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..04032ce
--- /dev/null
@@ -0,0 +1,633 @@
+/*
+ * 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;
+}
diff --git a/src/accel/accel_sensor_hal.h b/src/accel/accel_sensor_hal.h
new file mode 100755 (executable)
index 0000000..25a6b3c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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_*/
diff --git a/src/geo/CMakeLists.txt b/src/geo/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..4478781
--- /dev/null
@@ -0,0 +1,52 @@
+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)
diff --git a/src/geo/geo_sensor.cpp b/src/geo/geo_sensor.cpp
new file mode 100755 (executable)
index 0000000..6a80591
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * 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;
+}
diff --git a/src/geo/geo_sensor.h b/src/geo/geo_sensor.h
new file mode 100755 (executable)
index 0000000..449a4d2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_*/
diff --git a/src/geo/geo_sensor_hal.cpp b/src/geo/geo_sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..b1cadcf
--- /dev/null
@@ -0,0 +1,504 @@
+/*
+ * 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;
+}
diff --git a/src/geo/geo_sensor_hal.h b/src/geo/geo_sensor_hal.h
new file mode 100755 (executable)
index 0000000..066d672
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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_*/
diff --git a/src/gravity/CMakeLists.txt b/src/gravity/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..466f54b
--- /dev/null
@@ -0,0 +1,43 @@
+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)
diff --git a/src/gravity/gravity_sensor.cpp b/src/gravity/gravity_sensor.cpp
new file mode 100755 (executable)
index 0000000..34eee07
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * 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;
+}
diff --git a/src/gravity/gravity_sensor.h b/src/gravity/gravity_sensor.h
new file mode 100755 (executable)
index 0000000..0737707
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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_*/
diff --git a/src/gyro/CMakeLists.txt b/src/gyro/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..afef9f0
--- /dev/null
@@ -0,0 +1,52 @@
+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)
diff --git a/src/gyro/gyro_sensor.cpp b/src/gyro/gyro_sensor.cpp
new file mode 100755 (executable)
index 0000000..26b9830
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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;
+}
diff --git a/src/gyro/gyro_sensor.h b/src/gyro/gyro_sensor.h
new file mode 100755 (executable)
index 0000000..51eb31c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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
diff --git a/src/gyro/gyro_sensor_hal.cpp b/src/gyro/gyro_sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..0b94ae7
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * 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;
+}
diff --git a/src/gyro/gyro_sensor_hal.h b/src/gyro/gyro_sensor_hal.h
new file mode 100755 (executable)
index 0000000..0a145c3
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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_*/
diff --git a/src/libsensord/CMakeLists.txt b/src/libsensord/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..505303e
--- /dev/null
@@ -0,0 +1,69 @@
+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)
diff --git a/src/libsensord/client.cpp b/src/libsensord/client.cpp
new file mode 100755 (executable)
index 0000000..f978c66
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * 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;
+}
diff --git a/src/libsensord/client_common.cpp b/src/libsensord/client_common.cpp
new file mode 100755 (executable)
index 0000000..62aa507
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * 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);
+}
diff --git a/src/libsensord/client_common.h b/src/libsensord/client_common.h
new file mode 100755 (executable)
index 0000000..dc8c78b
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/command_channel.cpp b/src/libsensord/command_channel.cpp
new file mode 100755 (executable)
index 0000000..c9c6681
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * 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;
+}
diff --git a/src/libsensord/command_channel.h b/src/libsensord/command_channel.h
new file mode 100755 (executable)
index 0000000..13d84e1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/creg_event_info.h b/src/libsensord/creg_event_info.h
new file mode 100755 (executable)
index 0000000..9ccf473
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/csensor_event_listener.cpp b/src/libsensord/csensor_event_listener.cpp
new file mode 100755 (executable)
index 0000000..ae0fd4f
--- /dev/null
@@ -0,0 +1,818 @@
+/*
+ * 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;
+}
diff --git a/src/libsensord/csensor_event_listener.h b/src/libsensord/csensor_event_listener.h
new file mode 100755 (executable)
index 0000000..99ce5a3
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/csensor_handle_info.cpp b/src/libsensord/csensor_handle_info.cpp
new file mode 100755 (executable)
index 0000000..4b5b5fe
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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();
+}
+
diff --git a/src/libsensord/csensor_handle_info.h b/src/libsensord/csensor_handle_info.h
new file mode 100755 (executable)
index 0000000..78d5a33
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/poller.cpp b/src/libsensord/poller.cpp
new file mode 100755 (executable)
index 0000000..8411dcc
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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);
+}
+
diff --git a/src/libsensord/poller.h b/src/libsensord/poller.h
new file mode 100755 (executable)
index 0000000..b75fe9a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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_ */
diff --git a/src/libsensord/sensor.h b/src/libsensord/sensor.h
new file mode 100755 (executable)
index 0000000..794a497
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor.pc.in b/src/libsensord/sensor.pc.in
new file mode 100755 (executable)
index 0000000..10bb017
--- /dev/null
@@ -0,0 +1,13 @@
+# 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}
diff --git a/src/libsensord/sensor_accel.h b/src/libsensord/sensor_accel.h
new file mode 100755 (executable)
index 0000000..32622c4
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_context.h b/src/libsensord/sensor_context.h
new file mode 100755 (executable)
index 0000000..ff52265
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_geomag.h b/src/libsensord/sensor_geomag.h
new file mode 100755 (executable)
index 0000000..5270762
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_gravity.h b/src/libsensord/sensor_gravity.h
new file mode 100755 (executable)
index 0000000..16a5f82
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_gyro.h b/src/libsensord/sensor_gyro.h
new file mode 100755 (executable)
index 0000000..485628f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_light.h b/src/libsensord/sensor_light.h
new file mode 100755 (executable)
index 0000000..86aee82
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_linear_accel.h b/src/libsensord/sensor_linear_accel.h
new file mode 100755 (executable)
index 0000000..4a98503
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_motion.h b/src/libsensord/sensor_motion.h
new file mode 100755 (executable)
index 0000000..d9a51d8
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_orientation.h b/src/libsensord/sensor_orientation.h
new file mode 100755 (executable)
index 0000000..0444887
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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_*/
diff --git a/src/libsensord/sensor_proxi.h b/src/libsensord/sensor_proxi.h
new file mode 100755 (executable)
index 0000000..ce6b80c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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_*/
diff --git a/src/light/CMakeLists.txt b/src/light/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e32223b
--- /dev/null
@@ -0,0 +1,53 @@
+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)
diff --git a/src/light/light_sensor.cpp b/src/light/light_sensor.cpp
new file mode 100755 (executable)
index 0000000..4c8481d
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * 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;
+}
diff --git a/src/light/light_sensor.h b/src/light/light_sensor.h
new file mode 100755 (executable)
index 0000000..455df3d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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_*/
diff --git a/src/light/light_sensor_hal.cpp b/src/light/light_sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..06045db
--- /dev/null
@@ -0,0 +1,458 @@
+/*
+ * 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;
+}
diff --git a/src/light/light_sensor_hal.h b/src/light/light_sensor_hal.h
new file mode 100755 (executable)
index 0000000..2cba537
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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
diff --git a/src/linear_accel/CMakeLists.txt b/src/linear_accel/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..b158f2b
--- /dev/null
@@ -0,0 +1,44 @@
+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)
diff --git a/src/linear_accel/linear_accel_sensor.cpp b/src/linear_accel/linear_accel_sensor.cpp
new file mode 100755 (executable)
index 0000000..7465d61
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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;
+}
diff --git a/src/linear_accel/linear_accel_sensor.h b/src/linear_accel/linear_accel_sensor.h
new file mode 100755 (executable)
index 0000000..2d1e96f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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_*/
diff --git a/src/proxi/CMakeLists.txt b/src/proxi/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..6a52735
--- /dev/null
@@ -0,0 +1,53 @@
+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)
diff --git a/src/proxi/proxi_sensor.cpp b/src/proxi/proxi_sensor.cpp
new file mode 100755 (executable)
index 0000000..4799da4
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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;
+}
diff --git a/src/proxi/proxi_sensor.h b/src/proxi/proxi_sensor.h
new file mode 100755 (executable)
index 0000000..5b8a411
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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_*/
diff --git a/src/proxi/proxi_sensor_hal.cpp b/src/proxi/proxi_sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..eed0c9b
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * 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;
+}
diff --git a/src/proxi/proxi_sensor_hal.h b/src/proxi/proxi_sensor_hal.h
new file mode 100755 (executable)
index 0000000..d483814
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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
diff --git a/src/sensor_fusion/CMakeLists.txt b/src/sensor_fusion/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..d03dbde
--- /dev/null
@@ -0,0 +1,43 @@
+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)
diff --git a/src/sensor_fusion/lib_sensor_fusion.cpp b/src/sensor_fusion/lib_sensor_fusion.cpp
new file mode 100755 (executable)
index 0000000..0217c97
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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;
+}
diff --git a/src/sensor_fusion/lib_sensor_fusion.h b/src/sensor_fusion/lib_sensor_fusion.h
new file mode 100755 (executable)
index 0000000..85ddd3e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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_*/
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..4939cd4
--- /dev/null
@@ -0,0 +1,23 @@
+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)
diff --git a/src/server/command_worker.cpp b/src/server/command_worker.cpp
new file mode 100755 (executable)
index 0000000..2ef5562
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * 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();
+}
+
diff --git a/src/server/command_worker.h b/src/server/command_worker.h
new file mode 100755 (executable)
index 0000000..9f1d697
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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_ */
diff --git a/src/server/main.cpp b/src/server/main.cpp
new file mode 100755 (executable)
index 0000000..f1aeb85
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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;
+}
diff --git a/src/server/server.cpp b/src/server/server.cpp
new file mode 100755 (executable)
index 0000000..892b69a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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();
+}
diff --git a/src/server/server.h b/src/server/server.h
new file mode 100755 (executable)
index 0000000..b31e02f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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_*/
diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e23eb93
--- /dev/null
@@ -0,0 +1,99 @@
+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
+)
+
diff --git a/src/shared/cbase_lock.cpp b/src/shared/cbase_lock.cpp
new file mode 100755 (executable)
index 0000000..52b1993
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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;
+}
diff --git a/src/shared/cbase_lock.h b/src/shared/cbase_lock.h
new file mode 100755 (executable)
index 0000000..2bebf66
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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_*/
diff --git a/src/shared/cclient_info_manager.cpp b/src/shared/cclient_info_manager.cpp
new file mode 100755 (executable)
index 0000000..19347a0
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * 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;
+}
diff --git a/src/shared/cclient_info_manager.h b/src/shared/cclient_info_manager.h
new file mode 100755 (executable)
index 0000000..733b95a
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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_*/
diff --git a/src/shared/cclient_sensor_record.cpp b/src/shared/cclient_sensor_record.cpp
new file mode 100755 (executable)
index 0000000..9ddee5a
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * 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();
+}
+
diff --git a/src/shared/cclient_sensor_record.h b/src/shared/cclient_sensor_record.h
new file mode 100755 (executable)
index 0000000..17d1341
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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_*/
diff --git a/src/shared/cconfig.cpp b/src/shared/cconfig.cpp
new file mode 100755 (executable)
index 0000000..389ce24
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * 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);
+}
diff --git a/src/shared/cconfig.h b/src/shared/cconfig.h
new file mode 100755 (executable)
index 0000000..7b14edc
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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_*/
diff --git a/src/shared/cinterval_info_list.cpp b/src/shared/cinterval_info_list.cpp
new file mode 100755 (executable)
index 0000000..a4ba3ee
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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;
+}
+
diff --git a/src/shared/cinterval_info_list.h b/src/shared/cinterval_info_list.h
new file mode 100755 (executable)
index 0000000..bfb4240
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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_*/
diff --git a/src/shared/cmutex.cpp b/src/shared/cmutex.cpp
new file mode 100755 (executable)
index 0000000..d4720cf
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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);
+}
diff --git a/src/shared/cmutex.h b/src/shared/cmutex.h
new file mode 100755 (executable)
index 0000000..e59fba0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_*/
diff --git a/src/shared/common.cpp b/src/shared/common.cpp
new file mode 100755 (executable)
index 0000000..d02e20d
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * 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]));
+}
diff --git a/src/shared/common.h b/src/shared/common.h
new file mode 100755 (executable)
index 0000000..a2105ca
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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_*/
diff --git a/src/shared/cpacket.cpp b/src/shared/cpacket.cpp
new file mode 100755 (executable)
index 0000000..8bce6e9
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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;
+}
diff --git a/src/shared/cpacket.h b/src/shared/cpacket.h
new file mode 100755 (executable)
index 0000000..7eb653a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_*/
diff --git a/src/shared/crw_lock.cpp b/src/shared/crw_lock.cpp
new file mode 100755 (executable)
index 0000000..942a034
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * libsensord-share
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "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);
+}
diff --git a/src/shared/crw_lock.h b/src/shared/crw_lock.h
new file mode 100755 (executable)
index 0000000..2ec20db
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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_*/
diff --git a/src/shared/csensor_event_dispatcher.cpp b/src/shared/csensor_event_dispatcher.cpp
new file mode 100755 (executable)
index 0000000..db5d8c0
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * 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();
+}
diff --git a/src/shared/csensor_event_dispatcher.h b/src/shared/csensor_event_dispatcher.h
new file mode 100755 (executable)
index 0000000..569d134
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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_*/
diff --git a/src/shared/csensor_event_queue.cpp b/src/shared/csensor_event_queue.cpp
new file mode 100755 (executable)
index 0000000..e190005
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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;
+}
+
diff --git a/src/shared/csensor_event_queue.h b/src/shared/csensor_event_queue.h
new file mode 100755 (executable)
index 0000000..890e179
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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_*/
diff --git a/src/shared/csensor_usage.cpp b/src/shared/csensor_usage.cpp
new file mode 100755 (executable)
index 0000000..9f35198
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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;
+}
diff --git a/src/shared/csensor_usage.h b/src/shared/csensor_usage.h
new file mode 100755 (executable)
index 0000000..aed055f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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_ */
diff --git a/src/shared/csocket.cpp b/src/shared/csocket.cpp
new file mode 100755 (executable)
index 0000000..96d50fe
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * 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;
+}
diff --git a/src/shared/csocket.h b/src/shared/csocket.h
new file mode 100755 (executable)
index 0000000..2d9e3ce
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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_ */
diff --git a/src/shared/physical_sensor.cpp b/src/shared/physical_sensor.cpp
new file mode 100755 (executable)
index 0000000..a81e33f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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();
+}
diff --git a/src/shared/physical_sensor.h b/src/shared/physical_sensor.h
new file mode 100755 (executable)
index 0000000..d4438ce
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensor_base.cpp b/src/shared/sensor_base.cpp
new file mode 100755 (executable)
index 0000000..17ad75f
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * 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);
+}
diff --git a/src/shared/sensor_base.h b/src/shared/sensor_base.h
new file mode 100755 (executable)
index 0000000..1d60077
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensor_common.h b/src/shared/sensor_common.h
new file mode 100755 (executable)
index 0000000..3c218d6
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensor_fusion.cpp b/src/shared/sensor_fusion.cpp
new file mode 100755 (executable)
index 0000000..1189575
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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;
+}
diff --git a/src/shared/sensor_fusion.h b/src/shared/sensor_fusion.h
new file mode 100755 (executable)
index 0000000..3375dcb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensor_hal.cpp b/src/shared/sensor_hal.cpp
new file mode 100755 (executable)
index 0000000..d91a2ec
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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);
+}
diff --git a/src/shared/sensor_hal.h b/src/shared/sensor_hal.h
new file mode 100755 (executable)
index 0000000..8e8fed6
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensor_plugin_loader.cpp b/src/shared/sensor_plugin_loader.cpp
new file mode 100755 (executable)
index 0000000..368278a
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * 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;
+}
+
diff --git a/src/shared/sensor_plugin_loader.h b/src/shared/sensor_plugin_loader.h
new file mode 100755 (executable)
index 0000000..fd380df
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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_*/
diff --git a/src/shared/sensord-server.pc.in b/src/shared/sensord-server.pc.in
new file mode 100755 (executable)
index 0000000..d03b10f
--- /dev/null
@@ -0,0 +1,13 @@
+# 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}
diff --git a/src/shared/sf_common.h b/src/shared/sf_common.h
new file mode 100755 (executable)
index 0000000..caa7260
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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_*/
diff --git a/src/shared/sf_common.pc.in b/src/shared/sf_common.pc.in
new file mode 100755 (executable)
index 0000000..3c6eddc
--- /dev/null
@@ -0,0 +1,13 @@
+# 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}
diff --git a/src/shared/virtual_sensor.cpp b/src/shared/virtual_sensor.cpp
new file mode 100755 (executable)
index 0000000..c205fac
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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);
+}
diff --git a/src/shared/virtual_sensor.h b/src/shared/virtual_sensor.h
new file mode 100755 (executable)
index 0000000..2fd1bf2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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_*/
diff --git a/src/shared/worker_thread.cpp b/src/shared/worker_thread.cpp
new file mode 100755 (executable)
index 0000000..2982cf6
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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;
+}
diff --git a/src/shared/worker_thread.h b/src/shared/worker_thread.h
new file mode 100755 (executable)
index 0000000..63f2082
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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_*/