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