Sync with the latest one
[platform/framework/web/livebox-viewer.git] / src / client.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <pthread.h>
23
24 #include <dlog.h>
25 #include <glib.h>
26
27 #include <vconf.h>
28 #include <vconf-keys.h>
29
30 #include <packet.h>
31 #include <com-core.h>
32 #include <com-core_packet.h>
33 #include <livebox-errno.h>
34 #include <livebox-service.h>
35 #include <secure_socket.h>
36
37 #include "debug.h"
38 #include "client.h"
39 #include "livebox.h"
40 #include "livebox_internal.h"
41 #include "desc_parser.h"
42 #include "fb.h"
43 #include "util.h"
44 #include "master_rpc.h"
45 #include "conf.h"
46 #include "file_service.h"
47
48 int errno;
49
50 static struct info {
51         int fd;
52         guint timer_id;
53         char *client_addr;
54 } s_info = {
55         .fd = -1,
56         .timer_id = 0,
57         .client_addr = NULL,
58 };
59
60 static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet)
61 {
62         const char *pkgname;
63         const char *id;
64         const char *function;
65
66         if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) {
67                 ErrPrint("Invalid arguments\n");
68                 return NULL;
69         }
70
71         master_rpc_clear_fault_package(pkgname);
72         lb_invoke_fault_handler(LB_FAULT_DEACTIVATED, pkgname, id, function);
73         return NULL;
74 }
75
76 static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet)
77 {
78         struct livebox *handler;
79         const char *pkgname;
80         const char *id;
81         int seize;
82         int ret;
83
84         ret = packet_get(packet, "ssi", &pkgname, &id, &seize);
85         if (ret != 3) {
86                 ErrPrint("Invalid argument\n");
87                 goto out;
88         }
89
90         handler = lb_find_livebox(pkgname, id);
91         if (!handler) {
92                 ErrPrint("Instance(%s) is not exists\n", id);
93                 goto out;
94         }
95
96         DbgPrint("HOLD: %s %d\n", id, seize);
97         lb_invoke_event_handler(handler, seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL);
98
99 out:
100         return NULL;
101 }
102
103 static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet)
104 {
105         const char *pkgname;
106         const char *id;
107         const char *content;
108         struct livebox *handler;
109         char *new_content;
110         int ret;
111         int status;
112         int pinup;
113
114         ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content);
115         if (ret != 5) {
116                 ErrPrint("Invalid argument\n");
117                 goto out;
118         }
119
120         handler = lb_find_livebox(pkgname, id);
121         if (!handler) {
122                 ErrPrint("Instance (%s) is not exists\n", id);
123                 goto out;
124         }
125
126         if (status == 0) {
127                 new_content = strdup(content);
128                 if (new_content) {
129                         free(handler->content);
130                         handler->content = new_content;
131                         handler->is_pinned_up = pinup;
132                 } else {
133                         ErrPrint("Heap: %s\n", strerror(errno));
134                         status = LB_STATUS_ERROR_MEMORY;
135                 }
136         }
137
138         if (handler->pinup_cb) {
139                 ret_cb_t cb;
140                 void *cbdata;
141
142                 /* Make sure that user can call pinup API in its result callback */
143                 cb = handler->pinup_cb;
144                 cbdata = handler->pinup_cbdata;
145
146                 handler->pinup_cb = NULL;
147                 handler->pinup_cbdata = NULL;
148
149                 cb(handler, status, cbdata);
150         } else if (status == 0) {
151                 lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED);
152         }
153
154 out:
155         return NULL;
156 }
157
158 static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet)
159 {
160         const char *pkgname;
161         const char *id;
162         double timestamp;
163         struct livebox *handler;
164         int reason;
165
166         if (packet_get(packet, "ssdi", &pkgname, &id, &timestamp, &reason) != 4) {
167                 ErrPrint("Invalid arguemnt\n");
168                 goto out;
169         }
170
171         handler = lb_find_livebox_by_timestamp(timestamp);
172         if (!handler) {
173                 /*!
174                  * \note
175                  * This can be happens only if the user delete a livebox
176                  * right after create it before receive created event.
177                  */
178                 goto out;
179         }
180
181         /*!< Check validity of this "handler" */
182         if (handler->state != CREATE) {
183                 if (handler->state != DELETE) {
184                         /*!
185                          * \note
186                          * This is not possible
187                          */
188                         ErrPrint("Already deleted handler (%s - %s)\n", pkgname, id);
189                         return NULL;
190                 }
191         }
192
193         if (handler->created_cb) {
194                 ret_cb_t cb;
195                 void *cbdata;
196                 /*!
197                  * \note
198                  *
199                  * "if (handler->id == NULL) {"
200                  *
201                  * The instance is not created yet.
202                  * But the master forcely destroy it and send destroyed event to this
203                  * without the created event.
204                  *
205                  * It could be destroyed when a slave has critical error(fault)
206                  * before creating an instance successfully.
207                  */
208                 if (handler->created_cb == handler->deleted_cb) {
209                         if (handler->created_cbdata != handler->deleted_cbdata) {
210                                 DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id);
211                         }
212
213                         handler->deleted_cb = NULL;
214                         handler->deleted_cbdata = NULL;
215                 }
216
217                 cb = handler->created_cb;
218                 cbdata = handler->created_cbdata;
219
220                 handler->created_cb = NULL;
221                 handler->created_cbdata = NULL;
222
223                 if (reason == LB_STATUS_SUCCESS) {
224                         reason = LB_STATUS_ERROR_CANCEL;
225                 }
226                 cb(handler, reason, cbdata);
227         } else if (handler->id) {
228                 if (handler->deleted_cb) {
229                         ret_cb_t cb;
230                         void *cbdata;
231
232                         cb = handler->deleted_cb;
233                         cbdata = handler->deleted_cbdata;
234
235                         handler->deleted_cb = NULL;
236                         handler->deleted_cbdata = NULL;
237
238                         cb(handler, reason, cbdata);
239                 } else {
240                         lb_invoke_event_handler(handler, LB_EVENT_DELETED);
241                 }
242         }
243
244         /*!
245          * \note
246          * Lock file should be deleted after all callbacks are processed.
247          */
248         lb_destroy_lock_file(handler, 0);
249
250         /* Just try to delete it, if a user didn't remove it from the live box list */
251         lb_unref(handler);
252
253 out:
254         return NULL;
255 }
256
257 static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct packet *packet)
258 {
259         struct livebox *handler;
260         const char *pkgname;
261         const char *id;
262         const char *content;
263         const char *title;
264         const char *fbfile;
265         double priority;
266         int ret;
267
268         ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile);
269         if (ret != 6) {
270                 ErrPrint("Invalid argument\n");
271                 goto out;
272         }
273
274         handler = lb_find_livebox(pkgname, id);
275         if (!handler) {
276                 ErrPrint("Instance[%s] is not exists\n", id);
277                 goto out;
278         }
279
280         if (handler->state != CREATE) {
281                 ErrPrint("(%s) is not created\n", id);
282                 goto out;
283         }
284
285         lb_set_priority(handler, priority);
286         lb_set_content(handler, content);
287         lb_set_title(handler, title);
288
289         /*!
290          * \NOTE
291          * Width & Height is not changed in this case.
292          * If the active update is began, the size should not be changed,
293          * And if the size is changed, the provider should finish the updating first.
294          * And then begin updating again after change its size.
295          */
296         if (lb_get_lb_fb(handler)) {
297                 (void)lb_set_lb_fb(handler, fbfile);
298
299                 ret = livebox_sync_lb_fb(handler);
300                 if (ret != LB_STATUS_SUCCESS) {
301                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
302                 } else {
303                         lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN);
304                 }
305         } else {
306                 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
307         }
308
309 out:
310         return NULL;
311 }
312
313 static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct packet *packet)
314 {
315         struct livebox *handler;
316         const char *pkgname;
317         const char *id;
318         const char *fbfile;
319         int ret;
320
321         ret = packet_get(packet, "sss", &pkgname, &id, &fbfile);
322         if (ret != 2) {
323                 ErrPrint("Invalid argument\n");
324                 goto out;
325         }
326
327         handler = lb_find_livebox(pkgname, id);
328         if (!handler) {
329                 ErrPrint("Instance[%s] is not exists\n", id);
330                 goto out;
331         }
332
333         if (handler->state != CREATE) {
334                 ErrPrint("[%s] is not created\n", id);
335                 goto out;
336         }
337
338         if (lb_get_pd_fb(handler)) {
339                 (void)lb_set_lb_fb(handler, fbfile);
340
341                 ret = livebox_sync_lb_fb(handler);
342                 if (ret != LB_STATUS_SUCCESS) {
343                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
344                 } else {
345                         lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN);
346                 }
347         } else {
348                 ErrPrint("Invalid request[%s], %s\n", id, fbfile);
349         }
350
351 out:
352         return NULL;
353 }
354
355 static struct packet *master_lb_update_end(pid_t pid, int handle, const struct packet *packet)
356 {
357         struct livebox *handler;
358         const char *pkgname;
359         const char *id;
360         int ret;
361
362         ret = packet_get(packet, "ss", &pkgname, &id);
363         if (ret != 2) {
364                 ErrPrint("Invalid argument\n");
365                 goto out;
366         }
367
368         handler = lb_find_livebox(pkgname, id);
369         if (!handler) {
370                 ErrPrint("Instance[%s] is not exists\n", id);
371                 goto out;
372         }
373
374         if (handler->state != CREATE) {
375                 ErrPrint("[%s] is not created\n", id);
376                 goto out;
377         }
378
379         if (lb_get_lb_fb(handler)) {
380                 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END);
381         } else {
382                 ErrPrint("Invalid request[%s]\n", id);
383         }
384
385 out:
386         return NULL;
387 }
388
389 static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet)
390 {
391         struct livebox *handler;
392         const char *pkgname;
393         const char *id;
394         int ret;
395         int status;
396
397         ret = packet_get(packet, "ssi", &pkgname, &id, &status);
398         if (ret != 3) {
399                 ErrPrint("Invalid argument\n");
400                 goto out;
401         }
402
403         handler = lb_find_livebox(pkgname, id);
404         if (!handler) {
405                 ErrPrint("Instance[%s] is not exists\n", id);
406                 goto out;
407         }
408
409         if (handler->state != CREATE) {
410                 ErrPrint("[%s] is not created\n", id);
411                 goto out;
412         }
413
414         if (handler->key_event_cb) {
415                 ret_cb_t cb;
416                 void *cbdata;
417
418                 cb = handler->key_event_cb;
419                 cbdata = handler->key_event_cbdata;
420
421                 handler->key_event_cb = NULL;
422                 handler->key_event_cbdata = NULL;
423
424                 cb(handler, status, cbdata);
425         } else {
426                 ErrPrint("Invalid event[%s]\n", id);
427         }
428 out:
429         return NULL;
430 }
431
432 static struct packet *master_request_close_pd(pid_t pid, int handle, const struct packet *packet)
433 {
434         struct livebox *handler;
435         const char *pkgname;
436         const char *id;
437         int ret;
438         int reason;
439
440         ret = packet_get(packet, "ssi", &pkgname, &id, &reason);
441         if (ret != 3) {
442                 ErrPrint("Invalid argument\n");
443                 goto out;
444         }
445
446         handler = lb_find_livebox(pkgname, id);
447         if (!handler) {
448                 ErrPrint("Instance[%s] is not exists\n", id);
449                 goto out;
450         }
451
452         if (handler->state != CREATE) {
453                 ErrPrint("[%s] is not created\n", id);
454                 goto out;
455         }
456
457         DbgPrint("Reason: %d\n", reason);
458         lb_invoke_event_handler(handler, LB_EVENT_REQUEST_CLOSE_PD);
459 out:
460         return NULL;
461 }
462
463 static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet)
464 {
465         struct livebox *handler;
466         const char *pkgname;
467         const char *id;
468         int ret;
469         int status;
470
471         ret = packet_get(packet, "ssi", &pkgname, &id, &status);
472         if (ret != 3) {
473                 ErrPrint("Invalid argument\n");
474                 goto out;
475         }
476
477         handler = lb_find_livebox(pkgname, id);
478         if (!handler) {
479                 ErrPrint("Instance[%s] is not exists\n", id);
480                 goto out;
481         }
482
483         if (handler->state != CREATE) {
484                 ErrPrint("[%s] is not created\n", id);
485                 goto out;
486         }
487
488         if (handler->access_event_cb) {
489                 ret_cb_t cb;
490                 void *cbdata;
491
492                 cb = handler->access_event_cb;
493                 cbdata = handler->access_event_cbdata;
494
495                 handler->access_event_cb = NULL;
496                 handler->access_event_cbdata = NULL;
497
498                 cb(handler, status, cbdata);
499         } else {
500                 ErrPrint("Invalid event[%s]\n", id);
501         }
502 out:
503         return NULL;
504 }
505
506 static struct packet *master_pd_update_end(pid_t pid, int handle, const struct packet *packet)
507 {
508         struct livebox *handler;
509         const char *pkgname;
510         const char *id;
511         int ret;
512
513         ret = packet_get(packet, "ss", &pkgname, &id);
514         if (ret != 2) {
515                 ErrPrint("Invalid argument\n");
516                 goto out;
517         }
518
519         handler = lb_find_livebox(pkgname, id);
520         if (!handler) {
521                 ErrPrint("Instance[%s] is not exists\n", id);
522                 goto out;
523         }
524
525         if (handler->state != CREATE) {
526                 ErrPrint("[%s] is not created\n", id);
527                 goto out;
528         }
529
530         if (lb_get_lb_fb(handler)) {
531                 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END);
532         } else {
533                 ErrPrint("Invalid request[%s]", id);
534         }
535
536 out:
537         return NULL;
538 }
539
540 static struct packet *master_lb_updated(pid_t pid, int handle, const struct packet *packet)
541 {
542         const char *pkgname;
543         const char *id;
544         const char *fbfile;
545         const char *content;
546         const char *title;
547         const char *safe_file;
548         const char *icon;
549         const char *name;
550         struct livebox *handler;
551         int lb_w;
552         int lb_h;
553         double priority;
554         int ret;
555
556         ret = packet_get(packet, "sssiidsssss",
557                                 &pkgname, &id,
558                                 &fbfile, &lb_w, &lb_h,
559                                 &priority, &content, &title,
560                                 &safe_file, &icon, &name);
561         if (ret != 11) {
562                 ErrPrint("Invalid argument\n");
563                 goto out;
564         }
565
566         handler = lb_find_livebox(pkgname, id);
567         if (!handler) {
568                 ErrPrint("instance(%s) is not exists\n", id);
569                 goto out;
570         }
571
572         if (handler->state != CREATE) {
573                 /*!
574                  * \note
575                  * Already deleted by the user.
576                  * Don't try to notice anything with this, Just ignore all events
577                  * Beacuse the user doesn't wants know about this anymore
578                  */
579                 ErrPrint("(%s) is not exists, but updated\n", id);
580                 goto out;
581         }
582
583         lb_set_priority(handler, priority);
584         lb_set_content(handler, content);
585         lb_set_title(handler, title);
586         lb_set_size(handler, lb_w, lb_h);
587         lb_set_filename(handler, safe_file);
588
589         if (lb_text_lb(handler)) {
590                 (void)parse_desc(handler, livebox_filename(handler), 0);
591                 /*!
592                  * \note
593                  * DESC parser will call the "text event callback".
594                  * Don't need to call global event callback in this case.
595                  */
596                 goto out;
597         } else if (lb_get_lb_fb(handler)) {
598                 if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
599                         /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
600                         DbgPrint("Discards obsoloted update event\n");
601                         ret = LB_STATUS_ERROR_BUSY;
602                 } else {
603                         (void)lb_set_lb_fb(handler, fbfile);
604
605                         if (!conf_manual_sync()) {
606                                 ret = livebox_sync_lb_fb(handler);
607                                 if (ret != LB_STATUS_SUCCESS) {
608                                         ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret);
609                                 }
610                         } else {
611                                 ret = LB_STATUS_SUCCESS;
612                         }
613                 }
614         } else {
615                 ret = LB_STATUS_SUCCESS;
616         }
617
618         if (ret == LB_STATUS_SUCCESS) {
619                 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
620         }
621
622 out:
623         return NULL;
624 }
625
626 static struct packet *master_pd_created(pid_t pid, int handle, const struct packet *packet)
627 {
628         struct livebox *handler;
629         const char *pkgname;
630         const char *id;
631         const char *buf_id;
632         int width;
633         int height;
634         int ret;
635         int status;
636
637         ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status);
638         if (ret != 6) {
639                 ErrPrint("Invalid argument\n");
640                 goto out;
641         }
642
643         handler = lb_find_livebox(pkgname, id);
644         if (!handler) {
645                 ErrPrint("Instance(%s) is not exists\n", id);
646                 goto out;
647         }
648
649         if (handler->state != CREATE) {
650                 ErrPrint("Instance(%s) is not created\n", id);
651                 goto out;
652         }
653
654         lb_set_pdsize(handler, width, height);
655         if (lb_text_pd(handler)) {
656                 DbgPrint("Text TYPE does not need to handle this\n");
657         } else {
658                 (void)lb_set_pd_fb(handler, buf_id);
659                 ret = livebox_sync_pd_fb(handler);
660                 if (ret < 0) {
661                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
662                 }
663         }
664
665         handler->is_pd_created = (status == 0);
666
667         switch (handler->pd.type) {
668         case _PD_TYPE_SCRIPT:
669         case _PD_TYPE_BUFFER:
670                 switch (fb_type(lb_get_pd_fb(handler))) {
671                 case BUFFER_TYPE_FILE:
672                 case BUFFER_TYPE_SHM:
673                         lb_create_lock_file(handler, 1);
674                         break;
675                 case BUFFER_TYPE_PIXMAP:
676                 case BUFFER_TYPE_ERROR:
677                 default:
678                         break;
679                 }
680                 break;
681         case _PD_TYPE_TEXT:
682         default:
683                 break;
684         }
685
686         if (handler->pd_created_cb) {
687                 ret_cb_t cb;
688                 void *cbdata;
689
690                 cb = handler->pd_created_cb;
691                 cbdata = handler->pd_created_cbdata;
692
693                 handler->pd_created_cb = NULL;
694                 handler->pd_created_cbdata = NULL;
695
696                 /*!
697                  * Before call the Callback function,
698                  * pd_create_cb must be reset.
699                  * Because, in the create callback, user can call create_pd function again.
700                  */
701                 DbgPrint("PERF_DBOX\n");
702                 cb(handler, status, cbdata);
703         } else if (handler->is_pd_created) {
704                 lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED);
705         }
706
707 out:
708         return NULL;
709 }
710
711 static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct packet *packet)
712 {
713         struct livebox *handler;
714         const char *pkgname;
715         const char *id;
716         int ret;
717         int status;
718
719         ret = packet_get(packet, "ssi", &pkgname, &id, &status);
720         if (ret != 3) {
721                 ErrPrint("Invalid argument\n");
722                 goto out;
723         }
724
725         handler = lb_find_livebox(pkgname, id);
726         if (!handler) {
727                 ErrPrint("Instance(%s) is not exists\n", id);
728                 goto out;
729         }
730
731         if (handler->state != CREATE) {
732                 ErrPrint("Instance(%s) is not created\n", id);
733                 goto out;
734         }
735
736         handler->is_pd_created = 0;
737
738         if (handler->pd_destroyed_cb) {
739                 ret_cb_t cb;
740                 void *cbdata;
741
742                 cb = handler->pd_destroyed_cb;
743                 cbdata = handler->pd_destroyed_cbdata;
744
745                 handler->pd_destroyed_cb = NULL;
746                 handler->pd_destroyed_cbdata = NULL;
747
748                 /*!
749                  * Before call the Callback function,
750                  * pd_destroyed_cb must be reset.
751                  * Because, in the create callback, user can call destroy_pd function again.
752                  */
753                 cb(handler, status, cbdata);
754         } else if (status == 0) {
755                 lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED);
756         }
757
758         /*!
759          * \note
760          * Lock file should be deleted after all callbacks are processed.
761          */
762         switch (handler->pd.type) {
763         case _PD_TYPE_SCRIPT:
764         case _PD_TYPE_BUFFER:
765                 switch (fb_type(lb_get_pd_fb(handler))) {
766                 case BUFFER_TYPE_FILE:
767                 case BUFFER_TYPE_SHM:
768                         lb_destroy_lock_file(handler, 1);
769                         break;
770                 case BUFFER_TYPE_PIXMAP:
771                 case BUFFER_TYPE_ERROR:
772                 default:
773                         break;
774                 }
775                 break;
776         case _PD_TYPE_TEXT:
777         default:
778                 break;
779         }
780
781 out:
782         return NULL;
783 }
784
785 static struct packet *master_pd_updated(pid_t pid, int handle, const struct packet *packet)
786 {
787         const char *pkgname;
788         const char *id;
789         const char *descfile;
790         const char *fbfile;
791         int ret;
792         struct livebox *handler;
793         int pd_w;
794         int pd_h;
795
796         ret = packet_get(packet, "ssssii",
797                                 &pkgname, &id,
798                                 &descfile, &fbfile,
799                                 &pd_w, &pd_h);
800         if (ret != 6) {
801                 ErrPrint("Invalid argument\n");
802                 goto out;
803         }
804
805         handler = lb_find_livebox(pkgname, id);
806         if (!handler) {
807                 ErrPrint("Instance(%s) is not exists\n", id);
808                 goto out;
809         }
810
811         if (handler->state != CREATE) {
812                 /*!
813                  * \note
814                  * This handler is already deleted by the user.
815                  * So don't try to notice anything about this anymore.
816                  * Just ignore all events.
817                  */
818                 ErrPrint("Instance(%s) is not created\n", id);
819                 goto out;
820         }
821
822         lb_set_pdsize(handler, pd_w, pd_h);
823
824         if (lb_text_pd(handler)) {
825                 (void)parse_desc(handler, descfile, 1);
826         } else {
827                 if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
828                         /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
829                         DbgPrint("Discards obsoloted update event\n");
830                 } else {
831                         (void)lb_set_pd_fb(handler, fbfile);
832
833                          if (!conf_manual_sync()) {
834                                 ret = livebox_sync_pd_fb(handler);
835                                 if (ret < 0) {
836                                         ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret);
837                                 } else {
838                                         lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
839                                 }
840                         } else {
841                                 lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
842                         }
843                 }
844         }
845
846 out:
847         return NULL;
848 }
849
850 static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet)
851 {
852         struct livebox *handler;
853         const char *pkgname;
854         const char *id;
855         int active_mode;
856         int status;
857         int ret;
858
859         if (!packet) {
860                 ErrPrint("Invalid packet\n");
861                 goto out;
862         }
863
864         ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode);
865         if (ret != 4) {
866                 ErrPrint("Invalid argument\n");
867                 goto out;
868         }
869
870         handler = lb_find_livebox(pkgname, id);
871         if (!handler) {
872                 ErrPrint("Livebox(%s) is not found\n", id);
873                 goto out;
874         }
875
876         if (handler->state != CREATE) {
877                 ErrPrint("Livebox(%s) is not created yet\n", id);
878                 goto out;
879         }
880
881         if (status == LB_STATUS_SUCCESS) {
882                 lb_set_update_mode(handler, active_mode);
883         }
884
885         if (handler->update_mode_cb) {
886                 ret_cb_t cb;
887                 void *cbdata;
888
889                 cb = handler->update_mode_cb;
890                 cbdata = handler->update_mode_cbdata;
891
892                 handler->update_mode_cb = NULL;
893                 handler->update_mode_cbdata = NULL;
894
895                 cb(handler, status, cbdata);
896         } else {
897                 lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED);
898         }
899
900 out:
901         return NULL;
902 }
903
904 static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet)
905 {
906         struct livebox *handler;
907         const char *pkgname;
908         const char *id;
909         const char *fbfile;
910         int status;
911         int ret;
912         int w;
913         int h;
914         int is_pd;
915
916         if (!packet) {
917                 ErrPrint("Invalid packet\n");
918                 goto out;
919         }
920
921         ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_pd, &w, &h, &status);
922         if (ret != 7) {
923                 ErrPrint("Invalid argument\n");
924                 goto out;
925         }
926
927         handler = lb_find_livebox(pkgname, id);
928         if (!handler) {
929                 ErrPrint("Livebox(%s) is not found\n", id);
930                 goto out;
931         }
932
933         if (handler->state != CREATE) {
934                 ErrPrint("Livebox(%s) is not created yet\n", id);
935                 goto out;
936         }
937
938         if (is_pd) {
939                 /*!
940                  * \NOTE
941                  * PD is not able to resized by the client.
942                  * PD is only can be managed by the provider.
943                  * So the PD has no private resized event handler.
944                  * Notify it via global event handler only.
945                  */
946                 if (status == 0) {
947                         lb_set_pdsize(handler, w, h);
948                         lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED);
949                 } else {
950                         ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status);
951                 }
952         } else {
953                 if (status == 0) {
954                         lb_set_size(handler, w, h);
955
956                         /*!
957                          * \NOTE
958                          * If there is a created LB FB, 
959                          * Update it too.
960                          */
961                         if (lb_get_lb_fb(handler)) {
962                                 (void)lb_set_lb_fb(handler, fbfile);
963
964                                 ret = livebox_sync_lb_fb(handler);
965                                 if (ret < 0) {
966                                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
967                                 }
968
969                                 /* Just update the size info only. */
970                         }
971
972                         /*!
973                          * \NOTE
974                          * I cannot believe client.
975                          * So I added some log before & after call the user callback.
976                          */
977                         if (handler->size_changed_cb) {
978                                 ret_cb_t cb;
979                                 void *cbdata;
980
981                                 cb = handler->size_changed_cb;
982                                 cbdata = handler->size_cbdata;
983
984                                 handler->size_changed_cb = NULL;
985                                 handler->size_cbdata = NULL;
986
987                                 cb(handler, status, cbdata);
988                         } else {
989                                 lb_invoke_event_handler(handler, LB_EVENT_LB_SIZE_CHANGED);
990                         }
991                 } else {
992                         if (handler->size_changed_cb) {
993                                 ret_cb_t cb;
994                                 void *cbdata;
995
996                                 cb = handler->size_changed_cb;
997                                 cbdata = handler->size_cbdata;
998
999                                 handler->size_changed_cb = NULL;
1000                                 handler->size_cbdata = NULL;
1001
1002                                 cb(handler, status, cbdata);
1003                         }
1004                 }
1005         }
1006
1007 out:
1008         return NULL;
1009 }
1010
1011 static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet)
1012 {
1013         struct livebox *handler;
1014         const char *pkgname;
1015         const char *id;
1016         int ret;
1017         double period;
1018         int status;
1019
1020         ret = packet_get(packet, "idss", &status, &period, &pkgname, &id);
1021         if (ret != 4) {
1022                 ErrPrint("Invalid argument\n");
1023                 goto out;
1024         }
1025
1026         handler = lb_find_livebox(pkgname, id);
1027         if (!handler) {
1028                 ErrPrint("Livebox(%s) is not found\n", id);
1029                 goto out;
1030         }
1031
1032         if (handler->state != CREATE) {
1033                 ErrPrint("Livebox(%s) is not created\n", id);
1034                 goto out;
1035         }
1036
1037         if (status == 0) {
1038                 lb_set_period(handler, period);
1039         }
1040
1041         if (handler->period_changed_cb) {
1042                 ret_cb_t cb;
1043                 void *cbdata;
1044
1045                 cb = handler->period_changed_cb;
1046                 cbdata = handler->period_cbdata;
1047
1048                 handler->period_changed_cb = NULL;
1049                 handler->period_cbdata = NULL;
1050
1051                 cb(handler, status, cbdata);
1052         } else if (status == 0) {
1053                 lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED);
1054         }
1055
1056 out:
1057         return NULL;
1058 }
1059
1060 static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet)
1061 {
1062         struct livebox *handler;
1063         const char *pkgname;
1064         const char *id;
1065         int ret;
1066         const char *cluster;
1067         const char *category;
1068         int status;
1069
1070         ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category);
1071         if (ret != 5) {
1072                 ErrPrint("Invalid argument\n");
1073                 goto out;
1074         }
1075
1076         handler = lb_find_livebox(pkgname, id);
1077         if (!handler) {
1078                 ErrPrint("Livebox(%s) is not exists\n", id);
1079                 goto out;
1080         }
1081
1082         if (handler->state != CREATE) {
1083                 /*!
1084                  * \note
1085                  * Do no access this handler,
1086                  * You cannot believe this handler anymore.
1087                  */
1088                 ErrPrint("Livebox(%s) is not created\n", id);
1089                 goto out;
1090         }
1091
1092         if (status == 0) {
1093                 (void)lb_set_group(handler, cluster, category);
1094         }
1095
1096         if (handler->group_changed_cb) {
1097                 ret_cb_t cb;
1098                 void *cbdata;
1099
1100                 cb = handler->group_changed_cb;
1101                 cbdata = handler->group_cbdata;
1102
1103                 handler->group_changed_cb = NULL;
1104                 handler->group_cbdata = NULL;
1105
1106                 cb(handler, status, cbdata);
1107         } else if (status == 0) {
1108                 lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED);
1109         }
1110
1111 out:
1112         return NULL;
1113 }
1114
1115 static struct packet *master_created(pid_t pid, int handle, const struct packet *packet)
1116 {
1117         struct livebox *handler;
1118
1119         int lb_w;
1120         int lb_h;
1121         int pd_w;
1122         int pd_h;
1123         const char *pkgname;
1124         const char *id;
1125
1126         const char *content;
1127         const char *cluster;
1128         const char *category;
1129         const char *lb_fname;
1130         const char *pd_fname;
1131         const char *title;
1132
1133         double timestamp;
1134         const char *auto_launch;
1135         double priority;
1136         int size_list;
1137         int user;
1138         int pinup_supported;
1139         enum lb_type lb_type;
1140         enum pd_type pd_type;
1141         double period;
1142         int is_pinned_up;
1143
1144         int old_state = DESTROYED;
1145
1146         int ret;
1147
1148         ret = packet_get(packet, "dsssiiiisssssdiiiiidsi",
1149                         &timestamp,
1150                         &pkgname, &id, &content,
1151                         &lb_w, &lb_h, &pd_w, &pd_h,
1152                         &cluster, &category, &lb_fname, &pd_fname,
1153                         &auto_launch, &priority, &size_list, &user, &pinup_supported,
1154                         &lb_type, &pd_type, &period, &title, &is_pinned_up);
1155         if (ret != 22) {
1156                 ErrPrint("Invalid argument\n");
1157                 ret = LB_STATUS_ERROR_INVALID;
1158                 goto out;
1159         }
1160
1161         ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, "
1162                 "pd_w: %d, pd_h: %d, lb_w: %d, lb_h: %d, "
1163                 "cluster: %s, category: %s, lb_fname: \"%s\", pd_fname: \"%s\", "
1164                 "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, "
1165                 "lb_type: %d, pd_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n",
1166                 timestamp, pkgname, id, content,
1167                 pd_w, pd_h, lb_w, lb_h,
1168                 cluster, category, lb_fname, pd_fname,
1169                 auto_launch, priority, size_list, user, pinup_supported,
1170                 lb_type, pd_type, period, title, is_pinned_up);
1171
1172         handler = lb_find_livebox_by_timestamp(timestamp);
1173         if (!handler) {
1174                 handler = lb_new_livebox(pkgname, id, timestamp);
1175                 if (!handler) {
1176                         ErrPrint("Failed to create a new livebox\n");
1177                         ret = LB_STATUS_ERROR_FAULT;
1178                         goto out;
1179                 }
1180
1181                 old_state = handler->state;
1182         } else {
1183                 if (handler->state != CREATE) {
1184                         if (handler->state != DELETE) {
1185                                 /*!
1186                                  * \note
1187                                  * This is not possible!!!
1188                                  */
1189                                 ErrPrint("Invalid handler\n");
1190                                 ret = LB_STATUS_ERROR_INVALID;
1191                                 goto out;
1192                         }
1193
1194                         /*!
1195                          * \note
1196                          * After get the delete states,
1197                          * call the create callback with deleted result.
1198                          */
1199                 }
1200
1201                 old_state = handler->state;
1202
1203                 if (handler->id) {
1204                         ErrPrint("Already created: timestamp[%lf] "
1205                                 "pkgname[%s], id[%s] content[%s] "
1206                                 "cluster[%s] category[%s] lb_fname[%s] pd_fname[%s]\n",
1207                                         timestamp, pkgname, id,
1208                                         content, cluster, category,
1209                                         lb_fname, pd_fname);
1210
1211                         ret = LB_STATUS_ERROR_ALREADY;
1212                         goto out;
1213                 }
1214
1215                 lb_set_id(handler, id);
1216         }
1217
1218         lb_set_size(handler, lb_w, lb_h);
1219         handler->lb.type = lb_type;
1220         handler->is_pinned_up = is_pinned_up;
1221
1222         switch (lb_type) {
1223         case _LB_TYPE_FILE:
1224                 break;
1225         case _LB_TYPE_SCRIPT:
1226         case _LB_TYPE_BUFFER:
1227                 if (!strlen(lb_fname)) {
1228                         break;
1229                 }
1230                 (void)lb_set_lb_fb(handler, lb_fname);
1231
1232                 /*!
1233                  * \note
1234                  * Livebox should create the lock file from here.
1235                  * Even if the old_state == DELETE,
1236                  * the lock file will be deleted from deleted event callback.
1237                  */
1238                 switch (fb_type(lb_get_lb_fb(handler))) {
1239                 case BUFFER_TYPE_FILE:
1240                 case BUFFER_TYPE_SHM:
1241                         lb_create_lock_file(handler, 0);
1242                         break;
1243                 case BUFFER_TYPE_PIXMAP:
1244                 case BUFFER_TYPE_ERROR:
1245                 default:
1246                         break;
1247                 }
1248
1249                 ret = livebox_sync_lb_fb(handler);
1250                 if (ret < 0) {
1251                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1252                 }
1253                 break;
1254         case _LB_TYPE_TEXT:
1255                 lb_set_text_lb(handler);
1256                 break;
1257         default:
1258                 break;
1259         }
1260
1261         handler->pd.type = pd_type;
1262         lb_set_pdsize(handler, pd_w, pd_h);
1263         lb_set_default_pdsize(handler, pd_w, pd_h);
1264         switch (pd_type) {
1265         case _PD_TYPE_SCRIPT:
1266         case _PD_TYPE_BUFFER:
1267                 if (!strlen(pd_fname)) {
1268                         break;
1269                 }
1270
1271                 lb_set_pd_fb(handler, pd_fname);
1272                 ret = livebox_sync_pd_fb(handler);
1273                 if (ret < 0) {
1274                         ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
1275                 }
1276
1277                 /*!
1278                  * \brief
1279                  * PD doesn't need to create the lock file from here.
1280                  * Just create it from PD_CREATED event.
1281                  */
1282
1283                 break;
1284         case _PD_TYPE_TEXT:
1285                 lb_set_text_pd(handler);
1286                 break;
1287         default:
1288                 break;
1289         }
1290
1291         lb_set_priority(handler, priority);
1292
1293         lb_set_size_list(handler, size_list);
1294         lb_set_group(handler, cluster, category);
1295
1296         lb_set_content(handler, content);
1297         lb_set_title(handler, title);
1298
1299         lb_set_user(handler, user);
1300
1301         lb_set_auto_launch(handler, auto_launch);
1302         lb_set_pinup(handler, pinup_supported);
1303
1304         lb_set_period(handler, period);
1305
1306         ret = 0;
1307
1308         if (handler->state == CREATE) {
1309                 /*!
1310                  * \note
1311                  * These callback can change the handler->state.
1312                  * So we have to use the "old_state" which stored state before call these callbacks
1313                  */
1314
1315                 if (handler->created_cb) {
1316                         ret_cb_t cb;
1317                         void *cbdata;
1318
1319                         cb = handler->created_cb;
1320                         cbdata = handler->created_cbdata;
1321
1322                         handler->created_cb = NULL;
1323                         handler->created_cbdata = NULL;
1324
1325                         cb(handler, ret, cbdata);
1326                 } else {
1327                         lb_invoke_event_handler(handler, LB_EVENT_CREATED);
1328                 }
1329         }
1330
1331 out:
1332         if (ret == 0 && old_state == DELETE) {
1333                 lb_send_delete(handler, handler->delete_type, handler->created_cb, handler->created_cbdata);
1334
1335                 /*!
1336                  * \note
1337                  * handler->created_cb = NULL;
1338                  * handler->created_cbdata = NULL;
1339                  *
1340                  * Do not clear this to use this from the deleted event callback.
1341                  * if this value is not cleared when the deleted event callback check it,
1342                  * it means that the created function is not called yet.
1343                  * Then the call the deleted event callback with LB_STATUS_ERROR_CANCEL errno.
1344                  */
1345         }
1346
1347         return NULL;
1348 }
1349
1350 static struct method s_table[] = {
1351         {
1352                 .cmd = "lb_updated", /* pkgname, id, lb_w, lb_h, priority, ret */
1353                 .handler = master_lb_updated,
1354         },
1355         {
1356                 .cmd = "pd_updated", /* pkgname, id, descfile, pd_w, pd_h, ret */
1357                 .handler = master_pd_updated,
1358         },
1359         {
1360                 .cmd = "pd_created",
1361                 .handler = master_pd_created,
1362         },
1363         {
1364                 .cmd = "pd_destroyed",
1365                 .handler = master_pd_destroyed,
1366         },
1367         {
1368                 .cmd = "fault_package", /* pkgname, id, function, ret */
1369                 .handler = master_fault_package,
1370         },
1371         {
1372                 .cmd = "deleted", /* pkgname, id, timestamp, ret */
1373                 .handler = master_deleted,
1374         },
1375         {
1376                 .cmd = "created", /* timestamp, pkgname, id, content, lb_w, lb_h, pd_w, pd_h, cluster, category, lb_file, pd_file, auto_launch, priority, size_list, is_user, pinup_supported, text_lb, text_pd, period, ret */
1377                 .handler = master_created,
1378         },
1379         {
1380                 .cmd = "group_changed",
1381                 .handler = master_group_changed,
1382         },
1383         {
1384                 .cmd = "period_changed",
1385                 .handler = master_period_changed,
1386         },
1387         {
1388                 .cmd = "size_changed",
1389                 .handler = master_size_changed,
1390         },
1391         {
1392                 .cmd = "pinup",
1393                 .handler = master_pinup,
1394         },
1395         {
1396                 .cmd = "scroll",
1397                 .handler = master_hold_scroll,
1398         },
1399
1400         {
1401                 .cmd = "update_mode",
1402                 .handler = master_update_mode,
1403         },
1404
1405         {
1406                 .cmd = "lb_update_begin",
1407                 .handler = master_lb_update_begin,
1408         },
1409         {
1410                 .cmd = "lb_update_end",
1411                 .handler = master_lb_update_end,
1412         },
1413
1414         {
1415                 .cmd = "pd_update_begin",
1416                 .handler = master_pd_update_begin,
1417         },
1418         {
1419                 .cmd = "pd_update_end",
1420                 .handler = master_pd_update_end,
1421         },
1422
1423         {
1424                 .cmd = "access_status",
1425                 .handler = master_access_status,
1426         },
1427         {
1428                 .cmd = "key_status",
1429                 .handler = master_key_status,
1430         },
1431         {
1432                 .cmd = "close_pd",
1433                 .handler = master_request_close_pd,
1434         },
1435
1436         {
1437                 .cmd = NULL,
1438                 .handler = NULL,
1439         },
1440 };
1441
1442 static void acquire_cb(struct livebox *handler, const struct packet *result, void *data)
1443 {
1444         if (!result) {
1445                 DbgPrint("Result packet is not valid\n");
1446         } else {
1447                 int ret;
1448
1449                 if (packet_get(result, "i", &ret) != 1) {
1450                         ErrPrint("Invalid argument\n");
1451                 } else {
1452                         DbgPrint("Acquire returns: %d\n", ret);
1453                 }
1454         }
1455
1456         return;
1457 }
1458
1459 static inline int make_connection(void)
1460 {
1461         struct packet *packet;
1462         int ret;
1463
1464         DbgPrint("Let's making connection!\n");
1465
1466         s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table);
1467         if (s_info.fd < 0) {
1468                 ErrPrint("Try this again later\n");
1469                 return LB_STATUS_ERROR_IO;
1470         }
1471
1472         packet = packet_create("acquire", "d", util_timestamp());
1473         if (!packet) {
1474                 com_core_packet_client_fini(s_info.fd);
1475                 s_info.fd = -1;
1476                 return LB_STATUS_ERROR_FAULT;
1477         }
1478
1479         ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL);
1480         if (ret < 0) {
1481                 ErrPrint("Master RPC returns %d\n", ret);
1482                 com_core_packet_client_fini(s_info.fd);
1483                 s_info.fd = -1;
1484                 return LB_STATUS_ERROR_IO;
1485         }
1486
1487         return LB_STATUS_SUCCESS;
1488 }
1489
1490 static int connected_cb(int handle, void *data)
1491 {
1492         master_rpc_check_and_fire_consumer();
1493         return 0;
1494 }
1495
1496 static void master_started_cb(keynode_t *node, void *data)
1497 {
1498         int state = 0;
1499
1500         if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) {
1501                 ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED);
1502         }
1503
1504         DbgPrint("Master state: %d\n", state);
1505         if (state == 1 && make_connection() == LB_STATUS_SUCCESS) {
1506                 int ret;
1507                 ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1508                 DbgPrint("master_started vconf key de-registered [%d]\n", ret);
1509         }
1510 }
1511
1512 static gboolean timeout_cb(gpointer data)
1513 {
1514         if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1515                 ErrPrint("Failed to add vconf for monitoring service state\n");
1516         } else {
1517                 DbgPrint("vconf event callback is registered\n");
1518         }
1519
1520         master_started_cb(NULL, NULL);
1521
1522         s_info.timer_id = 0;
1523         return FALSE;
1524 }
1525
1526 static int disconnected_cb(int handle, void *data)
1527 {
1528         if (s_info.fd != handle) {
1529                 /*!< This handle is not my favor */
1530                 return 0;
1531         }
1532
1533         s_info.fd = -1; /*!< Disconnected */
1534
1535         master_rpc_clear_all_request();
1536         lb_invoke_fault_handler(LB_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected");
1537
1538         lb_delete_all();
1539
1540         /* Try to reconnect after 1 sec later */
1541         if (!s_info.timer_id) {
1542                 DbgPrint("Reconnecting timer is added\n");
1543                 s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL);
1544                 if (s_info.timer_id == 0) {
1545                         ErrPrint("Unable to add reconnecting timer\n");
1546                         return 0;
1547                 }
1548         } else {
1549                 ErrPrint("Reconnecting timer is already exists\n");
1550         }
1551
1552         return 0;
1553 }
1554
1555 int client_init(int use_thread)
1556 {
1557         com_core_packet_use_thread(use_thread);
1558
1559         s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR);
1560         if (!s_info.client_addr) {
1561                 s_info.client_addr = strdup(CLIENT_SOCKET);
1562                 if (!s_info.client_addr) {
1563                         ErrPrint("Heap: %s\n", strerror(errno));
1564                         return -ENOMEM;
1565                 }
1566         }
1567
1568         (void)file_service_init();
1569
1570         DbgPrint("Server Address: %s\n", s_info.client_addr);
1571
1572         com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1573         com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1574         if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) {
1575                 ErrPrint("Failed to add vconf for service state\n");
1576         } else {
1577                 DbgPrint("vconf event callback is registered\n");
1578         }
1579
1580         master_started_cb(NULL, NULL);
1581         return 0;
1582 }
1583
1584 int client_fd(void)
1585 {
1586         return s_info.fd;
1587 }
1588
1589 const char *client_addr(void)
1590 {
1591         return s_info.client_addr;
1592 }
1593
1594 int client_fini(void)
1595 {
1596         int ret;
1597
1598         (void)file_service_fini();
1599
1600         ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb);
1601         if (ret < 0) {
1602                 DbgPrint("Ignore vconf key: %d\n", ret);
1603         }
1604
1605         com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
1606         com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
1607         com_core_packet_client_fini(s_info.fd);
1608         s_info.fd = -1;
1609         free(s_info.client_addr);
1610         s_info.client_addr = NULL;
1611         return LB_STATUS_SUCCESS;
1612 }
1613
1614 /* End of a file */