52e51b4a9ae6157b40a9c55351a522fc5674423a
[platform/core/system/haptic-module-tizen.git] / tizen / DEVICE / src / sysnoti.c
1 /*
2  * haptic-module-tizen
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
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
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <stdarg.h>
26 #include <errno.h>
27
28 #include "haptic_module_log.h"
29
30 #define HAPTIC_RETRY_READ_COUNT                 5
31 #define HAPTIC_PARAM_CNT                                3
32 #define HAPTIC_MAXSTR                                   100
33 #define HAPTIC_MAXARG                                   16
34 #define PREDEF_HAPTIC                                   "haptic"
35 #define SYSNOTI_SOCKET_PATH                             "/tmp/sn"
36
37 enum sysnoti_cmd {
38         ADD_HAPTIC_ACTION,
39         CALL_HAPTIC_ACTION,
40 };
41
42 struct sysnoti_type {
43         int pid;
44         int cmd;
45         char *type;
46         char *path;
47         int argc;
48         char *argv[HAPTIC_MAXARG];
49 };
50
51 static inline int __send_int(int fd, int val)
52 {
53         return write(fd, &val, sizeof(int));
54 }
55
56 static inline int __send_str(int fd, char *str)
57 {
58         int len;
59         int r;
60
61         if (str == NULL) {
62                 len = 0;
63                 r = write(fd, &len, sizeof(int));
64         } else {
65                 len = strlen(str);
66                 if (len > HAPTIC_MAXSTR)
67                         len = HAPTIC_MAXSTR;
68                 r = write(fd, &len, sizeof(int));
69                 r = write(fd, str, len);
70         }
71
72         return r;
73 }
74
75 static int __sysnoti_send(struct sysnoti_type *msg)
76 {
77         int sockfd;
78         int len;
79         struct sockaddr_un addr;
80         int retry_cnt;
81         int ret;
82         int i;
83         int r;
84
85         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
86         if (sockfd == -1) {
87                 MODULE_ERROR("socket create failed");
88                 return -1;
89         }
90
91         bzero(&addr, sizeof(addr));
92         addr.sun_family = AF_UNIX;
93         strncpy(addr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(addr.sun_path) - 1);
94         len = sizeof(addr);
95
96         if (connect(sockfd, (struct sockaddr *)&addr, len) < 0) {
97                 MODULE_ERROR("connect failed");
98                 close(sockfd);
99                 return -1;
100         }
101
102         __send_int(sockfd, msg->pid);
103         __send_int(sockfd, msg->cmd);
104         __send_str(sockfd, msg->type);
105         __send_str(sockfd, msg->path);
106         __send_int(sockfd, msg->argc);
107         for (i = 0; i < msg->argc; i++)
108                 __send_str(sockfd, msg->argv[i]);
109
110         retry_cnt = 0;
111         while ((r = read(sockfd, &ret, sizeof(int))) < 0) {
112
113                 if (errno != EINTR) {
114                         MODULE_LOG("read fail : %s(%d)", strerror(errno), errno);
115                         ret = -1;
116                         break;
117                 }
118
119                 if (retry_cnt == HAPTIC_RETRY_READ_COUNT) {
120                         MODULE_ERROR("retry(%d) fail", retry_cnt);
121                         ret = -1;
122                         break;
123                 }
124
125                 MODULE_ERROR("Re-read for error(EINTR)");
126                 ++retry_cnt;
127         }
128
129         close(sockfd);
130         return ret;
131 }
132
133 int __haptic_call_predef_action(const char *type, int num, ...)
134 {
135         struct sysnoti_type msg;
136         char *args;
137         va_list argptr;
138         int i;
139
140         if (type == NULL || num > HAPTIC_MAXARG) {
141                 errno = EINVAL;
142                 return -1;
143         }
144
145         msg.pid = getpid();
146         msg.cmd = CALL_HAPTIC_ACTION;
147         msg.type = (char *)type;
148         msg.path = NULL;
149         msg.argc = num;
150
151         va_start(argptr, num);
152         for (i = 0; i < num; i++) {
153                 args = va_arg(argptr, char *);
154                 msg.argv[i] = args;
155         }
156         va_end(argptr);
157
158         return __sysnoti_send(&msg);
159 }
160