add exception code for g_variant_iter_free()
[profile/ivi/tel-plugin-dbus_tapi.git] / src / desc-dbus.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 <pthread.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <glib.h>
28 #include <glib-object.h>
29 #include <gio/gio.h>
30
31 #include <tcore.h>
32 #include <server.h>
33 #include <plugin.h>
34 #include <hal.h>
35 #include <communicator.h>
36 #include <storage.h>
37 #include <queue.h>
38 #include <user_request.h>
39 #include <co_network.h>
40 #include <co_sim.h>
41 #include <co_ps.h>
42
43 #include "generated-code.h"
44 #include "common.h"
45
46 static void add_modem(struct custom_data *ctx, TcorePlugin *p)
47 {
48         TelephonyObjectSkeleton *object;
49         char *plugin_name = NULL;
50         char *path = NULL;
51         GSList *co_list = NULL;
52
53         plugin_name = tcore_plugin_ref_plugin_name(p);
54         if (!plugin_name)
55                 return;
56
57         path = g_strdup_printf("%s/%s", MY_DBUS_PATH, plugin_name);
58         dbg("path = [%s]", path);
59
60         object = g_hash_table_lookup(ctx->objects, path);
61         if (object) {
62                 dbg("dbus interface object already created. (object = %p)", object);
63                 goto OUT;
64         }
65
66         object = telephony_object_skeleton_new(path);
67         dbg("new dbus object created. (object = %p)", object);
68         g_hash_table_insert(ctx->objects, g_strdup(path), object);
69
70         /* Add interfaces */
71         dbus_plugin_setup_modem_interface(object, ctx);
72
73         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_CALL);
74         if (co_list) {
75                 g_slist_free(co_list);
76                 dbus_plugin_setup_call_interface(object, ctx);
77         }
78
79
80         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_NETWORK);
81         if (co_list) {
82                 g_slist_free(co_list);
83                 dbus_plugin_setup_network_interface(object, ctx);
84         }
85
86         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_SS);
87         if (co_list) {
88                 g_slist_free(co_list);
89                 dbus_plugin_setup_ss_interface(object, ctx);
90         }
91
92         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_SMS);
93         if (co_list) {
94                 g_slist_free(co_list);
95                 dbus_plugin_setup_sms_interface(object, ctx);
96         }
97
98         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_SAT);
99         if (co_list) {
100                 g_slist_free(co_list);
101                 dbus_plugin_setup_sat_interface(object, ctx);
102         }
103
104         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_PHONEBOOK);
105         if (co_list) {
106                 g_slist_free(co_list);
107                 dbus_plugin_setup_phonebook_interface(object, ctx);
108         }
109
110         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_SAP);
111         if (co_list) {
112                 g_slist_free(co_list);
113                 dbus_plugin_setup_sap_interface(object, ctx);
114         }
115
116         co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_SIM);
117         if (co_list) {
118                 g_slist_free(co_list);
119                 dbus_plugin_setup_sim_interface(object, ctx);
120         }
121
122         g_dbus_object_manager_server_export (ctx->manager, G_DBUS_OBJECT_SKELETON (object));
123
124 OUT:
125         if (path)
126                 g_free(path);
127 }
128
129 static void refresh_object(struct custom_data *ctx)
130 {
131         GSList *plugins;
132         GSList *cur;
133         GSList *co_list;
134         TcorePlugin *p;
135
136         if (!ctx->manager) {
137                 dbg("not ready..");
138                 return;
139         }
140
141         plugins = tcore_server_ref_plugins(ctx->server);
142         if (!plugins)
143                 return;
144
145         cur = plugins;
146         for (cur = plugins; cur; cur = cur->next) {
147                 p = cur->data;
148                 if (!p)
149                         continue;
150
151                 co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_MODEM);
152                 if (!co_list)
153                         continue;
154
155                 if (!tcore_object_get_hal(co_list->data)) {
156                         g_slist_free(co_list);
157                         continue;
158                 }
159
160                 g_slist_free(co_list);
161
162                 add_modem(ctx, p);
163         }
164 }
165
166 static TReturn send_response(Communicator *comm, UserRequest *ur, enum tcore_response_command command, unsigned int data_len, const void *data)
167 {
168         struct custom_data *ctx = NULL;
169         const struct tcore_user_info *ui;
170
171         dbg("Response Command = [0x%x], data_len = %d", command, data_len);
172
173         ctx = tcore_communicator_ref_user_data(comm);
174         if (!ctx) {
175                 dbg("user_data is NULL");
176                 return FALSE;
177         }
178
179         ui = tcore_user_request_ref_user_info(ur);
180
181         switch (command & (TCORE_RESPONSE | 0x0FF00000)) {
182                 case TRESP_CALL:
183                         dbus_plugin_call_response(ctx, ur, ui->user_data, command, data_len, data);
184                         break;
185
186                 case TRESP_SS:
187                         dbus_plugin_ss_response(ctx, ur, ui->user_data, command, data_len, data);
188                         break;
189
190                 case TRESP_PS:
191                         break;
192
193                 case TRESP_SIM:
194                         dbus_plugin_sim_response(ctx, ur, ui->user_data, command, data_len, data);
195                         break;
196
197                 case TRESP_SAP:
198                         dbus_plugin_sap_response(ctx, ur, ui->user_data, command, data_len, data);
199                         break;
200
201                 case TRESP_PHONEBOOK:
202                         dbus_plugin_phonebook_response(ctx, ur, ui->user_data, command, data_len, data);
203                         break;
204
205                 case TRESP_MODEM:
206                         dbus_plugin_modem_response(ctx, ur, ui->user_data, command, data_len, data);
207                         break;
208
209                 case TRESP_SMS:
210                         dbus_plugin_sms_response(ctx, ur, ui->user_data, command, data_len, data);
211                         break;
212
213                 case TRESP_SAT:
214                         dbus_plugin_sat_response(ctx, ur, ui->user_data, command, data_len, data);
215                         break;
216                 case TRESP_CUSTOM:
217                         break;
218
219                 case TRESP_NETWORK:
220                         dbus_plugin_network_response(ctx, ur, ui->user_data, command, data_len, data);
221                         break;
222
223                 default:
224                         warn("unknown command (0x%x)", command);
225                         break;
226         }
227
228         return FALSE;
229 }
230
231 static TReturn send_notification(Communicator *comm, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, const void *data)
232 {
233         struct custom_data *ctx = NULL;
234         char *plugin_name;
235         char *path;
236         TelephonyObjectSkeleton *object;
237
238         dbg("notification !!! (command = 0x%x, data_len = %d)", command, data_len);
239
240         ctx = tcore_communicator_ref_user_data(comm);
241         if (!ctx) {
242                 dbg("user_data is NULL");
243                 return FALSE;
244         }
245
246         plugin_name = tcore_plugin_ref_plugin_name(tcore_object_ref_plugin(source));
247         if (plugin_name) {
248                 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, plugin_name);
249         }
250         else {
251                 path = g_strdup_printf("%s", MY_DBUS_PATH);
252         }
253         dbg("path = [%s]", path);
254
255         object = g_hash_table_lookup(ctx->objects, path);
256         dbg("dbus inteface object = %p", object);
257
258         switch (command & (TCORE_NOTIFICATION | 0x0FF00000)) {
259                 case TNOTI_CALL:
260                         dbus_plugin_call_notification(ctx, plugin_name, object, command, data_len, data);
261                         break;
262
263                 case TNOTI_SS:
264                         dbus_plugin_ss_notification(ctx, plugin_name, object, command, data_len, data);
265                         break;
266
267                 case TNOTI_PS:
268                         break;
269
270                 case TNOTI_SIM:
271                         dbus_plugin_sim_notification(ctx, plugin_name, object, command, data_len, data);
272                         break;
273
274                 case TNOTI_SAP:
275                         dbus_plugin_sap_notification(ctx, plugin_name, object, command, data_len, data);
276                         break;
277
278                 case TNOTI_PHONEBOOK:
279                         dbus_plugin_phonebook_notification(ctx, plugin_name, object, command, data_len, data);
280                         break;
281
282                 case TNOTI_MODEM:
283                         dbus_plugin_modem_notification(ctx, plugin_name, object, command, data_len, data);
284                         break;
285
286                 case TNOTI_SMS:
287                         dbus_plugin_sms_notification(ctx, plugin_name, object, command, data_len, data);
288                         break;
289
290                 case TNOTI_SAT:
291                         dbus_plugin_sat_notification(ctx, plugin_name, object, command, data_len, data);
292                         break;
293                 case TNOTI_CUSTOM:
294                         break;
295
296                 case TNOTI_NETWORK:
297                         dbus_plugin_network_notification(ctx, plugin_name, object, command, data_len, data);
298                         break;
299
300                 case TNOTI_SERVER:
301                         if (command == TNOTI_SERVER_RUN) {
302                                 refresh_object(ctx);
303                         }
304                         break;
305
306                 default:
307                         warn("unknown command (0x%x)", command);
308                         break;
309         }
310
311         return FALSE;
312 }
313
314
315 static gboolean
316 on_manager_getmodems (TelephonyManager *mgr,
317                 GDBusMethodInvocation  *invocation,
318                 gpointer                user_data)
319 {
320         struct custom_data *ctx = user_data;
321         GSList *plugins;
322         GSList *cur;
323         GSList *co_list;
324         int max_count = 0;
325         int count;
326         TcorePlugin *p;
327         gchar **list;
328
329         plugins = tcore_server_ref_plugins(ctx->server);
330         if (!plugins) {
331                 telephony_manager_complete_get_modems(mgr, invocation, NULL);
332                 return TRUE;
333         }
334
335         max_count = g_slist_length(plugins);
336         list = calloc(sizeof(gchar *) * max_count, 1);
337         count = 0;
338
339         cur = plugins;
340         for (cur = plugins; cur; cur = cur->next) {
341                 p = cur->data;
342                 if (!p)
343                         continue;
344
345                 co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_MODEM);
346                 if (!co_list)
347                         continue;
348
349                 if (!tcore_object_get_hal(co_list->data)) {
350                         g_slist_free(co_list);
351                         continue;
352                 }
353                 g_slist_free(co_list);
354
355                 list[count] = g_strdup(tcore_plugin_get_description(p)->name);
356                 count++;
357         }
358
359         telephony_manager_complete_get_modems(mgr, invocation, (const gchar **)list);
360
361         for (;count >= 0; count--) {
362                 if (list[count]) {
363                         g_free(list[count]);
364                 }
365         }
366         free(list);
367
368         return TRUE;
369 }
370
371 static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
372 {
373         gboolean rv = FALSE;
374         gpointer handle = NULL;
375         static Storage *strg;
376         struct custom_data *ctx = user_data;
377         TelephonyManager *mgr;
378
379         ctx->manager = g_dbus_object_manager_server_new (MY_DBUS_PATH);
380
381         refresh_object(ctx);
382
383         /* Add interface to default object path */
384         mgr = telephony_manager_skeleton_new();
385         g_signal_connect (mgr,
386                         "handle-get-modems",
387                         G_CALLBACK (on_manager_getmodems),
388                         ctx); /* user_data */
389
390         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(mgr), conn, MY_DBUS_PATH, NULL);
391
392         g_dbus_object_manager_server_set_connection (ctx->manager, conn);
393
394         //set telephony ready registry
395         strg = tcore_server_find_storage(ctx->server, "vconf");
396         handle = tcore_storage_create_handle(strg, "vconf");
397
398         rv = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, TRUE);
399         if(!rv){
400                 dbg("fail to set the telephony status to registry");
401         }
402
403         dbg("done to acquire the dbus");
404 }
405
406 struct tcore_communitor_operations ops = {
407         .send_response = send_response,
408         .send_notification = send_notification,
409 };
410
411 static gboolean on_load()
412 {
413         dbg("i'm load!");
414
415         return TRUE;
416 }
417
418 static gboolean on_init(TcorePlugin *p)
419 {
420         Communicator *comm;
421         struct custom_data *data;
422         guint id;
423
424         if (!p)
425                 return FALSE;
426
427         dbg("i'm init!");
428
429         data = calloc(sizeof(struct custom_data), 1);
430         if (!data) {
431                 return FALSE;
432         }
433
434         data->plugin = p;
435
436         comm = tcore_communicator_new(p, "dbus", &ops);
437         tcore_communicator_link_user_data(comm, data);
438
439         data->comm = comm;
440         data->server = tcore_plugin_ref_server(p);
441
442         data->objects = g_hash_table_new(g_str_hash, g_str_equal);
443         data->cached_sat_main_menu = NULL;
444
445         dbg("data = %p", data);
446
447         id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
448                         MY_DBUS_SERVICE,
449                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
450                         on_bus_acquired,
451                         NULL, NULL,
452                         data,
453                         NULL);
454
455         return TRUE;
456 }
457
458 static void on_unload(TcorePlugin *p)
459 {
460         struct custom_data *data;
461         Communicator *comm;
462
463         if (!p)
464                 return;
465
466         dbg("i'm unload");
467
468         comm = tcore_server_find_communicator(tcore_plugin_ref_server(p), "dbus");
469         if (!comm)
470                 return;
471
472         data = tcore_communicator_ref_user_data(comm);
473         if (!data)
474                 return;
475
476         g_hash_table_destroy(data->objects);
477
478         free(data);
479 }
480
481 struct tcore_plugin_define_desc plugin_define_desc =
482 {
483         .name = "NEW_DBUS_COMMUNICATOR",
484         .priority = TCORE_PLUGIN_PRIORITY_HIGH,
485         .version = 1,
486         .load = on_load,
487         .init = on_init,
488         .unload = on_unload
489 };