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");
189 return HAPTIC_MODULE_OPERATION_FAILED;
194 MODULE_ERROR("To get file descriptor is failed");
195 return HAPTIC_MODULE_OPERATION_FAILED;
200 MODULE_ERROR("To be synchronized with the disk is failed");
201 return HAPTIC_MODULE_OPERATION_FAILED;
209 static int __vibrate(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority)
216 status = __to_level(feedback, &level);
217 if (status != HAPTIC_MODULE_ERROR_NONE)
220 status = PlayBuffer(device_handle, vibe_buffer, iteration, level);
222 MODULE_ERROR("PlayHapticBuffer fail : %d", status);
223 return HAPTIC_MODULE_OPERATION_FAILED;
229 static void *_create_handle(void)
231 return ((getpid()<<16)|time(NULL));
233 /* END of Static Function Section */
236 static int _get_device_count(int *count)
239 return HAPTIC_MODULE_INVALID_ARGUMENT;
241 *count = DEFAULT_MOTOR_COUNT;
242 return HAPTIC_MODULE_ERROR_NONE;
245 static int _open_device(int device_index, int *device_handle)
250 if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL)
251 return HAPTIC_MODULE_INVALID_ARGUMENT;
253 if (device_handle == NULL)
254 return HAPTIC_MODULE_INVALID_ARGUMENT;
256 handle = _create_handle();
257 status = OpenDevice(handle);
259 MODULE_ERROR("OpenHapticDevice fail :%d", status);
260 return HAPTIC_MODULE_OPERATION_FAILED;
263 *device_handle = handle;
264 return HAPTIC_MODULE_ERROR_NONE;
267 static int _close_device(int device_handle)
271 if (device_handle < 0)
272 return HAPTIC_MODULE_INVALID_ARGUMENT;
274 status = CloseDevice(device_handle);
276 MODULE_ERROR("CloseHapticDevice fail : %d", status);
277 return HAPTIC_MODULE_OPERATION_FAILED;
280 return HAPTIC_MODULE_ERROR_NONE;
283 static int _vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
288 if (device_handle < 0)
289 return HAPTIC_MODULE_INVALID_ARGUMENT;
292 return HAPTIC_MODULE_INVALID_ARGUMENT;
294 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
295 return HAPTIC_MODULE_INVALID_ARGUMENT;
297 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
298 return HAPTIC_MODULE_INVALID_ARGUMENT;
300 if (effect_handle == NULL)
301 return HAPTIC_MODULE_INVALID_ARGUMENT;
303 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
304 return HAPTIC_MODULE_ERROR_NONE;
306 status = __to_level(feedback, &level);
307 if (status != HAPTIC_MODULE_ERROR_NONE)
310 status = PlayOneshot(device_handle, duration, level);
312 MODULE_ERROR("PlayOneshot fail : %d", status);
313 return HAPTIC_MODULE_OPERATION_FAILED;
316 *effect_handle = DEFAULT_EFFECT_HANDLE;
317 return HAPTIC_MODULE_ERROR_NONE;
320 static int _vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle)
323 unsigned char *vibe_buffer;
325 if (device_handle < 0)
326 return HAPTIC_MODULE_INVALID_ARGUMENT;
328 if (file_path == NULL)
329 return HAPTIC_MODULE_INVALID_ARGUMENT;
331 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
332 return HAPTIC_MODULE_INVALID_ARGUMENT;
334 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
335 return HAPTIC_MODULE_INVALID_ARGUMENT;
337 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
338 return HAPTIC_MODULE_INVALID_ARGUMENT;
340 if (effect_handle == NULL)
341 return HAPTIC_MODULE_INVALID_ARGUMENT;
343 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
344 return HAPTIC_MODULE_ERROR_NONE;
346 vibe_buffer = __convert_file_to_buffer(file_path);
348 MODULE_ERROR("File load filed");
349 return HAPTIC_MODULE_OPERATION_FAILED;
352 status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
358 static int _vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
360 if (device_handle < 0)
361 return HAPTIC_MODULE_INVALID_ARGUMENT;
363 if (vibe_buffer == NULL)
364 return HAPTIC_MODULE_INVALID_ARGUMENT;
366 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
367 return HAPTIC_MODULE_INVALID_ARGUMENT;
369 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
370 return HAPTIC_MODULE_INVALID_ARGUMENT;
372 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
373 return HAPTIC_MODULE_INVALID_ARGUMENT;
375 if (effect_handle == NULL)
376 return HAPTIC_MODULE_INVALID_ARGUMENT;
378 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
379 return HAPTIC_MODULE_ERROR_NONE;
381 return __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
384 static int _stop_effect(int device_handle, int effect_handle)
388 if (device_handle < 0)
389 return HAPTIC_MODULE_INVALID_ARGUMENT;
391 if (effect_handle < 0)
392 return HAPTIC_MODULE_INVALID_ARGUMENT;
394 status = Stop(device_handle);
396 MODULE_ERROR("StopHaptic fail : %d", status);
397 return HAPTIC_MODULE_OPERATION_FAILED;
400 return HAPTIC_MODULE_ERROR_NONE;
403 static int _stop_all_effects(int device_handle)
407 if (device_handle < 0)
408 return HAPTIC_MODULE_INVALID_ARGUMENT;
410 status = Stop(device_handle);
412 MODULE_ERROR("StopHaptic fail : %d", status);
413 return HAPTIC_MODULE_OPERATION_FAILED;
416 return HAPTIC_MODULE_ERROR_NONE;
419 static int _pause_effect(int device_handle, int effect_handle)
421 if (device_handle < 0)
422 return HAPTIC_MODULE_INVALID_ARGUMENT;
424 if (effect_handle < 0)
425 return HAPTIC_MODULE_INVALID_ARGUMENT;
427 MODULE_ERROR("This device is not supported this function(%s)", __func__);
428 return HAPTIC_MODULE_NOT_SUPPORTED;
431 static int _resume_effect(int device_handle, int effect_handle)
433 if (device_handle < 0)
434 return HAPTIC_MODULE_INVALID_ARGUMENT;
436 if (effect_handle < 0)
437 return HAPTIC_MODULE_INVALID_ARGUMENT;
439 MODULE_ERROR("This device is not supported this function(%s)", __func__);
440 return HAPTIC_MODULE_NOT_SUPPORTED;
443 static int _get_effect_state(int device_handle, int effect_handle, int *state)
445 if (device_handle < 0)
446 return HAPTIC_MODULE_INVALID_ARGUMENT;
448 if (effect_handle < 0)
449 return HAPTIC_MODULE_INVALID_ARGUMENT;
452 return HAPTIC_MODULE_INVALID_ARGUMENT;
454 MODULE_ERROR("This device is not supported this function(%s)", __func__);
455 return HAPTIC_MODULE_NOT_SUPPORTED;
458 static int _create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
464 if (vibe_buffer == NULL)
465 return HAPTIC_MODULE_INVALID_ARGUMENT;
468 return HAPTIC_MODULE_INVALID_ARGUMENT;
470 if (elem_arr == NULL)
471 return HAPTIC_MODULE_INVALID_ARGUMENT;
474 return HAPTIC_MODULE_INVALID_ARGUMENT;
476 status = InitializeBuffer(vibe_buffer, max_bufsize);
478 MODULE_ERROR("InitializeHapticBuffer fail: %d", status);
479 return HAPTIC_MODULE_OPERATION_FAILED;
482 MODULE_LOG("effect count : %d", max_elemcnt);
483 for (i = 0; i < max_elemcnt; ++i) {
484 elem.duration = elem_arr[i].haptic_duration;
485 elem.level = elem_arr[i].haptic_level;
486 MODULE_LOG("%d) duration : %d, level : %d", i, elem_arr[i].haptic_duration, elem_arr[i].haptic_level);
488 status = InsertElement(vibe_buffer, max_bufsize, &elem);
490 MODULE_ERROR("InsertHapticElement fail: %d", status);
491 return HAPTIC_MODULE_OPERATION_FAILED;
495 return HAPTIC_MODULE_ERROR_NONE;
498 static int _save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
503 if (vibe_buffer == NULL)
504 return HAPTIC_MODULE_INVALID_ARGUMENT;
507 return HAPTIC_MODULE_INVALID_ARGUMENT;
509 if (file_path == NULL)
510 return HAPTIC_MODULE_INVALID_ARGUMENT;
512 status = GetBufferSize(vibe_buffer, &size);
514 MODULE_ERROR("GetHapticBufferSize fail: %d", status);
515 return HAPTIC_MODULE_OPERATION_FAILED;
518 return __save_file(vibe_buffer, size, file_path);
521 static int _get_file_duration(int device_handle, const char *file_path, int *file_duration)
524 unsigned char *vibe_buffer;
527 if (device_handle < 0)
528 return HAPTIC_MODULE_INVALID_ARGUMENT;
530 if (file_path == NULL)
531 return HAPTIC_MODULE_INVALID_ARGUMENT;
533 if (file_duration == NULL)
534 return HAPTIC_MODULE_INVALID_ARGUMENT;
536 vibe_buffer = __convert_file_to_buffer(file_path);
538 MODULE_ERROR("File load filed");
539 return HAPTIC_MODULE_OPERATION_FAILED;
542 status = GetBufferDuration(vibe_buffer, &duration);
545 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
546 return HAPTIC_MODULE_OPERATION_FAILED;
549 *file_duration = duration;
550 return HAPTIC_MODULE_ERROR_NONE;
553 static int _get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
558 if (device_handle < 0)
559 return HAPTIC_MODULE_INVALID_ARGUMENT;
561 if (vibe_buffer == NULL)
562 return HAPTIC_MODULE_INVALID_ARGUMENT;
564 if (buffer_duration == NULL)
565 return HAPTIC_MODULE_INVALID_ARGUMENT;
567 status = GetBufferDuration(vibe_buffer, &duration);
569 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
570 return HAPTIC_MODULE_OPERATION_FAILED;
573 *buffer_duration = duration;
574 return HAPTIC_MODULE_ERROR_NONE;
577 static int _convert_binary (void)
579 MODULE_ERROR("This device is not supported this function(%s)", __func__);
580 return HAPTIC_MODULE_NOT_SUPPORTED;
583 static const haptic_plugin_interface haptic_plugin_tizen = {
584 .haptic_internal_get_device_count = _get_device_count,
585 .haptic_internal_open_device = _open_device,
586 .haptic_internal_close_device = _close_device,
587 .haptic_internal_vibrate_monotone = _vibrate_monotone,
588 .haptic_internal_vibrate_file = _vibrate_file,
589 .haptic_internal_vibrate_buffer = _vibrate_buffer,
590 .haptic_internal_stop_effect = _stop_effect,
591 .haptic_internal_stop_all_effects = _stop_all_effects,
592 .haptic_internal_pause_effect = _pause_effect,
593 .haptic_internal_resume_effect = _resume_effect,
594 .haptic_internal_get_effect_state = _get_effect_state,
595 .haptic_internal_create_effect = _create_effect,
596 .haptic_internal_save_effect = _save_effect,
597 .haptic_internal_get_file_duration = _get_file_duration,
598 .haptic_internal_get_buffer_duration = _get_buffer_duration,
599 .haptic_internal_convert_binary = _convert_binary,
603 const haptic_plugin_interface *get_haptic_plugin_interface()
605 return &haptic_plugin_tizen;