d1260c32e22907faeb89c2529f16a376222cc031
[platform/core/telephony/tel-plugin-dbus_tapi.git] / src / dtapi_main.c
1 /*
2  * tel-plugin-dbus-tapi
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@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 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <time.h>
25
26 #include <glib.h>
27 #include <gio/gio.h>
28
29 #include <tcore.h>
30 #include <server.h>
31 #include <plugin.h>
32 #include <communicator.h>
33 #include <storage.h>
34 #include <user_request.h>
35 #include <co_network.h>
36 #include <co_sim.h>
37 #include <co_ps.h>
38
39 #include "generated-code.h"
40 #include "dtapi_common.h"
41
42 static void __dtapi_initialize_properties(CoreObject *source,
43         TelephonyObjectSkeleton *object)
44 {
45         TelephonyNetwork *network;
46         TelephonyModem *modem;
47         TelephonySim *sim;
48
49         if (!object) {
50                 err("object is NULL");
51                 return;
52         }
53
54         /* initialize network dbus properties */
55         network = telephony_object_peek_network(TELEPHONY_OBJECT(object));
56         if (network == NULL) {
57                 err("Network object is NULL!!!");
58         } else {
59                 telephony_network_set_access_technology(network, NETWORK_ACT_UNKNOWN);
60                 telephony_network_set_cell_id(network, 0);
61                 telephony_network_set_ims_voice_status(network, NETWORK_IMS_VOICE_UNKNOWN);
62                 telephony_network_set_circuit_status(network, NETWORK_SERVICE_DOMAIN_STATUS_NO);
63                 telephony_network_set_lac(network, 0);
64                 telephony_network_set_name_option(network, NETWORK_NAME_OPTION_NONE);
65                 telephony_network_set_packet_status(network, NETWORK_SERVICE_DOMAIN_STATUS_NO);
66                 telephony_network_set_sig_dbm(network, 0);
67                 telephony_network_set_roaming_status(network, FALSE);
68                 telephony_network_set_ps_type(network, TELEPHONY_HSDPA_OFF);
69                 telephony_network_set_service_type(network, NETWORK_SERVICE_TYPE_UNKNOWN);
70                 telephony_network_set_sig_level(network, 0);
71                 telephony_network_set_plmn(network, NULL);
72                 telephony_network_set_spn_name(network, NULL);
73                 telephony_network_set_network_name(network, NULL);
74         }
75
76         /* initialize modem dbus properties */
77         modem = telephony_object_peek_modem(TELEPHONY_OBJECT(object));
78         if (modem == NULL) {
79                 err("Modem object is NULL!!!");
80         } else {
81                 telephony_modem_set_dongle_status(modem, 0);
82                 telephony_modem_set_dongle_login(modem, 0);
83                 telephony_modem_set_power(modem, MODEM_STATE_UNKNOWN);
84         }
85
86         /* initialize sim dbus properties */
87         sim = telephony_object_peek_sim(TELEPHONY_OBJECT(object));
88         if (sim == NULL)
89                 err("Sim object is NULL!!!");
90         else
91                 telephony_sim_set_cf_state(sim, FALSE);
92 }
93
94 static void __dtapi_add_modem(struct custom_data *ctx, TcorePlugin *p)
95 {
96         TelephonyObjectSkeleton *object;
97         char *path = NULL;
98         CoreObject *co;
99         const char *cp_name;
100
101         /* Get CP Name */
102         cp_name = tcore_server_get_cp_name_by_plugin(p);
103         if (cp_name == NULL) {
104                 err("CP Name is NULL");
105                 return;
106         }
107
108         path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
109
110         object = g_hash_table_lookup(ctx->objects, path);
111         if (object) {
112                 dbg("DBUS interface object(%p) already created (path: %s)", object, path);
113
114                 /* Freeing memory */
115                 g_free(path);
116
117                 return;
118         }
119
120         object = telephony_object_skeleton_new(path);
121         if (object == NULL) {
122                 err("New DBUS object is NULL");
123
124                 /* Freeing memory */
125                 g_free(path);
126
127                 return;
128         }
129
130         info("New DBUS object(%p) created (path: %s)", object, path);
131         g_hash_table_insert(ctx->objects, g_strdup(path), object);
132
133         /* Freeing memory */
134         g_free(path);
135
136         /*
137          * Add interfaces
138          *
139          * Interfaces are exposed only if Core object is available (supported)
140          */
141         /* Modem interface */
142         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_MODEM);
143         if (co)
144                 dbus_plugin_setup_modem_interface(object, ctx);
145
146         /* Call interface */
147         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
148         if (co)
149                 dbus_plugin_setup_call_interface(object, ctx);
150
151         /* Network interface */
152         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_NETWORK);
153         if (co)
154                 dbus_plugin_setup_network_interface(object, ctx);
155
156         /* SS interface */
157         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
158         if (co)
159                 dbus_plugin_setup_ss_interface(object, ctx);
160
161         /* SMS interface */
162         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SMS);
163         if (co)
164                 dbus_plugin_setup_sms_interface(object, ctx);
165
166         /* SAT interface */
167         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAT);
168         if (co)
169                 dbus_plugin_setup_sat_interface(object, ctx);
170
171         /* Phonebook interface */
172         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PHONEBOOK);
173         if (co)
174                 dbus_plugin_setup_phonebook_interface(object, ctx);
175
176         /* SAP interface */
177         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAP);
178         if (co)
179                 dbus_plugin_setup_sap_interface(object, ctx);
180
181         /* SIM interface */
182         co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SIM);
183         if (co)
184                 dbus_plugin_setup_sim_interface(object, ctx);
185
186         /* OEM interface */
187         dbus_plugin_setup_oem_interface(object, ctx);
188
189         /* Export the Object to Manager */
190         g_dbus_object_manager_server_export(ctx->manager,
191         G_DBUS_OBJECT_SKELETON(object));
192 }
193
194 static void __dtapi_refresh_object(struct custom_data *ctx)
195 {
196         GSList *modem_plg_list;
197         TcorePlugin *modem_plg;
198         GSList *cur;
199
200         if (!ctx->manager) {
201                 dbg("Telephony not ready...");
202                 return;
203         }
204
205         modem_plg_list = tcore_server_get_modem_plugin_list(ctx->server);
206         for (cur = modem_plg_list; cur; cur = cur->next) {
207                 modem_plg = cur->data;
208                 if (modem_plg)
209                         __dtapi_add_modem(ctx, modem_plg); /* Add modem */
210         }
211         g_slist_free(modem_plg_list);
212 }
213
214 static gboolean on_manager_getmodems(TelephonyManager *mgr,
215         GDBusMethodInvocation  *invocation, gpointer user_data)
216 {
217         struct custom_data *ctx = user_data;
218         GSList *cp_name_list;
219         GSList *cp_name_list_temp;
220         gchar **list;
221         const char *name = NULL;
222         int count, index;
223
224         cp_name_list = tcore_server_get_cp_name_list(ctx->server);
225         if (cp_name_list == NULL) {
226                 telephony_manager_complete_get_modems(mgr, invocation, &name);
227                 return TRUE;
228         }
229
230         count = g_slist_length(cp_name_list);
231         list = g_try_malloc0(sizeof(gchar *) * (count + 1));
232         if (list == NULL) {
233                 err("Failed to allocate list");
234                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
235
236                 /* Freeing the received list of CP names */
237                 g_slist_free_full(cp_name_list, g_free);
238
239                 return TRUE;
240         }
241
242         /*
243          * fix memory leak
244          *  - Shouldn't move directly GSList pointer which is allocated in g_slist_append().
245          *  - It cause memory leak.
246          */
247         for (index = 0; index < count; index++) {
248                 cp_name_list_temp = g_slist_nth(cp_name_list, index);
249                 if(cp_name_list_temp == NULL)
250                         continue;
251                 list[index] = g_strdup(cp_name_list_temp->data);
252                 dbg("list[%d]: %s", index, list[index]);
253         }
254
255         telephony_manager_complete_get_modems(mgr, invocation, (const gchar **)list);
256
257         /* Free memory */
258         g_strfreev(list);
259         g_slist_free_full(cp_name_list, g_free);
260
261         return TRUE;
262 }
263
264 static void on_name_lost(GDBusConnection *conn,
265         const gchar *name, gpointer user_data)
266 {
267         info("Lost the name '%s' on the Session bus!!!", name);
268 }
269
270 static void on_name_acquired(GDBusConnection *conn,
271         const gchar *name, gpointer user_data)
272 {
273         struct custom_data *ctx = user_data;
274         Storage *strg;
275         int count;
276
277         ctx->name_acquired = TRUE; /* Setting Bus acquried flag after Bus name is acquired */
278
279         info("Acquired the name '%s' on the Session bus", name);
280         strg = tcore_server_find_storage(ctx->server, "vconf");
281
282         count = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT);
283         if (count < 0) {
284                 err("SIM slot count not yet set");
285         } else {
286                 if (tcore_storage_get_bool(strg, STORAGE_KEY_TELEPHONY_READY) == FALSE) {
287                         gboolean b_set;
288
289                         b_set = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, TRUE);
290                         if (b_set == FALSE) {
291                                 err("Fail to set telephony ready");
292
293                                 /* Reset STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT */
294                                 b_set = tcore_storage_set_int(strg, STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT, -1);
295                                 warn("Reset STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT!!!");
296                         } else {
297 #ifdef ENABLE_KPI_LOGS
298                                 TIME_CHECK("Setting VCONFKEY_TELEPHONY_READY to TRUE");
299 #else
300                                 msg("Setting VCONFKEY_TELEPHONY_READY to TRUE");
301 #endif
302                         }
303                 }
304         }
305 }
306
307 static void on_bus_acquired(GDBusConnection *conn,
308         const gchar *name, gpointer user_data)
309 {
310         struct custom_data *ctx = user_data;
311
312         info("dbus registered");
313
314         /*
315          * Refresh object
316          */
317         __dtapi_refresh_object(ctx);
318
319         /*
320          * Add interface to 'default' object path
321          */
322         ctx->mgr = telephony_manager_skeleton_new();
323
324         /*
325          * Register Manager signal handler(s)
326          */
327         g_signal_connect(ctx->mgr,
328                 "handle-get-modems",
329                 G_CALLBACK(on_manager_getmodems),
330                 ctx); /* user_data */
331
332         /*
333          * Export interface onto Connection (conn) with 'path' (MY_DBUS_PATH)
334          */
335         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(ctx->mgr),
336                 conn, MY_DBUS_PATH, NULL);
337
338         /*
339          * Exports all objects managed by 'manager' on Connection (conn)
340          */
341         g_dbus_object_manager_server_set_connection(ctx->manager, conn);
342
343         dbg("Aquire DBUS - COMPLETE");
344 }
345
346 static TReturn dtapi_send_response(Communicator *comm, UserRequest *ur,
347         enum tcore_response_command command, unsigned int data_len, const void *data)
348 {
349         struct custom_data *ctx = NULL;
350         struct dbus_request_info *dbus_info;
351         gboolean ret = FALSE;
352
353         ctx = tcore_communicator_ref_user_data(comm);
354         if (!ctx) {
355                 err("user_data is NULL");
356                 return TCORE_RETURN_EINVAL;
357         }
358
359         dbus_info = (struct dbus_request_info *)tcore_user_request_ref_user_info(ur);
360         if (!dbus_info) {
361                 err("dbus_info is NULL");
362                 return TCORE_RETURN_EINVAL;
363         }
364
365         if (!data) {
366                 err("data is NULL");
367                 FAIL_RESPONSE(dbus_info->invocation, "Request failed");
368
369                 return TCORE_RETURN_SUCCESS;
370         }
371
372         dbg("cmd[0x%x] len[%d]", command, data_len);
373
374         switch (command & (TCORE_RESPONSE | 0x0FF00000)) {
375         case TRESP_CALL:
376                 ret = dbus_plugin_call_response(ctx, ur, dbus_info, command, data_len, data);
377         break;
378
379         case TRESP_SS:
380                 ret = dbus_plugin_ss_response(ctx, ur, dbus_info, command, data_len, data);
381         break;
382
383         case TRESP_PS:
384                 warn("Unhandled command (0x%x)", command);
385         break;
386
387         case TRESP_SIM:
388                 ret = dbus_plugin_sim_response(ctx, ur, dbus_info, command, data_len, data);
389         break;
390
391         case TRESP_SAP:
392                 ret = dbus_plugin_sap_response(ctx, ur, dbus_info, command, data_len, data);
393         break;
394
395         case TRESP_PHONEBOOK:
396                 ret = dbus_plugin_phonebook_response(ctx, ur, dbus_info, command, data_len, data);
397         break;
398
399         case TRESP_MODEM:
400                 ret = dbus_plugin_modem_response(ctx, ur, dbus_info, command, data_len, data);
401         break;
402
403         case TRESP_SMS:
404                 ret = dbus_plugin_sms_response(ctx, ur, dbus_info, command, data_len, data);
405         break;
406
407         case TRESP_SAT:
408                 ret = dbus_plugin_sat_response(ctx, ur, dbus_info, command, data_len, data);
409         break;
410
411         case TRESP_CUSTOM:
412                 ret = dbus_plugin_oem_response(ctx, ur, dbus_info, command, data_len, data);
413         break;
414
415         case TRESP_NETWORK:
416                 ret = dbus_plugin_network_response(ctx, ur, dbus_info, command, data_len, data);
417         break;
418
419         default:
420                 warn("unknown command (0x%x)", command);
421         break;
422         }
423
424         if (ret == TRUE)
425                 return TCORE_RETURN_SUCCESS;
426         else
427                 return TCORE_RETURN_FAILURE;
428 }
429
430 static TReturn dtapi_send_notification(Communicator *comm, CoreObject *source,
431         enum tcore_notification_command command, unsigned int data_len, const void *data)
432 {
433         struct custom_data *ctx = NULL;
434         unsigned int noti = 0;
435         gboolean ret = FALSE;
436
437         ctx = tcore_communicator_ref_user_data(comm);
438         if (ctx == NULL) {
439                 err("user_data is NULL");
440                 return TCORE_RETURN_EINVAL;
441         }
442
443         noti = (command & (TCORE_NOTIFICATION | 0x0FF00000));
444
445         /*
446          * Notifications are classified into -
447          *      Server (System) notifications
448          *      Module notifications
449          */
450         if (noti == TNOTI_SERVER) {
451                 dbg("Server (System) Notification (0x%x)", command);
452
453                 switch (command) {
454                 case TNOTI_SERVER_ADDED_MODEM_PLUGIN: {
455                         const char *cp_name;
456
457                         cp_name = tcore_server_get_cp_name_by_plugin((TcorePlugin *)data);
458                         dbg("Modem Plug-in (%s) is added... Exporting interfaces for the modem", cp_name);
459
460                         __dtapi_add_modem(ctx, (TcorePlugin *)data); /* Add modem */
461
462                         ret = TRUE;
463                 }
464                 break;
465
466                 case TNOTI_SERVER_ADDED_MODEM_PLUGIN_COMPLETED: {
467                         Storage *strg;
468                         gboolean b_set;
469                         int *count;
470
471                         if (data == NULL) {
472                                 err("data is NULL");
473                                 break;
474                         }
475
476                         count = (int *)data;
477                         dbg("[%d] Modem plug-ins are added...", *count);
478
479                         strg = tcore_server_find_storage(ctx->server, "vconf");
480
481                         b_set = tcore_storage_set_int(strg, STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT, *count);
482                         if (b_set == FALSE) {
483                                 err("Fail to set the sim slot count vconf");
484
485                                 /* Reset STORAGE_KEY_TELEPHONY_READY */
486                                 b_set = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, FALSE);
487                                 warn("Reset TELEPHONY_READY!!!");
488                         } else {
489                                 if (ctx->name_acquired == TRUE
490                                         && tcore_storage_get_bool(strg, STORAGE_KEY_TELEPHONY_READY) == FALSE) {
491                                         b_set = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, TRUE);
492                                         if (b_set == FALSE) {
493                                                 err("Fail to set telephony ready");
494
495                                                 /* Reset STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT */
496                                                 b_set = tcore_storage_set_int(strg, STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT, -1);
497                                                 warn("Reset STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT!!!");
498                                         } else {
499 #ifdef ENABLE_KPI_LOGS
500                                                 TIME_CHECK("Setting VCONFKEY_TELEPHONY_READY to TRUE");
501 #else
502                                                 msg("Setting VCONFKEY_TELEPHONY_READY to TRUE");
503 #endif
504                                         }
505                                 }
506                                 dbg("Bus acquired...[%s]", (ctx->name_acquired) ? "YES" : "NO");
507                         }
508                         ret = TRUE;
509                 }
510                 break;
511
512                 case TNOTI_SERVER_REMOVED_MODEM_PLUGIN: {
513                         TcorePlugin *plugin = tcore_communicator_ref_plugin(comm);
514                         TelephonyObjectSkeleton *object;
515                         const char *cp_name;
516                         char *path;
517
518                         dbg("plugin: [%p]", plugin);
519                         cp_name = tcore_server_get_cp_name_by_plugin((TcorePlugin *)data);
520                         if (cp_name == NULL) {
521                                 warn("CP name is NULL. cmd:(0x%x)", command);
522                                 return TCORE_RETURN_FAILURE;
523                         }
524
525                         path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
526
527                         /* Look-up Hash table for Object */
528                         object = g_hash_table_lookup(ctx->objects, path);
529
530                         __dtapi_initialize_properties(source, object);
531
532                         g_free(path);
533                 }
534                 break;
535
536                 case TNOTI_SERVER_RUN:
537                         dbg("TNOTI_SERVER_RUN");
538                 break;
539
540                 case TNOTI_SERVER_ADDED_PLUGIN:
541                         dbg("TNOTI_SERVER_ADDED_PLUGIN");
542                 break;
543
544                 case TNOTI_SERVER_ADDED_COMMUNICATOR:
545                         dbg("TNOTI_SERVER_ADDED_COMMUNICATOR");
546                 break;
547
548                 case TNOTI_SERVER_ADDED_HAL:
549                         dbg("TNOTI_SERVER_ADDED_HAL");
550                 break;
551
552                 case TNOTI_SERVER_EXIT: {
553                         Storage *strg = NULL;
554
555                         dbg("TNOTI_SERVER_EXIT");
556
557                         /* Reset STORAGE_KEY_TELEPHONY_READY */
558                         strg = tcore_server_find_storage(ctx->server, "vconf");
559                         tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, FALSE);
560
561                         /*
562                          * Exit Telephony daemon
563                          */
564                         if (TCORE_RETURN_SUCCESS == tcore_server_exit(ctx->server))
565                                 ret = TRUE;
566                 }
567                 break;
568
569                 default:
570                         warn("Unsupported System notification: (0x%x)", command);
571                 break;
572                 }
573         } else {
574                 TelephonyObjectSkeleton *object;
575                 const char *cp_name;
576                 char *path;
577
578                 cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
579                 if (cp_name == NULL) {
580                         warn("CP name is NULL. cmd:(0x%x)", command);
581                         return TCORE_RETURN_FAILURE;
582                 }
583
584                 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
585
586                 /* Look-up Hash table for Object */
587                 object = g_hash_table_lookup(ctx->objects, path);
588
589                 dbg("[%s]:(cmd[0x%x] len[%d])", cp_name, command, data_len);
590
591                 g_free(path);
592                 if (object == NULL) {
593                         err("Object is NOT defined!!!");
594                         return TCORE_RETURN_FAILURE;
595                 }
596
597                 switch (noti) {
598                 case TNOTI_CALL:
599                         ret = dbus_plugin_call_notification(ctx, source, object, command, data_len, data);
600                 break;
601
602                 case TNOTI_SS:
603                         ret = dbus_plugin_ss_notification(ctx, source, object, command, data_len, data);
604                 break;
605
606                 case TNOTI_PS:
607                         /* dbg("PS Notification (0x%x)... Not handled!!!", noti); */
608                 break;
609
610                 case TNOTI_SIM:
611                         ret = dbus_plugin_sim_notification(ctx, source, object, command, data_len, data);
612                 break;
613
614                 case TNOTI_SAP:
615                         ret = dbus_plugin_sap_notification(ctx, source, object, command, data_len, data);
616                 break;
617
618                 case TNOTI_PHONEBOOK:
619                         ret = dbus_plugin_phonebook_notification(ctx, source, object, command, data_len, data);
620                 break;
621
622                 case TNOTI_MODEM:
623                         ret = dbus_plugin_modem_notification(ctx, source, object, command, data_len, data);
624                 break;
625
626                 case TNOTI_SMS:
627                         ret = dbus_plugin_sms_notification(ctx, source, object, command, data_len, data);
628                 break;
629
630                 case TNOTI_SAT:
631                         ret = dbus_plugin_sat_notification(ctx, source, object, command, data_len, data);
632                 break;
633
634                 case TNOTI_NETWORK:
635                         ret = dbus_plugin_network_notification(ctx, source, object, command, data_len, data);
636                 break;
637
638                 default:
639                         if ((command & (TCORE_NOTIFICATION | 0x0F000000)) == TNOTI_CUSTOM)
640                                 ret = dbus_plugin_oem_notification(ctx, source, object, command, data_len, data);
641                         else
642                                 warn("Unknown/Unhandled Notification: [0x%x]", command);
643
644                 break;
645                 }
646         }
647
648         if (ret == TRUE)
649                 return TCORE_RETURN_SUCCESS;
650         else
651                 return TCORE_RETURN_FAILURE;
652 }
653
654 /*
655  * DBUS communicator operations
656  */
657 struct tcore_communicator_operations dbus_ops = {
658         .send_response = dtapi_send_response,
659         .send_notification = dtapi_send_notification,
660 };
661
662 gboolean dtapi_init(TcorePlugin *p)
663 {
664         Communicator *comm;
665         struct custom_data *data;
666         guint id;
667
668         dbg("Enter");
669
670         data = calloc(1, sizeof(struct custom_data));
671         if (!data)
672                 return FALSE;
673
674         data->plugin = p;
675
676         comm = tcore_communicator_new(p, "dbus", &dbus_ops);
677         tcore_communicator_link_user_data(comm, data);
678
679         data->comm = comm;
680         data->server = tcore_plugin_ref_server(p);
681
682         data->objects = g_hash_table_new(g_str_hash, g_str_equal);
683         data->cached_data = NULL;
684
685         dbg("data = %p", data);
686
687         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
688                 MY_DBUS_SERVICE,
689                 G_BUS_NAME_OWNER_FLAGS_REPLACE,
690                 on_bus_acquired,
691                 on_name_acquired, on_name_lost,
692                 data,
693                 NULL);
694
695         data->owner_id = id;
696         dbg("owner id=[%d]", data->owner_id);
697
698         data->manager = g_dbus_object_manager_server_new(MY_DBUS_PATH);
699         __dtapi_refresh_object(data);
700
701         return TRUE;
702 }
703
704 void dtapi_deinit(TcorePlugin *p)
705 {
706         struct custom_data *data = 0;
707         Communicator *comm = 0;
708         Server *s = tcore_plugin_ref_server(p);
709         GSList *list = NULL;
710         struct cached_data *object = NULL;
711
712         dbg("Enter");
713
714         comm = tcore_server_find_communicator(s, "dbus");
715         if (!comm)
716                 return;
717
718         data = tcore_communicator_ref_user_data(comm);
719         if (!data)
720                 return;
721
722         g_bus_unown_name(data->owner_id);
723         g_object_unref(data->manager);
724         g_hash_table_destroy(data->objects);
725
726         for (list = data->cached_data; list; list = list->next) {
727                 object = (struct cached_data *)list->data;
728                 if (object == NULL)
729                         continue;
730
731                 g_variant_unref(object->cached_sat_main_menu);
732                 g_free(object->cp_name);
733                 g_free(object);
734         }
735         g_slist_free(data->cached_data);
736
737         free(data);
738
739         tcore_server_remove_communicator(s, comm);
740 }
741