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