Apply coding rule
[platform/core/api/notification.git] / src / notification_ipc.c
1 /*
2  *  libnotification
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26
27 #include <vconf.h>
28
29 #include <packet.h>
30 #include <com-core.h>
31 #include <com-core_packet.h>
32
33 #include <notification_ipc.h>
34 #include <notification_db.h>
35 #include <notification_type.h>
36 #include <notification_private.h>
37 #include <notification_debug.h>
38 #include <notification_setting_internal.h>
39
40 #define NOTIFICATION_IPC_TIMEOUT 0.0
41
42 #if !defined(VCONFKEY_MASTER_STARTED)
43 #define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
44 #endif
45
46 static struct info {
47         int server_fd;
48         int server_cl_fd;
49         int server_cl_fd_ref_cnt;
50         int client_fd;
51         const char *socket_file;
52         struct {
53                 int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
54                 void *data;
55         } server_cb;
56         int initialized;
57         int is_started_cb_set_svc;
58         int is_started_cb_set_task;
59 } s_info = {
60         .server_fd = -1,
61         .server_cl_fd = -1,
62         .server_cl_fd_ref_cnt = 0,
63         .client_fd = -1,
64         .socket_file = NOTIFICATION_ADDR,
65         .initialized = 0,
66         .is_started_cb_set_svc = 0,
67         .is_started_cb_set_task = 0,
68 };
69
70 typedef struct _task_list task_list;
71 struct _task_list {
72         task_list *prev;
73         task_list *next;
74
75         void (*task_cb) (void *data);
76         void *data;
77 };
78
79 typedef struct _result_cb_item {
80         void (*result_cb)(int priv_id, int result, void *data);
81         void *data;
82 } result_cb_item;
83
84 static task_list *g_task_list;
85
86 static int notification_ipc_monitor_register(void);
87 static int notification_ipc_monitor_deregister(void);
88 static void _do_deffered_task(void);
89 static void _master_started_cb_task(keynode_t *node, void *data);
90
91 static inline char *_string_get(char *string)
92 {
93         if (string == NULL)
94                 return NULL;
95
96         if (string[0] == '\0')
97                 return NULL;
98
99         return string;
100 }
101
102 /*!
103  * functions to check state of master
104  */
105 static inline void _set_master_started_cb(vconf_callback_fn cb)
106 {
107         int ret = -1;
108
109         ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, cb, NULL);
110         if (ret != 0)
111                 NOTIFICATION_ERR("failed to notify key(%s) : %d",
112                                 VCONFKEY_MASTER_STARTED, ret);
113 }
114
115 static inline void _unset_master_started_cb(vconf_callback_fn cb)
116 {
117         int ret = -1;
118
119         ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, cb);
120         if (ret != 0)
121                 NOTIFICATION_ERR("failed to notify key(%s) : %d",
122                                 VCONFKEY_MASTER_STARTED, ret);
123 }
124
125 int notification_ipc_is_master_ready(void)
126 {
127         int ret = -1, is_master_started = 0;
128
129         ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
130         if (ret == 0 && is_master_started == 1) {
131                 NOTIFICATION_ERR("the master has been started");
132         } else {
133                 is_master_started = 0;
134                 NOTIFICATION_ERR("the master has been stopped");
135         }
136
137         return is_master_started;
138 }
139
140 int notification_ipc_add_deffered_task(
141                 void (*deferred_task_cb)(void *data),
142                 void *user_data)
143 {
144         task_list *list = NULL;
145         task_list *list_new = NULL;
146
147         list_new =
148             (task_list *) malloc(sizeof(task_list));
149
150         if (list_new == NULL)
151                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
152
153         if (s_info.is_started_cb_set_task == 0) {
154                 _set_master_started_cb(_master_started_cb_task);
155                 s_info.is_started_cb_set_task = 1;
156         }
157
158         list_new->next = NULL;
159         list_new->prev = NULL;
160
161         list_new->task_cb = deferred_task_cb;
162         list_new->data = user_data;
163
164         if (g_task_list == NULL) {
165                 g_task_list = list_new;
166         } else {
167                 list = g_task_list;
168
169                 while (list->next != NULL)
170                         list = list->next;
171
172
173                 list->next = list_new;
174                 list_new->prev = list;
175         }
176         return NOTIFICATION_ERROR_NONE;
177 }
178
179 int
180 notification_ipc_del_deffered_task(
181                 void (*deferred_task_cb)(void *data))
182 {
183         task_list *list_del = NULL;
184         task_list *list_prev = NULL;
185         task_list *list_next = NULL;
186
187         list_del = g_task_list;
188
189         if (list_del == NULL)
190                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
191
192
193         while (list_del->prev != NULL)
194                 list_del = list_del->prev;
195
196
197         do {
198                 if (list_del->task_cb == deferred_task_cb) {
199                         list_prev = list_del->prev;
200                         list_next = list_del->next;
201
202                         if (list_prev == NULL)
203                                 g_task_list = list_next;
204                         else
205                                 list_prev->next = list_next;
206
207                         if (list_next == NULL) {
208                                 if (list_prev != NULL)
209                                         list_prev->next = NULL;
210
211                         } else {
212                                 list_next->prev = list_prev;
213                         }
214
215                         free(list_del);
216
217                         if (g_task_list == NULL) {
218                                 if (s_info.is_started_cb_set_task == 1) {
219                                         _unset_master_started_cb(_master_started_cb_task);
220                                         s_info.is_started_cb_set_task = 0;
221                                 }
222                         }
223
224                         return NOTIFICATION_ERROR_NONE;
225                 }
226                 list_del = list_del->next;
227         } while (list_del != NULL);
228
229         return NOTIFICATION_ERROR_INVALID_PARAMETER;
230 }
231
232 static void _do_deffered_task(void)
233 {
234         task_list *list_do = NULL;
235         task_list *list_temp = NULL;
236
237         if (g_task_list == NULL)
238                 return;
239
240         list_do = g_task_list;
241         g_task_list = NULL;
242         if (s_info.is_started_cb_set_task == 1) {
243                 _unset_master_started_cb(_master_started_cb_task);
244                 s_info.is_started_cb_set_task = 0;
245         }
246
247         while (list_do->prev != NULL)
248                 list_do = list_do->prev;
249
250
251         while (list_do != NULL) {
252                 if (list_do->task_cb != NULL) {
253                         list_do->task_cb(list_do->data);
254                         NOTIFICATION_DBG("called:%p", list_do->task_cb);
255                 }
256                 list_temp = list_do->next;
257                 free(list_do);
258                 list_do = list_temp;
259         }
260 }
261
262 static void _master_started_cb_service(keynode_t *node,
263                 void *data) {
264         int ret = NOTIFICATION_ERROR_NONE;
265
266         if (notification_ipc_is_master_ready()) {
267                 NOTIFICATION_ERR("try to register a notification service");
268                 ret = notification_ipc_monitor_deregister();
269                 if (ret != NOTIFICATION_ERROR_NONE)
270                         NOTIFICATION_ERR("failed to unregister a monitor");
271
272                 ret = notification_ipc_monitor_register();
273                 if (ret != NOTIFICATION_ERROR_NONE)
274                         NOTIFICATION_ERR("failed to register a monitor");
275
276         } else {
277                 NOTIFICATION_ERR("try to unregister a notification service");
278                 ret = notification_ipc_monitor_deregister();
279                 if (ret != NOTIFICATION_ERROR_NONE)
280                         NOTIFICATION_ERR("failed to deregister a monitor");
281
282         }
283 }
284
285 static void _master_started_cb_task(keynode_t *node,
286                 void *data) {
287
288         if (notification_ipc_is_master_ready())
289                 _do_deffered_task();
290 }
291
292 /*!
293  * functions to create operation list
294  */
295 notification_op *notification_ipc_create_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
296 {
297         int i = 0;
298         notification_op *op_list = NULL;
299
300         if (num_op <= 0)
301                 return NULL;
302
303         op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
304
305         if (op_list == NULL) {
306                 NOTIFICATION_ERR("malloc failed");
307                 return NULL;
308         }
309
310         memset(op_list, 0x0, sizeof(notification_op) * num_op);
311
312         for (i = 0; i < num_op; i++) {
313                 (op_list + i)->type = type;
314                 if (list_priv_id != NULL)
315                         (op_list + i)->priv_id = *(list_priv_id + i);
316
317                 if (noti_list != NULL)
318                         (op_list + i)->noti = *(noti_list + i);
319         }
320
321         return op_list;
322 }
323
324 /*!
325  * utility functions creating notification packet
326  */
327 static inline char *_dup_string(const char *string)
328 {
329         char *ret;
330
331         if (string == NULL)
332                 return NULL;
333
334         if (string[0] == '\0')
335                 return NULL;
336
337         ret = strdup(string);
338         if (!ret)
339                 NOTIFICATION_ERR("Error: %s\n", strerror(errno));
340
341         return ret;
342 }
343
344 static inline bundle *_create_bundle_from_string(unsigned char *string)
345 {
346         if (string == NULL)
347                 return NULL;
348
349         if (string[0] == '\0')
350                 return NULL;
351
352         return bundle_decode(string, strlen((char *)string));
353 }
354
355 /*!
356  * functions creating notification packet
357  */
358 EXPORT_API int notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
359 {
360         int i = 0;
361         int ret = 0;
362         int type;
363         int layout;
364         int group_id;
365         int internal_group_id;
366         int priv_id;
367         char *caller_pkgname = NULL;
368         char *launch_pkgname = NULL;
369         unsigned char *args = NULL;
370         unsigned char *group_args = NULL;
371         unsigned char *b_execute_option = NULL;
372         unsigned char *b_service_responding = NULL;
373         unsigned char *b_service_single_launch = NULL;
374         unsigned char *b_service_multi_launch = NULL;
375         unsigned char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL, };
376         char *domain = NULL;
377         char *dir = NULL;
378         unsigned char *b_text = NULL;
379         unsigned char *b_key = NULL;
380         unsigned char *b_format_args = NULL;
381         int num_format_args;
382         unsigned char *b_image_path = NULL;
383         int sound_type;
384         char *sound_path = NULL;
385         int vibration_type;
386         char *vibration_path = NULL;
387         int led_operation;
388         int led_argb;
389         int led_on_ms;
390         int led_off_ms;
391         time_t time;
392         time_t insert_time;
393         int flags_for_property;
394         int display_applist;
395         double progress_size;
396         double progress_percentage;
397         char *app_icon_path = NULL;
398         char *app_name = NULL;
399         char *temp_title = NULL;
400         char *temp_content = NULL;
401         char *tag = NULL;
402         bool *ongoing_flag;
403         bool *auto_remove;
404
405         if (noti == NULL) {
406                 NOTIFICATION_ERR("invalid data");
407                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
408         }
409
410         ret = packet_get(packet,
411                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
412                         &type,
413                         &layout,
414                         &group_id,
415                         &internal_group_id,
416                         &priv_id,
417                         &caller_pkgname,
418                         &launch_pkgname,
419                         &args,
420                         &group_args,
421                         &b_execute_option,
422                         &b_service_responding,
423                         &b_service_single_launch,
424                         &b_service_multi_launch,
425                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1],
426                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2],
427                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3],
428                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4],
429                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5],
430                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6],
431                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON],
432                         &b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL],
433                         &domain,
434                         &dir,
435                         &b_text,
436                         &b_key,
437                         &b_format_args,
438                         &num_format_args,
439                         &b_image_path,
440                         &sound_type,
441                         &sound_path,
442                         &vibration_type,
443                         &vibration_path,
444                         &led_operation,
445                         &led_argb,
446                         &led_on_ms,
447                         &led_off_ms,
448                         &time,
449                         &insert_time,
450                         &flags_for_property,
451                         &display_applist,
452                         &progress_size,
453                         &progress_percentage,
454                         &app_icon_path,
455                         &app_name,
456                         &temp_title,
457                         &temp_content,
458                         &tag,
459                         &ongoing_flag,
460                         &auto_remove);
461
462         if (ret != 49) {
463                 NOTIFICATION_ERR("failed to create a noti from packet");
464                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
465         }
466
467         /*!
468          * This is already allocated from the notification_create function.
469          * Before reallocate string to here.
470          * We have to release old one first.
471          */
472         free(noti->caller_pkgname);
473         noti->caller_pkgname = _dup_string(caller_pkgname);
474         noti->launch_pkgname = _dup_string(launch_pkgname);
475         noti->args = _create_bundle_from_string(args);
476         noti->group_args = _create_bundle_from_string(group_args);
477         noti->b_execute_option = _create_bundle_from_string(b_execute_option);
478         noti->b_service_responding = _create_bundle_from_string(b_service_responding);
479         noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
480         noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
481         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++)
482                 noti->b_event_handler[i] = _create_bundle_from_string(b_event_handler[i]);
483
484         noti->domain = _dup_string(domain);
485         noti->dir = _dup_string(dir);
486         noti->b_text = _create_bundle_from_string(b_text);
487         noti->b_key = _create_bundle_from_string(b_key);
488         noti->b_format_args = _create_bundle_from_string(b_format_args);
489         noti->b_image_path = _create_bundle_from_string(b_image_path);
490         noti->sound_path = _dup_string(sound_path);
491         noti->vibration_path = _dup_string(vibration_path);
492         noti->app_icon_path = _dup_string(app_icon_path);
493         noti->app_name = _dup_string(app_name);
494         noti->temp_title = _dup_string(temp_title);
495         noti->temp_content = _dup_string(temp_content);
496
497         noti->type = type;
498         noti->layout = layout;
499         noti->group_id = group_id;
500         noti->internal_group_id = internal_group_id;
501         noti->priv_id = priv_id;
502         noti->num_format_args = num_format_args;
503         noti->sound_type = sound_type;
504         noti->vibration_type = vibration_type;
505         noti->led_operation = led_operation;
506         noti->led_argb = led_argb;
507         noti->led_on_ms = led_on_ms;
508         noti->led_off_ms = led_off_ms;
509         noti->time = time;
510         noti->insert_time = insert_time;
511         noti->flags_for_property = flags_for_property;
512         noti->display_applist = display_applist;
513         noti->progress_size = progress_size;
514         noti->progress_percentage = progress_percentage;
515         noti->tag = _dup_string(tag);
516         noti->ongoing_flag = ongoing_flag;
517         noti->auto_remove = auto_remove;
518
519         return NOTIFICATION_ERROR_NONE;
520 }
521
522 EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
523 {
524         int i = 0;
525         int b_encode_len = 0;
526         struct packet *result = NULL;
527         char *args = NULL;
528         char *group_args = NULL;
529         char *b_image_path = NULL;
530         char *b_execute_option = NULL;
531         char *b_service_responding = NULL;
532         char *b_service_single_launch = NULL;
533         char *b_service_multi_launch = NULL;
534         char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
535         char *b_text = NULL;
536         char *b_key = NULL;
537         char *b_format_args = NULL;
538         struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
539         char *title_key = NULL;
540         char buf_key[32] = { 0, };
541
542         /* Decode bundle to insert DB */
543         if (noti->args)
544                 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
545
546         if (noti->group_args)
547                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
548                               &b_encode_len);
549
550         if (noti->b_execute_option)
551                 bundle_encode(noti->b_execute_option,
552                               (bundle_raw **) & b_execute_option, &b_encode_len);
553
554         if (noti->b_service_responding)
555                 bundle_encode(noti->b_service_responding,
556                               (bundle_raw **) & b_service_responding, &b_encode_len);
557
558         if (noti->b_service_single_launch)
559                 bundle_encode(noti->b_service_single_launch,
560                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
561
562         if (noti->b_service_multi_launch)
563                 bundle_encode(noti->b_service_multi_launch,
564                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
565
566         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
567                 if (noti->b_event_handler[i])
568                         bundle_encode(noti->b_event_handler[i],
569                                         (bundle_raw **) & b_event_handler[i], &b_encode_len);
570
571         }
572
573         if (noti->b_text)
574                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
575
576         if (noti->b_key)
577                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
578
579         if (noti->b_format_args)
580                 bundle_encode(noti->b_format_args,
581                               (bundle_raw **) & b_format_args, &b_encode_len);
582
583         if (noti->b_image_path)
584                 bundle_encode(noti->b_image_path,
585                               (bundle_raw **) & b_image_path, &b_encode_len);
586
587         if (noti->b_key != NULL) {
588                 snprintf(buf_key, sizeof(buf_key), "%d",
589                          NOTIFICATION_TEXT_TYPE_TITLE);
590
591                 bundle_get_str(noti->b_key, buf_key, &title_key);
592         }
593
594         if (title_key == NULL && noti->b_text != NULL) {
595                 snprintf(buf_key, sizeof(buf_key), "%d",
596                          NOTIFICATION_TEXT_TYPE_TITLE);
597
598                 bundle_get_str(noti->b_text, buf_key, &title_key);
599         }
600
601         if (title_key == NULL)
602                 title_key = noti->caller_pkgname;
603
604
605         if (packet_type == 1)
606                 func_to_create_packet = packet_create;
607         else if (packet_type == 2)
608                 func_to_create_packet = packet_create_noack;
609         else
610                 goto out;
611
612         result = func_to_create_packet(command,
613                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
614                         noti->type,
615                         noti->layout,
616                         noti->group_id,
617                         noti->internal_group_id,
618                         noti->priv_id,
619                         NOTIFICATION_CHECK_STR(noti->caller_pkgname),
620                         NOTIFICATION_CHECK_STR(noti->launch_pkgname),
621                         NOTIFICATION_CHECK_STR(args),
622                         NOTIFICATION_CHECK_STR(group_args),
623                         NOTIFICATION_CHECK_STR(b_execute_option),
624                         NOTIFICATION_CHECK_STR(b_service_responding),
625                         NOTIFICATION_CHECK_STR(b_service_single_launch),
626                         NOTIFICATION_CHECK_STR(b_service_multi_launch),
627                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
628                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
629                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
630                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
631                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
632                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
633                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
634                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
635                         NOTIFICATION_CHECK_STR(noti->domain),
636                         NOTIFICATION_CHECK_STR(noti->dir),
637                         NOTIFICATION_CHECK_STR(b_text),
638                         NOTIFICATION_CHECK_STR(b_key),
639                         NOTIFICATION_CHECK_STR(b_format_args),
640                         noti->num_format_args,
641                         NOTIFICATION_CHECK_STR(b_image_path),
642                         noti->sound_type,
643                         NOTIFICATION_CHECK_STR(noti->sound_path),
644                         noti->vibration_type,
645                         NOTIFICATION_CHECK_STR(noti->vibration_path),
646                         noti->led_operation,
647                         noti->led_argb,
648                         noti->led_on_ms,
649                         noti->led_off_ms,
650                         noti->time,
651                         noti->insert_time,
652                         noti->flags_for_property,
653                         noti->display_applist,
654                         noti->progress_size,
655                         noti->progress_percentage,
656                         NOTIFICATION_CHECK_STR(noti->app_icon_path),
657                         NOTIFICATION_CHECK_STR(noti->app_name),
658                         NOTIFICATION_CHECK_STR(noti->temp_title),
659                         NOTIFICATION_CHECK_STR(noti->temp_content),
660                         NOTIFICATION_CHECK_STR(noti->tag),
661                         noti->ongoing_flag,
662                         noti->auto_remove);
663
664 out:
665         /* Free decoded data */
666         if (args)
667                 free(args);
668
669         if (group_args)
670                 free(group_args);
671
672         if (b_execute_option)
673                 free(b_execute_option);
674
675         if (b_service_responding)
676                 free(b_service_responding);
677
678         if (b_service_single_launch)
679                 free(b_service_single_launch);
680
681         if (b_service_multi_launch)
682                 free(b_service_multi_launch);
683
684         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
685                 if (b_event_handler[i])
686                         free(b_event_handler[i]);
687         }
688
689         if (b_text)
690                 free(b_text);
691
692         if (b_key)
693                 free(b_key);
694
695         if (b_format_args)
696                 free(b_format_args);
697
698         if (b_image_path)
699                 free(b_image_path);
700
701         return result;
702 }
703
704 EXPORT_API struct packet *notification_ipc_make_reply_packet_from_noti(notification_h noti, struct packet *packet)
705 {
706         int i = 0;
707         int b_encode_len = 0;
708         struct packet *result = NULL;
709         char *args = NULL;
710         char *group_args = NULL;
711         char *b_image_path = NULL;
712         char *b_execute_option = NULL;
713         char *b_service_responding = NULL;
714         char *b_service_single_launch = NULL;
715         char *b_service_multi_launch = NULL;
716         char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
717         char *b_text = NULL;
718         char *b_key = NULL;
719         char *b_format_args = NULL;
720         char *title_key = NULL;
721         char buf_key[32] = { 0, };
722
723         /* Decode bundle to insert DB */
724         if (noti->args)
725                 bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
726
727         if (noti->group_args)
728                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
729                               &b_encode_len);
730
731         if (noti->b_execute_option)
732                 bundle_encode(noti->b_execute_option,
733                               (bundle_raw **) & b_execute_option, &b_encode_len);
734
735         if (noti->b_service_responding)
736                 bundle_encode(noti->b_service_responding,
737                               (bundle_raw **) & b_service_responding, &b_encode_len);
738
739         if (noti->b_service_single_launch)
740                 bundle_encode(noti->b_service_single_launch,
741                               (bundle_raw **) & b_service_single_launch, &b_encode_len);
742
743         if (noti->b_service_multi_launch)
744                 bundle_encode(noti->b_service_multi_launch,
745                               (bundle_raw **) & b_service_multi_launch, &b_encode_len);
746
747         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
748                 if (noti->b_event_handler[i])
749                         bundle_encode(noti->b_event_handler[i],
750                                         (bundle_raw **) & b_event_handler[i], &b_encode_len);
751         }
752
753         if (noti->b_text)
754                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
755
756         if (noti->b_key)
757                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
758
759         if (noti->b_format_args)
760                 bundle_encode(noti->b_format_args,
761                               (bundle_raw **) & b_format_args, &b_encode_len);
762
763         if (noti->b_image_path)
764                 bundle_encode(noti->b_image_path,
765                               (bundle_raw **) & b_image_path, &b_encode_len);
766
767         if (noti->b_key != NULL) {
768                 snprintf(buf_key, sizeof(buf_key), "%d",
769                          NOTIFICATION_TEXT_TYPE_TITLE);
770
771                 bundle_get_str(noti->b_key, buf_key, &title_key);
772         }
773
774         if (title_key == NULL && noti->b_text != NULL) {
775                 snprintf(buf_key, sizeof(buf_key), "%d",
776                          NOTIFICATION_TEXT_TYPE_TITLE);
777
778                 bundle_get_str(noti->b_text, buf_key, &title_key);
779         }
780
781         if (title_key == NULL)
782                 title_key = noti->caller_pkgname;
783
784         result = packet_create_reply(packet,
785                         "iiiiisssssssssssssssssssssisisisiiiiiiiiddsssssii",
786                         noti->type,
787                         noti->layout,
788                         noti->group_id,
789                         noti->internal_group_id,
790                         noti->priv_id,
791                         NOTIFICATION_CHECK_STR(noti->caller_pkgname),
792                         NOTIFICATION_CHECK_STR(noti->launch_pkgname),
793                         NOTIFICATION_CHECK_STR(args),
794                         NOTIFICATION_CHECK_STR(group_args),
795                         NOTIFICATION_CHECK_STR(b_execute_option),
796                         NOTIFICATION_CHECK_STR(b_service_responding),
797                         NOTIFICATION_CHECK_STR(b_service_single_launch),
798                         NOTIFICATION_CHECK_STR(b_service_multi_launch),
799                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
800                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
801                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
802                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
803                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
804                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
805                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
806                         NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
807                         NOTIFICATION_CHECK_STR(noti->domain),
808                         NOTIFICATION_CHECK_STR(noti->dir),
809                         NOTIFICATION_CHECK_STR(b_text),
810                         NOTIFICATION_CHECK_STR(b_key),
811                         NOTIFICATION_CHECK_STR(b_format_args),
812                         noti->num_format_args,
813                         NOTIFICATION_CHECK_STR(b_image_path),
814                         noti->sound_type,
815                         NOTIFICATION_CHECK_STR(noti->sound_path),
816                         noti->vibration_type,
817                         NOTIFICATION_CHECK_STR(noti->vibration_path),
818                         noti->led_operation,
819                         noti->led_argb,
820                         noti->led_on_ms,
821                         noti->led_off_ms,
822                         noti->time,
823                         noti->insert_time,
824                         noti->flags_for_property,
825                         noti->display_applist,
826                         noti->progress_size,
827                         noti->progress_percentage,
828                         NOTIFICATION_CHECK_STR(noti->app_icon_path),
829                         NOTIFICATION_CHECK_STR(noti->app_name),
830                         NOTIFICATION_CHECK_STR(noti->temp_title),
831                         NOTIFICATION_CHECK_STR(noti->temp_content),
832                         NOTIFICATION_CHECK_STR(noti->tag),
833                         noti->ongoing_flag,
834                         noti->auto_remove);
835
836         /* Free decoded data */
837         if (args)
838                 free(args);
839
840         if (group_args)
841                 free(group_args);
842
843         if (b_execute_option)
844                 free(b_execute_option);
845
846         if (b_service_responding)
847                 free(b_service_responding);
848
849         if (b_service_single_launch)
850                 free(b_service_single_launch);
851
852         if (b_service_multi_launch)
853                 free(b_service_multi_launch);
854
855
856         for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
857                 if (b_event_handler[i])
858                         free(b_event_handler[i]);
859         }
860
861         if (b_text)
862                 free(b_text);
863
864         if (b_key)
865                 free(b_key);
866
867         if (b_format_args)
868                 free(b_format_args);
869
870         if (b_image_path)
871                 free(b_image_path);
872
873         return result;
874 }
875
876 /*!
877  * functions to handler services
878  */
879 static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
880 {
881         notification_h noti = NULL;
882         notification_op *noti_op;
883
884         if (!packet) {
885                 NOTIFICATION_ERR("a packet is null");
886                 return NULL;
887         }
888         noti = notification_create(NOTIFICATION_TYPE_NOTI);
889         if (!noti) {
890                 NOTIFICATION_ERR("failed to create a notification");
891                 return NULL;
892         }
893         notification_ipc_make_noti_from_packet(noti, packet);
894
895         if (noti->flags_for_property
896                 & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
897                 /* Disable changed cb */
898         } else {
899                 /* Enable changed cb */
900                 noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, &noti);
901                 if (noti_op != NULL) {
902                         notification_call_changed_cb(noti_op, 1);
903                         free(noti_op);
904                 }
905         }
906         notification_free(noti);
907
908         return NULL;
909 }
910
911 static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
912 {
913         notification_h noti = NULL;
914         notification_op *noti_op;
915
916         if (!packet) {
917                 NOTIFICATION_ERR("a packet is null");
918                 return NULL;
919         }
920
921         noti = notification_create(NOTIFICATION_TYPE_NOTI);
922         if (!noti) {
923                 NOTIFICATION_ERR("failed to create a notification");
924                 return NULL;
925         }
926
927         notification_ipc_make_noti_from_packet(noti, packet);
928
929         noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, &noti);
930         if (noti_op != NULL) {
931                 notification_call_changed_cb(noti_op, 1);
932                 free(noti_op);
933         }
934
935         notification_free(noti);
936
937         return NULL;
938 }
939
940 static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
941 {
942         notification_op *noti_op;
943
944         if (!packet) {
945                 NOTIFICATION_ERR("a packet is null");
946                 return NULL;
947         }
948
949         noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
950         if (noti_op != NULL) {
951                 notification_call_changed_cb(noti_op, 1);
952                 free(noti_op);
953         }
954
955         return NULL;
956 }
957
958 static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
959 {
960         int num_deleted = 0;
961         int priv_id = NOTIFICATION_PRIV_ID_NONE;
962         notification_op *noti_op;
963
964         if (!packet) {
965                 NOTIFICATION_ERR("a packet is null");
966                 return NULL;
967         }
968         if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
969                 noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
970                 if (noti_op != NULL) {
971                         notification_call_changed_cb(noti_op, 1);
972                         free(noti_op);
973                 }
974         }
975
976         return NULL;
977 }
978
979 static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
980 {
981         int ret = 0;
982         int buf[10] = {0,};
983         int num_deleted = 0;
984         notification_op *noti_op;
985
986         NOTIFICATION_INFO("delete_noti_multiple");
987
988         if (!packet) {
989                 NOTIFICATION_ERR("a packet is null");
990                 return NULL;
991         }
992         ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
993                         &(buf[0]),
994                         &(buf[1]),
995                         &(buf[2]),
996                         &(buf[3]),
997                         &(buf[4]),
998                         &(buf[5]),
999                         &(buf[6]),
1000                         &(buf[7]),
1001                         &(buf[8]),
1002                         &(buf[9]));
1003
1004         NOTIFICATION_INFO("packet data count:%d", ret);
1005         NOTIFICATION_INFO("packet data num deleted:%d", num_deleted);
1006
1007         int i = 0;
1008         for (i = 0 ; i < 10 ; i++)
1009                 NOTIFICATION_INFO("packet data[%d]:%d", i, buf[i]);
1010
1011
1012         if (ret == 11) {
1013                 noti_op = notification_ipc_create_op(
1014                                 NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
1015                 if (noti_op == NULL) {
1016                         NOTIFICATION_ERR("notification_ipc_create_op failed");
1017                         return NULL;
1018                 }
1019                 notification_call_changed_cb(noti_op, num_deleted);
1020                 free(noti_op);
1021         }
1022
1023         return NULL;
1024 }
1025
1026 static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
1027 {
1028         int ret;
1029         notification_op *noti_op;
1030
1031         if (!packet) {
1032                 NOTIFICATION_ERR("Packet is not valid\n");
1033                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1034         } else if (packet_get(packet, "i", &ret) != 1) {
1035                 NOTIFICATION_ERR("Packet is not valid\n");
1036                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1037         } else {
1038                 if (ret == 0) {
1039                         noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
1040                         if (noti_op != NULL) {
1041                                 notification_call_changed_cb(noti_op, 1);
1042                                 free(noti_op);
1043                         }
1044                 }
1045         }
1046         return ret;
1047 }
1048
1049 /*!
1050  * functions to initialize and register a monitor
1051  */
1052 static int notification_ipc_monitor_register(void)
1053 {
1054         int ret;
1055         struct packet *packet;
1056         static struct method service_table[] = {
1057                 {
1058                         .cmd = "add_noti",
1059                         .handler = _handler_insert,
1060                 },
1061                 {
1062                         .cmd = "update_noti",
1063                         .handler = _handler_update,
1064                 },
1065                 {
1066                         .cmd = "refresh_noti",
1067                         .handler = _handler_refresh,
1068                 },
1069                 {
1070                         .cmd = "del_noti_single",
1071                         .handler = _handler_delete_single,
1072                 },
1073                 {
1074                         .cmd = "del_noti_multiple",
1075                         .handler = _handler_delete_multiple,
1076                 },
1077                 {
1078                         .cmd = NULL,
1079                         .handler = NULL,
1080                 },
1081         };
1082
1083         if (s_info.initialized == 1)
1084                 return NOTIFICATION_ERROR_NONE;
1085         else
1086                 s_info.initialized = 1;
1087
1088         NOTIFICATION_ERR("register a service\n");
1089
1090         com_core_packet_use_thread(1);
1091         s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
1092         if (s_info.server_fd < 0) {
1093                 NOTIFICATION_ERR("Failed to make a connection to the master\n");
1094                 return NOTIFICATION_ERROR_IO_ERROR;
1095         }
1096
1097         packet = packet_create("service_register", "");
1098         if (!packet) {
1099                 NOTIFICATION_ERR("Failed to build a packet\n");
1100                 com_core_packet_client_fini(s_info.server_fd);
1101                 return NOTIFICATION_ERROR_IO_ERROR;
1102         }
1103
1104         ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
1105         NOTIFICATION_DBG("Service register sent: %d\n", ret);
1106         packet_destroy(packet);
1107         if (ret != 0) {
1108                 com_core_packet_client_fini(s_info.server_fd);
1109                 s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1110                 ret = NOTIFICATION_ERROR_IO_ERROR;
1111         } else {
1112                 ret = NOTIFICATION_ERROR_NONE;
1113         }
1114
1115         NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
1116         return ret;
1117 }
1118
1119 int notification_ipc_monitor_deregister(void)
1120 {
1121         if (s_info.initialized == 0)
1122                 return NOTIFICATION_ERROR_NONE;
1123
1124         com_core_packet_client_fini(s_info.server_fd);
1125         s_info.server_fd = NOTIFICATION_ERROR_INVALID_PARAMETER;
1126
1127         s_info.initialized = 0;
1128
1129         return NOTIFICATION_ERROR_NONE;
1130 }
1131
1132 int notification_ipc_monitor_init(void)
1133 {
1134         int ret = NOTIFICATION_ERROR_NONE;
1135
1136         if (notification_ipc_is_master_ready())
1137                 ret = notification_ipc_monitor_register();
1138
1139         if (s_info.is_started_cb_set_svc == 0) {
1140                 _set_master_started_cb(_master_started_cb_service);
1141                 s_info.is_started_cb_set_svc = 1;
1142         }
1143
1144         return ret;
1145 }
1146
1147 int notification_ipc_monitor_fini(void)
1148 {
1149         int ret = NOTIFICATION_ERROR_NONE;
1150
1151         if (s_info.is_started_cb_set_svc == 1) {
1152                 _unset_master_started_cb(_master_started_cb_service);
1153                 s_info.is_started_cb_set_svc = 0;
1154         }
1155
1156         ret = notification_ipc_monitor_deregister();
1157
1158         return ret;
1159 }
1160
1161 /*!
1162  * functions to request the service
1163  */
1164 int notification_ipc_request_insert(notification_h noti, int *priv_id)
1165 {
1166         int status = 0;
1167         int id = NOTIFICATION_PRIV_ID_NONE;
1168         struct packet *packet;
1169         struct packet *result;
1170
1171         /* Initialize private ID */
1172         noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
1173         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
1174         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
1175
1176         packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
1177         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1178                         packet,
1179                         NOTIFICATION_IPC_TIMEOUT);
1180         packet_destroy(packet);
1181
1182         if (result != NULL) {
1183                 if (packet_get(result, "ii", &status, &id) != 2) {
1184                         NOTIFICATION_ERR("Failed to get a result packet");
1185                         packet_unref(result);
1186                         return NOTIFICATION_ERROR_IO_ERROR;
1187                 }
1188
1189                 if (status != NOTIFICATION_ERROR_NONE) {
1190                         packet_unref(result);
1191                         return status;
1192                 }
1193                 packet_unref(result);
1194         } else {
1195                 NOTIFICATION_ERR("failed to receive answer(insert)");
1196                 if (notification_ipc_is_master_ready() == 1)
1197                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1198                 else
1199                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1200         }
1201
1202         if (priv_id != NULL)
1203                 *priv_id = id;
1204
1205         return NOTIFICATION_ERROR_NONE;
1206 }
1207
1208 int notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
1209 {
1210         int status = 0;
1211         int id = NOTIFICATION_PRIV_ID_NONE;
1212         struct packet *packet;
1213         struct packet *result;
1214
1215         packet = packet_create("del_noti_single", "si", pkgname, priv_id);
1216         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1217                         packet,
1218                         NOTIFICATION_IPC_TIMEOUT);
1219         packet_destroy(packet);
1220
1221         if (result != NULL) {
1222                 if (packet_get(result, "ii", &status, &id) != 2) {
1223                         NOTIFICATION_ERR("Failed to get a result packet");
1224                         packet_unref(result);
1225                         return NOTIFICATION_ERROR_IO_ERROR;
1226                 }
1227                 packet_unref(result);
1228         } else {
1229                 NOTIFICATION_ERR("failed to receive answer(delete)");
1230                 if (notification_ipc_is_master_ready() == 1)
1231                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1232                 else
1233                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1234         }
1235
1236         return status;
1237 }
1238
1239 int notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
1240 {
1241         int status = 0;
1242         int num_deleted = 0;
1243         struct packet *packet;
1244         struct packet *result;
1245
1246         packet = packet_create("del_noti_multiple", "si", pkgname, type);
1247         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1248                         packet,
1249                         NOTIFICATION_IPC_TIMEOUT);
1250         packet_destroy(packet);
1251
1252         if (result != NULL) {
1253                 if (packet_get(result, "ii", &status, &num_deleted) != 2) {
1254                         NOTIFICATION_ERR("Failed to get a result packet");
1255                         packet_unref(result);
1256                         return NOTIFICATION_ERROR_IO_ERROR;
1257                 }
1258                 NOTIFICATION_ERR("num deleted:%d", num_deleted);
1259                 packet_unref(result);
1260         } else {
1261                 NOTIFICATION_ERR("failed to receive answer(delete multiple)");
1262                 if (notification_ipc_is_master_ready() == 1)
1263                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1264                 else
1265                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1266         }
1267
1268         return status;
1269 }
1270
1271 int notification_ipc_request_update(notification_h noti)
1272 {
1273         int status = 0;
1274         int id = NOTIFICATION_PRIV_ID_NONE;
1275         struct packet *packet;
1276         struct packet *result;
1277
1278         packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1279         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1280                         packet,
1281                         NOTIFICATION_IPC_TIMEOUT);
1282         packet_destroy(packet);
1283
1284         if (result != NULL) {
1285                 if (packet_get(result, "ii", &status, &id) != 2) {
1286                         NOTIFICATION_ERR("Failed to get a result packet");
1287                         packet_unref(result);
1288                         return NOTIFICATION_ERROR_IO_ERROR;
1289                 }
1290                 packet_unref(result);
1291         } else {
1292                 NOTIFICATION_ERR("failed to receive answer(update)");
1293                 if (notification_ipc_is_master_ready() == 1)
1294                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1295                 else
1296                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1297         }
1298
1299         return status;
1300 }
1301
1302 static int _notification_ipc_update_cb(pid_t pid, int handle, const struct packet *packet, void *data)
1303 {
1304         int status = 0;
1305         int id = NOTIFICATION_PRIV_ID_NONE;
1306         result_cb_item *cb_item = (result_cb_item *)data;
1307
1308         if (cb_item == NULL) {
1309                 NOTIFICATION_ERR("Failed to get a callback item");
1310                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
1311         }
1312         s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1313         if (s_info.server_cl_fd_ref_cnt <= 0) {
1314                 NOTIFICATION_DBG("REFCNT: %d (fd: %d)", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1315                 int fd_temp = s_info.server_cl_fd;
1316                 s_info.server_cl_fd = -1;
1317                 com_core_packet_client_fini(fd_temp);
1318                 NOTIFICATION_DBG("FD(%d) finalized", fd_temp);
1319         }
1320
1321         if (packet != NULL) {
1322                 if (packet_get(packet, "ii", &status, &id) != 2) {
1323                         NOTIFICATION_ERR("Failed to get a result packet");
1324                         status = NOTIFICATION_ERROR_IO_ERROR;
1325                 }
1326         }
1327
1328         if (cb_item->result_cb != NULL)
1329                 cb_item->result_cb(id, status, cb_item->data);
1330
1331         free(cb_item);
1332
1333         return status;
1334 }
1335
1336 int notification_ipc_request_update_async(notification_h noti,
1337                 void (*result_cb)(int priv_id, int result, void *data), void *user_data)
1338 {
1339         int ret = NOTIFICATION_ERROR_NONE;
1340         int ret_con = 0;
1341         struct packet *packet = NULL;
1342         result_cb_item *cb_item = NULL;
1343
1344         packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
1345         if (packet == NULL) {
1346                 ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
1347                 goto fail;
1348         }
1349
1350         cb_item = calloc(1, sizeof(result_cb_item));
1351         if (cb_item == NULL) {
1352                 ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
1353                 goto fail;
1354         }
1355
1356         if (s_info.server_cl_fd < 0) {
1357                 com_core_packet_use_thread(1);
1358                 s_info.server_cl_fd = com_core_packet_client_init(s_info.socket_file, 0, NULL);
1359                 if (s_info.server_cl_fd < 0) {
1360                         NOTIFICATION_DBG("Failed to init client: %d", s_info.server_cl_fd);
1361                         if (notification_ipc_is_master_ready() == 1)
1362                                 ret = NOTIFICATION_ERROR_PERMISSION_DENIED;
1363                         else
1364                                 ret =  NOTIFICATION_ERROR_SERVICE_NOT_READY;
1365
1366                         goto fail;
1367                 }
1368                 s_info.server_cl_fd_ref_cnt = 1;
1369         } else {
1370                 s_info.server_cl_fd_ref_cnt++;
1371         }
1372
1373         cb_item->result_cb = result_cb;
1374         cb_item->data = user_data;
1375
1376         NOTIFICATION_INFO("Connection count:%d, fd:%d", s_info.server_cl_fd_ref_cnt, s_info.server_cl_fd);
1377
1378         ret_con = com_core_packet_async_send(s_info.server_cl_fd, packet, 0.0f,
1379                         _notification_ipc_update_cb, cb_item);
1380         if (ret_con < 0) {
1381                 NOTIFICATION_ERR("Failed to request update, %d\n", ret_con);
1382                 s_info.server_cl_fd_ref_cnt = (s_info.server_cl_fd_ref_cnt <= 1) ? 0 : s_info.server_cl_fd_ref_cnt - 1;
1383                 if (s_info.server_cl_fd_ref_cnt <= 0) {
1384                         int fd_temp = s_info.server_cl_fd;
1385                         s_info.server_cl_fd = -1;
1386                         com_core_packet_client_fini(fd_temp);
1387                         NOTIFICATION_INFO("FD(%d) finalized", fd_temp);
1388                 }
1389                 ret = NOTIFICATION_ERROR_IO_ERROR;
1390                 goto fail;
1391         } else {
1392                 ret = NOTIFICATION_ERROR_NONE;
1393                 goto success;
1394         }
1395
1396 fail:
1397         if (cb_item) free(cb_item);
1398         NOTIFICATION_ERR("Err: %d\n", ret);
1399
1400 success:
1401         if (packet) packet_destroy(packet);
1402
1403         return ret;
1404 }
1405
1406 int notification_ipc_request_refresh(void)
1407 {
1408         int status = 0;
1409         struct packet *packet;
1410         struct packet *result;
1411
1412         packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
1413         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1414                         packet,
1415                         NOTIFICATION_IPC_TIMEOUT);
1416         packet_destroy(packet);
1417
1418         if (result != NULL) {
1419                 if (packet_get(result, "i", &status) != 1) {
1420                         NOTIFICATION_ERR("Failed to get a result packet");
1421                         packet_unref(result);
1422                         return NOTIFICATION_ERROR_IO_ERROR;
1423                 }
1424                 packet_unref(result);
1425         } else {
1426                 NOTIFICATION_ERR("failed to receive answer(refresh)");
1427                 if (notification_ipc_is_master_ready() == 1)
1428                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1429                 else
1430                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1431         }
1432
1433         return status;
1434 }
1435
1436
1437 int notification_ipc_update_setting(notification_setting_h setting)
1438 {
1439         int status = 0;
1440         int ret = 0;
1441         struct packet *packet;
1442         struct packet *result;
1443
1444         packet = packet_create("update_noti_setting", "siii", setting->package_name, (int)(setting->allow_to_notify), (int)(setting->do_not_disturb_except), (int)(setting->visibility_class));
1445         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1446                 packet,
1447                 NOTIFICATION_IPC_TIMEOUT);
1448         packet_destroy(packet);
1449
1450         if (result != NULL) {
1451                 if (packet_get(result, "ii", &status, &ret) != 2) {
1452                         NOTIFICATION_ERR("Failed to get a result packet");
1453                         packet_unref(result);
1454                         return NOTIFICATION_ERROR_IO_ERROR;
1455                 }
1456                 packet_unref(result);
1457         } else {
1458                 NOTIFICATION_ERR("failed to receive answer(delete)");
1459                 if (notification_ipc_is_master_ready() == 1)
1460                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1461                 else
1462                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1463         }
1464
1465         return status;
1466 }
1467
1468 int notification_ipc_update_system_setting(notification_system_setting_h system_setting)
1469 {
1470         int status = 0;
1471         int ret = 0;
1472         struct packet *packet = NULL;
1473         struct packet *result = NULL;
1474
1475         packet = packet_create("update_noti_sys_setting", "ii", (int)(system_setting->do_not_disturb), (int)(system_setting->visibility_class));
1476         if (packet == NULL) {
1477                 NOTIFICATION_ERR("packet_create failed.");
1478                 goto out;
1479         }
1480         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR, packet, NOTIFICATION_IPC_TIMEOUT);
1481         packet_destroy(packet);
1482
1483         if (result != NULL) {
1484                 if (packet_get(result, "ii", &status, &ret) != 2) {
1485                         NOTIFICATION_ERR("Failed to get a result packet");
1486                         status = NOTIFICATION_ERROR_IO_ERROR;
1487                         goto out;
1488                 }
1489
1490         } else {
1491                 NOTIFICATION_ERR("failed to receive answer(delete)");
1492                 if (notification_ipc_is_master_ready() == 1) {
1493                         status = NOTIFICATION_ERROR_PERMISSION_DENIED;
1494                         goto out;
1495                 } else {
1496                         status = NOTIFICATION_ERROR_SERVICE_NOT_READY;
1497                         goto out;
1498                 }
1499         }
1500 out:
1501         if (result)
1502                 packet_unref(result);
1503
1504         return status;
1505 }
1506
1507 int notification_ipc_noti_setting_property_set(const char *pkgname, const char *property, const char *value)
1508 {
1509         int status = 0;
1510         int ret = 0;
1511         struct packet *packet;
1512         struct packet *result;
1513
1514         packet = packet_create("set_noti_property", "sss", pkgname, property, value);
1515         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1516                         packet,
1517                         NOTIFICATION_IPC_TIMEOUT);
1518         packet_destroy(packet);
1519
1520         if (result != NULL) {
1521                 if (packet_get(result, "ii", &status, &ret) != 2) {
1522                         NOTIFICATION_ERR("Failed to get a result packet");
1523                         packet_unref(result);
1524                         return NOTIFICATION_ERROR_IO_ERROR;
1525                 }
1526                 packet_unref(result);
1527         } else {
1528                 NOTIFICATION_ERR("failed to receive answer(delete)");
1529                 if (notification_ipc_is_master_ready() == 1)
1530                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1531                 else
1532                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1533         }
1534
1535         return status;
1536 }
1537
1538 int notification_ipc_noti_setting_property_get(const char *pkgname, const char *property, char **value)
1539 {
1540         int status = 0;
1541         char *ret = NULL;
1542         struct packet *packet;
1543         struct packet *result;
1544
1545         packet = packet_create("get_noti_property", "ss", pkgname, property);
1546         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1547                         packet,
1548                         NOTIFICATION_IPC_TIMEOUT);
1549         packet_destroy(packet);
1550
1551         if (result != NULL) {
1552                 if (packet_get(result, "is", &status, &ret) != 2) {
1553                         NOTIFICATION_ERR("Failed to get a result packet");
1554                         packet_unref(result);
1555                         return NOTIFICATION_ERROR_IO_ERROR;
1556                 }
1557                 if (status == NOTIFICATION_ERROR_NONE && ret != NULL)
1558                         *value = strdup(ret);
1559
1560                 packet_unref(result);
1561         } else {
1562                 NOTIFICATION_ERR("failed to receive answer(delete)");
1563                 if (notification_ipc_is_master_ready() == 1)
1564                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1565                 else
1566                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1567         }
1568
1569         return status;
1570 }
1571
1572 int notification_ipc_request_load_noti_by_tag(notification_h noti, const char *pkgname, const char *tag)
1573 {
1574         struct packet *packet;
1575         struct packet *result;
1576
1577         packet = packet_create("load_noti_by_tag", "ss", pkgname, tag);
1578         result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
1579                         packet,
1580                         NOTIFICATION_IPC_TIMEOUT);
1581         packet_destroy(packet);
1582
1583         if (result != NULL) {
1584                 if (notification_ipc_make_noti_from_packet(noti, result) != NOTIFICATION_ERROR_NONE) {
1585                         NOTIFICATION_ERR("Failed to get a result packet");
1586                         packet_unref(result);
1587                         return NOTIFICATION_ERROR_IO_ERROR;
1588                 }
1589
1590                 packet_unref(result);
1591         } else {
1592                 NOTIFICATION_ERR("failed to receive answer(load noti by tag)");
1593                 if (notification_ipc_is_master_ready() == 1)
1594                         return NOTIFICATION_ERROR_PERMISSION_DENIED;
1595                 else
1596                         return NOTIFICATION_ERROR_SERVICE_NOT_READY;
1597         }
1598
1599         return NOTIFICATION_ERROR_NONE;
1600 }
1601