summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSehong Na <sehong.na@samsung.com>2014-05-31 12:44:46 +0900
committerSehong Na <sehong.na@samsung.com>2014-05-31 12:44:46 +0900
commit0d1076505eb0109cd6f515a1a7f067bd5bfdec62 (patch)
tree603c1818787697334e80bfe721a973acdffe1aac
downloadhaptic-module-tizen-0d1076505eb0109cd6f515a1a7f067bd5bfdec62.tar.gz
haptic-module-tizen-0d1076505eb0109cd6f515a1a7f067bd5bfdec62.tar.bz2
haptic-module-tizen-0d1076505eb0109cd6f515a1a7f067bd5bfdec62.zip
-rw-r--r--AUTHORS2
-rwxr-xr-xCMakeLists.txt26
-rw-r--r--LICENSE.APLv2202
-rw-r--r--NOTICE7
-rwxr-xr-xinclude/haptic_module_log.h34
-rw-r--r--packaging/haptic-module-tizen.spec46
-rw-r--r--test/test.c117
-rw-r--r--tizen/DEVICE/CMakeLists.txt30
-rw-r--r--tizen/DEVICE/include/file.h75
-rw-r--r--tizen/DEVICE/src/file.c460
-rw-r--r--tizen/DEVICE/src/haptic.c622
-rw-r--r--tizen/DEVICE/src/sysnoti.c163
-rw-r--r--tizen/SIMULATOR/CMakeLists.txt27
-rw-r--r--tizen/SIMULATOR/src/haptic.c312
14 files changed, 2123 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..f782d40
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Jiyoung Yun <jy910.yun at samsung dot com>
+Jae-young Hwang <j-zero.hwang at samsung dot com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..bc6d74a
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,26 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(haptic-module C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+
+MESSAGE ("architecture name : ${ARCH}")
+MESSAGE ("SIMULATOR: ${SIMULATOR}")
+IF("${SIMULATOR}" MATCHES "yes")
+ SET(TIZEN_TARGET "SIMULATOR")
+ELSEIF("${ARCH}" MATCHES "^arm.*")
+ SET(TIZEN_TARGET "DEVICE")
+ELSEIF("${ARCH}" MATCHES ".*86.*")
+ SET(TIZEN_TARGET "DEVICE")
+ELSE("${SIMULATOR}" MATCHES "yes")
+ MESSAGE(SEND_ERROR "Unknown architecture: ${ARCH}")
+ENDIF("${SIMULATOR}" MATCHES "yes")
+
+ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/tizen/${TIZEN_TARGET})
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644
index 0000000..c7f3cb1
--- /dev/null
+++ b/LICENSE.APLv2
@@ -0,0 +1,202 @@
+ License APLv2
+ 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/NOTICE b/NOTICE
new file mode 100644
index 0000000..83451e8
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,7 @@
+Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License, Version 2 terms and conditions.
+
+IP Rights Notice: The feature implemented by this module may be intellectual property(ies) of
+other entities. Tizen device manufacturers may be required to pay royalty to such entities to
+enable the features on their devices
diff --git a/include/haptic_module_log.h b/include/haptic_module_log.h
new file mode 100755
index 0000000..87b27e5
--- /dev/null
+++ b/include/haptic_module_log.h
@@ -0,0 +1,34 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __HAPTIC_MODULE_LOG_H__
+#define __HAPTIC_MODULE_LOG_H__
+
+#define FEATURE_HAPTIC_MODULE_DLOG
+
+#ifdef FEATURE_HAPTIC_MODULE_DLOG
+ #define LOG_TAG "HAPTIC_MODULE"
+ #include <dlog.h>
+ #define MODULE_LOG(fmt, args...) SLOGD(fmt, ##args)
+ #define MODULE_ERROR(fmt, args...) SLOGE(fmt, ##args)
+#else
+ #define MODULE_LOG(x, ...)
+ #define MODULE_ERROR(x, ...)
+#endif
+
+#endif //__HAPTIC_MODULE_LOG_H__
diff --git a/packaging/haptic-module-tizen.spec b/packaging/haptic-module-tizen.spec
new file mode 100644
index 0000000..db4d6bc
--- /dev/null
+++ b/packaging/haptic-module-tizen.spec
@@ -0,0 +1,46 @@
+#sbs-git:slp/pkgs/d/devman devman 0.1.6 5bf2e95e0bb15c43ff928f7375e1978b0accb0f8
+Name: haptic-module-tizen
+Summary: Haptic Module library
+Version: 0.1.0
+Release: 9
+Group: System/Libraries
+License: APLv2
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(haptic-plugin)
+BuildRequires: pkgconfig(device-node)
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+
+%prep
+%setup -q
+
+%build
+%if 0%{?simulator}
+%cmake . -DSIMULATOR=yes
+%else
+%ifarch %{ix86}
+CFLAGS=`echo %{optflags} |sed 's/\-fexceptions//g'`
+%endif
+%cmake . -DSIMULATOR=no
+%endif
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+mkdir -p %{buildroot}%{_datadir}/license
+cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%{_libdir}/libhaptic-module.so
+%{_datadir}/license/%{name}
diff --git a/test/test.c b/test/test.c
new file mode 100644
index 0000000..b8cb94e
--- /dev/null
+++ b/test/test.c
@@ -0,0 +1,117 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <vconf.h>
+#include <dlfcn.h>
+
+#include <haptic_plugin_intf.h>
+
+#define HAPTIC_MODULE_PATH "/usr/lib/libhaptic-module.so"
+
+static void *dlopen_handle;
+static const haptic_plugin_interface *plugin_intf;
+
+int main ()
+{
+ char *error = NULL;
+
+ printf("start!\n");
+ dlopen_handle = dlopen(HAPTIC_MODULE_PATH, RTLD_NOW);
+ if (!dlopen_handle) {
+ printf("fail dlopen\n");
+ printf("%s\n", dlerror());
+ return -1;
+ }
+
+ const haptic_plugin_interface *(*get_haptic_plugin_interface) ();
+ get_haptic_plugin_interface = dlsym(dlopen_handle, "get_haptic_plugin_interface");
+
+ if ((error = dlerror()) != NULL) {
+ printf("dlsym error\n");
+ printf("%s\n", error);
+ dlclose(dlopen_handle);
+ return -1;
+ }
+
+ plugin_intf = get_haptic_plugin_interface();
+ if (!plugin_intf) {
+ printf("plugin_intf error\n");
+ dlclose(dlopen_handle);
+ return -1;
+ }
+
+ while (1)
+ {
+ char input = -1;
+ int duration = -1;
+ int handle = -1;
+ int status = -1;
+
+ printf ("============================================\n");
+ printf ("haptic_internal_vibrate_monotone : a\n");
+ printf ("hatpic_internal_stop_all_effects : b\n");
+ printf ("Quit : z\n");
+ printf ("============================================\n");
+
+ status = scanf ("%c", &input);
+
+ switch (input)
+ {
+ case 'a' :
+ printf ("Handle : ");
+ status = scanf ("%d", &handle);
+ if (status < 0)
+ return status;
+
+ printf ("Duration : ");
+ status = scanf ("%d", &duration);
+ if (status < 0)
+ return status;
+
+ plugin_intf->haptic_internal_vibrate_monotone(handle, duration, HAPTIC_MODULE_FEEDBACK_MAX, HAPTIC_MODULE_PRIORITY_HIGH, &handle);
+ break;
+
+ case 'b':
+ printf ("Handle : ");
+ status = scanf ("%d", &handle);
+ if (status < 0)
+ return status;
+ plugin_intf->haptic_internal_stop_all_effects(handle);
+ break;
+
+ case 'c':
+ break;
+
+ case 'z':
+ return 0;
+ }
+ }
+
+ if (dlopen_handle) {
+ dlclose(dlopen_handle);
+ }
+
+ return 0;
+}
diff --git a/tizen/DEVICE/CMakeLists.txt b/tizen/DEVICE/CMakeLists.txt
new file mode 100644
index 0000000..8d68793
--- /dev/null
+++ b/tizen/DEVICE/CMakeLists.txt
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(SRCS
+ src/haptic.c
+ src/file.c
+ src/sysnoti.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+SET(DEPENDENTS "dlog vconf haptic-plugin device-node")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED ${DEPENDENTS})
+
+FOREACH(flag ${rpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--no-as-needed")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DENABLE_DLOG_OUT -DSLP_DEBUG")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS})
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/tizen/DEVICE/include/file.h b/tizen/DEVICE/include/file.h
new file mode 100644
index 0000000..798ad5d
--- /dev/null
+++ b/tizen/DEVICE/include/file.h
@@ -0,0 +1,75 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __FILE_H__
+#define __FILE_H__
+
+#define GCC_PACK __attribute__((packed))
+
+/* little-endian form */
+#define mmioHeaderID(ch0,ch1,ch2,ch3) \
+ ((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | \
+ ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24))
+
+#define HEADER_ID mmioHeaderID('T','H','F','M') // 0x4D464854
+#define FMT_ID mmioHeaderID('f','m','t',' ') // 0x20746D66
+#define DATA_ID mmioHeaderID('d','a','t','a') // 0x61746164
+
+typedef unsigned int ID; /* a four character code */
+
+typedef struct _FormatChunk {
+ ID chunkID; /* chunk ID */
+ int chunkSize; /* chunk Size */
+ unsigned short wChannels; /* number of channels (Mono = 1, Stereo = 2, etc.) */
+ unsigned short wBlockAlign; /* block size of data (wChannels*1byte) */
+ unsigned int dwMagnitude; /* max magnitude */
+ unsigned int dwDuration; /* duration */
+} GCC_PACK FormatChunk;
+
+typedef struct _DataChunk {
+ ID chunkID;
+ int chunkSize;
+ unsigned char pData[];
+} GCC_PACK DataChunk;
+
+typedef struct _HapticFile {
+ ID chunkID; /* chunk ID */
+ int chunkSize; /* chunk Size */
+ FormatChunk fmt; /* Format chunk */
+ DataChunk data; /* Data chunk */
+} GCC_PACK HapticFile;
+
+typedef struct _HapticElement {
+ int duration;
+ int level;
+} HapticElement;
+
+int GetHapticLevelMax(int *max);
+
+int InitializeBuffer(unsigned char *vibe_buffer, int max_bufsize);
+int InsertElement(unsigned char *vibe_buffer, int max_bufsize, HapticElement *element);
+int GetBufferSize(const unsigned char *vibe_buffer, int *size);
+int GetBufferDuration(const unsigned char *vibe_buffer, int *duration);
+int PlayOneshot(int handle, int duration, int level);
+int PlayBuffer(int handle, const unsigned char *vibe_buffer, int iteration, int level);
+int Stop(int handle);
+int OpenDevice(int handle);
+int CloseDevice(int handle);
+int GetState(int handle, int *state);
+
+#endif // __FIEL_H__
diff --git a/tizen/DEVICE/src/file.c b/tizen/DEVICE/src/file.c
new file mode 100644
index 0000000..1a6ae80
--- /dev/null
+++ b/tizen/DEVICE/src/file.c
@@ -0,0 +1,460 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <device-node.h>
+
+#include "file.h"
+#include "haptic_module_log.h"
+
+#define BITPERMS 50
+#define MAX_LEVEL 255.0f
+#define DEFAULT_EFFECT_HANDLE 0x02
+
+#define STATE_PLAY 0
+#define STATE_STOP 1
+
+#define PREDEF_HAPTIC "haptic"
+
+enum {
+ OPEN = 0,
+ CLOSE,
+ PLAY,
+ ONESHOT,
+ STOP,
+ LEVEL,
+};
+
+typedef struct {
+ int handle;
+ unsigned char **ppbuffer;
+ int channels;
+ int length;
+ int iteration;
+} BUFFER;
+
+static pthread_t tid;
+static BUFFER gbuffer;
+static int stop;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int _check_valid_haptic_format(HapticFile *file)
+{
+ if (file->chunkID != HEADER_ID)
+ return -1;
+
+ if (file->fmt.chunkID != FMT_ID)
+ return -1;
+
+ if (file->data.chunkID != DATA_ID)
+ return -1;
+
+ return 0;
+}
+
+static int __haptic_predefine_action(int handle, int prop, int val)
+{
+ char buf_pid[32];
+ char buf_prop[32];
+ char buf_handle[32];
+ char buf_val[32];
+
+ snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+ snprintf(buf_prop, sizeof(buf_prop), "%d", prop);
+ snprintf(buf_handle, sizeof(buf_handle), "%d", handle);
+ snprintf(buf_val, sizeof(buf_val), "%d", val);
+
+ MODULE_LOG("pid : %s(%d), prop : %s, handle : %s", buf_pid, pthread_self(), buf_prop, buf_handle);
+ return __haptic_call_predef_action(PREDEF_HAPTIC, 4, buf_pid, buf_prop, buf_handle, buf_val);
+}
+
+static int _create_thread(void* data, void*(*func)(void*))
+{
+ if (tid) {
+ MODULE_ERROR("pthread already created");
+ return -1;
+ }
+
+ if (pthread_create(&tid, NULL, func, data) != 0) {
+ MODULE_ERROR("pthread_create is failed : %s", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _cancel_thread(void)
+{
+ int *ptr;
+ int ret;
+
+ if (!tid) {
+ MODULE_LOG("pthread not initialized");
+ return 0;
+ }
+
+ MODULE_LOG("cancel thread!!!");
+
+ stop = 1;
+
+ while (pthread_mutex_trylock(&mutex) == EBUSY) {
+ usleep(100);
+ MODULE_LOG("Already locked..");
+ }
+
+ pthread_mutex_unlock(&mutex);
+
+ if ((ret = pthread_cancel(tid)) < 0) {
+ MODULE_ERROR("pthread_cancel is failed : %s, ret(%d)", strerror(errno), ret);
+ return -1;
+ }
+
+ if (pthread_join(tid, (void**)&ptr) < 0) {
+ MODULE_ERROR("pthread_join is failed : %s", strerror(errno));
+ return -1;
+ }
+
+ stop = 0;
+
+ tid = 0;
+ if (ptr == PTHREAD_CANCELED) {
+ MODULE_LOG("pthread canceled");
+ } else {
+ MODULE_LOG("pthread already finished");
+ }
+
+ return 0;
+}
+
+static void __clean_up(void *arg)
+{
+ BUFFER *pbuffer = (BUFFER*)arg;
+ int i;
+
+ MODULE_LOG("clean up handler!!! : %d", tid);
+
+ for (i = 0; i < pbuffer->channels; ++i) {
+ free(pbuffer->ppbuffer[i]);
+ pbuffer->ppbuffer[i] = NULL;
+ }
+
+ free(pbuffer->ppbuffer);
+ pbuffer->ppbuffer = NULL;
+
+ pbuffer->channels = 0;
+ pbuffer->length = 0;
+
+ if(stop){
+ __haptic_predefine_action(gbuffer.handle, STOP, NULL);
+ pthread_mutex_unlock(&mutex);
+ }
+}
+
+static void* __play_cb(void *arg)
+{
+ BUFFER *pbuffer = (BUFFER*)arg;
+ int i, j, k;
+ unsigned char ch;
+ unsigned char prev = -1;
+
+ MODULE_LOG("Start thread");
+
+ pthread_cleanup_push(__clean_up, arg);
+
+ /* Copy buffer from source buffer */
+ for (i = 0; i < pbuffer->iteration; i++) {
+ for (j = 0; j < pbuffer->length; ++j) {
+ for (k = 0; k < pbuffer->channels; ++k) {
+ pthread_mutex_lock(&mutex);
+ if (stop) {
+ pthread_exit((void*)0);
+ }
+ ch = pbuffer->ppbuffer[k][j];
+ if (ch != prev) {
+ __haptic_predefine_action(pbuffer->handle, LEVEL, ch);
+ prev = ch;
+ }
+ pthread_mutex_unlock(&mutex);
+ usleep(BITPERMS * 1000);
+ }
+ }
+ }
+
+ pthread_mutex_lock(&mutex);
+ __haptic_predefine_action(gbuffer.handle, STOP, NULL);
+ pthread_mutex_unlock(&mutex);
+
+ pthread_cleanup_pop(1);
+ pthread_exit((void *)0);
+}
+
+int GetHapticLevelMax(int *max)
+{
+ int status;
+ status = device_get_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_LEVEL_MAX, max);
+ if (status < 0) {
+ MODULE_ERROR("device_get_property fail : %d", status);
+ return -1;
+ }
+ return 0;
+}
+
+int InitializeBuffer(unsigned char *vibe_buffer, int max_bufsize)
+{
+ HapticFile *pfile;
+
+ if (max_bufsize < sizeof(HapticFile)) {
+ MODULE_ERROR("buffer lacks a memory : size(%d) minimum size(%d)",
+ max_bufsize, sizeof(HapticFile));
+ return -1;
+ }
+
+ memset(vibe_buffer, 0, sizeof(char)*max_bufsize);
+
+ pfile = (HapticFile*)vibe_buffer;
+
+ pfile->chunkID = HEADER_ID;
+ pfile->chunkSize = sizeof(HapticFile);
+ pfile->fmt.chunkID = FMT_ID;
+ pfile->fmt.chunkSize = sizeof(FormatChunk);
+ pfile->fmt.wChannels = 1;
+ pfile->fmt.wBlockAlign = 1; // wChannels*1byte
+ pfile->fmt.dwMagnitude = 99;
+ pfile->fmt.dwDuration = 0;
+ pfile->data.chunkID = DATA_ID;
+ pfile->data.chunkSize = sizeof(DataChunk);
+ return 0;
+}
+
+int InsertElement(unsigned char *vibe_buffer, int max_bufsize, HapticElement *element)
+{
+ HapticFile *pfile;
+ int databuf;
+ int needbuf;
+ int duration;
+ unsigned char level;
+ int i;
+
+ pfile = (HapticFile*)vibe_buffer;
+ if (_check_valid_haptic_format(pfile) < 0) {
+ MODULE_ERROR("this buffer is not HapticFormat");
+ return -1;
+ }
+
+ duration = element->duration/BITPERMS;
+ level = (unsigned char)((unsigned int)element->level*MAX_LEVEL/100);
+
+ databuf = max_bufsize - sizeof(HapticFile);
+ needbuf = (pfile->fmt.dwDuration + duration)*pfile->fmt.wBlockAlign;
+ MODULE_LOG("Need buffer size : %d", needbuf);
+
+ if (databuf < needbuf) {
+ MODULE_ERROR("buffer lacks a memory : data buf(%d), need buf(%d)", databuf, needbuf);
+ return -1;
+ }
+
+ for (i = pfile->fmt.dwDuration; i < pfile->fmt.dwDuration+duration; i++) {
+ pfile->data.pData[i] = level;
+ }
+
+ pfile->chunkSize = sizeof(HapticFile)+needbuf ;
+ pfile->fmt.dwDuration = pfile->fmt.dwDuration+duration;
+ pfile->data.chunkSize = sizeof(DataChunk)+needbuf;
+ return 0;
+}
+
+int GetBufferSize(const unsigned char *vibe_buffer, int *size)
+{
+ HapticFile *pfile;
+
+ pfile = (HapticFile*)vibe_buffer;
+ if (_check_valid_haptic_format(pfile) < 0) {
+ MODULE_ERROR("this buffer is not HapticFormat");
+ return -1;
+ }
+
+ *size = pfile->chunkSize;
+ return 0;
+}
+
+int GetBufferDuration(const unsigned char *vibe_buffer, int *duration)
+{
+ HapticFile *pfile;
+
+ pfile = (HapticFile*)vibe_buffer;
+ if (_check_valid_haptic_format(pfile) < 0) {
+ MODULE_ERROR("this buffer is not HapticFormat");
+ return -1;
+ }
+
+ *duration = pfile->fmt.dwDuration;
+ return 0;
+}
+
+int PlayOneshot(int handle, int duration, int level)
+{
+ char buf_pid[32];
+ char buf_prop[32];
+ char buf_handle[32];
+ char buf_duration[32];
+ char buf_level[32];
+
+ if (_cancel_thread() < 0) {
+ MODULE_ERROR("_cancel_thread fail");
+ return -1;
+ }
+
+ snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+ snprintf(buf_prop, sizeof(buf_prop), "%d", ONESHOT);
+ snprintf(buf_handle, sizeof(buf_handle), "%d", handle);
+ snprintf(buf_duration, sizeof(buf_duration), "%d", duration);
+ snprintf(buf_level, sizeof(buf_level), "%d", level);
+
+ MODULE_LOG("pid : %s, prop : %s, handle : %s", buf_pid, buf_prop, buf_handle);
+ return __haptic_call_predef_action(PREDEF_HAPTIC, 5, buf_pid, buf_prop,
+ buf_handle, buf_duration, buf_level);
+}
+
+int PlayBuffer(int handle, const unsigned char *vibe_buffer, int iteration, int level)
+{
+ HapticFile *pfile;
+ unsigned char **ppbuffer;
+ unsigned int channels, length, align;
+ unsigned char data;
+ int i, j;
+
+ pfile = (HapticFile*)vibe_buffer;
+ if (_check_valid_haptic_format(pfile) < 0) {
+ MODULE_ERROR("this buffer is not HapticFormat");
+ return -1;
+ }
+
+ /* Temporary code
+ This code does not support handle and multi channel concept.
+ Only this code adds to test for playing file. */
+
+ if (_cancel_thread() < 0) {
+ MODULE_ERROR("_cancel_thread fail");
+ return -1;
+ }
+
+ channels = pfile->fmt.wChannels;
+ align = pfile->fmt.wBlockAlign;
+ length = (pfile->data.chunkSize-8)/align;
+ MODULE_LOG("channels : %d, length : %d, align : %d, level : %d", channels, length, align, level);
+
+ /* Create buffer */
+ ppbuffer = (unsigned char**)malloc(sizeof(unsigned char*)*channels);
+ for (i = 0; i < channels; ++i) {
+ ppbuffer[i] = (unsigned char*)malloc(sizeof(unsigned char)*length);
+ memset(ppbuffer[i], 0, sizeof(unsigned char)*length);
+ }
+
+ /* Copy buffer from source buffer */
+ for (i = 0; i < length; ++i) {
+ for (j = 0; j < channels; ++j) {
+ data = (unsigned char)(pfile->data.pData[i*align+j]);
+ ppbuffer[j][i] = (unsigned char)(data*level/0xFF);
+ MODULE_LOG("ppbuffer[%2d][%2d] : data(%x) -> (%x)", j, i, data, ppbuffer[j][i]);
+ }
+ }
+
+ gbuffer.handle = handle;
+ gbuffer.ppbuffer = ppbuffer;
+ gbuffer.channels = channels;
+ gbuffer.length = length;
+ gbuffer.iteration = iteration;
+
+ __haptic_predefine_action(gbuffer.handle, PLAY, NULL);
+
+ /* Start thread */
+ if (_create_thread(&gbuffer, __play_cb) < 0) {
+ MODULE_ERROR("_create_thread fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+int Stop(int handle)
+{
+ char buf_pid[32];
+ char buf_prop[32];
+ char buf_handle[32];
+
+ if (_cancel_thread() < 0) {
+ MODULE_ERROR("_cancel_thread fail");
+ return -1;
+ }
+
+ snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+ snprintf(buf_prop, sizeof(buf_prop), "%d", STOP);
+ snprintf(buf_handle, sizeof(buf_handle), "%d", handle);
+
+ MODULE_LOG("pid : %s, prop : %s, handle : %s", buf_pid, buf_prop, buf_handle);
+ return __haptic_call_predef_action(PREDEF_HAPTIC, 3, buf_pid, buf_prop, buf_handle);
+}
+
+int OpenDevice(int handle)
+{
+ char buf_pid[32];
+ char buf_prop[32];
+ char buf_handle[32];
+
+ snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+ snprintf(buf_prop, sizeof(buf_prop), "%d", OPEN);
+ snprintf(buf_handle, sizeof(buf_handle), "%d", handle);
+
+ MODULE_LOG("pid : %s, prop : %s, handle : %s", buf_pid, buf_prop, buf_handle);
+ return __haptic_call_predef_action(PREDEF_HAPTIC, 3, buf_pid, buf_prop, buf_handle);
+}
+
+int CloseDevice(int handle)
+{
+ char buf_pid[32];
+ char buf_prop[32];
+ char buf_handle[32];
+
+ if (_cancel_thread() < 0) {
+ MODULE_ERROR("_cancel_thread fail");
+ return -1;
+ }
+
+ snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+ snprintf(buf_prop, sizeof(buf_prop), "%d", CLOSE);
+ snprintf(buf_handle, sizeof(buf_handle), "%d", handle);
+
+ MODULE_LOG("pid : %s, prop : %s, handle : %s", buf_pid, buf_prop, buf_handle);
+ return __haptic_call_predef_action(PREDEF_HAPTIC, 3, buf_pid, buf_prop, buf_handle);
+}
+
+int GetState(int handle, int *state)
+{
+ if (gbuffer.handle == handle) {
+ *state = STATE_PLAY;
+ return 0;
+ }
+
+ *state = STATE_STOP;
+ return 0;
+}
diff --git a/tizen/DEVICE/src/haptic.c b/tizen/DEVICE/src/haptic.c
new file mode 100644
index 0000000..e7605de
--- /dev/null
+++ b/tizen/DEVICE/src/haptic.c
@@ -0,0 +1,622 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <time.h>
+#include <vconf.h>
+
+#include <haptic_plugin_intf.h>
+#include "haptic_module_log.h"
+#include "file.h"
+
+#ifndef EXTAPI
+#define EXTAPI __attribute__ ((visibility("default")))
+#endif
+
+#define DEFAULT_EFFECT_HANDLE 0xFFFF
+#define DEFAULT_MOTOR_COUNT 1
+#define HAPTIC_PLAY_FILE_EXT ".tht"
+
+/* START of Static Function Section */
+static int __to_level(int feedback, int *type)
+{
+ static int max = -1;
+ int t;
+
+ if (max == -1) {
+ int status = GetHapticLevelMax(&max);
+ if (status < 0) {
+ MODULE_ERROR("GetHapticLevelMax fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+ }
+
+ t = feedback * max / HAPTIC_MODULE_FEEDBACK_MAX;
+ MODULE_LOG("feedback value is changed : %d -> %d", feedback, t);
+
+ if (type)
+ *type = t;
+
+ return 0;
+}
+
+static void __trim_name(const char *file_name, char *vibe_buffer, int size)
+{
+ int length;
+
+ assert(file_name);
+ assert(vibe_buffer);
+ assert(size > 0);
+
+ snprintf(vibe_buffer, size, "%s", file_name);
+
+ length = strlen(vibe_buffer);
+ while (vibe_buffer[--length] == ' ');
+ vibe_buffer[length + 1] = '\0';
+}
+
+static int __check_ext(const char *name)
+{
+ char *ext;
+
+ assert(name);
+
+ ext = strrchr(name, '.');
+ if (ext && !strcmp(ext, HAPTIC_PLAY_FILE_EXT))
+ return 1;
+
+ return 0;
+}
+
+static int __get_size(FILE *pf, const char *fname)
+{
+ int status;
+ int size;
+
+ assert(pf);
+
+ status = fseek(pf, 0, SEEK_END);
+ if (status == -1) {
+ MODULE_ERROR("fseek failed: %s", fname);
+ return -1;
+ }
+
+ size = ftell(pf);
+
+ status = fseek(pf, 0, SEEK_SET);
+ if (status == -1) {
+ MODULE_ERROR("fseek failed: %s", fname);
+ return -1;
+ }
+
+ return size;
+}
+
+static unsigned char *__read_file(const char *fname)
+{
+ int status;
+ FILE *pf;
+ long size;
+ unsigned char *vibe_buffer;
+
+ assert(fname);
+
+ pf = fopen(fname, "rb");
+ if (!pf) {
+ MODULE_ERROR("fopen failed: %s", fname);
+ return NULL;
+ }
+
+ size = __get_size(pf, fname);
+ if (size <= 0) {
+ fclose(pf);
+ return NULL;
+ }
+
+ vibe_buffer = malloc(size);
+ if (!vibe_buffer) {
+ fclose(pf);
+ MODULE_ERROR("buffer alloc failed");
+ return NULL;
+ }
+
+ status = fread(vibe_buffer, 1, size, pf);
+ if (status != size) {
+ MODULE_ERROR("fread failed: expect %d read %d", size, status);
+ free(vibe_buffer);
+ vibe_buffer = NULL;
+ }
+
+ fclose(pf);
+
+ return vibe_buffer;
+}
+
+static unsigned char* __convert_file_to_buffer(const char *file_name)
+{
+ char fname[FILENAME_MAX];
+ int status;
+
+ __trim_name(file_name, fname, sizeof(fname));
+ status = __check_ext(fname);
+ if (!status) {
+ MODULE_ERROR("__check_file faild");
+ return NULL;
+ }
+
+ return __read_file(fname);
+}
+
+static int __save_file(const unsigned char *vibe_buferf, int size, const char *file_name)
+{
+ int status;
+ FILE *pf;
+ int fd;
+
+ pf = fopen(file_name, "wb+");
+ if (pf == NULL) {
+ MODULE_ERROR("To open file is failed");
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ status = fwrite(vibe_buferf, 1, size, pf);
+ if (status != size) {
+ MODULE_ERROR("To write file is failed");
+ fclose(pf);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ fd = fileno(pf);
+ if (fd == -1) {
+ MODULE_ERROR("To get file descriptor is failed");
+ fclose(pf);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ status = fsync(fd);
+ if (status == -1) {
+ MODULE_ERROR("To be synchronized with the disk is failed");
+ fclose(pf);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ fclose(pf);
+
+ return 0;
+}
+
+static int __vibrate(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority)
+{
+ int status;
+ int level;
+
+ assert(vibe_buffer);
+
+ status = __to_level(feedback, &level);
+ if (status != HAPTIC_MODULE_ERROR_NONE)
+ return status;
+
+ status = PlayBuffer(device_handle, vibe_buffer, iteration, level);
+ if (status < 0) {
+ MODULE_ERROR("PlayHapticBuffer fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ return 0;
+}
+
+static void *_create_handle(void)
+{
+ static int i = 0;
+ return ((getpid()<<16)|(time(NULL)+(i++)));
+}
+/* END of Static Function Section */
+
+static int _get_device_count(int *count)
+{
+ if (count == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ *count = DEFAULT_MOTOR_COUNT;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _open_device(int device_index, int *device_handle)
+{
+ int handle;
+ int status;
+
+ if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (device_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ handle = _create_handle();
+ status = OpenDevice(handle);
+ if (status < 0) {
+ MODULE_ERROR("OpenHapticDevice fail :%d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ *device_handle = handle;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _close_device(int device_handle)
+{
+ int status;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = CloseDevice(device_handle);
+ if (status < 0) {
+ MODULE_ERROR("CloseHapticDevice fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
+{
+ int status;
+ int level;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (duration < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ status = __to_level(feedback, &level);
+ if (status != HAPTIC_MODULE_ERROR_NONE)
+ return status;
+
+ status = PlayOneshot(device_handle, duration, level);
+ if (status < 0) {
+ MODULE_ERROR("PlayOneshot fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle)
+{
+ int status;
+ unsigned char *vibe_buffer;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ vibe_buffer = __convert_file_to_buffer(file_path);
+ if (!vibe_buffer) {
+ MODULE_ERROR("File load filed");
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
+ free(vibe_buffer);
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return status;
+}
+
+static int _vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
+{
+ int status;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return status;
+}
+
+static int _stop_effect(int device_handle, int effect_handle)
+{
+ int status;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = Stop(device_handle);
+ if (status < 0) {
+ MODULE_ERROR("StopHaptic fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _stop_all_effects(int device_handle)
+{
+ int status;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = Stop(device_handle);
+ if (status < 0) {
+ MODULE_ERROR("StopHaptic fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _pause_effect(int device_handle, int effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_ERROR("This device is not supported this function(%s)", __func__);
+ return HAPTIC_MODULE_NOT_SUPPORTED;
+}
+
+static int _resume_effect(int device_handle, int effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_ERROR("This device is not supported this function(%s)", __func__);
+ return HAPTIC_MODULE_NOT_SUPPORTED;
+}
+
+static int _get_effect_state(int device_handle, int effect_handle, int *state)
+{
+ int status;
+ int cur_state;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (state == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = GetState(device_handle, &cur_state);
+ if (status < 0) {
+ MODULE_ERROR("GetState fail : %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ *state = cur_state;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
+{
+ int status;
+ int i;
+ HapticElement elem;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_bufsize < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (elem_arr == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_elemcnt < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = InitializeBuffer(vibe_buffer, max_bufsize);
+ if (status < 0) {
+ MODULE_ERROR("InitializeHapticBuffer fail: %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ MODULE_LOG("effect count : %d", max_elemcnt);
+ for (i = 0; i < max_elemcnt; ++i) {
+ elem.duration = elem_arr[i].haptic_duration;
+ elem.level = elem_arr[i].haptic_level;
+ MODULE_LOG("%d) duration : %d, level : %d", i, elem_arr[i].haptic_duration, elem_arr[i].haptic_level);
+
+ status = InsertElement(vibe_buffer, max_bufsize, &elem);
+ if (status < 0) {
+ MODULE_ERROR("InsertHapticElement fail: %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+ }
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
+{
+ int status;
+ int size;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_bufsize < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = GetBufferSize(vibe_buffer, &size);
+ if (status < 0) {
+ MODULE_ERROR("GetHapticBufferSize fail: %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ return __save_file(vibe_buffer, size, file_path);
+}
+
+static int _get_file_duration(int device_handle, const char *file_path, int *file_duration)
+{
+ int status;
+ unsigned char *vibe_buffer;
+ int duration;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_duration == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ vibe_buffer = __convert_file_to_buffer(file_path);
+ if (!vibe_buffer) {
+ MODULE_ERROR("File load filed");
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ status = GetBufferDuration(vibe_buffer, &duration);
+ free(vibe_buffer);
+ if (status < 0) {
+ MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ *file_duration = duration;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
+{
+ int status;
+ int duration;
+
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (buffer_duration == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ status = GetBufferDuration(vibe_buffer, &duration);
+ if (status < 0) {
+ MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
+ return HAPTIC_MODULE_OPERATION_FAILED;
+ }
+
+ *buffer_duration = duration;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _convert_binary (void)
+{
+ MODULE_ERROR("This device is not supported this function(%s)", __func__);
+ return HAPTIC_MODULE_NOT_SUPPORTED;
+}
+
+static const haptic_plugin_interface haptic_plugin_tizen = {
+ .haptic_internal_get_device_count = _get_device_count,
+ .haptic_internal_open_device = _open_device,
+ .haptic_internal_close_device = _close_device,
+ .haptic_internal_vibrate_monotone = _vibrate_monotone,
+ .haptic_internal_vibrate_file = _vibrate_file,
+ .haptic_internal_vibrate_buffer = _vibrate_buffer,
+ .haptic_internal_stop_effect = _stop_effect,
+ .haptic_internal_stop_all_effects = _stop_all_effects,
+ .haptic_internal_pause_effect = _pause_effect,
+ .haptic_internal_resume_effect = _resume_effect,
+ .haptic_internal_get_effect_state = _get_effect_state,
+ .haptic_internal_create_effect = _create_effect,
+ .haptic_internal_save_effect = _save_effect,
+ .haptic_internal_get_file_duration = _get_file_duration,
+ .haptic_internal_get_buffer_duration = _get_buffer_duration,
+ .haptic_internal_convert_binary = _convert_binary,
+};
+
+EXTAPI
+const haptic_plugin_interface *get_haptic_plugin_interface()
+{
+ return &haptic_plugin_tizen;
+}
diff --git a/tizen/DEVICE/src/sysnoti.c b/tizen/DEVICE/src/sysnoti.c
new file mode 100644
index 0000000..56aaad8
--- /dev/null
+++ b/tizen/DEVICE/src/sysnoti.c
@@ -0,0 +1,163 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "haptic_module_log.h"
+
+#define HAPTIC_RETRY_READ_COUNT 5
+#define HAPTIC_PARAM_CNT 3
+#define HAPTIC_MAXSTR 100
+#define HAPTIC_MAXARG 16
+#define PREDEF_HAPTIC "haptic"
+#define SYSNOTI_SOCKET_PATH "/tmp/sn"
+
+enum sysnoti_cmd {
+ ADD_HAPTIC_ACTION,
+ CALL_HAPTIC_ACTION,
+};
+
+struct sysnoti_type {
+ int pid;
+ int cmd;
+ char *type;
+ char *path;
+ int argc;
+ char *argv[HAPTIC_MAXARG];
+};
+
+static inline int __send_int(int fd, int val)
+{
+ return write(fd, &val, sizeof(int));
+}
+
+static inline int __send_str(int fd, char *str)
+{
+ int len;
+ int r;
+
+ if (str == NULL) {
+ len = 0;
+ r = write(fd, &len, sizeof(int));
+ } else {
+ len = strlen(str);
+ if (len > HAPTIC_MAXSTR)
+ len = HAPTIC_MAXSTR;
+ r = write(fd, &len, sizeof(int));
+ r = write(fd, str, len);
+ }
+
+ return r;
+}
+
+static int __sysnoti_send(struct sysnoti_type *msg)
+{
+ int sockfd;
+ int len;
+ struct sockaddr_un addr;
+ int retry_cnt;
+ int ret;
+ int i;
+ int r;
+
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sockfd == -1) {
+ MODULE_ERROR("socket create failed");
+ return -1;
+ }
+
+ bzero(&addr, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(addr.sun_path) - 1);
+ len = sizeof(addr);
+
+ if (connect(sockfd, (struct sockaddr *)&addr, len) < 0) {
+ MODULE_ERROR("connect failed");
+ close(sockfd);
+ return -1;
+ }
+ MODULE_LOG("connect : %x", sockfd);
+
+ __send_int(sockfd, msg->pid);
+ __send_int(sockfd, msg->cmd);
+ __send_str(sockfd, msg->type);
+ __send_str(sockfd, msg->path);
+ __send_int(sockfd, msg->argc);
+ for (i = 0; i < msg->argc; i++)
+ __send_str(sockfd, msg->argv[i]);
+
+ MODULE_LOG("read");
+ retry_cnt = 0;
+ while ((r = read(sockfd, &ret, sizeof(int))) < 0) {
+
+ if (errno != EINTR) {
+ MODULE_LOG("read fail : %s(%d)", strerror(errno), errno);
+ ret = -1;
+ break;
+ }
+
+ if (retry_cnt == HAPTIC_RETRY_READ_COUNT) {
+ MODULE_ERROR("retry(%d) fail", retry_cnt);
+ ret = -1;
+ break;
+ }
+
+ MODULE_ERROR("Re-read for error(EINTR)");
+ ++retry_cnt;
+ }
+
+ MODULE_LOG("close (ret : %d) : %x", ret, sockfd);
+ close(sockfd);
+ return ret;
+}
+
+int __haptic_call_predef_action(const char *type, int num, ...)
+{
+ struct sysnoti_type msg;
+ char *args;
+ va_list argptr;
+ int i;
+
+ if (type == NULL || num > HAPTIC_MAXARG) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ msg.pid = getpid();
+ msg.cmd = CALL_HAPTIC_ACTION;
+ msg.type = (char *)type;
+ msg.path = NULL;
+ msg.argc = num;
+
+ va_start(argptr, num);
+ for (i = 0; i < num; i++) {
+ args = va_arg(argptr, char *);
+ msg.argv[i] = args;
+ }
+ va_end(argptr);
+
+ return __sysnoti_send(&msg);
+}
+
diff --git a/tizen/SIMULATOR/CMakeLists.txt b/tizen/SIMULATOR/CMakeLists.txt
new file mode 100644
index 0000000..91a79a3
--- /dev/null
+++ b/tizen/SIMULATOR/CMakeLists.txt
@@ -0,0 +1,27 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(DEPENDENTS "dlog haptic-plugin")
+
+SET(SRCS
+ src/haptic.c)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(rpkgs REQUIRED ${DEPENDENTS})
+
+FOREACH(flag ${rpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--no-as-needed")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS})
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DENABLE_DLOG_OUT -DSLP_DEBUG")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/tizen/SIMULATOR/src/haptic.c b/tizen/SIMULATOR/src/haptic.c
new file mode 100644
index 0000000..c81fe2a
--- /dev/null
+++ b/tizen/SIMULATOR/src/haptic.c
@@ -0,0 +1,312 @@
+/*
+ * haptic-module-tizen
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <haptic_plugin_intf.h>
+#include "haptic_module_log.h"
+
+#ifndef EXTAPI
+#define EXTAPI __attribute__ ((visibility("default")))
+#endif
+
+#define DEFAULT_MOTOR_COUNT 1
+#define DEFAULT_DEVICE_HANDLE 0x01
+#define DEFAULT_EFFECT_HANDLE 0x02
+
+static int _get_device_count(int *count)
+{
+ if (count == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ *count = DEFAULT_MOTOR_COUNT;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _open_device(int device_index, int *device_handle)
+{
+ if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (device_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ *device_handle = DEFAULT_DEVICE_HANDLE;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _close_device(int device_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (duration < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ MODULE_LOG("call %s function", __func__);
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ MODULE_LOG("call %s function", __func__);
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
+ return HAPTIC_MODULE_ERROR_NONE;
+
+ MODULE_LOG("call %s function", __func__);
+
+ *effect_handle = DEFAULT_EFFECT_HANDLE;
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _stop_effect(int device_handle, int effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _stop_all_effects(int device_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _pause_effect(int device_handle, int effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _resume_effect(int device_handle, int effect_handle)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _get_effect_state(int device_handle, int effect_handle, int *effect_state)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (effect_state == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _create_effect(const unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
+{
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_bufsize < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (elem_arr == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_elemcnt < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
+{
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (max_bufsize < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _get_file_duration(int device_handle, const char *file_path, int *file_duration)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_path == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (file_duration == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
+{
+ if (device_handle < 0)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (vibe_buffer == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ if (buffer_duration == NULL)
+ return HAPTIC_MODULE_INVALID_ARGUMENT;
+
+ MODULE_LOG("call %s function", __func__);
+
+ return HAPTIC_MODULE_ERROR_NONE;
+}
+
+static int _convert_binary (void)
+{
+ MODULE_ERROR("This device is not supported this function(%s)", __func__);
+ return HAPTIC_MODULE_NOT_SUPPORTED;
+}
+
+static haptic_plugin_interface haptic_plugin_emul = {
+ .haptic_internal_get_device_count = _get_device_count,
+ .haptic_internal_open_device = _open_device,
+ .haptic_internal_close_device = _close_device,
+ .haptic_internal_vibrate_monotone = _vibrate_monotone,
+ .haptic_internal_vibrate_file = _vibrate_file,
+ .haptic_internal_vibrate_buffer = _vibrate_buffer,
+ .haptic_internal_stop_effect = _stop_effect,
+ .haptic_internal_stop_all_effects = _stop_all_effects,
+ .haptic_internal_pause_effect = _pause_effect,
+ .haptic_internal_resume_effect = _resume_effect,
+ .haptic_internal_get_effect_state = _get_effect_state,
+ .haptic_internal_create_effect = _create_effect,
+ .haptic_internal_save_effect = _save_effect,
+ .haptic_internal_get_file_duration = _get_file_duration,
+ .haptic_internal_get_buffer_duration = _get_buffer_duration,
+ .haptic_internal_convert_binary = _convert_binary,
+};
+
+EXTAPI
+const haptic_plugin_interface *get_haptic_plugin_interface()
+{
+ return &haptic_plugin_emul;
+}