Tizen 2.1 base
[platform/core/system/libslp-sysman.git] / sysnoti.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <vconf.h>
26 #include <vconf-keys.h>
27
28 #include "sysman.h"
29 #include "sysman-priv.h"
30
31 #define PREDEF_PWROFF_POPUP                     "pwroff-popup"
32 #define PREDEF_ENTERSLEEP                       "entersleep"
33 #define PREDEF_LEAVESLEEP                       "leavesleep"
34 #define PREDEF_REBOOT                           "reboot"
35 #define PREDEF_BACKGRD                          "backgrd"
36 #define PREDEF_FOREGRD                          "foregrd"
37 #define PREDEF_ACTIVE                           "active"
38 #define PREDEF_INACTIVE                         "inactive"
39 #define PREDEF_SET_DATETIME                     "set_datetime"
40 #define PREDEF_SET_TIMEZONE                     "set_timezone"
41 #define PREDEF_MOUNT_MMC                        "mountmmc"
42 #define PREDEF_UNMOUNT_MMC                      "unmountmmc"
43 #define PREDEF_FORMAT_MMC                       "formatmmc"
44
45 #define PREDEF_SET_MAX_FREQUENCY                "set_max_frequency"
46 #define PREDEF_SET_MIN_FREQUENCY                "set_min_frequency"
47 #define PREDEF_RELEASE_MAX_FREQUENCY            "release_max_frequency"
48 #define PREDEF_RELEASE_MIN_FREQUENCY            "release_min_frequency"
49
50 enum sysnoti_cmd {
51         ADD_SYSMAN_ACTION,
52         CALL_SYSMAN_ACTION
53 };
54
55 #define SYSNOTI_SOCKET_PATH "/tmp/sn"
56
57 static inline int send_int(int fd, int val)
58 {
59         return write(fd, &val, sizeof(int));
60 }
61
62 static inline int send_str(int fd, char *str)
63 {
64         int len;
65         int ret;
66         if (str == NULL) {
67                 len = 0;
68                 ret = write(fd, &len, sizeof(int));
69         } else {
70                 len = strlen(str);
71                 if (len > SYSMAN_MAXSTR)
72                         len = SYSMAN_MAXSTR;
73                 write(fd, &len, sizeof(int));
74                 ret = write(fd, str, len);
75         }
76         return ret;
77 }
78
79 static int sysnoti_send(struct sysnoti *msg)
80 {
81         ERR("--- %s: start", __FUNCTION__);
82         int client_len;
83         int client_sockfd;
84         int result;
85         struct sockaddr_un clientaddr;
86         int i;
87
88         client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
89         if (client_sockfd == -1) {
90                 ERR("%s: socket create failed\n", __FUNCTION__);
91                 return -1;
92         }
93         bzero(&clientaddr, sizeof(clientaddr));
94         clientaddr.sun_family = AF_UNIX;
95         strncpy(clientaddr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1);
96         client_len = sizeof(clientaddr);
97
98         if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) <
99             0) {
100                 ERR("%s: connect failed\n", __FUNCTION__);
101                 close(client_sockfd);
102                 return -1;
103         }
104
105         send_int(client_sockfd, msg->pid);
106         send_int(client_sockfd, msg->cmd);
107         send_str(client_sockfd, msg->type);
108         send_str(client_sockfd, msg->path);
109         send_int(client_sockfd, msg->argc);
110         for (i = 0; i < msg->argc; i++)
111                 send_str(client_sockfd, msg->argv[i]);
112
113         ERR("--- %s: read", __FUNCTION__);
114         read(client_sockfd, &result, sizeof(int));
115
116         close(client_sockfd);
117         ERR("--- %s: end", __FUNCTION__);
118         return result;
119 }
120
121 API int sysman_call_predef_action(const char *type, int num, ...)
122 {
123         ERR("--- %s: start", __FUNCTION__);
124         struct sysnoti *msg;
125         int ret;
126         va_list argptr;
127
128         int i;
129         char *args = NULL;
130
131         if (type == NULL || num > SYSMAN_MAXARG) {
132                 errno = EINVAL;
133                 return -1;
134         }
135
136         msg = malloc(sizeof(struct sysnoti));
137
138         if (msg == NULL) {
139                 /* Do something for not enought memory error */
140                 return -1;
141         }
142
143         msg->pid = getpid();
144         msg->cmd = CALL_SYSMAN_ACTION;
145         msg->type = (char *)type;
146         msg->path = NULL;
147
148         msg->argc = num;
149         va_start(argptr, num);
150         for (i = 0; i < num; i++) {
151                 args = va_arg(argptr, char *);
152                 msg->argv[i] = args;
153         }
154         va_end(argptr);
155
156         ERR("--- %s: send msg", __FUNCTION__);
157         ret = sysnoti_send(msg);
158         free(msg);
159
160         ERR("--- %s: end", __FUNCTION__);
161         return ret;
162 }
163
164 API int sysman_inform_foregrd(void)
165 {
166         char buf[255];
167         snprintf(buf, sizeof(buf), "%d", getpid());
168         return sysman_call_predef_action(PREDEF_FOREGRD, 1, buf);
169 }
170
171 API int sysman_inform_backgrd(void)
172 {
173         char buf[255];
174         snprintf(buf, sizeof(buf), "%d", getpid());
175         return sysman_call_predef_action(PREDEF_BACKGRD, 1, buf);
176 }
177
178 API int sysman_inform_active(pid_t pid)
179 {
180         char buf[255];
181         snprintf(buf, sizeof(buf), "%d", pid);
182         return sysman_call_predef_action(PREDEF_ACTIVE, 1, buf);
183 }
184
185 API int sysman_inform_inactive(pid_t pid)
186 {
187         char buf[255];
188         snprintf(buf, sizeof(buf), "%d", pid);
189         return sysman_call_predef_action(PREDEF_INACTIVE, 1, buf);
190 }
191
192 API int sysman_request_poweroff(void)
193 {
194         return sysman_call_predef_action(PREDEF_PWROFF_POPUP, 0);
195 }
196
197 API int sysman_request_entersleep(void)
198 {
199         return sysman_call_predef_action(PREDEF_ENTERSLEEP, 0);
200 }
201
202 API int sysman_request_leavesleep(void)
203 {
204         return sysman_call_predef_action(PREDEF_LEAVESLEEP, 0);
205 }
206
207 API int sysman_request_reboot(void)
208 {
209         return sysman_call_predef_action(PREDEF_REBOOT, 0);
210 }
211
212 API int sysman_set_datetime(time_t timet)
213 {
214         if (timet < 0L)
215                 return -1;
216         char buf[255] = { 0 };
217         snprintf(buf, sizeof(buf), "%ld", timet);
218         return sysman_call_predef_action(PREDEF_SET_DATETIME, 1, buf);
219 }
220
221 API int sysman_set_timezone(char *tzpath_str)
222 {
223         if (tzpath_str == NULL)
224                 return -1;
225         char buf[255];
226         snprintf(buf, sizeof(buf), "%s", tzpath_str);
227         return sysman_call_predef_action(PREDEF_SET_TIMEZONE, 1, buf);
228 }
229
230 static int sysnoti_mount_mmc_cb(keynode_t *key_nodes, void *data)
231 {
232         struct mmc_contents *mmc_data;
233         mmc_data = (struct mmc_contents *)data;
234         DBG("mountmmc_cb called");
235         if (vconf_keynode_get_int(key_nodes) ==
236             VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED) {
237                 DBG("mount ok");
238                 (mmc_data->mmc_cb)(0, mmc_data->user_data); 
239         } else if (vconf_keynode_get_int(key_nodes) ==
240                    VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY) {
241                 DBG("mount already");
242                 (mmc_data->mmc_cb)(-2, mmc_data->user_data); 
243         } else {
244                 DBG("mount fail");
245                 (mmc_data->mmc_cb)(-1, mmc_data->user_data); 
246         }
247         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_MOUNT,
248                                  (void *)sysnoti_mount_mmc_cb);
249         return 0;
250 }
251
252 API int sysman_request_mount_mmc(struct mmc_contents *mmc_data)
253 {
254         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
255                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_MOUNT,
256                                          (void *)sysnoti_mount_mmc_cb, (void *)mmc_data);
257         return sysman_call_predef_action(PREDEF_MOUNT_MMC, 0);
258 }
259
260 static int sysnoti_unmount_mmc_cb(keynode_t *key_nodes, void *data)
261 {
262         struct mmc_contents *mmc_data;
263         mmc_data = (struct mmc_contents *)data;
264         DBG("unmountmmc_cb called");
265         if (vconf_keynode_get_int(key_nodes) ==
266             VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED) {
267                 DBG("unmount ok");
268                 (mmc_data->mmc_cb)(0, mmc_data->user_data); 
269         } else {
270                 DBG("unmount fail");
271                 (mmc_data->mmc_cb)(-1, mmc_data->user_data); 
272         }
273         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_UNMOUNT,
274                                  (void *)sysnoti_unmount_mmc_cb);
275         return 0;
276 }
277
278 API int sysman_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
279 {
280         char buf[255];
281         if (option != 1 && option != 2) {
282                 DBG("option is wrong. default option 1 will be used");
283                 option = 1;
284         }
285         snprintf(buf, sizeof(buf), "%d", option);
286
287         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
288                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_UNMOUNT,
289                                          (void *)sysnoti_unmount_mmc_cb,
290                                          (void *)mmc_data);
291         return sysman_call_predef_action(PREDEF_UNMOUNT_MMC, 1, buf);
292 }
293
294 static int sysnoti_format_mmc_cb(keynode_t *key_nodes, void *data)
295 {
296         struct mmc_contents *mmc_data;
297         mmc_data = (struct mmc_contents *)data;
298         DBG("format_cb called");
299         if (vconf_keynode_get_int(key_nodes) ==
300             VCONFKEY_SYSMAN_MMC_FORMAT_COMPLETED) {
301                 DBG("format ok");
302                 (mmc_data->mmc_cb)(0, mmc_data->user_data); 
303
304         } else {
305                 DBG("format fail");
306                 (mmc_data->mmc_cb)(-1, mmc_data->user_data); 
307         }
308         vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_FORMAT,
309                                  (void *)sysnoti_format_mmc_cb);
310         return 0;
311 }
312
313 API int sysman_request_format_mmc(struct mmc_contents *mmc_data)
314 {
315         if (mmc_data != NULL && mmc_data->mmc_cb != NULL)
316                 vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_FORMAT,
317                                          (void *)sysnoti_format_mmc_cb,
318                                          (void *)mmc_data);
319         return sysman_call_predef_action(PREDEF_FORMAT_MMC, 0);
320 }
321
322 API int sysman_request_set_cpu_max_frequency(int val)
323 {
324         char buf_pid[8];
325         char buf_freq[256];
326         
327         // to do - need to check new frequncy is valid
328         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
329         snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
330
331         return sysman_call_predef_action(PREDEF_SET_MAX_FREQUENCY, 2, buf_pid, buf_freq);
332 }
333
334 API int sysman_request_set_cpu_min_frequency(int val)
335 {
336         char buf_pid[8];
337         char buf_freq[256];
338         
339         // to do - need to check new frequncy is valid
340         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
341         snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
342
343         return sysman_call_predef_action(PREDEF_SET_MIN_FREQUENCY, 2, buf_pid, buf_freq);
344 }
345
346 API int sysman_release_cpu_max_frequency()
347 {
348         char buf_pid[8];
349         
350         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
351         
352         return sysman_call_predef_action(PREDEF_RELEASE_MAX_FREQUENCY, 1, buf_pid);
353 }
354
355 API int sysman_release_cpu_min_frequency()
356 {
357         char buf_pid[8];
358         
359         snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
360
361         return sysman_call_predef_action(PREDEF_RELEASE_MIN_FREQUENCY, 1, buf_pid);
362 }