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