3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
23 #include <sys/types.h>
30 #include <haptic_plugin_intf.h>
31 #include "haptic_module_log.h"
35 #define EXTAPI __attribute__ ((visibility("default")))
38 #define DEFAULT_MOTOR_COUNT 1
39 #define DEFAULT_DEVICE_HANDLE 0x01
40 #define DEFAULT_EFFECT_HANDLE 0x02
41 #define HAPTIC_FEEDBACK_AUTO 101
42 #define HAPTIC_PLAY_FILE_EXT ".tht"
44 /* START of Static Function Section */
45 static int __to_level(int feedback, int *type)
51 int status = GetHapticLevelMax(&max);
53 MODULE_ERROR("GetHapticLevelMax fail : %d", status);
54 return HAPTIC_MODULE_OPERATION_FAILED;
58 t = feedback * max / HAPTIC_MODULE_FEEDBACK_MAX;
59 MODULE_LOG("feedback value is changed : %d -> %d", feedback, t);
67 static void __trim_name(const char *file_name, char *vibe_buffer, int size)
75 snprintf(vibe_buffer, size, "%s", file_name);
77 length = strlen(vibe_buffer);
78 while (vibe_buffer[--length] == ' ');
79 vibe_buffer[length + 1] = '\0';
82 static int __check_ext(const char *name)
88 ext = strrchr(name, '.');
89 if (ext && !strcmp(ext, HAPTIC_PLAY_FILE_EXT))
95 static int __get_size(FILE *pf, const char *fname)
102 status = fseek(pf, 0, SEEK_END);
104 MODULE_ERROR("fseek failed: %s", fname);
110 status = fseek(pf, 0, SEEK_SET);
112 MODULE_ERROR("fseek failed: %s", fname);
119 static unsigned char *__read_file(const char *fname)
124 unsigned char *vibe_buffer;
128 pf = fopen(fname, "rb");
130 MODULE_ERROR("fopen failed: %s", fname);
134 size = __get_size(pf, fname);
140 vibe_buffer = malloc(size);
143 MODULE_ERROR("buffer alloc failed");
147 status = fread(vibe_buffer, 1, size, pf);
148 if (status != size) {
149 MODULE_ERROR("fread failed: expect %d read %d", size, status);
159 static unsigned char* __convert_file_to_buffer(const char *file_name)
161 char fname[FILENAME_MAX];
164 __trim_name(file_name, fname, sizeof(fname));
165 status = __check_ext(fname);
167 MODULE_ERROR("__check_file faild");
171 return __read_file(fname);
174 static int __save_file(const unsigned char *vibe_buferf, int size, const char *file_name)
180 pf = fopen(file_name, "wb+");
182 MODULE_ERROR("To open file is failed");
183 return HAPTIC_MODULE_OPERATION_FAILED;
186 status = fwrite(vibe_buferf, 1, size, pf);
187 if (status != size) {
188 MODULE_ERROR("To write file is failed");
190 return HAPTIC_MODULE_OPERATION_FAILED;
195 MODULE_ERROR("To get file descriptor is failed");
197 return HAPTIC_MODULE_OPERATION_FAILED;
202 MODULE_ERROR("To be synchronized with the disk is failed");
204 return HAPTIC_MODULE_OPERATION_FAILED;
212 static int __vibrate(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority)
219 status = __to_level(feedback, &level);
220 if (status != HAPTIC_MODULE_ERROR_NONE)
223 status = PlayBuffer(device_handle, vibe_buffer, iteration, level);
225 MODULE_ERROR("PlayHapticBuffer fail : %d", status);
226 return HAPTIC_MODULE_OPERATION_FAILED;
232 static void *_create_handle(void)
234 return ((getpid()<<16)|time(NULL));
236 /* END of Static Function Section */
239 static int _get_device_count(int *count)
242 return HAPTIC_MODULE_INVALID_ARGUMENT;
244 *count = DEFAULT_MOTOR_COUNT;
245 return HAPTIC_MODULE_ERROR_NONE;
248 static int _open_device(int device_index, int *device_handle)
253 if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL)
254 return HAPTIC_MODULE_INVALID_ARGUMENT;
256 if (device_handle == NULL)
257 return HAPTIC_MODULE_INVALID_ARGUMENT;
259 handle = _create_handle();
260 status = OpenDevice(handle);
262 MODULE_ERROR("OpenHapticDevice fail :%d", status);
263 return HAPTIC_MODULE_OPERATION_FAILED;
266 *device_handle = handle;
267 return HAPTIC_MODULE_ERROR_NONE;
270 static int _close_device(int device_handle)
274 if (device_handle < 0)
275 return HAPTIC_MODULE_INVALID_ARGUMENT;
277 status = CloseDevice(device_handle);
279 MODULE_ERROR("CloseHapticDevice fail : %d", status);
280 return HAPTIC_MODULE_OPERATION_FAILED;
283 return HAPTIC_MODULE_ERROR_NONE;
286 static int _vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
291 if (device_handle < 0)
292 return HAPTIC_MODULE_INVALID_ARGUMENT;
295 return HAPTIC_MODULE_INVALID_ARGUMENT;
297 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
298 return HAPTIC_MODULE_INVALID_ARGUMENT;
300 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
301 return HAPTIC_MODULE_INVALID_ARGUMENT;
303 if (effect_handle == NULL)
304 return HAPTIC_MODULE_INVALID_ARGUMENT;
306 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
307 return HAPTIC_MODULE_ERROR_NONE;
309 status = __to_level(feedback, &level);
310 if (status != HAPTIC_MODULE_ERROR_NONE)
313 status = PlayOneshot(device_handle, duration, level);
315 MODULE_ERROR("PlayOneshot fail : %d", status);
316 return HAPTIC_MODULE_OPERATION_FAILED;
319 *effect_handle = DEFAULT_EFFECT_HANDLE;
320 return HAPTIC_MODULE_ERROR_NONE;
323 static int _vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle)
326 unsigned char *vibe_buffer;
328 if (device_handle < 0)
329 return HAPTIC_MODULE_INVALID_ARGUMENT;
331 if (file_path == NULL)
332 return HAPTIC_MODULE_INVALID_ARGUMENT;
334 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
335 return HAPTIC_MODULE_INVALID_ARGUMENT;
337 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
338 return HAPTIC_MODULE_INVALID_ARGUMENT;
340 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
341 return HAPTIC_MODULE_INVALID_ARGUMENT;
343 if (effect_handle == NULL)
344 return HAPTIC_MODULE_INVALID_ARGUMENT;
346 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
347 return HAPTIC_MODULE_ERROR_NONE;
349 vibe_buffer = __convert_file_to_buffer(file_path);
351 MODULE_ERROR("File load filed");
352 return HAPTIC_MODULE_OPERATION_FAILED;
355 status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
361 static int _vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
363 if (device_handle < 0)
364 return HAPTIC_MODULE_INVALID_ARGUMENT;
366 if (vibe_buffer == NULL)
367 return HAPTIC_MODULE_INVALID_ARGUMENT;
369 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
370 return HAPTIC_MODULE_INVALID_ARGUMENT;
372 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
373 return HAPTIC_MODULE_INVALID_ARGUMENT;
375 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
376 return HAPTIC_MODULE_INVALID_ARGUMENT;
378 if (effect_handle == NULL)
379 return HAPTIC_MODULE_INVALID_ARGUMENT;
381 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
382 return HAPTIC_MODULE_ERROR_NONE;
384 return __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
387 static int _stop_effect(int device_handle, int effect_handle)
391 if (device_handle < 0)
392 return HAPTIC_MODULE_INVALID_ARGUMENT;
394 if (effect_handle < 0)
395 return HAPTIC_MODULE_INVALID_ARGUMENT;
397 status = Stop(device_handle);
399 MODULE_ERROR("StopHaptic fail : %d", status);
400 return HAPTIC_MODULE_OPERATION_FAILED;
403 return HAPTIC_MODULE_ERROR_NONE;
406 static int _stop_all_effects(int device_handle)
410 if (device_handle < 0)
411 return HAPTIC_MODULE_INVALID_ARGUMENT;
413 status = Stop(device_handle);
415 MODULE_ERROR("StopHaptic fail : %d", status);
416 return HAPTIC_MODULE_OPERATION_FAILED;
419 return HAPTIC_MODULE_ERROR_NONE;
422 static int _pause_effect(int device_handle, int effect_handle)
424 if (device_handle < 0)
425 return HAPTIC_MODULE_INVALID_ARGUMENT;
427 if (effect_handle < 0)
428 return HAPTIC_MODULE_INVALID_ARGUMENT;
430 MODULE_ERROR("This device is not supported this function(%s)", __func__);
431 return HAPTIC_MODULE_NOT_SUPPORTED;
434 static int _resume_effect(int device_handle, int effect_handle)
436 if (device_handle < 0)
437 return HAPTIC_MODULE_INVALID_ARGUMENT;
439 if (effect_handle < 0)
440 return HAPTIC_MODULE_INVALID_ARGUMENT;
442 MODULE_ERROR("This device is not supported this function(%s)", __func__);
443 return HAPTIC_MODULE_NOT_SUPPORTED;
446 static int _get_effect_state(int device_handle, int effect_handle, int *state)
448 if (device_handle < 0)
449 return HAPTIC_MODULE_INVALID_ARGUMENT;
451 if (effect_handle < 0)
452 return HAPTIC_MODULE_INVALID_ARGUMENT;
455 return HAPTIC_MODULE_INVALID_ARGUMENT;
457 MODULE_ERROR("This device is not supported this function(%s)", __func__);
458 return HAPTIC_MODULE_NOT_SUPPORTED;
461 static int _create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
467 if (vibe_buffer == NULL)
468 return HAPTIC_MODULE_INVALID_ARGUMENT;
471 return HAPTIC_MODULE_INVALID_ARGUMENT;
473 if (elem_arr == NULL)
474 return HAPTIC_MODULE_INVALID_ARGUMENT;
477 return HAPTIC_MODULE_INVALID_ARGUMENT;
479 status = InitializeBuffer(vibe_buffer, max_bufsize);
481 MODULE_ERROR("InitializeHapticBuffer fail: %d", status);
482 return HAPTIC_MODULE_OPERATION_FAILED;
485 MODULE_LOG("effect count : %d", max_elemcnt);
486 for (i = 0; i < max_elemcnt; ++i) {
487 elem.duration = elem_arr[i].haptic_duration;
488 elem.level = elem_arr[i].haptic_level;
489 MODULE_LOG("%d) duration : %d, level : %d", i, elem_arr[i].haptic_duration, elem_arr[i].haptic_level);
491 status = InsertElement(vibe_buffer, max_bufsize, &elem);
493 MODULE_ERROR("InsertHapticElement fail: %d", status);
494 return HAPTIC_MODULE_OPERATION_FAILED;
498 return HAPTIC_MODULE_ERROR_NONE;
501 static int _save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
506 if (vibe_buffer == NULL)
507 return HAPTIC_MODULE_INVALID_ARGUMENT;
510 return HAPTIC_MODULE_INVALID_ARGUMENT;
512 if (file_path == NULL)
513 return HAPTIC_MODULE_INVALID_ARGUMENT;
515 status = GetBufferSize(vibe_buffer, &size);
517 MODULE_ERROR("GetHapticBufferSize fail: %d", status);
518 return HAPTIC_MODULE_OPERATION_FAILED;
521 return __save_file(vibe_buffer, size, file_path);
524 static int _get_file_duration(int device_handle, const char *file_path, int *file_duration)
527 unsigned char *vibe_buffer;
530 if (device_handle < 0)
531 return HAPTIC_MODULE_INVALID_ARGUMENT;
533 if (file_path == NULL)
534 return HAPTIC_MODULE_INVALID_ARGUMENT;
536 if (file_duration == NULL)
537 return HAPTIC_MODULE_INVALID_ARGUMENT;
539 vibe_buffer = __convert_file_to_buffer(file_path);
541 MODULE_ERROR("File load filed");
542 return HAPTIC_MODULE_OPERATION_FAILED;
545 status = GetBufferDuration(vibe_buffer, &duration);
548 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
549 return HAPTIC_MODULE_OPERATION_FAILED;
552 *file_duration = duration;
553 return HAPTIC_MODULE_ERROR_NONE;
556 static int _get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
561 if (device_handle < 0)
562 return HAPTIC_MODULE_INVALID_ARGUMENT;
564 if (vibe_buffer == NULL)
565 return HAPTIC_MODULE_INVALID_ARGUMENT;
567 if (buffer_duration == NULL)
568 return HAPTIC_MODULE_INVALID_ARGUMENT;
570 status = GetBufferDuration(vibe_buffer, &duration);
572 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
573 return HAPTIC_MODULE_OPERATION_FAILED;
576 *buffer_duration = duration;
577 return HAPTIC_MODULE_ERROR_NONE;
580 static int _convert_binary (void)
582 MODULE_ERROR("This device is not supported this function(%s)", __func__);
583 return HAPTIC_MODULE_NOT_SUPPORTED;
586 static const haptic_plugin_interface haptic_plugin_tizen = {
587 .haptic_internal_get_device_count = _get_device_count,
588 .haptic_internal_open_device = _open_device,
589 .haptic_internal_close_device = _close_device,
590 .haptic_internal_vibrate_monotone = _vibrate_monotone,
591 .haptic_internal_vibrate_file = _vibrate_file,
592 .haptic_internal_vibrate_buffer = _vibrate_buffer,
593 .haptic_internal_stop_effect = _stop_effect,
594 .haptic_internal_stop_all_effects = _stop_all_effects,
595 .haptic_internal_pause_effect = _pause_effect,
596 .haptic_internal_resume_effect = _resume_effect,
597 .haptic_internal_get_effect_state = _get_effect_state,
598 .haptic_internal_create_effect = _create_effect,
599 .haptic_internal_save_effect = _save_effect,
600 .haptic_internal_get_file_duration = _get_file_duration,
601 .haptic_internal_get_buffer_duration = _get_buffer_duration,
602 .haptic_internal_convert_binary = _convert_binary,
606 const haptic_plugin_interface *get_haptic_plugin_interface()
608 return &haptic_plugin_tizen;