Before send a packet, check the status of socket.
[platform/framework/web/data-provider-master.git] / src / event.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <errno.h>
20 #include <pthread.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26
27 #include <linux/input.h>
28
29 #include <Eina.h>
30 #include <Ecore.h>
31 #include <dlog.h>
32 #include <livebox-errno.h>
33
34 #include "util.h"
35 #include "debug.h"
36 #include "conf.h"
37 #include "event.h"
38
39 #define EVENT_CH        'e'
40
41 int errno;
42
43 static struct info {
44         pthread_t tid;
45         Eina_List *event_list;
46         int handle;
47         pthread_mutex_t event_list_lock;
48         int evt_pipe[PIPE_MAX];
49         int tcb_pipe[PIPE_MAX];
50         Ecore_Fd_Handler *event_handler;
51
52         int (*event_cb)(enum event_state state, struct event_data *event, void *data);
53         void *cbdata;
54
55         enum event_state event_state;
56         struct event_data event_data;
57
58         int x;
59         int y;
60 } s_info = {
61         .event_list = NULL,
62         .handle = -1,
63         .event_handler = NULL,
64
65         .event_cb = NULL,
66         .cbdata = NULL,
67
68         .event_state = EVENT_STATE_DEACTIVATE,
69
70         .event_data = {
71                 .x = 0,
72                 .y = 0,
73                 .device = -1,
74         },
75 };
76
77 HAPI int event_init(void)
78 {
79         int ret;
80         ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
81         if (ret != 0) {
82                 ErrPrint("Mutex: %s\n", strerror(ret));
83                 return LB_STATUS_ERROR_FAULT;
84         }
85         return LB_STATUS_SUCCESS;
86 }
87
88 HAPI int event_fini(void)
89 {
90         int ret;
91         ret = pthread_mutex_destroy(&s_info.event_list_lock);
92         if (ret != 0)
93                 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
94         return LB_STATUS_SUCCESS;
95 }
96
97 static inline int processing_input_event(struct input_event *event)
98 {
99         struct event_data *item;
100
101         switch (event->type) {
102         case EV_SYN:
103                 switch (event->code) {
104                 case SYN_REPORT:
105                         if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
106                                 /* Waiting full event packet */
107                                 break;
108                         }
109
110                         item = malloc(sizeof(*item));
111                         if (item) {
112                                 char event_ch;
113
114                                 memcpy(item, &s_info.event_data, sizeof(*item));
115
116                                 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
117                                 s_info.event_list = eina_list_append(s_info.event_list, item);
118                                 CRITICAL_SECTION_END(&s_info.event_list_lock);
119
120                                 event_ch = EVENT_CH;
121                                 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
122                                         ErrPrint("Unable to send an event: %s\n", strerror(errno));
123                                         return LB_STATUS_ERROR_IO;
124                                 }
125
126                                 /* Take a breathe */
127                                 pthread_yield();
128                         }
129                         break;
130                 case SYN_CONFIG:
131                         break;
132                 case SYN_MT_REPORT:
133                         break;
134                 /*
135                 case SYN_DROPPED:
136                         DbgPrint("EV_SYN, SYN_DROPPED\n");
137                         break;
138                 */
139                 default:
140                         DbgPrint("EV_SYN, 0x%x\n", event->code);
141                         break;
142                 }
143                 break;
144         case EV_KEY:
145                 break;
146         case EV_REL:
147                 break;
148         case EV_ABS:
149                 switch (event->code) {
150                 case ABS_DISTANCE:
151                         break;
152                 case ABS_MT_POSITION_X:
153                         s_info.event_data.x = event->value - s_info.x;
154                         break;
155                 case ABS_MT_POSITION_Y:
156                         s_info.event_data.y = event->value - s_info.y;
157                         break;
158                 case ABS_MT_SLOT:
159                         break;
160                 case ABS_MT_TRACKING_ID:
161                         s_info.event_data.device = event->value;
162                         break;
163                 case ABS_MT_TOUCH_MAJOR:
164                         break;
165                 case ABS_MT_TOUCH_MINOR:
166                         break;
167                 case ABS_MT_WIDTH_MAJOR:
168                         break;
169                 case ABS_MT_WIDTH_MINOR:
170                         break;
171                 default:
172                         DbgPrint("EV_ABS, 0x%x\n", event->code);
173                         break;
174                 }
175                 break;
176         case EV_MSC:
177                 break;
178         case EV_SW:
179                 break;
180         case EV_LED:
181                 break;
182         case EV_SND:
183                 break;
184         case EV_REP:
185                 break;
186         case EV_FF:
187                 break;
188         case EV_PWR:
189                 break;
190         case EV_FF_STATUS:
191                 break;
192         default:
193                 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
194                 break;
195         }
196
197         return LB_STATUS_SUCCESS;
198 }
199
200 static void *event_thread_main(void *data)
201 {
202         fd_set set;
203         int ret = 0;
204         struct input_event input_event;
205         char *ptr = (char *)&input_event;
206         int offset = 0;
207         int readsize = 0;
208         int fd;
209
210         DbgPrint("Initiated\n");
211
212         while (1) {
213                 FD_ZERO(&set);
214                 FD_SET(s_info.handle, &set);
215                 FD_SET(s_info.tcb_pipe[PIPE_READ], &set);
216
217                 fd = s_info.handle > s_info.tcb_pipe[PIPE_READ] ? s_info.handle : s_info.tcb_pipe[PIPE_READ];
218                 ret = select(fd + 1, &set, NULL, NULL, NULL);
219                 if (ret < 0) {
220                         ret = -errno;
221                         if (errno == EINTR) {
222                                 DbgPrint("Select receives INTR\n");
223                                 continue;
224                         }
225                         ErrPrint("Error: %s\n", strerror(errno));
226                         break;
227                 } else if (ret == 0) {
228                         ErrPrint("Timeout expired\n");
229                         ret = LB_STATUS_ERROR_TIMEOUT;
230                         break;
231                 }
232
233                 if (FD_ISSET(s_info.handle, &set)) {
234                         readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
235                         if (readsize < 0) {
236                                 ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
237                                 ret = LB_STATUS_ERROR_FAULT;
238                                 break;
239                         }
240
241                         offset += readsize;
242                         if (offset == sizeof(input_event)) {
243                                 offset = 0;
244                                 if (processing_input_event(&input_event) < 0) {
245                                         ret = LB_STATUS_ERROR_FAULT;
246                                         break;
247                                 }
248                         }
249                 }
250
251                 if (FD_ISSET(s_info.tcb_pipe[PIPE_READ], &set)) {
252                         char event_ch;
253
254                         if (read(s_info.tcb_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch))
255                                 ErrPrint("Unable to read TCB_PIPE: %s\n", strerror(errno));
256
257                         ret = LB_STATUS_ERROR_CANCEL;
258                         break;
259                 }
260         }
261
262         return (void *)ret;
263 }
264
265 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
266 {
267         int fd;
268         struct event_data *item;
269         char event_ch;
270
271         fd = ecore_main_fd_handler_fd_get(handler);
272         if (fd < 0) {
273                 ErrPrint("Invalid fd\n");
274                 return ECORE_CALLBACK_CANCEL;
275         }
276
277         if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
278                 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
279                 return ECORE_CALLBACK_CANCEL;
280         }
281
282         CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
283         item = eina_list_nth(s_info.event_list, 0);
284         if (item)
285                 s_info.event_list = eina_list_remove(s_info.event_list, item);
286         else
287                 ErrPrint("Unable to get event\n");
288         CRITICAL_SECTION_END(&s_info.event_list_lock);
289
290         if (item && s_info.event_cb) {
291                 switch (s_info.event_state) {
292                 case EVENT_STATE_DEACTIVATE:
293                         s_info.event_state = EVENT_STATE_ACTIVATE;
294                         break;
295                 case EVENT_STATE_ACTIVATE:
296                         s_info.event_state = EVENT_STATE_ACTIVATED;
297                         break;
298                 case EVENT_STATE_ACTIVATED:
299                 default:
300                         break;
301                 }
302                 s_info.event_cb(s_info.event_state, item, s_info.cbdata);
303         }
304
305         free(item);
306         return ECORE_CALLBACK_RENEW;
307 }
308
309 /*!
310  * x, y is the starting point.
311  */
312 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
313 {
314         int status;
315
316         if (s_info.handle >= 0) {
317                 DbgPrint("Already activated\n");
318                 return LB_STATUS_SUCCESS;
319         }
320
321         s_info.handle = open(INPUT_PATH, O_RDONLY);
322         if (s_info.handle < 0) {
323                 ErrPrint("Unable to access the device: %s\n", strerror(errno));
324                 return LB_STATUS_ERROR_IO;
325         }
326
327         if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0)
328                 ErrPrint("Error: %s\n", strerror(errno));
329
330         if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0)
331                 ErrPrint("Error: %s\n", strerror(errno));
332
333         status = pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC);
334         if (status < 0) {
335                 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
336                 if (close(s_info.handle) < 0)
337                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
338                 s_info.handle = -1;
339                 return LB_STATUS_ERROR_FAULT;
340         }
341
342         status = pipe2(s_info.tcb_pipe, O_NONBLOCK | O_CLOEXEC);
343         if (status < 0) {
344                 ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
345                 if (close(s_info.handle) < 0)
346                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
347                 s_info.handle = -1;
348                 CLOSE_PIPE(s_info.evt_pipe);
349                 return LB_STATUS_ERROR_FAULT;
350         }
351
352         s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
353         if (!s_info.event_handler) {
354                 if (close(s_info.handle) < 0)
355                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
356                 s_info.handle = -1;
357
358                 CLOSE_PIPE(s_info.tcb_pipe);
359                 CLOSE_PIPE(s_info.evt_pipe);
360                 return LB_STATUS_ERROR_FAULT;
361         }
362
363         status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
364         if (status != 0) {
365                 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
366                 ecore_main_fd_handler_del(s_info.event_handler);
367                 s_info.event_handler = NULL;
368
369                 if (close(s_info.handle) < 0)
370                         ErrPrint("close: %s\n", strerror(errno));
371                 s_info.handle = -1;
372
373                 CLOSE_PIPE(s_info.tcb_pipe);
374                 CLOSE_PIPE(s_info.evt_pipe);
375                 return LB_STATUS_ERROR_FAULT;
376         }
377
378         s_info.event_cb = event_cb;
379         s_info.cbdata = data;
380         s_info.x = x;
381         s_info.y = y;
382
383         DbgPrint("Event handler activated\n");
384         return LB_STATUS_SUCCESS;
385 }
386
387 HAPI int event_deactivate(void)
388 {
389         int status;
390         struct event_data *event;
391         void *ret;
392         char event_ch = EVENT_CH;
393
394         if (s_info.handle < 0) {
395                 ErrPrint("Event handler is not actiavated\n");
396                 return LB_STATUS_SUCCESS;
397         }
398
399         if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch))
400                 ErrPrint("Unable to write tcb_pipe: %s\n", strerror(errno));
401
402         status = pthread_join(s_info.tid, &ret);
403         if (status != 0)
404                 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
405         else
406                 DbgPrint("Thread returns: %d\n", (int)ret);
407
408         ecore_main_fd_handler_del(s_info.event_handler);
409         s_info.event_handler = NULL;
410
411         if (close(s_info.handle) < 0)
412                 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
413
414         s_info.handle = -1;
415         DbgPrint("Event handler deactivated\n");
416
417         CLOSE_PIPE(s_info.tcb_pipe);
418         CLOSE_PIPE(s_info.evt_pipe);
419
420         EINA_LIST_FREE(s_info.event_list, event) {
421                 if (s_info.event_cb) {
422                         if (s_info.event_state == EVENT_STATE_DEACTIVATE) {
423                                 s_info.event_state = EVENT_STATE_ACTIVATE;
424                         } else if (s_info.event_state == EVENT_STATE_ACTIVATE) {
425                                 s_info.event_state = EVENT_STATE_ACTIVATED;
426                         }
427                         s_info.event_cb(s_info.event_state, event, s_info.cbdata);
428                 }
429                 free(event);
430         }
431
432         if (s_info.event_state != EVENT_STATE_DEACTIVATE) {
433                 s_info.event_state = EVENT_STATE_DEACTIVATE;
434
435                 if (s_info.event_cb)
436                         s_info.event_cb(s_info.event_state, &s_info.event_data, s_info.cbdata);
437         }
438
439         s_info.event_data.x = -1;
440         s_info.event_data.y = -1;
441         return LB_STATUS_SUCCESS;
442 }
443
444 HAPI int event_is_activated(void)
445 {
446         return s_info.handle >= 0;
447 }
448
449 /* End of a file */