Parse and vibrate using standard pattern
[platform/core/system/feedbackd.git] / src / haptic / standard.c
1 /*
2  * feedbackd
3  *
4  * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29 #include <dirent.h>
30 #include <linux/input.h>
31
32 #include "core/log.h"
33 #include "core/list.h"
34 #include "haptic.h"
35 #include "standard-vibcore.h"
36
37 #define MAX_MAGNITUDE                   0xFFFF
38 #define PERIODIC_MAX_MAGNITUDE  0x7FFF  /* 0.5 * MAX_MAGNITUDE */
39 #define RUMBLE_MAX_MAGNITUDE    0xFFFF
40
41 #define DEV_INPUT   "/dev/input"
42 #define EVENT           "event"
43
44 #define MAX_DATA 16
45 #define FF_INFO_MAGIC 0xDEADFEED
46
47 struct ff_info_header {
48         unsigned int magic;
49         int iteration;
50         int ff_info_data_count;
51 };
52
53 struct ff_info_data {
54         int type;/* play, stop etc */
55         int magnitude; /* strength */
56         int length; /* in ms for stop, play*/
57 };
58
59 struct ff_info_buffer {
60         struct ff_info_header header;
61         struct ff_info_data data[MAX_DATA];
62 };
63
64 struct ff_info {
65         int handle;
66         guint timer;
67         struct ff_effect effect;
68         struct ff_info_buffer *ffinfobuffer;
69         int currentindex;
70 };
71
72 static int ff_fd;
73 static dd_list *ff_list;
74 static dd_list *handle_list;
75 static char ff_path[PATH_MAX];
76 static int unique_number;
77
78 struct ff_info *read_from_list(int handle)
79 {
80         struct ff_info *temp;
81         dd_list *elem;
82
83         DD_LIST_FOREACH(ff_list, elem, temp) {
84                 if (temp->handle == handle)
85                         return temp;
86         }
87         return NULL;
88 }
89
90 static bool check_valid_handle(struct ff_info *info)
91 {
92         struct ff_info *temp;
93         dd_list *elem;
94
95         DD_LIST_FOREACH(ff_list, elem, temp) {
96                 if (temp == info)
97                         break;
98         }
99
100         if (!temp)
101                 return false;
102         return true;
103 }
104
105 static bool check_fd(int *fd)
106 {
107         int ffd;
108
109         if (*fd > 0)
110                 return true;
111
112         ffd = open(ff_path, O_RDWR);
113         if (ffd < 0)
114                 return false;
115
116         *fd = ffd;
117         return true;
118 }
119
120 static int ff_stop(int fd, struct ff_effect *effect);
121 static gboolean timer_cb(void *data)
122 {
123         struct ff_info *info = (struct ff_info *)data;
124
125         if (!info)
126                 return G_SOURCE_REMOVE;
127
128         if (!check_valid_handle(info))
129                 return G_SOURCE_REMOVE;
130
131         _I("stop vibration by timer : id(%d)", info->effect.id);
132
133         /* stop previous vibration */
134         ff_stop(ff_fd, &info->effect);
135
136         /* reset timer */
137         info->timer = 0;
138
139         return G_SOURCE_REMOVE;
140 }
141
142 static int ff_find_device(void)
143 {
144         DIR *dir;
145         struct dirent *dent;
146         char ev_path[PATH_MAX];
147         unsigned long features[1+FF_MAX/sizeof(unsigned long)];
148         int fd, ret;
149
150         dir = opendir(DEV_INPUT);
151         if (!dir)
152                 return -errno;
153
154         while (1) {
155                 dent = readdir(dir);
156                 if (dent == NULL)
157                         break;
158
159                 if (dent->d_type == DT_DIR ||
160                         !strstr(dent->d_name, "event"))
161                         continue;
162
163                 snprintf(ev_path, sizeof(ev_path), "%s/%s", DEV_INPUT, dent->d_name);
164
165                 fd = open(ev_path, O_RDWR);
166                 if (fd < 0)
167                         continue;
168
169                 /* get force feedback device */
170                 memset(features, 0, sizeof(features));
171                 ret = ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features);
172                 if (ret == -1) {
173                         close(fd);
174                         continue;
175                 }
176
177                 if (test_bit(FF_CONSTANT, features))
178                         _D("%s type : constant", ev_path);
179                 if (test_bit(FF_PERIODIC, features))
180                         _D("%s type : periodic", ev_path);
181                 if (test_bit(FF_SPRING, features))
182                         _D("%s type : spring", ev_path);
183                 if (test_bit(FF_FRICTION, features))
184                         _D("%s type : friction", ev_path);
185                 if (test_bit(FF_RUMBLE, features))
186                         _D("%s type : rumble", ev_path);
187
188                 if (test_bit(FF_RUMBLE, features)) {
189                         memcpy(ff_path, ev_path, strlen(ev_path));
190                         close(fd);
191                         closedir(dir);
192                         return 0;
193                 }
194
195                 close(fd);
196         }
197
198         closedir(dir);
199         return -1;
200 }
201
202 static int ff_init_effect(struct ff_effect *effect)
203 {
204         if (!effect)
205                 return -EINVAL;
206
207         /*Only rumble supported as of now*/
208         effect->type = FF_RUMBLE;
209         effect->replay.length = 0;
210         effect->replay.delay = 10;
211         effect->id = -1;
212         effect->u.rumble.strong_magnitude = 0x8000;
213         effect->u.rumble.weak_magnitude = 0xc000;
214
215         return 0;
216 }
217
218 static int ff_set_effect(struct ff_effect *effect, int length, int level)
219 {
220         double magnitude;
221
222         if (!effect)
223                 return -EINVAL;
224
225         magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX;
226         magnitude *= RUMBLE_MAX_MAGNITUDE;
227
228         _I("info : magnitude(%d) length(%d)", (int)magnitude, length);
229
230         /* set member variables in effect struct */
231         effect->u.rumble.strong_magnitude = (int)magnitude;
232         effect->replay.length = length;         /* length millisecond */
233
234         return 0;
235 }
236
237 static int ff_play(int fd, struct ff_effect *effect)
238 {
239         struct input_event play;
240         int ret;
241
242         if (fd < 0 || !effect) {
243                 if (fd < 0)
244                         _E("fail to check fd");
245                 else
246                         _E("fail to check effect");
247                 return -EINVAL;
248         }
249
250         /* upload an effect */
251         if (ioctl(fd, EVIOCSFF, effect) == -1) {
252                 _E("fail to ioctl");
253                 return -errno;
254         }
255
256         /* play vibration*/
257         play.type = EV_FF;
258         play.code = effect->id;
259         play.value = 1; /* 1 : PLAY, 0 : STOP */
260
261         ret = write(fd, (const void *)&play, sizeof(play));
262         if (ret == -1) {
263                 _E("fail to write");
264                 return -errno;
265         }
266
267         return 0;
268 }
269
270 static int ff_stop(int fd, struct ff_effect *effect)
271 {
272         struct input_event stop;
273         int ret;
274
275         if (fd < 0)
276                 return -EINVAL;
277
278         /* Stop vibration */
279         stop.type = EV_FF;
280         stop.code = effect->id;
281         stop.value = 0; /* 1 : PLAY, 0 : STOP */
282         ret = write(fd, (const void *)&stop, sizeof(stop));
283         if (ret == -1)
284                 return -errno;
285
286         /* removing an effect from the device */
287         if (ioctl(fd, EVIOCRMFF, effect->id) == -1)
288                 return -errno;
289
290         /* reset effect id */
291         effect->id = -1;
292
293         return 0;
294 }
295
296 /* START: Haptic Module APIs */
297 static int get_device_count(int *count)
298 {
299         /* suppose there is just one haptic device */
300         if (count)
301                 *count = 1;
302
303         return 0;
304 }
305
306 static int open_device(int device_index, int *device_handle)
307 {
308         struct ff_info *info;
309         int n;
310         bool found = false;
311         dd_list *elem;
312
313         if (!device_handle)
314                 return -EINVAL;
315
316         /* if it is the first element */
317         n = DD_LIST_LENGTH(ff_list);
318         if (n == 0 && !ff_fd) {
319                 _I("First element: open ff driver");
320                 /* open ff driver */
321                 ff_fd = open(ff_path, O_RDWR);
322                 if (ff_fd < 0) {
323                         _E("Failed to open %s : %d", ff_path, errno);
324                         return -errno;
325                 }
326         }
327
328         /* allocate memory */
329         info = calloc(sizeof(struct ff_info), 1);
330         if (!info) {
331                 _E("Failed to allocate memory : %d", errno);
332                 return -errno;
333         }
334
335         /* initialize ff_effect structure */
336         ff_init_effect(&info->effect);
337
338         if (unique_number == INT_MAX)
339                 unique_number = 0;
340
341         while (found != true) {
342                 ++unique_number;
343                 elem = DD_LIST_FIND(handle_list, (gpointer)(long)unique_number);
344                 if (!elem)
345                         found = true;
346         }
347
348         info->handle = unique_number;
349
350         /* add info to local list */
351         DD_LIST_APPEND(ff_list, info);
352         DD_LIST_APPEND(handle_list, (gpointer)(long)info->handle);
353
354         *device_handle = info->handle;
355         return 0;
356 }
357
358 static int close_device(int device_handle)
359 {
360         struct ff_info *info;
361         int r, n;
362
363         info = read_from_list(device_handle);
364         if (!info)
365                 return -EINVAL;
366
367         if (!check_valid_handle(info))
368                 return -EINVAL;
369
370         if (!check_fd(&ff_fd))
371                 return -ENODEV;
372
373         /* stop vibration */
374         r = ff_stop(ff_fd, &info->effect);
375         if (r < 0)
376                 _I("already stopped or failed to stop effect : %d", r);
377
378         /* unregister existing timer */
379         if (r >= 0 && info->timer) {
380                 _D("device handle %d is closed and timer deleted", device_handle);
381                 g_source_remove(info->timer);
382                 info->timer = 0;
383         }
384
385         standard_vibrate_close();
386
387         DD_LIST_REMOVE(handle_list, (gpointer)(long)info->handle);
388
389         safe_free(info->ffinfobuffer);
390         /* remove info from local list */
391         DD_LIST_REMOVE(ff_list, info);
392         safe_free(info);
393
394         /* if it is the last element */
395         n = DD_LIST_LENGTH(ff_list);
396         if (n == 0 && ff_fd) {
397                 _I("Last element: close ff driver");
398                 /* close ff driver */
399                 close(ff_fd);
400                 ff_fd = 0;
401         }
402
403         return 0;
404 }
405
406 static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
407 {
408         struct ff_info *info;
409         int ret;
410
411         info = read_from_list(device_handle);
412         if (!info) {
413                 _E("fail to check list");
414                 return -EINVAL;
415         }
416
417         if (!check_valid_handle(info)) {
418                 _E("fail to check handle");
419                 return -EINVAL;
420         }
421
422         if (!check_fd(&ff_fd))
423                 return -ENODEV;
424
425         /* Zero(0) is the infinitely vibration value */
426         if (duration == HAPTIC_MODULE_DURATION_UNLIMITED)
427                 duration = 0;
428
429         /* unregister existing timer */
430         if (info->timer) {
431                 ff_stop(ff_fd, &info->effect);
432                 g_source_remove(info->timer);
433                 info->timer = 0;
434         }
435
436         /* set effect as per arguments */
437         ff_init_effect(&info->effect);
438         ret = ff_set_effect(&info->effect, duration, feedback);
439         if (ret < 0) {
440                 _E("failed to set effect(duration:%d, feedback:%d) : %d",
441                                 duration, feedback, ret);
442                 return ret;
443         }
444
445         /* play effect as per arguments */
446         ret = ff_play(ff_fd, &info->effect);
447         if (ret < 0) {
448                 _E("failed to play haptic effect(fd:%d id:%d) : %d",
449                                 ff_fd, info->effect.id, ret);
450                 return ret;
451         }
452
453         /* register timer */
454         if (duration) {
455                 info->timer = g_timeout_add(duration, timer_cb, info);
456                 if (!info->timer)
457                         _E("Failed to add timer callback");
458         }
459
460         _D("device handle %d effect id : %d %dms", device_handle, info->effect.id, duration);
461         if (effect_handle)
462                 *effect_handle = info->effect.id;
463
464         return 0;
465 }
466
467 static gboolean _buffer_play(void *cbdata)
468 {
469         struct ff_info *info = (struct ff_info *)cbdata;
470         struct ff_info_header *header = &info->ffinfobuffer->header;
471         struct ff_info_data   *data = info->ffinfobuffer->data;
472         int index = info->currentindex;
473         int play_type = (index < header->ff_info_data_count) ? data[index].type : 0;
474         int length = (index < header->ff_info_data_count) ? data[index].length : 1;
475         int ret;
476
477         ff_set_effect(&info->effect, length, 1);
478         if (play_type != 0) {
479                 _D("Going to play for %d ms", length);
480                 ret = ff_play(ff_fd, &info->effect);
481                 if (ret < 0)
482                         _D("Failed to play the effect %d", ret);
483         } else {
484                 _D("Going to stop for %d ms", length);
485                 ret = ff_stop(ff_fd, &info->effect);
486                 if (ret < 0)
487                         _D("Failed to stop the effect %d", ret);
488         }
489
490         if (info->currentindex < header->ff_info_data_count) {
491                 info->currentindex++;
492                 info->timer = g_timeout_add(length, _buffer_play, info);
493         } else {
494                 --header->iteration;
495                 if (header->iteration > 0) {
496                         info->currentindex = 0;
497                         info->timer = g_timeout_add(0, _buffer_play, info);
498                 } else
499                         info->timer = 0;
500         }
501
502         return G_SOURCE_REMOVE;
503 }
504
505 static void print_buffer(const unsigned char *vibe_buffer)
506 {
507         struct ff_info_buffer fb;
508         int i = 0;
509         memcpy(&fb.header, vibe_buffer, sizeof(struct ff_info_header));
510         memcpy(&fb.data, (unsigned char *)vibe_buffer+sizeof(struct ff_info_header),
511                         sizeof(struct ff_info_data) * fb.header.ff_info_data_count);
512         _D("\nMagic %x\niteration %d\ncount %d\n", fb.header.magic,
513                         fb.header.iteration, fb.header.ff_info_data_count);
514
515         for (i = 0; i < fb.header.ff_info_data_count; i++)
516                 _D("type %d\nmagn 0x%x\nlen %d\n", fb.data[i].type,
517                                 fb.data[i].magnitude, fb.data[i].length);
518 }
519
520 static int vibrate_custom_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
521 {
522         struct ff_info *info;
523         struct ff_info_header *header;
524         struct ff_info_data   *data;
525
526         info = read_from_list(device_handle);
527         if (!info)
528                 return -EINVAL;
529
530         if (!check_valid_handle(info))
531                 return -EINVAL;
532
533         if (!check_fd(&ff_fd))
534                 return -ENODEV;
535
536         if (!info->ffinfobuffer)
537                 info->ffinfobuffer = (struct ff_info_buffer *)calloc(sizeof(struct ff_info_buffer), 1);
538         if (!info->ffinfobuffer)
539                 return -ENOMEM;
540
541         header = &info->ffinfobuffer->header;
542         data = info->ffinfobuffer->data;
543
544         memcpy(header, vibe_buffer, sizeof(struct ff_info_header));
545         if (header->ff_info_data_count < 0 || header->ff_info_data_count > MAX_DATA)
546                 return -EINVAL;
547
548         memcpy(data, vibe_buffer+sizeof(struct ff_info_header), sizeof(struct ff_info_data) * header->ff_info_data_count);
549
550         info->currentindex = 0;
551         if (info->timer)
552                 g_source_remove(info->timer);
553
554         if (header->iteration > 0)
555                 _buffer_play(info);
556
557         return 0;
558 }
559
560 static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
561 {
562         int magic = 0;
563
564         if (!device_handle)
565                 return -EINVAL;
566
567         if (vibe_buffer)
568                 magic = *(int *)vibe_buffer;
569
570         if (magic == FF_INFO_MAGIC) {
571                 print_buffer(vibe_buffer);
572                 return vibrate_custom_buffer(device_handle, vibe_buffer, iteration, feedback, priority, effect_handle);
573         } else
574                 return vibrate_monotone(device_handle, 300, feedback, priority, effect_handle);
575 }
576
577 static int stop_device(int device_handle)
578 {
579         struct ff_info *info;
580         int r;
581
582         info = read_from_list(device_handle);
583         if (!info)
584                 return -EINVAL;
585
586         if (!check_valid_handle(info))
587                 return -EINVAL;
588
589         if (!check_fd(&ff_fd))
590                 return -ENODEV;
591
592         if (cur_h_data.handle > 0 && cur_h_data.handle != info->handle) {
593                 _E("Only same handle can stop current vibration");
594                 return -EPERM;
595         }
596
597         /* Remove duration_timer for vibrate_effect */
598         standard_vibrate_close();
599
600         /* stop effect */
601         r = ff_stop(ff_fd, &info->effect);
602         if (r < 0)
603                 _E("failed to stop effect(id:%d) : %d", info->effect.id, r);
604         else
605                 _D("succeed to stop effect");
606
607         /* unregister existing timer */
608         if (r >= 0 && info->timer) {
609                 g_source_remove(info->timer);
610                 info->timer = 0;
611         }
612
613         return 0;
614 }
615
616 static int get_device_state(int device_index, int *effect_state)
617 {
618         struct ff_info *info;
619         dd_list *elem;
620         int status = false;
621
622         if (!effect_state)
623                 return -EINVAL;
624
625         /* suppose there is just one haptic device */
626         DD_LIST_FOREACH(ff_list, elem, info) {
627                 if (info->effect.id >= 0) {
628                         status = true;
629                         break;
630                 }
631         }
632
633         *effect_state = status;
634         return 0;
635 }
636
637 static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt)
638 {
639         _E("Not support feature");
640         return -EACCES;
641 }
642
643 static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
644 {
645         _E("Not support feature");
646         return -EACCES;
647 }
648
649 static int convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
650 {
651         _E("Not support feature");
652         return -EACCES;
653 }
654 /* END: Haptic Module APIs */
655
656 static const struct haptic_plugin_ops default_plugin = {
657         .get_device_count    = get_device_count,
658         .open_device         = open_device,
659         .close_device        = close_device,
660         .vibrate_monotone    = vibrate_monotone,
661         .vibrate_buffer      = vibrate_buffer,
662         .vibrate_effect      = standard_vibrate_effect,
663         .is_supported        = standard_is_supported,
664         .stop_device         = stop_device,
665         .get_device_state    = get_device_state,
666         .create_effect       = create_effect,
667         .get_buffer_duration = get_buffer_duration,
668         .convert_binary      = convert_binary,
669 };
670
671 static bool is_valid(void)
672 {
673         int ret;
674
675         ret = ff_find_device();
676         if (ret < 0) {
677                 _E("Do not support standard haptic device");
678                 return false;
679         }
680
681         standard_config_parse();
682
683         _I("Support standard haptic device");
684         return true;
685 }
686
687 static const struct haptic_plugin_ops *load(void)
688 {
689         standard_set_vib_function(&vibrate_monotone);
690         return &default_plugin;
691 }
692
693 static const struct haptic_ops std_ops = {
694         .type     = HAPTIC_STANDARD,
695         .is_valid = is_valid,
696         .load     = load,
697 };
698
699 HAPTIC_OPS_REGISTER(&std_ops)