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_EFFECT_HANDLE 0xFFFF
39 #define DEFAULT_MOTOR_COUNT 1
40 #define HAPTIC_PLAY_FILE_EXT ".tht"
42 /* START of Static Function Section */
43 static int __to_level(int feedback, int *type)
49 int status = GetHapticLevelMax(&max);
51 MODULE_ERROR("GetHapticLevelMax fail : %d", status);
52 return HAPTIC_MODULE_OPERATION_FAILED;
56 t = feedback * max / HAPTIC_MODULE_FEEDBACK_MAX;
57 MODULE_LOG("feedback value is changed : %d -> %d", feedback, t);
65 static void __trim_name(const char *file_name, char *vibe_buffer, int size)
73 snprintf(vibe_buffer, size, "%s", file_name);
75 length = strlen(vibe_buffer);
76 while (vibe_buffer[--length] == ' ');
77 vibe_buffer[length + 1] = '\0';
80 static int __check_ext(const char *name)
86 ext = strrchr(name, '.');
87 if (ext && !strcmp(ext, HAPTIC_PLAY_FILE_EXT))
93 static int __get_size(FILE *pf, const char *fname)
100 status = fseek(pf, 0, SEEK_END);
102 MODULE_ERROR("fseek failed: %s", fname);
108 status = fseek(pf, 0, SEEK_SET);
110 MODULE_ERROR("fseek failed: %s", fname);
117 static unsigned char *__read_file(const char *fname)
122 unsigned char *vibe_buffer;
126 pf = fopen(fname, "rb");
128 MODULE_ERROR("fopen failed: %s", fname);
132 size = __get_size(pf, fname);
138 vibe_buffer = malloc(size);
141 MODULE_ERROR("buffer alloc failed");
145 status = fread(vibe_buffer, 1, size, pf);
146 if (status != size) {
147 MODULE_ERROR("fread failed: expect %d read %d", size, status);
157 static unsigned char* __convert_file_to_buffer(const char *file_name)
159 char fname[FILENAME_MAX];
162 __trim_name(file_name, fname, sizeof(fname));
163 status = __check_ext(fname);
165 MODULE_ERROR("__check_file faild");
169 return __read_file(fname);
172 static int __save_file(const unsigned char *vibe_buferf, int size, const char *file_name)
178 pf = fopen(file_name, "wb+");
180 MODULE_ERROR("To open file is failed");
181 return HAPTIC_MODULE_OPERATION_FAILED;
184 status = fwrite(vibe_buferf, 1, size, pf);
185 if (status != size) {
186 MODULE_ERROR("To write file is failed");
188 return HAPTIC_MODULE_OPERATION_FAILED;
193 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");
202 return HAPTIC_MODULE_OPERATION_FAILED;
210 static int __vibrate(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority)
217 status = __to_level(feedback, &level);
218 if (status != HAPTIC_MODULE_ERROR_NONE)
221 status = PlayBuffer(device_handle, vibe_buffer, iteration, level);
223 MODULE_ERROR("PlayHapticBuffer fail : %d", status);
224 return HAPTIC_MODULE_OPERATION_FAILED;
230 static void *_create_handle(void)
233 return ((getpid()<<16)|(time(NULL)+(i++)));
235 /* END of Static Function Section */
237 static int _get_device_count(int *count)
240 return HAPTIC_MODULE_INVALID_ARGUMENT;
242 *count = DEFAULT_MOTOR_COUNT;
243 return HAPTIC_MODULE_ERROR_NONE;
246 static int _open_device(int device_index, int *device_handle)
251 if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL)
252 return HAPTIC_MODULE_INVALID_ARGUMENT;
254 if (device_handle == NULL)
255 return HAPTIC_MODULE_INVALID_ARGUMENT;
257 handle = _create_handle();
258 status = OpenDevice(handle);
260 MODULE_ERROR("OpenHapticDevice fail :%d", status);
261 return HAPTIC_MODULE_OPERATION_FAILED;
264 *device_handle = handle;
265 return HAPTIC_MODULE_ERROR_NONE;
268 static int _close_device(int device_handle)
272 if (device_handle < 0)
273 return HAPTIC_MODULE_INVALID_ARGUMENT;
275 status = CloseDevice(device_handle);
277 MODULE_ERROR("CloseHapticDevice fail : %d", status);
278 return HAPTIC_MODULE_OPERATION_FAILED;
281 return HAPTIC_MODULE_ERROR_NONE;
284 static int _vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
289 if (device_handle < 0)
290 return HAPTIC_MODULE_INVALID_ARGUMENT;
293 return HAPTIC_MODULE_INVALID_ARGUMENT;
295 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
296 return HAPTIC_MODULE_INVALID_ARGUMENT;
298 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
299 return HAPTIC_MODULE_INVALID_ARGUMENT;
301 if (effect_handle == NULL)
302 return HAPTIC_MODULE_INVALID_ARGUMENT;
304 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
305 return HAPTIC_MODULE_ERROR_NONE;
307 status = __to_level(feedback, &level);
308 if (status != HAPTIC_MODULE_ERROR_NONE)
311 status = PlayOneshot(device_handle, duration, level);
313 MODULE_ERROR("PlayOneshot fail : %d", status);
314 return HAPTIC_MODULE_OPERATION_FAILED;
317 *effect_handle = DEFAULT_EFFECT_HANDLE;
318 return HAPTIC_MODULE_ERROR_NONE;
321 static int _vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle)
324 unsigned char *vibe_buffer;
326 if (device_handle < 0)
327 return HAPTIC_MODULE_INVALID_ARGUMENT;
329 if (file_path == NULL)
330 return HAPTIC_MODULE_INVALID_ARGUMENT;
332 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
333 return HAPTIC_MODULE_INVALID_ARGUMENT;
335 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
336 return HAPTIC_MODULE_INVALID_ARGUMENT;
338 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
339 return HAPTIC_MODULE_INVALID_ARGUMENT;
341 if (effect_handle == NULL)
342 return HAPTIC_MODULE_INVALID_ARGUMENT;
344 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
345 return HAPTIC_MODULE_ERROR_NONE;
347 vibe_buffer = __convert_file_to_buffer(file_path);
349 MODULE_ERROR("File load filed");
350 return HAPTIC_MODULE_OPERATION_FAILED;
353 status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
356 *effect_handle = DEFAULT_EFFECT_HANDLE;
360 static int _vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
364 if (device_handle < 0)
365 return HAPTIC_MODULE_INVALID_ARGUMENT;
367 if (vibe_buffer == NULL)
368 return HAPTIC_MODULE_INVALID_ARGUMENT;
370 if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE)
371 return HAPTIC_MODULE_INVALID_ARGUMENT;
373 if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX)
374 return HAPTIC_MODULE_INVALID_ARGUMENT;
376 if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH)
377 return HAPTIC_MODULE_INVALID_ARGUMENT;
379 if (effect_handle == NULL)
380 return HAPTIC_MODULE_INVALID_ARGUMENT;
382 if (feedback == HAPTIC_MODULE_FEEDBACK_MIN)
383 return HAPTIC_MODULE_ERROR_NONE;
385 status = __vibrate(device_handle, vibe_buffer, iteration, feedback, priority);
387 *effect_handle = DEFAULT_EFFECT_HANDLE;
391 static int _stop_effect(int device_handle, int effect_handle)
395 if (device_handle < 0)
396 return HAPTIC_MODULE_INVALID_ARGUMENT;
398 if (effect_handle < 0)
399 return HAPTIC_MODULE_INVALID_ARGUMENT;
401 status = Stop(device_handle);
403 MODULE_ERROR("StopHaptic fail : %d", status);
404 return HAPTIC_MODULE_OPERATION_FAILED;
407 return HAPTIC_MODULE_ERROR_NONE;
410 static int _stop_all_effects(int device_handle)
414 if (device_handle < 0)
415 return HAPTIC_MODULE_INVALID_ARGUMENT;
417 status = Stop(device_handle);
419 MODULE_ERROR("StopHaptic fail : %d", status);
420 return HAPTIC_MODULE_OPERATION_FAILED;
423 return HAPTIC_MODULE_ERROR_NONE;
426 static int _pause_effect(int device_handle, int effect_handle)
428 if (device_handle < 0)
429 return HAPTIC_MODULE_INVALID_ARGUMENT;
431 if (effect_handle < 0)
432 return HAPTIC_MODULE_INVALID_ARGUMENT;
434 MODULE_ERROR("This device is not supported this function(%s)", __func__);
435 return HAPTIC_MODULE_NOT_SUPPORTED;
438 static int _resume_effect(int device_handle, int effect_handle)
440 if (device_handle < 0)
441 return HAPTIC_MODULE_INVALID_ARGUMENT;
443 if (effect_handle < 0)
444 return HAPTIC_MODULE_INVALID_ARGUMENT;
446 MODULE_ERROR("This device is not supported this function(%s)", __func__);
447 return HAPTIC_MODULE_NOT_SUPPORTED;
450 static int _get_effect_state(int device_handle, int effect_handle, int *state)
455 if (device_handle < 0)
456 return HAPTIC_MODULE_INVALID_ARGUMENT;
458 if (effect_handle < 0)
459 return HAPTIC_MODULE_INVALID_ARGUMENT;
462 return HAPTIC_MODULE_INVALID_ARGUMENT;
464 status = GetState(device_handle, &cur_state);
466 MODULE_ERROR("GetState fail : %d", status);
467 return HAPTIC_MODULE_OPERATION_FAILED;
471 return HAPTIC_MODULE_ERROR_NONE;
474 static int _create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
480 if (vibe_buffer == NULL)
481 return HAPTIC_MODULE_INVALID_ARGUMENT;
484 return HAPTIC_MODULE_INVALID_ARGUMENT;
486 if (elem_arr == NULL)
487 return HAPTIC_MODULE_INVALID_ARGUMENT;
490 return HAPTIC_MODULE_INVALID_ARGUMENT;
492 status = InitializeBuffer(vibe_buffer, max_bufsize);
494 MODULE_ERROR("InitializeHapticBuffer fail: %d", status);
495 return HAPTIC_MODULE_OPERATION_FAILED;
498 MODULE_LOG("effect count : %d", max_elemcnt);
499 for (i = 0; i < max_elemcnt; ++i) {
500 elem.duration = elem_arr[i].haptic_duration;
501 elem.level = elem_arr[i].haptic_level;
502 MODULE_LOG("%d) duration : %d, level : %d", i, elem_arr[i].haptic_duration, elem_arr[i].haptic_level);
504 status = InsertElement(vibe_buffer, max_bufsize, &elem);
506 MODULE_ERROR("InsertHapticElement fail: %d", status);
507 return HAPTIC_MODULE_OPERATION_FAILED;
511 return HAPTIC_MODULE_ERROR_NONE;
514 static int _save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
519 if (vibe_buffer == NULL)
520 return HAPTIC_MODULE_INVALID_ARGUMENT;
523 return HAPTIC_MODULE_INVALID_ARGUMENT;
525 if (file_path == NULL)
526 return HAPTIC_MODULE_INVALID_ARGUMENT;
528 status = GetBufferSize(vibe_buffer, &size);
530 MODULE_ERROR("GetHapticBufferSize fail: %d", status);
531 return HAPTIC_MODULE_OPERATION_FAILED;
534 return __save_file(vibe_buffer, size, file_path);
537 static int _get_file_duration(int device_handle, const char *file_path, int *file_duration)
540 unsigned char *vibe_buffer;
543 if (device_handle < 0)
544 return HAPTIC_MODULE_INVALID_ARGUMENT;
546 if (file_path == NULL)
547 return HAPTIC_MODULE_INVALID_ARGUMENT;
549 if (file_duration == NULL)
550 return HAPTIC_MODULE_INVALID_ARGUMENT;
552 vibe_buffer = __convert_file_to_buffer(file_path);
554 MODULE_ERROR("File load filed");
555 return HAPTIC_MODULE_OPERATION_FAILED;
558 status = GetBufferDuration(vibe_buffer, &duration);
561 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
562 return HAPTIC_MODULE_OPERATION_FAILED;
565 *file_duration = duration;
566 return HAPTIC_MODULE_ERROR_NONE;
569 static int _get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
574 if (device_handle < 0)
575 return HAPTIC_MODULE_INVALID_ARGUMENT;
577 if (vibe_buffer == NULL)
578 return HAPTIC_MODULE_INVALID_ARGUMENT;
580 if (buffer_duration == NULL)
581 return HAPTIC_MODULE_INVALID_ARGUMENT;
583 status = GetBufferDuration(vibe_buffer, &duration);
585 MODULE_ERROR("GetHapticBufferDuration fail: %d", status);
586 return HAPTIC_MODULE_OPERATION_FAILED;
589 *buffer_duration = duration;
590 return HAPTIC_MODULE_ERROR_NONE;
593 static int _convert_binary (void)
595 MODULE_ERROR("This device is not supported this function(%s)", __func__);
596 return HAPTIC_MODULE_NOT_SUPPORTED;
599 static const haptic_plugin_interface haptic_plugin_tizen = {
600 .haptic_internal_get_device_count = _get_device_count,
601 .haptic_internal_open_device = _open_device,
602 .haptic_internal_close_device = _close_device,
603 .haptic_internal_vibrate_monotone = _vibrate_monotone,
604 .haptic_internal_vibrate_file = _vibrate_file,
605 .haptic_internal_vibrate_buffer = _vibrate_buffer,
606 .haptic_internal_stop_effect = _stop_effect,
607 .haptic_internal_stop_all_effects = _stop_all_effects,
608 .haptic_internal_pause_effect = _pause_effect,
609 .haptic_internal_resume_effect = _resume_effect,
610 .haptic_internal_get_effect_state = _get_effect_state,
611 .haptic_internal_create_effect = _create_effect,
612 .haptic_internal_save_effect = _save_effect,
613 .haptic_internal_get_file_duration = _get_file_duration,
614 .haptic_internal_get_buffer_duration = _get_buffer_duration,
615 .haptic_internal_convert_binary = _convert_binary,
619 const haptic_plugin_interface *get_haptic_plugin_interface()
621 return &haptic_plugin_tizen;