From 0b62190f51cfc6938776770083386a856581e303 Mon Sep 17 00:00:00 2001 From: Kibum Kim Date: Sat, 7 Jan 2012 00:42:57 +0900 Subject: [PATCH] Git init --- AUTHORS | 1 + CMakeLists.txt | 90 ++ LICENSE | 206 ++++ capi-system-sensor.pc.in | 15 + debian/README | 0 debian/capi-system-sensor-dev.install | 4 + debian/capi-system-sensor-dev.postinst | 1 + debian/capi-system-sensor.install | 1 + debian/capi-system-sensor.postinst | 1 + debian/changelog | 29 + debian/compat | 1 + debian/control | 22 + debian/rules | 65 ++ include/sensor_private.h | 106 ++ include/sensors.h | 1220 ++++++++++++++++++++++++ packaging/capi-system-sensor.spec | 53 + phone_facedown.png | Bin 0 -> 26918 bytes phone_panning.png | Bin 0 -> 29808 bytes phone_snap.png | Bin 0 -> 64576 bytes src/sensor.c | 889 +++++++++++++++++ 20 files changed, 2704 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100755 LICENSE create mode 100644 capi-system-sensor.pc.in create mode 100644 debian/README create mode 100644 debian/capi-system-sensor-dev.install create mode 100644 debian/capi-system-sensor-dev.postinst create mode 100644 debian/capi-system-sensor.install create mode 100644 debian/capi-system-sensor.postinst create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100755 debian/rules create mode 100755 include/sensor_private.h create mode 100755 include/sensors.h create mode 100644 packaging/capi-system-sensor.spec create mode 100755 phone_facedown.png create mode 100755 phone_panning.png create mode 100755 phone_snap.png create mode 100644 src/sensor.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..0a63eea --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Pius Lee diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b6a2175 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-system-sensor") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +SET(dependents "dlog sensor capi-base-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${dependents}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DTIZEN_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +aux_source_directory(src SOURCES) +ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/system + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${dependents}) +SET(PC_LDFLAGS -l${fw_name}) +SET(PC_CFLAGS -I\${includedir}/system) + +CONFIGURE_FILE( + ${fw_name}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + +#ADD_SUBDIRECTORY(test) + +IF(UNIX) + +ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution) +ADD_CUSTOM_COMMAND( + DEPENDS clean + COMMENT "distribution clean" + COMMAND find + ARGS . + -not -name config.cmake -and \( + -name tester.c -or + -name Testing -or + -name CMakeFiles -or + -name cmake.depends -or + -name cmake.check_depends -or + -name CMakeCache.txt -or + -name cmake.check_cache -or + -name *.cmake -or + -name Makefile -or + -name core -or + -name core.* -or + -name gmon.out -or + -name install_manifest.txt -or + -name *.pc -or + -name *~ \) + | grep -v TC | xargs rm -rf + TARGET distclean + VERBATIM +) + +ENDIF(UNIX) + diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..bbe9d02 --- /dev/null +++ b/LICENSE @@ -0,0 +1,206 @@ +Copyright (c) 2000 - 2011 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/capi-system-sensor.pc.in b/capi-system-sensor.pc.in new file mode 100644 index 0000000..f758dbd --- /dev/null +++ b/capi-system-sensor.pc.in @@ -0,0 +1,15 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include/system + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} @PC_CFLAGS@ + diff --git a/debian/README b/debian/README new file mode 100644 index 0000000..e69de29 diff --git a/debian/capi-system-sensor-dev.install b/debian/capi-system-sensor-dev.install new file mode 100644 index 0000000..761a28b --- /dev/null +++ b/debian/capi-system-sensor-dev.install @@ -0,0 +1,4 @@ +/usr/include/* +/usr/include/*/* +/usr/lib/pkgconfig/*.pc + diff --git a/debian/capi-system-sensor-dev.postinst b/debian/capi-system-sensor-dev.postinst new file mode 100644 index 0000000..1a24852 --- /dev/null +++ b/debian/capi-system-sensor-dev.postinst @@ -0,0 +1 @@ +#!/bin/sh diff --git a/debian/capi-system-sensor.install b/debian/capi-system-sensor.install new file mode 100644 index 0000000..4a755a4 --- /dev/null +++ b/debian/capi-system-sensor.install @@ -0,0 +1 @@ +/usr/lib/lib*.so* diff --git a/debian/capi-system-sensor.postinst b/debian/capi-system-sensor.postinst new file mode 100644 index 0000000..1a24852 --- /dev/null +++ b/debian/capi-system-sensor.postinst @@ -0,0 +1 @@ +#!/bin/sh diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..2a85778 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,29 @@ +capi-system-sensor (0.1.0-6) unstable; urgency=low + + * fix bug for calibration callback's invalidate user data + * Git: api/sensor + * Tag: capi-system-sensor_0.1.0-6 + + -- Pius Lee Tue, 27 Dec 2011 16:11:32 +0900 + +capi-system-sensor (0.1.0-5) unstable; urgency=low + + * fix bugs in the every read functions + * Git: api/sensor + * Tag: capi-system-sensor_0.1.0-5 + + -- Pius Lee Wed, 21 Dec 2011 20:45:19 +0900 + +capi-system-sensor (0.1.0-4) unstable; urgency=low + + * update version + * Git: api/sensor + * Tag: capi-system-sensor_0.1.0-4 + + -- Pius Lee Thu, 15 Dec 2011 13:53:27 +0900 + +capi-system-sensor (0.0.1-1) unstable; urgency=low + + * Initial release. + + -- Pius Lee Wed, 07 Dec 2011 12:53:15 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..a8922d8 --- /dev/null +++ b/debian/control @@ -0,0 +1,22 @@ + +Source: capi-system-sensor +Section: libs +Priority: extra +Maintainer: pius lee +Build-Depends: debhelper (>= 5), dlog-dev, libslp-sensor-dev, capi-base-common-dev, libglib2.0-dev + +Package: capi-system-sensor +Architecture: any +Depends: ${shilbs:Depends}, ${misc:Depends} +Description: A Sensor library in Tizen Native API + +Package: capi-system-sensor-dev +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, capi-system-sensor (= ${Source-Version}), dlog-dev, libslp-sensor-dev, capi-base-common-dev +Description: A Sensor library in Tizen Native API (DEV) + +Package: capi-system-sensor-dbg +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, capi-system-sensor (= ${Source-Version}) +Description: A Sensor library in Tizen Native API (DBG) + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..2f99f75 --- /dev/null +++ b/debian/rules @@ -0,0 +1,65 @@ +#!/usr/bin/make -f + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +CMAKE_ROOT_DIR ?= $(CURDIR) +CMAKE_BUILD_DIR ?= $(CURDIR)/cmake_build_tmp + +configure: configure-stamp +configure-stamp: + dh_testdir + mkdir -p $(CMAKE_BUILD_DIR) && cd $(CMAKE_BUILD_DIR) && cmake .. + touch configure-stamp + + +build: build-stamp +build-stamp: configure-stamp + dh_testdir + cd $(CMAKE_BUILD_DIR) && $(MAKE) + touch $@ + +clean: + cd $(CMAKE_ROOT_DIR) + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + rm -f `find . -name *.pc` + rm -rf $(CMAKE_BUILD_DIR) + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cd $(CMAKE_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp + dh_installman + dh_link + dh_strip --dbg-package=capi-system-sensor-dbg + dh_fixperms + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure + diff --git a/include/sensor_private.h b/include/sensor_private.h new file mode 100755 index 0000000..7147ae8 --- /dev/null +++ b/include/sensor_private.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + +#ifndef __TIZEN_SYSTEM_SENSOR_PRIVATE_H__ +#define __TIZEN_SYSTEM_SENSOR_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum _sensor_ids_index{ + ID_ACCELEOMETER, + ID_GEOMAGNETIC, + ID_GYROSCOPE, + ID_LIGHT, + ID_PROXIMITY, + ID_MOTION, + ID_NUMBERS +}; + +#define CB_NUMBERS (SENSOR_MOTION_FACEDOWN+1) +#define CALIB_CB_NUMBERS (SENSOR_ORIENTATION+1) + +struct sensor_handle_s { + int ids[ID_NUMBERS]; +// sensor_type_e type; + int started[CB_NUMBERS]; + void* cb_func[CB_NUMBERS]; + void* cb_user_data[CB_NUMBERS]; + + void* calib_func[CALIB_CB_NUMBERS]; + void* calib_user_data[CALIB_CB_NUMBERS]; +}; + +#define SENSOR_INIT(handle) \ + do { \ + handle->ids[ID_ACCELEOMETER] = -1; \ + handle->ids[ID_GEOMAGNETIC] = -1; \ + handle->ids[ID_GYROSCOPE] = -1; \ + handle->ids[ID_LIGHT] = -1; \ + handle->ids[ID_PROXIMITY] = -1; \ + handle->ids[ID_MOTION] = -1; \ + handle->started[SENSOR_ACCELEROMETER] = 0; \ + handle->started[SENSOR_MAGNETIC] = 0; \ + handle->started[SENSOR_ORIENTATION] = 0; \ + handle->started[SENSOR_GYROSCOPE] = 0; \ + handle->started[SENSOR_LIGHT] = 0; \ + handle->started[SENSOR_PROXIMITY] = 0; \ + handle->started[SENSOR_MOTION_SNAP] = 0; \ + handle->started[SENSOR_MOTION_SHAKE] = 0; \ + handle->started[SENSOR_MOTION_DOUBLETAP] = 0; \ + handle->started[SENSOR_MOTION_PANNING] = 0; \ + handle->started[SENSOR_MOTION_FACEDOWN] = 0; \ + handle->cb_func[SENSOR_ACCELEROMETER] = NULL; \ + handle->cb_func[SENSOR_MAGNETIC] = NULL; \ + handle->cb_func[SENSOR_ORIENTATION] = NULL; \ + handle->cb_func[SENSOR_GYROSCOPE] = NULL; \ + handle->cb_func[SENSOR_LIGHT] = NULL; \ + handle->cb_func[SENSOR_PROXIMITY] = NULL; \ + handle->cb_func[SENSOR_MOTION_SNAP] = NULL; \ + handle->cb_func[SENSOR_MOTION_SHAKE] = NULL; \ + handle->cb_func[SENSOR_MOTION_DOUBLETAP] = NULL; \ + handle->cb_func[SENSOR_MOTION_PANNING] = NULL; \ + handle->cb_func[SENSOR_MOTION_FACEDOWN] = NULL; \ + handle->cb_user_data[SENSOR_ACCELEROMETER] = NULL; \ + handle->cb_user_data[SENSOR_MAGNETIC] = NULL; \ + handle->cb_user_data[SENSOR_ORIENTATION] = NULL; \ + handle->cb_user_data[SENSOR_GYROSCOPE] = NULL; \ + handle->cb_user_data[SENSOR_LIGHT] = NULL; \ + handle->cb_user_data[SENSOR_PROXIMITY] = NULL; \ + handle->cb_user_data[SENSOR_MOTION_SNAP] = NULL; \ + handle->cb_user_data[SENSOR_MOTION_SHAKE] = NULL; \ + handle->cb_user_data[SENSOR_MOTION_DOUBLETAP] = NULL; \ + handle->cb_user_data[SENSOR_MOTION_PANNING] = NULL; \ + handle->cb_user_data[SENSOR_MOTION_FACEDOWN] = NULL; \ + handle->calib_func[SENSOR_ACCELEROMETER] = NULL; \ + handle->calib_func[SENSOR_MAGNETIC] = NULL; \ + handle->calib_func[SENSOR_ORIENTATION] = NULL; \ + handle->calib_user_data[SENSOR_ACCELEROMETER] = NULL; \ + handle->calib_user_data[SENSOR_MAGNETIC] = NULL; \ + handle->calib_user_data[SENSOR_ORIENTATION] = NULL; \ + }while(0) \ + + +#ifdef __cplusplus +} +#endif + +#endif // __TIZEN_SYSTEM_SENSOR_PRIVATE_H__ diff --git a/include/sensors.h b/include/sensors.h new file mode 100755 index 0000000..fe4fa39 --- /dev/null +++ b/include/sensors.h @@ -0,0 +1,1220 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + +#ifndef __TIZEN_SYSTEM_SENSOR_H__ +#define __TIZEN_SYSTEM_SENSOR_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MODULE + * @{ + */ + +/** + * @brief The sensor handle. + */ +typedef struct sensor_handle_s* sensor_h; + +/** +* @brief Enumerations of sensor data accuracy. +*/ +typedef enum +{ + SENSOR_DATA_ACCURACY_UNDEFINED = -1, /**< Undefined accuracy */ + SENSOR_DATA_ACCURACY_BAD = 0, /**< Bad accuracy */ + SENSOR_DATA_ACCURACY_NORMAL = 1, /**< Normal accuracy */ + SENSOR_DATA_ACCURACY_GOOD = 2, /**< Good accuracy */ + SENSOR_DATA_ACCURACY_VERYGOOD = 3 /**< Very good accuracy */ +} sensor_data_accuracy_e; + + +/** +* @brief Enumerations of error code for sensor. +*/ +typedef enum +{ + SENSOR_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + SENSOR_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + SENSOR_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + SENSOR_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_SYSTEM_CLASS | 0x02, /**< Out of memory */ + SENSOR_ERROR_NOT_NEED_CALIBRATION = TIZEN_ERROR_SYSTEM_CLASS | 0x03, /**< Sensor doesn't need calibration */ + SENSOR_ERROR_NOT_SUPPORTED = TIZEN_ERROR_SYSTEM_CLASS | 0x04, /**< Unsupported sensor in current device */ + SENSOR_ERROR_OPERATION_FAILED = TIZEN_ERROR_SYSTEM_CLASS | 0x06, /**< Operation failed */ + +} sensor_error_e; + + +/** +* @brief Enumerations of sensor type. +*/ +typedef enum +{ + SENSOR_ACCELEROMETER, /**< Accelerometer */ + SENSOR_MAGNETIC, /**< Magnetic sensor */ + SENSOR_ORIENTATION, /**< Orientation sensor */ + SENSOR_GYROSCOPE, /**< Gyroscope sensor */ + SENSOR_LIGHT, /**< Light sensor */ + SENSOR_PROXIMITY, /**< Proximity sensor */ + SENSOR_MOTION_SNAP, /**< Snap motion sensor */ + SENSOR_MOTION_SHAKE, /**< Shake motion sensor */ + SENSOR_MOTION_DOUBLETAP, /**< Double tap motion sensor */ + SENSOR_MOTION_PANNING, /**< Panning motion sensor */ + SENSOR_MOTION_FACEDOWN /**< Face to down motion sensor */ +} sensor_type_e; +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SNAP_MODULE + * @{ + */ + +/** + * @brief Enumerations of snap motion event. + */ +typedef enum +{ + SENSOR_MOTION_SNAP_NONE, /**< No Snap */ + SENSOR_MOTION_SNAP_LEFT, /**< Snap left to right */ + SENSOR_MOTION_SNAP_RIGHT, /**< Snap right to left */ +} sensor_motion_snap_e; +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SHAKE_MODULE + * @{ + */ + +/** + * @brief Enumerations of shake motion event. + */ +typedef enum +{ + SENSOR_MOTION_SHAKE_NONE, /**< No Shake */ + SENSOR_MOTION_SHAKE_DETECTED, /**< Shake motion detected */ + SENSOR_MOTION_SHAKE_CONTINUING, /**< Shake motion continuing */ + SENSOR_MOTION_SHAKE_FINISHED, /**< Shake motion finished */ + SENSOR_MOTION_SHAKE_BROKEN, /**< Shake motion broken */ +} sensor_motion_shake_e; +/** + * @} + */ + + +/** + * @} +*/ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MODULE + * @{ + */ + +/** + * @brief Called when the current sensor reading falls outside of a defined normal range. + * + * @details When something is artificially influencing, such as ferrous metal objects or + * electromagnetic fields (car electrical systems, automobile engines, steel pitons, etc.), this callback is called. + * One way of implementing this callback is to notice a user to make big 8-like gesture with device. + * + * @param[in] user_data The user data passed from the callback registration function + * + * @see sensor_magnetic_set_calibration_cb() + * @see sensor_magnetic_unset_calibration_cb() + * @see sensor_orientation_set_calibration_cb() + * @see sensor_orientation_unset_calibration_cb() + */ +typedef void (*sensor_calibration_cb)(void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_ACCELEROMETER_MODULE + * @{ + */ + +/** + * @brief Called when an accelerometer event occurs. + * + * @param[in] accuracy The accuracy of @a x, @a y, and @a z values + * @param[in] x The acceleration minus Gx on the x-axis in [m/s^2] + * @param[in] y The acceleration minus Gy on the y-axis in [m/s^2] + * @param[in] z The acceleration minus Gz on the z-axis in [m/s^2] + * @param[in] user_data The user data passed from the callback registration function + * + * @pre sensor_start() will invoke this callback if you register this callback using sensor_accelerometer_set_cb(). + * + * @see sensor_accelerometer_set_cb() + * @see sensor_accelerometer_unset_cb() + */ +typedef void (*sensor_accelerometer_event_cb)( + sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data); +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_GYROSCOPE_MODULE + * @{ + */ + +/** + * @brief Called when a gyroscope event occurs. + * + * @remark + * All values are in radians/second and measure the rate of rotation around the X, Y and Z axis. \n + * The coordinate system is the same as is used for the acceleration sensor. Rotation is positive \n + * in the counter-clockwise direction. That is, an observer looking from some positive location \n + * on the @a x, @a y, or @a z axis at a device positioned on the origin would report positive rotation if \n + * the device appeared to be rotating counter clockwise. Note that this is the standard mathematical \n + * definition of positive rotation and does not agree with the definition of roll given earlier. + * + * @param[in] accuracy The accuracy of @a x, @a y, and @a z values + * @param[in] x Angular speed around the x-axis in degree per second + * @param[in] y Angular speed around the y-axis in degree per second + * @param[in] z Angular speed around the z-axis in degree per second + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_gyroscope_set_cb(). + * @see sensor_gyroscope_set_cb() + * @see sensor_gyroscope_unset_cb() + */ +typedef void (*sensor_gyroscope_event_cb)( + sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data); +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_LIGHT_MODULE + * @{ + */ + +/** + * @brief Called when a light event occurs. + * + * @remark + * All values are neither SI lux units (lx), nor adc.\n + * Values returned by sensor may vary depending on a hardware. In the case of some\n + * HW, level 1 can mean 1 ~ 100 lux, while in some other case, level 1 can mean 1~50 lux.\n + * You should use light level between min and max values obtained \n + * with #sensor_get_spec(). In most cases min is 1 and max is 10. + * + * @param[in] accuracy The accuracy of @a level, @a y, and @a z values + * @param[in] level Actual light level + * @param[in] level Ambient light level between min and max values obtained with #sensor_get_spec().\n + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_light_set_cb(). + * @see sensor_light_set_cb() + * @see sensor_light_unset_cb() + */ +typedef void (*sensor_light_event_cb)( + sensor_data_accuracy_e accuracy, int level, void *user_data); +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MAGNETIC_MODULE + * @{ + */ + +/** + * @brief Called when a magnetic event occurs. + * + * @remark @a x, @a y, and @a z values are in micro-Teslas(uT) and measure the ambient magnetic field in the X, Y and Z axis. + * + * @param[in] accuracy The accuracy of @a x, @a y, and @a z values + * @param[in] x Micro-Tesla value from ambient magnetic field on the x-axis + * @param[in] y Micro-Tesla value from ambient magnetic field on the y-axis + * @param[in] z Micro-Tesla value from ambient magnetic field on the z-axis + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_magnetic_set_cb(). + * @see sensor_magnetic_set_cb() + * @see sensor_magnetic_unset_cb() + */ +typedef void (*sensor_magnetic_event_cb)( + sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data); +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_ORIENTATION_MODULE + * @{ + */ + +/** + * @brief Called when an orientation event occurs. + * + * @remark All values are angles in degrees. + * + * @param[in] accuracy The accuracy of @a x, @a y, and @a z values + * @param[in] azimuth The angle between the magnetic north direction and the y-axis, around the z-axis [0 ~ 359]. \n + * 0 = North, 90 = East, 180 = South, 270 = West + * @param[in] pitch The rotation around x-axis [-180 ~ 180], with positive values when the z-axis moves \n + * toward the y-axis + * @param[in] roll The rotation around y-axis [-90 ~ 90], with positive values when the x-axis moves \n + * toward the z-axis + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_orientation_set_cb(). + * @see sensor_orientation_set_cb() + * @see sensor_orientation_unset_cb() + */ +typedef void (*sensor_orientation_event_cb)( + sensor_data_accuracy_e accuracy, float azimuth, float pitch, float roll, void *user_data); +/** + * @} + */ + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_PROXIMITY_MODULE + * @{ + */ + +/** + * @brief Called when a proximity event occurs. + * + * @param[out] is_near @c true if an object is close to the phone, otherwise @c false + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_proximity_set_cb(). + * @see sensor_proximity_set_cb() + * @see sensor_proximity_unset_cb() + */ +typedef void (*sensor_proximity_event_cb)(bool is_near, void *user_data); +/** + * @} + */ + + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SNAP_MODULE + * @{ + */ + +/** + * @brief Called when a snap motion event occurs. + * @image html phone_snap.png + * + * @param[in] snap The type of motion snap + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_motion_snap_set_cb(). + * @see sensor_motion_snap_set_cb() + * @see sensor_motion_snap_unset_cb() + */ +typedef void (*sensor_motion_snap_event_cb) (sensor_motion_snap_e snap, void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SHAKE_MODULE + * @{ + */ + +/** + * @brief Called when a shake motion event occurs. + * + * @param[in] shake The type of motion shake + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_motion_shake_set_cb(). + * @see sensor_motion_shake_set_cb() + * @see sensor_motion_shake_unset_cb() + */ +typedef void (*sensor_motion_shake_event_cb) (sensor_motion_shake_e shake, void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_DOUBLETAP_MODULE + * @{ + */ + +/** + * @brief Called when a double tap motion event occurs. + * + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_motion_doubletap_set_cb(). + * @see sensor_motion_doubletap_set_cb() + * @see sensor_motion_doubletap_unset_cb() + */ +typedef void (*sensor_motion_doubletap_event_cb) (void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_PANNING_MODULE + * @{ + */ + +/** + * @brief Called when a panning tap motion event occurs. + * @image html phone_panning.png + * + * @param[in] x 1/10 angle on x-axis + * @param[in] y 1/10 angle on y-axis + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_motion_panning_set_cb(). + * @see sensor_motion_panning_set_cb() + * @see sensor_motion_panning_unset_cb() + */ +typedef void (*sensor_motion_panning_event_cb) (int x, int y, void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_FACEDOWN_MODULE + * @{ + */ + +/** + * @brief Called when a facedown tap motion event occurs. + * @details + * This event occurs when device is flipped as follows: + * @image html phone_facedown.png + * This motion event will fire only when the device is flipped from face to back. + * It will not occur when the device is flipped from back to face. + * + * @param[in] user_data The user data passed from the callback registration function + * @pre sensor_start() will invoke this callback if you register this callback using sensor_motion_facedown_set_cb(). + * @see sensor_motion_facedown_set_cb() + * @see sensor_motion_facedown_unset_cb() + */ +typedef void (*sensor_motion_facedown_event_cb) (void *user_data); +/** + * @} + */ + + +/** + * @addtogroup CAPI_SYSTEM_SENSOR_MODULE + * @{ + */ + + +/** + * @brief Checks whether the given sensor type is available on a device. + * @details + * You need to check availability of a sensor first because this sensor may not be supported on the device. + * + * @param[in] type The sensor type to check + * @param[out] supported @c true if this sensor type is supported, otherwise @c false + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * + */ +int sensor_is_supported(sensor_type_e type, bool *supported); + + +/** + * @brief Gets data specification for a sensor type, except motion sensors. + * + * @remark When the given @a type is one of the motion sensors, this function returns #SENSOR_ERROR_INVALID_PARAMETER. + * + * @param[in] type The sensor type to check + * @param[out] max The maximum range of the sensor in the sensor's unit + * @param[out] min The minimum range of the sensor in the sensor's unit + * @param[out] resolution The resolution of the sensor + * + * @return 0 on success, otherwise a negative error value. + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_NOT_SUPPORTED The sensor type is not supported in current device + * + * @pre #sensor_is_supported() + */ +int sensor_get_spec(sensor_type_e type, float *max, float *min, float *resolution); + + +/** + * @brief Creates a sensor handle. + * + * @remarks @a sensor must be released sensor_destroy() by you. + * + * @param[out] sensor A new sensor handle to the sensors + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_OUT_OF_MEMORY Out of memory + * + * @see sensor_destroy() + */ +int sensor_create(sensor_h *sensor); + + +/** + * @brief Destroys the sensor handle and releases all its resources. + * + * @remark After this function is called, the attached sensor will be detached and + * the corresponding sensor connection will be released. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see sensor_create() + */ +int sensor_destroy(sensor_h sensor); + + +/** + * @brief Starts sensor server for the given sensor handle and sensor type. + * @details + * After this function is called, sensor events will occur and + * the specific sensor type related callback function will be called. An application can read sensor data. + * + * @param[in] sensor The sensor handle + * @param[in] type The sensor type + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_NOT_SUPPORTED The sensor type is not supported in current device + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @pre call sensor_create() before using this function. + * @post This function invokes sensor_calibration_cb(), sensor_accelerometer_event_cb(), sensor_magnetic_event_cb(), + * sensor_orientation_event_cb(), sensor_gyroscope_event_cb(), sensor_light_event_cb(), + * sensor_proximity_event_cb(), sensor_motion_snap_event_cb(), sensor_motion_shake_event_cb(), + * sensor_motion_doubletap_event_cb(), sensor_motion_panning_event_cb(), or sensor_motion_facedown_event_cb(). + * + * @see sensor_stop() + */ +int sensor_start(sensor_h sensor, sensor_type_e type); + + +/** + * @brief Stops sensor server for the given sensor handle and type. + * @details The given @a type event will not occur any more and the callback functions also won't be called. + * + * @param[in] sensor The sensor handle + * @param[in] type The sensor type + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * + * @see sensor_start() + */ +int sensor_stop(sensor_h sensor, sensor_type_e type); + + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_ACCELEROMETER_MODULE + * @{ + */ + + +/** + * @brief Registers a callback function to be invoked when an accelerometer event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] interval_ms The interval sensor events are delivered at (in milliseconds) \n + * If @a rate is zero, it uses default value(100ms) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_accelerometer_event_cb() will be invoked. + * + * @see sensor_accelerometer_event_cb() + * @see sensor_accelerometer_unset_cb() + */ +int sensor_accelerometer_set_cb(sensor_h sensor, int interval_ms, sensor_accelerometer_event_cb callback, void *user_data); + + +/** + * @brief Unregister the accelerometer callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_accelerometer_set_cb() + */ +int sensor_accelerometer_unset_cb(sensor_h sensor); + + +/** + * @brief Gets sensor data from the accelerometer sensor. + * + * @param[in] sensor The sensor handle + * @param[out] accuracy The accuracy of this data + * @param[out] x The acceleration minus Gx on the x-axis in meters per second squared (m/s^2) + * @param[out] y The acceleration minus Gy on the y-axis in meters per second squared (m/s^2) + * @param[out] z The acceleration minus Gz on the z-axis in meters per second squared (m/s^2) + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * + * @pre In order to read sensor data, an application should call sensor_start(). + */ +int sensor_accelerometer_read_data(sensor_h sensor, sensor_data_accuracy_e *accuracy, float *x, float *y, float *z); + + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_GYROSCOPE_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a gyroscope event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] interval_ms The interval sensor events are delivered in (in milliseconds) \n + * If @a interval_ms is zero, it uses default value (100ms) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_gyroscope_event_cb() will be invoked + * + * @see sensor_gyroscope_event_cb() + * @see sensor_gyroscope_unset_cb() + */ +int sensor_gyroscope_set_cb(sensor_h sensor, int interval_ms, sensor_gyroscope_event_cb callback, void *user_data); + +/** + * @brief Unregister the gyroscope callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_gyroscope_set_cb() + */ +int sensor_gyroscope_unset_cb(sensor_h sensor); + +/** + * @brief + * Gets sensor data from the gyroscope sensor. + * + * @param[in] sensor The sensor handle + * @param[out] accuracy The accuracy of this data + * @param[out] x The angular speed around the x-axis in degree per second + * @param[out] y The angular speed around the y-axis in degree per second + * @param[out] z The angular speed around the z-axis in degree per second + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * + * @pre In order to read sensor data, an application should call sensor_start(). + * @see sensor_start() + */ +int sensor_gyroscope_read_data(sensor_h sensor, sensor_data_accuracy_e *accuracy, float *x, float *y, float *z); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_LIGHT_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a light event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] interval_ms The interval sensor events are delivered in (in milliseconds) \n + * If @a interval_ms is zero, it uses default value (100ms) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_light_event_cb() will be invoked. + * + * @see sensor_light_event_cb() + * @see sensor_light_unset_cb() + */ +int sensor_light_set_cb(sensor_h sensor, int interval_ms, sensor_light_event_cb callback, void *user_data); + +/** + * @brief Unregister the light callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_light_set_cb() + */ +int sensor_light_unset_cb(sensor_h sensor); + +/** + * @brief Gets sensor data from the light sensor. + * + * @remark + * All values are neither SI lux units (lx), nor adc.\n + * Values returned by sensor may vary depending on a hardware. In some devices, + * HW level 1 can mean 1 ~ 100 lux, while in others, HW level 1 can mean 1 ~ 50 lux.\n + * You should use light level between min and max values obtained \n + * with #sensor_get_spec(). In most cases min is 1 and max is 10. + * + * @param[in] sensor The sensor handle + * @param[out] accuracy The accuracy of this data + * @param[out] level The ambient light level in SI lux units \n + * @a level is between min and max values obtained with #sensor_get_spec().\n + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @pre In order to read sensor data, an application should call sensor_start(). + * @see #sensor_data_accuracy_e + * @see sensor_start() + */ +int sensor_light_read_data(sensor_h sensor, sensor_data_accuracy_e *accuracy, int *level); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MAGNETIC_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a magnetic event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] interval_ms The interval sensor events are delivered in (in milliseconds) \n + * If @a interval_ms is zero, it uses default value (100ms) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_magnetic_event_cb() will be invoked. + * + * @see sensor_magnetic_event_cb() + * @see sensor_magnetic_unset_cb() + */ +int sensor_magnetic_set_cb(sensor_h sensor, int interval_ms, sensor_magnetic_event_cb callback, void *user_data); + +/** + * @brief Unregister the magnetic callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_magnetic_set_cb() + */ +int sensor_magnetic_unset_cb(sensor_h sensor); + +/** + * @brief Gets sensor data from the magnetic sensor. + * + * @remark All values are in micro-Teslas (uT) and measure the ambient magnetic field in the X, Y and Z axis. + * + * @param[in] sensor The sensor handle + * @param[out] accuracy The accuracy of this data + * @param[out] x Micro-Tesla value on the x-axis + * @param[out] y Micro-Tesla value on the y-axis + * @param[out] z Micro-Tesla value on the z-axis + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * + * @pre In order to read sensor data, an application should call sensor_start(). + * + * @see sensor_start() + */ +int sensor_magnetic_read_data(sensor_h sensor, sensor_data_accuracy_e *accuracy, float *x, float *y, float *z); + +/** + * @brief Registers a callback function to be invoked when the current sensor reading falls outside of a defined normal range. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * @retval #SENSOR_ERROR_NOT_NEED_CALIBRATION Sensor doesn't need calibration + * + * @post sensor_calibration_cb() will be invoked. + * + * @see sensor_calibration_cb() + * @see sensor_magnetic_unset_calibration_cb() + */ +int sensor_magnetic_set_calibration_cb(sensor_h sensor, sensor_calibration_cb callback, void *user_data); + +/** + * @brief Unregisters the magnetic calibration callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * @retval #SENSOR_ERROR_NOT_NEED_CALIBRATION Sensor doesn't need calibration + * @see sensor_magnetic_set_calibration_cb() + */ +int sensor_magnetic_unset_calibration_cb(sensor_h sensor); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_ORIENTATION_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when an orientation event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] interval_ms The interval sensor events are delivered in (in milliseconds) \n + * If @a interval_ms is zero, it uses default value (100ms) + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_orientation_event_cb() will be invoked. + * + * @see sensor_orientation_event_cb() + * @see sensor_orientation_unset_cb() +*/ +int sensor_orientation_set_cb(sensor_h sensor, int interval_ms, sensor_orientation_event_cb callback, void *user_data); + +/** + * @brief Unregister the orientation callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_orientation_set_cb() + */ +int sensor_orientation_unset_cb(sensor_h sensor); + +/** + * @brief Registers a callback function to be invoked when the current sensor reading falls outside of a defined normal range. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * @retval #SENSOR_ERROR_NOT_NEED_CALIBRATION Sensor doesn't need calibration + * + * @post sensor_calibration_cb() will be invoked. + * + * @see sensor_calibration_cb() + * @see sensor_orientation_unset_calibration_cb() + */ +int sensor_orientation_set_calibration_cb(sensor_h sensor, sensor_calibration_cb callback, void *user_data); + +/** + * @brief Unregister the orientation calibration callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * @retval #SENSOR_ERROR_NOT_NEED_CALIBRATION Sensor doesn't need calibration + * + * @see sensor_orientation_set_calibration_cb() + */ +int sensor_orientation_unset_calibration_cb(sensor_h sensor); + +/** + * @brief Gets sensor data from the orientation sensor. + * + * @remark + * All values are angles in degrees. + * + * @param[in] sensor The sensor handle + * @param[out] accuracy The accuracy of this data + * @param[out] azimuth The angle in degrees between the magnetic north direction and the y-axis, \n + * around the z-axis [0 ~ 359]. 0=North, 90=East, 180=South, 270=West + * @param[out] pitch The rotation in degrees around x-axis [-180 ~ 180], with positive values when the \n + * z-axis moves toward the y-axis + * @param[out] roll The rotation in degrees around y-axis [-90 ~ 90], with positive values when the \n + * x-axis moves toward the z-axis + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * + * @pre In order to read sensor data, an application should call sensor_start(). + * @see sensor_start() + */ +int sensor_orientation_read_data(sensor_h sensor, sensor_data_accuracy_e *accuracy, float *azimuth, float *pitch, float *roll); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_PROXIMITY_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a proximity event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_proximity_event_cb() will be invoked. + * + * @see sensor_proximity_event_cb() + * @see sensor_proximity_unset_cb() + */ +int sensor_proximity_set_cb(sensor_h sensor, sensor_proximity_event_cb callback, void *user_data); + +/** + * @brief Unregister the proximity callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_proximity_set_cb() + */ +int sensor_proximity_unset_cb(sensor_h sensor); + +/** + * @} + * + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_MODULE + * @{ + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_DOUBLETAP_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a motion doubletap event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_motion_doubletap_event_cb() will be invoked. + * + * @see sensor_motion_doubletap_event_cb() + * @see sensor_motion_doubletap_unset_cb() + */ +int sensor_motion_doubletap_set_cb(sensor_h sensor, sensor_motion_doubletap_event_cb callback, void *user_data); + +/** + * @brief Unregister the doubletap callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_motion_doubletap_set_cb() + */ +int sensor_motion_doubletap_unset_cb(sensor_h sensor); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SNAP_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a motion snap event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_motion_snap_event_cb() will be invoked. + * + * @see sensor_motion_snap_event_cb() + * @see sensor_motion_snap_unset_cb() + */ +int sensor_motion_snap_set_cb(sensor_h sensor, sensor_motion_snap_event_cb callback, void *user_data); + +/** + * @brief Unregister the snap callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_motion_snap_set_cb() + */ +int sensor_motion_snap_unset_cb(sensor_h sensor); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_SHAKE_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a motion shake event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_motion_shake_event_cb() will be invoked. + * + * @see sensor_motion_shake_event_cb() + * @see sensor_motion_shake_unset_cb() + */ +int sensor_motion_shake_set_cb(sensor_h sensor, sensor_motion_shake_event_cb callback, void *user_data); + +/** + * @brief Unregister the callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_motion_shake_set_cb() + */ +int sensor_motion_shake_unset_cb(sensor_h sensor); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_PANNING_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a motion panning event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_motion_panning_event_cb() will be invoked. + * + * @see sensor_motion_panning_event_cb() + * @see sensor_motion_panning_unset_cb() + */ +int sensor_motion_panning_set_cb(sensor_h sensor, sensor_motion_panning_event_cb callback, void *user_data); + +/** + * @brief Unregister the callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_motion_panning_set_cb() + */ +int sensor_motion_panning_unset_cb(sensor_h sensor); + +/** + * @} + * + * @addtogroup CAPI_SYSTEM_SENSOR_MOTION_FACEDOWN_MODULE + * @{ + */ + +/** + * @brief Registers a callback function to be invoked when a motion facedown event occurs. + * + * @param[in] sensor The sensor handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @post sensor_motion_facedown_event_cb() will be invoked. + * + * @see sensor_motion_facedown_event_cb() + * @see sensor_motion_facedown_unset_cb() + */ +int sensor_motion_facedown_set_cb(sensor_h sensor, sensor_motion_facedown_event_cb callback, void *user_data); + +/** + * @brief Unregister the facedown callback function. + * + * @param[in] sensor The sensor handle + * + * @return 0 on success, otherwise a negative error value + * @retval #SENSOR_ERROR_NONE Successful + * @retval #SENSOR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SENSOR_ERROR_IO_ERROR I/O error + * @retval #SENSOR_ERROR_OPERATION_FAILED Operation failed + * + * @see sensor_motion_facedown_set_cb() + */ +int sensor_motion_facedown_unset_cb(sensor_h sensor); + +/** + * @} + * + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/packaging/capi-system-sensor.spec b/packaging/capi-system-sensor.spec new file mode 100644 index 0000000..588d867 --- /dev/null +++ b/packaging/capi-system-sensor.spec @@ -0,0 +1,53 @@ +Name: capi-system-sensor +Summary: A Sensor library in TIZEN C API +Version: 0.0.1 +Release: 1 +Group: TO_BE/FILLED_IN +License: TO BE FILLED IN +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(sensor) +BuildRequires: pkgconfig(capi-base-common) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description + + +%package devel +Summary: A Sensor library in TIZEN C API (Development) +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description devel + + + +%prep +%setup -q + + +%build +cmake . -DCMAKE_INSTALL_PREFIX=/usr + + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%{_libdir}/libcapi-system-sensor.so + +%files devel +%{_includedir}/system/sensors.h +%{_libdir}/pkgconfig/*.pc + + diff --git a/phone_facedown.png b/phone_facedown.png new file mode 100755 index 0000000000000000000000000000000000000000..5a28ed3a30ab0d671c00d30807c7e76bda62b81c GIT binary patch literal 26918 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 literal 0 HcmV?d00001 diff --git a/phone_panning.png b/phone_panning.png new file mode 100755 index 0000000000000000000000000000000000000000..d6f6f3961970f53b46c20b292543e5fb0cae3794 GIT binary patch literal 29808 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 literal 0 HcmV?d00001 diff --git a/phone_snap.png b/phone_snap.png new file mode 100755 index 0000000000000000000000000000000000000000..bc239d5211f7d627b87b2186deaede849422e41c GIT binary patch literal 64576 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 z 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 literal 0 HcmV?d00001 diff --git a/src/sensor.c b/src/sensor.c new file mode 100644 index 0000000..f0f4cd3 --- /dev/null +++ b/src/sensor.c @@ -0,0 +1,889 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _DEBUG 1 + +#ifdef _DEBUG +#undef LOG_TAG +#define LOG_TAG "TIZEN_SYSTEM_SENSOR" +#include +#include +static char* _DONT_USE_THIS_ARRAY_DIRECTLY[] = { + "ACCELEROMETER", + "MAGNETIC", + "ORIENTATION", + "GYROSCOPE", + "LIGHT", + "PROXIMITY", + "MOTION_SNAP", + "MOTION_SHAKE", + "MOTION_DOUBLETAP", + "MOTION_PANNING", + "MOTION_FACEDOWN" +}; + +#define _MSG_SENSOR_ERROR_IO_ERROR "Io Error" +#define _MSG_SENSOR_ERROR_INVALID_PARAMETER "Invalid Parameter" +#define _MSG_SENSOR_ERROR_OUT_OF_MEMORY "Out of Memory" +#define _MSG_SENSOR_ERROR_NOT_NEED_CALIBRATION "Not need calibration" +#define _MSG_SENSOR_ERROR_NOT_SUPPORTED "Not supported" +#define _MSG_SENSOR_ERROR_OPERATION_FAILED "Operation failed" + +#define TYPE_NAME(type) _DONT_USE_THIS_ARRAY_DIRECTLY[type] + +#define DEBUG_PRINT(txt) LOGD("%s : " txt, __FUNCTION__) +#define DEBUG_PRINTF(fmt, ...) LOGD("%s : " fmt, __FUNCTION__, __VA_ARGS__) +#define ERROR_PRINT(err) LOGD("[%s]" _MSG_##err "(0x%08x)", __FUNCTION__, err) +#define ERROR_PRINTF(err, fmt, ...) LOGD("[%s]" _MSG_##err "(0x%08x) : " fmt, __FUNCTION__, err, __VA_ARGS__) +#else +#define TYPE_NAME(type) "" +#define DEBUG_PRINT(txt) +#define DEBUG_PRINTF(fmt, ...) +#define ERROR_PRINT(err) +#define ERROR_PRINTF(err) +#endif + +#define RETURN_VAL_IF(expr, err) \ + do { \ + if (expr) { \ + ERROR_PRINT(err); \ + return (err); \ + } \ + } while(0) + +#define RETURN_ERROR(err) \ + do { \ + ERROR_PRINT(err); \ + return err; \ + } while(0) + + +#define RETURN_IF_NOT_HANDLE(handle) \ + RETURN_VAL_IF(handle == NULL, SENSOR_ERROR_INVALID_PARAMETER) + +#define RETURN_IF_NOT_TYPE(type) \ + RETURN_VAL_IF(type > SENSOR_MOTION_FACEDOWN || type < 0, SENSOR_ERROR_INVALID_PARAMETER) + +#define RETURN_IF_MOTION_TYPE(type) \ + RETURN_VAL_IF(type > SENSOR_PROXIMITY && type <= SENSOR_MOTION_FACEDOWN, SENSOR_ERROR_INVALID_PARAMETER) + +#define RETURN_IF_ERROR(val) \ + RETURN_VAL_IF(val < 0, val) + +sensor_data_accuracy_e _accu_table[] = { + SENSOR_ACCURACY_UNDEFINED, + SENSOR_ACCURACY_BAD, + SENSOR_ACCURACY_NORMAL, + SENSOR_ACCURACY_GOOD, + SENSOR_ACCURACY_VERYGOOD, +}; + +sensor_type_t _TYPE[] = { + ACCELEROMETER_SENSOR, + GEOMAGNETIC_SENSOR, + GEOMAGNETIC_SENSOR, + GYROSCOPE_SENSOR, + LIGHT_SENSOR, + PROXIMITY_SENSOR, + MOTION_SENSOR, + MOTION_SENSOR, + MOTION_SENSOR, + MOTION_SENSOR, + MOTION_SENSOR, +}; + +int _DTYPE[] = { + ACCELEROMETER_BASE_DATA_SET, + GEOMAGNETIC_RAW_DATA_SET, // really magnetic? + GEOMAGNETIC_BASE_DATA_SET, // really orientation? + GYRO_BASE_DATA_SET, + LIGHT_BASE_DATA_SET, + PROXIMITY_BASE_DATA_SET, +}; + +int _EVENT[] = { + ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME, + GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME, // really magnetic? + GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME, // really orientation? + GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME, + LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME, // rate = 500ms + PROXIMITY_EVENT_CHANGE_STATE, + MOTION_ENGINE_EVENT_SNAP, + MOTION_ENGINE_EVENT_SHAKE, + MOTION_ENGINE_EVENT_DOUBLETAP, + MOTION_ENGINE_EVENT_PANNING, + MOTION_ENGINE_EVENT_TOP_TO_BOTTOM, +}; + +int _CALIBRATION[] = { + ACCELEROMETER_EVENT_CALIBRATION_NEEDED, + GEOMAGNETIC_EVENT_CALIBRATION_NEEDED, + GEOMAGNETIC_EVENT_CALIBRATION_NEEDED, +}; + +int _sensor_ids[] = { + ID_ACCELEOMETER, + ID_GEOMAGNETIC, + ID_GEOMAGNETIC, + ID_GYROSCOPE, + ID_LIGHT, + ID_PROXIMITY, + ID_MOTION, + ID_MOTION, + ID_MOTION, + ID_MOTION, + ID_MOTION +}; + +#define _SID(id) (_sensor_ids[id]) +#define _ACCU(accuracy) (_accu_table[accuracy + 1]) + +static int _sensor_connect(sensor_h handle, sensor_type_e type) +{ + int id = 0; + bool support = true; + + RETURN_IF_NOT_TYPE(type); + + if(handle->ids[_SID(type)] < 0){ + sensor_is_supported(type, &support); + if(!support) + return SENSOR_ERROR_NOT_SUPPORTED; + + id = sf_connect(_TYPE[type]); + + DEBUG_PRINTF("%s sensor connect legacy=[%d] type=[%d]", TYPE_NAME(type), type, _TYPE[type]); + if(id < 0){ + return id == -2 ? SENSOR_ERROR_IO_ERROR : SENSOR_ERROR_OPERATION_FAILED; + } + DEBUG_PRINTF("%s sensor id created [%d]", TYPE_NAME(type), id); + handle->ids[_SID(type)] = id; + } + return SENSOR_ERROR_NONE; +} + +static void _sensor_callback (unsigned int event_type, sensor_event_data_t* event, void* udata) +{ + int i = 0; + int data_num = 0; + sensor_data_t *data = NULL; + sensor_panning_data_t *panning_data = NULL; + int motion = 0; + int nid = 0; + bool proximity = 0; + + sensor_h sensor = (sensor_h)udata; + + switch(event_type) + { + case MOTION_ENGINE_EVENT_SNAP: + nid = SENSOR_MOTION_SNAP; + break; + case MOTION_ENGINE_EVENT_SHAKE: + nid = SENSOR_MOTION_SHAKE; + break; + case MOTION_ENGINE_EVENT_DOUBLETAP: + nid = SENSOR_MOTION_DOUBLETAP; + break; + case MOTION_ENGINE_EVENT_PANNING: + nid = SENSOR_MOTION_PANNING; + break; + case MOTION_ENGINE_EVENT_TOP_TO_BOTTOM: + nid = SENSOR_MOTION_FACEDOWN; + break; + case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME : + nid = SENSOR_ACCELEROMETER; + break; + case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME : + nid = SENSOR_MAGNETIC; + break; + case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME : + nid = SENSOR_ORIENTATION; + break; + case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME : + nid = SENSOR_GYROSCOPE; + break; + case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME : + nid = SENSOR_LIGHT; + break; + case PROXIMITY_EVENT_CHANGE_STATE : + nid = SENSOR_PROXIMITY; + break; + } + + if(sensor->cb_func[nid] == NULL || sensor->started[nid] == 0) + return; + + switch(event_type) + { + case MOTION_ENGINE_EVENT_SNAP: + case MOTION_ENGINE_EVENT_SHAKE: + motion = *(int*)event->event_data; + break; + case MOTION_ENGINE_EVENT_PANNING: + panning_data = (sensor_panning_data_t *)event->event_data; + break; + case MOTION_ENGINE_EVENT_DOUBLETAP: + motion = *(int*)event->event_data; + if(motion != MOTION_ENGIEN_DOUBLTAP_DETECTION) + return; + break; + case MOTION_ENGINE_EVENT_TOP_TO_BOTTOM: + motion = *(int*)event->event_data; + if(motion != MOTION_ENGIEN_TOP_TO_BOTTOM_DETECTION) + return; + break; + + case ACCELEROMETER_EVENT_RAW_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 : + data = (sensor_data_t*)(event->event_data); + data_num = (event->event_data_size)/sizeof(sensor_data_t); + break; + case PROXIMITY_EVENT_CHANGE_STATE : + proximity = *(int*)(event->event_data) == PROXIMITY_STATE_FAR ? 0 : 1; + break; + default: + DEBUG_PRINTF("unknown typed sensor happen!! event=%d\n", event_type); + return; + + } + + switch(event_type) + { + case MOTION_ENGINE_EVENT_SNAP: + ((sensor_motion_snap_event_cb)sensor->cb_func[nid])(motion, sensor->cb_user_data[nid]); + break; + case MOTION_ENGINE_EVENT_SHAKE: + ((sensor_motion_shake_event_cb)sensor->cb_func[nid])(motion, sensor->cb_user_data[nid]); + break; + case MOTION_ENGINE_EVENT_DOUBLETAP: + ((sensor_motion_doubletap_event_cb)sensor->cb_func[nid])(sensor->cb_user_data[nid]); + break; + case MOTION_ENGINE_EVENT_TOP_TO_BOTTOM: + ((sensor_motion_facedown_event_cb)sensor->cb_func[nid])(sensor->cb_user_data[nid]); + break; + case MOTION_ENGINE_EVENT_PANNING: + ((sensor_motion_panning_event_cb)sensor->cb_func[nid])(panning_data->x, panning_data->y, + sensor->cb_user_data[nid]); + break; + case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME : + for(i=0; icb_func[nid]) + (_ACCU(data[i].data_accuracy), + data[i].values[0], data[i].values[1], data[i].values[2], + sensor->cb_user_data[nid]); + } + break; + case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME : + for(i=0; icb_func[nid]) + (_ACCU(data[i].data_accuracy), + data[i].values[0], data[i].values[1], data[i].values[2], + sensor->cb_user_data[nid]); + } + break; + case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME : + for(i=0; icb_func[nid]) + (_ACCU(data[i].data_accuracy), + data[i].values[0], data[i].values[1], data[i].values[2], + sensor->cb_user_data[nid]); + } + break; + case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME : + for(i=0; icb_func[nid]) + (_ACCU(data[i].data_accuracy), + data[i].values[0], data[i].values[1], data[i].values[2], + sensor->cb_user_data[nid]); + } + break; + case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME : + for(i=0; icb_func[nid]) + (_ACCU(data[i].data_accuracy), + (int)data[i].values[0], + sensor->cb_user_data[nid]); + } + break; + case PROXIMITY_EVENT_CHANGE_STATE : + ((sensor_proximity_event_cb)sensor->cb_func[nid]) + (proximity, sensor->cb_user_data[nid]); + break; + } +} + +int sensor_is_supported(sensor_type_e type, bool* supported) +{ + DEBUG_PRINT("sensor_is_support"); + + RETURN_IF_NOT_TYPE(type); + + if(supported == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *supported = !(sf_is_sensor_event_available(_TYPE[type], _EVENT[type]) < 0); + DEBUG_PRINTF("%s sensor available function return [%d]", TYPE_NAME(type), *supported); + + return SENSOR_ERROR_NONE; +} + +int sensor_get_spec(sensor_type_e type, float* max, float* min, float* resolution) +{ + sensor_properties_t property; + + DEBUG_PRINT("sensor_get_spec"); + + RETURN_IF_MOTION_TYPE(type); + + RETURN_IF_NOT_TYPE(type); + + if(sf_get_properties(_TYPE[type], &property) < 0) + RETURN_ERROR(SENSOR_ERROR_NOT_SUPPORTED); + + *max = property.sensor_max_range; + *min = property.sensor_min_range; + *resolution = property.sensor_resolution; + + DEBUG_PRINTF("success get %s's format max=%f, min=%f, res=%f\n", TYPE_NAME(type), *max, *min, *resolution); + + return SENSOR_ERROR_NONE; +} + + +int sensor_create(sensor_h* handle) +{ + struct sensor_handle_s* sensor = NULL; + + DEBUG_PRINT("sensor_create"); + + if(handle == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + sensor = (struct sensor_handle_s*)malloc( sizeof(struct sensor_handle_s) ); + if(sensor==NULL) + RETURN_ERROR(SENSOR_ERROR_OUT_OF_MEMORY); + else + { + SENSOR_INIT(sensor); + + *handle = (sensor_h)sensor; + + return SENSOR_ERROR_NONE; + } +} + +int sensor_destroy(sensor_h handle) +{ + + int i=0; + bool failed = false; + RETURN_IF_NOT_HANDLE(handle); + + DEBUG_PRINT("sensor_destroy"); + + for(i=0; iids[i] >= 0 ){ + if(sf_disconnect(handle->ids[i]) < 0) + failed = true; + else + handle->ids[i] = -1; + } + } + + free(handle); + handle = NULL; + + return SENSOR_ERROR_NONE; +} + +int sensor_start(sensor_h handle, sensor_type_e type) +{ + int err; + DEBUG_PRINT("sensor_start"); + RETURN_IF_NOT_HANDLE(handle); + RETURN_IF_NOT_TYPE(type); + + if( (err = _sensor_connect(handle, type)) != SENSOR_ERROR_NONE){ + return err; + } + + if (sf_start(handle->ids[_SID(type)], 0) < 0) { + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + } else { + handle->started[type] = 1; + return SENSOR_ERROR_NONE; + } +} + +int sensor_stop(sensor_h handle, sensor_type_e type) +{ + DEBUG_PRINT("sensor_stop"); + RETURN_IF_NOT_HANDLE(handle); + RETURN_IF_NOT_TYPE(type); + if (sf_stop(handle->ids[_SID(type)]) < 0) { + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + } else { + handle->started[type] = 0; + return SENSOR_ERROR_NONE; + } +} + +static void _sensor_calibration (unsigned int event_type, sensor_event_data_t* event, void* udata) +{ + sensor_h sensor = (sensor_h)udata; + + switch (event_type) { + case ACCELEROMETER_EVENT_CALIBRATION_NEEDED: + if(sensor->calib_func[SENSOR_ACCELEROMETER] != NULL){ + ((sensor_calibration_cb)sensor->calib_func[SENSOR_ACCELEROMETER])(sensor->calib_user_data[SENSOR_ACCELEROMETER]); + } + break; + case GEOMAGNETIC_EVENT_CALIBRATION_NEEDED: + if(sensor->calib_func[SENSOR_MAGNETIC] != NULL){ + ((sensor_calibration_cb)sensor->calib_func[SENSOR_MAGNETIC])(sensor->calib_user_data[SENSOR_MAGNETIC]); + } + if(sensor->calib_func[SENSOR_ORIENTATION] != NULL){ + ((sensor_calibration_cb)sensor->calib_func[SENSOR_ORIENTATION])(sensor->calib_user_data[SENSOR_ORIENTATION]); + } + break; + default: + DEBUG_PRINTF("not calibration event happened in calibration callback!! event=%d", event_type); + return; + } +} + +static int _sensor_set_calibration_cb(sensor_h handle, sensor_type_e type, sensor_calibration_cb callback, void *user_data) +{ + int ret, err; + + DEBUG_PRINTF("%s sensor register calibration callback", TYPE_NAME(type)); + + RETURN_IF_NOT_HANDLE(handle); + switch(type){ + case SENSOR_ACCELEROMETER: + case SENSOR_MAGNETIC: + case SENSOR_ORIENTATION: + break; + default: + RETURN_ERROR(SENSOR_ERROR_NOT_NEED_CALIBRATION); + } + + ret = sf_is_sensor_event_available( _TYPE[type], _CALIBRATION[type] ); + if (ret != 0 ){ + DEBUG_PRINTF("Unsupported calibration ret=[%d] error=[%d] legacy=[%d] type=[%d] cal_id=[%d]", ret, SENSOR_ERROR_NOT_NEED_CALIBRATION, type, _TYPE[type], _CALIBRATION[type]); + RETURN_ERROR(SENSOR_ERROR_NOT_NEED_CALIBRATION); + } + + if( (err = _sensor_connect(handle, type)) != SENSOR_ERROR_NONE){ + return err; + } + + handle->calib_func[type] = callback; + handle->calib_user_data[type] = user_data; + + DEBUG_PRINTF("type : %s / id : %d / event : %x ", TYPE_NAME(type), handle->ids[_SID(type)], _CALIBRATION[type]); + + ret = sf_register_event(handle->ids[_SID(type)], _CALIBRATION[type], NULL, _sensor_calibration, handle); + if(ret < 0){ + handle->calib_func[type] = NULL; + handle->calib_user_data[type] = NULL; + if(ret == -2) + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + else + RETURN_ERROR(SENSOR_ERROR_OPERATION_FAILED); + } + + return SENSOR_ERROR_NONE; +} + +static int _sensor_unset_calibration_cb(sensor_h handle, sensor_type_e type) +{ + int ret; + + DEBUG_PRINTF("%s sensor register calibration callback", TYPE_NAME(type)); + + RETURN_IF_NOT_HANDLE(handle); + switch (type) { + case SENSOR_ACCELEROMETER: + case SENSOR_MAGNETIC: + case SENSOR_ORIENTATION: + break; + default: + RETURN_ERROR(SENSOR_ERROR_NOT_NEED_CALIBRATION); + } + + if(handle->calib_func[type] == NULL) + return SENSOR_ERROR_NONE; + + ret = sf_unregister_event(handle->ids[_SID(type)], _CALIBRATION[type]); + + if (ret < 0){ + if(ret == -2) + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + else + RETURN_ERROR(SENSOR_ERROR_OPERATION_FAILED); + } + + handle->calib_func[type] = NULL; + handle->calib_user_data[type] = NULL; + + return SENSOR_ERROR_NONE; +} + + +static int _sensor_set_data_cb (sensor_h handle, sensor_type_e type, int rate, void* cb, void* user_data) +{ + int err = 0; + event_condition_t condition; + + RETURN_IF_NOT_HANDLE(handle); + RETURN_IF_NOT_TYPE(type); + + DEBUG_PRINTF("sensor register callback %s", TYPE_NAME(type)); + + if(rate < 0){ + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + } + + if(rate > 0){ + condition.cond_op = CONDITION_EQUAL; + condition.cond_value1 = rate; + } + + handle->cb_func[type] = cb; + handle->cb_user_data[type] = user_data; + + if( (err = _sensor_connect(handle, type)) != SENSOR_ERROR_NONE){ + DEBUG_PRINTF("%s sensor connect error handle=[%d] legacy=[%d] err=[%d]", TYPE_NAME(type), handle, type, err); + return err; + } + + err = sf_register_event(handle->ids[_SID(type)], _EVENT[type], + (rate > 0 ? &condition : NULL), _sensor_callback, handle); + + DEBUG_PRINTF("%s sensor register function return [%d] event=[%d]", TYPE_NAME(type), err, _EVENT[type]); + + if(err < 0){ + handle->cb_func[type] = NULL; + handle->cb_user_data[type] = NULL; + if(err == -2) + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + else + RETURN_ERROR(SENSOR_ERROR_OPERATION_FAILED); + } + + return SENSOR_ERROR_NONE; +} + +static int _sensor_unset_data_cb (sensor_h handle, sensor_type_e type) +{ + int error; + DEBUG_PRINTF("sensor unregister callback %s", TYPE_NAME(type)); + RETURN_IF_NOT_HANDLE(handle); + if (handle->ids[_SID(type)] < 0 ) + return SENSOR_ERROR_INVALID_PARAMETER; + + error = sf_unregister_event(handle->ids[_SID(type)], _EVENT[type]); + + if (error < 0){ + if(error == -2) + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + else + RETURN_ERROR(SENSOR_ERROR_OPERATION_FAILED); + } + + handle->cb_func[type] = NULL; + handle->cb_user_data[type] = NULL; + return SENSOR_ERROR_NONE; +} + +int sensor_accelerometer_set_cb (sensor_h handle, + int rate, sensor_accelerometer_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_ACCELEROMETER, rate, (void*) callback, user_data); +} + +int sensor_accelerometer_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_ACCELEROMETER); +} + +int sensor_magnetic_set_cb (sensor_h handle, + int rate, sensor_magnetic_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MAGNETIC, rate, (void*) callback, user_data); +} + +int sensor_magnetic_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MAGNETIC); +} + +int sensor_magnetic_set_calibration_cb (sensor_h handle, sensor_calibration_cb callback, void *user_data) +{ + return _sensor_set_calibration_cb(handle, SENSOR_MAGNETIC, callback, user_data); +} +int sensor_magnetic_unset_calibration_cb (sensor_h handle) +{ + return _sensor_unset_calibration_cb(handle, SENSOR_MAGNETIC); +} + +int sensor_orientation_set_cb (sensor_h handle, + int rate, sensor_orientation_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_ORIENTATION, rate, (void*) callback, user_data); +} + +int sensor_orientation_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_ORIENTATION); +} +int sensor_orientation_set_calibration_cb (sensor_h handle, sensor_calibration_cb callback, void *user_data) +{ + return _sensor_set_calibration_cb(handle, SENSOR_ORIENTATION, callback, user_data); +} +int sensor_orientation_unset_calibration_cb (sensor_h handle) +{ + return _sensor_unset_calibration_cb(handle, SENSOR_ORIENTATION); +} + +int sensor_gyroscope_set_cb (sensor_h handle, + int rate, sensor_gyroscope_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_GYROSCOPE, rate, (void*) callback, user_data); +} + +int sensor_gyroscope_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_GYROSCOPE); +} + +int sensor_light_set_cb (sensor_h handle, + int rate, sensor_light_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_LIGHT, rate, (void*) callback, user_data); +} + +int sensor_light_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_LIGHT); +} + +int sensor_proximity_set_cb (sensor_h handle, sensor_proximity_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_PROXIMITY, 0, (void*) callback, user_data); +} + +int sensor_proximity_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_PROXIMITY); +} + +static int _sensor_read_data(sensor_h handle, sensor_type_e type, + sensor_data_accuracy_e* accuracy, float* values, int values_size) +{ + int err = 0; + sensor_data_t data; + + RETURN_IF_NOT_HANDLE(handle); + if(type > SENSOR_PROXIMITY && type <= SENSOR_MOTION_DOUBLETAP) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + RETURN_IF_NOT_TYPE(type); + + DEBUG_PRINTF("sensor read data %s", TYPE_NAME(type)); + + if( (err = _sensor_connect(handle, type)) != SENSOR_ERROR_NONE) + return err; + if ( sf_get_data(handle->ids[_SID(type)], _DTYPE[type], &data) < 0 ) + { + RETURN_ERROR(SENSOR_ERROR_IO_ERROR); + } + + // this error will never happen. but it exist for more safe code.. + if(values_size > 12 || values_size < 0) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + if(accuracy != NULL) + *accuracy = _ACCU(data.data_accuracy); + memcpy(values, data.values, values_size * sizeof(float)); + + return SENSOR_ERROR_NONE; +} + +int sensor_accelerometer_read_data (sensor_h handle, + sensor_data_accuracy_e* accuracy, float* x, float* y, float* z) +{ + float values[3] = {0,0,0}; + int err = _sensor_read_data(handle, SENSOR_ACCELEROMETER, accuracy, values, 3); + if(err < 0) return err; + + if(x == NULL || y == NULL || z == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *x = values[0]; + *y = values[1]; + *z = values[2]; + + return SENSOR_ERROR_NONE; +} + +int sensor_magnetic_read_data (sensor_h handle, sensor_data_accuracy_e* accuracy, float* x, float* y, float* z) +{ + float values[3] = {0,0,0}; + int err = _sensor_read_data(handle, SENSOR_MAGNETIC, accuracy, values, 3); + if(err < 0) return err; + + if(x == NULL || y == NULL || z == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *x = values[0]; + *y = values[1]; + *z = values[2]; + + return SENSOR_ERROR_NONE; +} + +int sensor_orientation_read_data (sensor_h handle, sensor_data_accuracy_e* accuracy, float* azimuth, float* pitch, float* roll) +{ + float values[3] = {0,0,0}; + int err = _sensor_read_data(handle, SENSOR_ORIENTATION, accuracy, values, 3); + if(err < 0) return err; + + if(azimuth == NULL || pitch == NULL || roll == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *azimuth = values[0]; + *pitch = values[1]; + *roll = values[2]; + + return SENSOR_ERROR_NONE; +} + +int sensor_gyroscope_read_data (sensor_h handle, sensor_data_accuracy_e* accuracy, float* x, float* y, float* z) +{ + float values[3] = {0,0,0}; + int err = _sensor_read_data(handle, SENSOR_GYROSCOPE, accuracy, values, 3); + if(err < 0) return err; + + if(x == NULL || y == NULL || z == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *x = values[0]; + *y = values[1]; + *z = values[2]; + + return SENSOR_ERROR_NONE; +} + +int sensor_light_read_data (sensor_h handle, sensor_data_accuracy_e* accuracy, int* level) +{ + float values[1] = {0}; + int err = _sensor_read_data(handle, SENSOR_LIGHT, accuracy, values, 1); + if(err < 0) return err; + + if(level == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *level = (int)values[0]; + + return SENSOR_ERROR_NONE; +} + +int sensor_proximity_read_data (sensor_h handle, sensor_data_accuracy_e* accuracy, bool* is_near) +{ + float values[1] = {0}; + int err = _sensor_read_data(handle, SENSOR_PROXIMITY, accuracy, values, 1); + if(err < 0) return err; + + if(is_near == NULL) + RETURN_ERROR(SENSOR_ERROR_INVALID_PARAMETER); + + *is_near = (bool)values[0]; + + return SENSOR_ERROR_NONE; +} + + +int sensor_motion_snap_set_cb (sensor_h handle, sensor_motion_snap_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MOTION_SNAP, 0, (void*) callback, user_data); +} + +int sensor_motion_snap_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MOTION_SNAP); +} + +int sensor_motion_shake_set_cb (sensor_h handle, sensor_motion_shake_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MOTION_SHAKE, 0, (void*) callback, user_data); +} + +int sensor_motion_shake_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MOTION_SHAKE); +} + +int sensor_motion_doubletap_set_cb (sensor_h handle, sensor_motion_doubletap_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MOTION_DOUBLETAP, 0, (void*) callback, user_data); +} + +int sensor_motion_doubletap_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MOTION_DOUBLETAP); +} + +int sensor_motion_panning_set_cb (sensor_h handle, sensor_motion_panning_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MOTION_PANNING, 0, (void*) callback, user_data); +} + +int sensor_motion_panning_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MOTION_PANNING); +} + +int sensor_motion_facedown_set_cb (sensor_h handle, sensor_motion_facedown_event_cb callback, void *user_data) +{ + return _sensor_set_data_cb(handle, SENSOR_MOTION_FACEDOWN, 0, (void*) callback, user_data); +} + +int sensor_motion_facedown_unset_cb (sensor_h handle) +{ + return _sensor_unset_data_cb(handle, SENSOR_MOTION_FACEDOWN); +} -- 2.34.1