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