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