Updating dlog TAG from TEL_PLUGIN_DBUS_TAPI to DBUS_TAPI and added additional logs.
[platform/core/telephony/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 #ifndef PLUGIN_VERSION
44 #define PLUGIN_VERSION 1
45 #endif
46
47 #include "generated-code.h"
48 #include "common.h"
49
50 static void add_modem(struct custom_data *ctx, TcorePlugin *p)
51 {
52         TelephonyObjectSkeleton *object;
53         static Storage *strg;
54         CoreObject *co_sim;
55         char *path = NULL;
56         const char *cp_name;
57         gboolean rv;
58         dbg("Entry");
59
60         /* Get CP Name */
61         cp_name = tcore_server_get_cp_name_by_plugin(p);
62         if (cp_name == NULL) {
63                 err("CP Name is NULL");
64                 return;
65         }
66
67         path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
68         dbg("PATH: [%s]", path);
69
70         object = g_hash_table_lookup(ctx->objects, path);
71         if (object == NULL) {
72                 /* Create new DBUS Interface object */
73                 object = telephony_object_skeleton_new(path);
74
75                 /* Insert the Object to DBUS interfaces HASH Table */
76                 dbg("New DBUS Interface object created!!! (object = %p)", object);
77                 if (object == NULL)
78                         goto OUT;
79
80                 g_hash_table_insert(ctx->objects, g_strdup(path), object);
81         } else
82                 dbg("DBUS Interface object already created!!! (object = %p)", object);
83
84
85         /* Add DBUS Interfaces for all Modules supported */
86
87         /* MODEM */
88         dbus_plugin_setup_modem_interface(object, ctx);
89
90         /* CALL */
91         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL) != NULL)
92                 dbus_plugin_setup_call_interface(object, ctx);
93
94         /* NETWORK */
95         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_NETWORK) != NULL)
96                 dbus_plugin_setup_network_interface(object, ctx);
97
98         /* SS */
99         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS) != NULL)
100                 dbus_plugin_setup_ss_interface(object, ctx);
101
102         /* SMS */
103         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SMS) != NULL)
104                 dbus_plugin_setup_sms_interface(object, ctx);
105
106         /* SIM */
107         co_sim = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SIM);
108         if (co_sim != NULL)
109                 dbus_plugin_setup_sim_interface(object, ctx);
110
111         /* SAT */
112         if ((co_sim != NULL) && (tcore_sim_get_status(co_sim) >= SIM_STATUS_INITIALIZING))
113                 if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAT) != NULL)
114                         dbus_plugin_setup_sat_interface(object, ctx);
115
116         /* PHONEBOOK */
117         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PHONEBOOK) != NULL)
118                 dbus_plugin_setup_phonebook_interface(object, ctx);
119
120         /* SAP */
121         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAP) != NULL)
122                 dbus_plugin_setup_sap_interface(object, ctx);
123
124         /* GPS */
125         if (tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_GPS) != NULL)
126                 dbus_plugin_setup_gps_interface(object, ctx);
127
128         /* Export the Object to Manager */
129         g_dbus_object_manager_server_export(ctx->manager, G_DBUS_OBJECT_SKELETON(object));
130
131         /*
132          * Set Telephony Ready registry
133          *
134          * At this point we can convey upper Layer that Telephony is Ready.
135          */
136         strg = tcore_server_find_storage(ctx->server, "vconf");
137         rv = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, TRUE);
138         if(rv == FALSE){
139                 err("Set Telephony Ready (TRUE) to registry - FAIL");
140         } else {
141                 dbg("Set Telephony Ready (TRUE) to registry - SUCCESS");
142         }
143
144 OUT:
145         /* Freeing memory */
146         g_free(path);
147 }
148
149 static void refresh_object(struct custom_data *ctx)
150 {
151         GSList *plugins;
152         GSList *cur;
153         TcorePlugin *p;
154         CoreObject *co;
155         dbg("Entry");
156
157         if (ctx->manager == NULL) {
158                 err("not ready..");
159                 return;
160         }
161
162         plugins = tcore_server_ref_plugins(ctx->server);
163         if (plugins == NULL)
164                 return;
165
166         cur = plugins;
167         for (cur = plugins; cur; cur = cur->next) {
168                 p = cur->data;
169                 /* AT Standard Plug-in is not considered */
170                 if ((p == NULL)
171                                 || (strcmp(tcore_plugin_ref_plugin_name(p), "AT") == 0)) {
172                         dbg("Plug-in Name: [%s]", tcore_plugin_ref_plugin_name(p));
173                         continue;
174                 }
175
176                 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_MODEM);
177                 if (co == NULL)
178                         continue;
179
180                 /* Add modem */
181                 add_modem(ctx, p);
182         }
183 }
184
185 static TReturn send_response(Communicator *comm, UserRequest *ur, enum tcore_response_command command, unsigned int data_len, const void *data)
186 {
187         struct custom_data *ctx = NULL;
188         const struct tcore_user_info *ui;
189
190         dbg("Response Command = [0x%x], data_len = %d", command, data_len);
191
192         ctx = tcore_communicator_ref_user_data(comm);
193         if (ctx == NULL) {
194                 dbg("user_data is NULL");
195                 return FALSE;
196         }
197
198         ui = tcore_user_request_ref_user_info(ur);
199
200         switch (command & (TCORE_RESPONSE | 0x0FF00000)) {
201                 case TRESP_CALL:
202                         dbus_plugin_call_response(ctx, ur, ui->user_data, command, data_len, data);
203                         break;
204
205                 case TRESP_SS:
206                         dbus_plugin_ss_response(ctx, ur, ui->user_data, command, data_len, data);
207                         break;
208
209                 case TRESP_PS:
210                         break;
211
212                 case TRESP_SIM:
213                         dbus_plugin_sim_response(ctx, ur, ui->user_data, command, data_len, data);
214                         break;
215
216                 case TRESP_SAP:
217                         dbus_plugin_sap_response(ctx, ur, ui->user_data, command, data_len, data);
218                         break;
219
220                 case TRESP_PHONEBOOK:
221                         dbus_plugin_phonebook_response(ctx, ur, ui->user_data, command, data_len, data);
222                         break;
223
224                 case TRESP_MODEM:
225                         dbus_plugin_modem_response(ctx, ur, ui->user_data, command, data_len, data);
226                         break;
227
228                 case TRESP_SMS:
229                         dbus_plugin_sms_response(ctx, ur, ui->user_data, command, data_len, data);
230                         break;
231
232                 case TRESP_SAT:
233                         dbus_plugin_sat_response(ctx, ur, ui->user_data, command, data_len, data);
234                         break;
235                 case TRESP_CUSTOM:
236                         break;
237
238                 case TRESP_NETWORK:
239                         dbus_plugin_network_response(ctx, ur, ui->user_data, command, data_len, data);
240                         break;
241
242                 case TRESP_GPS:
243                         dbus_plugin_gps_response(ctx, ur, ui->user_data, command, data_len, data);
244                         break;
245
246                 default:
247                         warn("unknown command (0x%x)", command);
248                         break;
249         }
250
251         return FALSE;
252 }
253
254 static TReturn send_notification(Communicator *comm, CoreObject *source, enum tcore_notification_command command, unsigned int data_len, const void *data)
255 {
256         struct custom_data *ctx = NULL;
257         TelephonyObjectSkeleton *object;
258         TcorePlugin *p;
259         const char *cp_name;
260         char *path = NULL;
261
262         dbg("Notification!!! (command = 0x%x, data_len = %d)", command, data_len);
263
264         if (command == TNOTI_SERVER_ADDED_PLUGIN)
265                 p = (TcorePlugin *)data;
266         else
267                 p = tcore_object_ref_plugin(source);
268
269         cp_name = tcore_server_get_cp_name_by_plugin(p);
270         if (cp_name == NULL)
271                 return TCORE_RETURN_FAILURE;
272         dbg("CP Name: [%s]", cp_name);
273
274         ctx = tcore_communicator_ref_user_data(comm);
275         if (ctx == NULL) {
276                 dbg("user_data is NULL");
277                 return TCORE_RETURN_FAILURE;
278         }
279
280         if (cp_name) {
281                 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
282         }
283         else {
284                 path = g_strdup_printf("%s", MY_DBUS_PATH);
285         }
286         dbg("PATH: [%s]", path);
287
288         object = g_hash_table_lookup(ctx->objects, path);
289         dbg("DBUS interface Object = [0x%x]", object);
290
291         switch (command & (TCORE_NOTIFICATION | 0x0FF00000)) {
292                 case TNOTI_CALL:
293                         dbus_plugin_call_notification(ctx, cp_name, object, command, data_len, data);
294                         break;
295
296                 case TNOTI_SS:
297                         dbus_plugin_ss_notification(ctx, cp_name, object, command, data_len, data);
298                         break;
299
300                 case TNOTI_PS:
301                         break;
302
303                 case TNOTI_SIM:
304                         dbus_plugin_sim_notification(ctx, cp_name, object, command, data_len, data);
305                         break;
306
307                 case TNOTI_SAP:
308                         dbus_plugin_sap_notification(ctx, cp_name, object, command, data_len, data);
309                         break;
310
311                 case TNOTI_PHONEBOOK:
312                         dbus_plugin_phonebook_notification(ctx, cp_name, object, command, data_len, data);
313                         break;
314
315                 case TNOTI_MODEM:
316                         dbus_plugin_modem_notification(ctx, cp_name, object, command, data_len, data);
317                         break;
318
319                 case TNOTI_SMS:
320                         dbus_plugin_sms_notification(ctx, cp_name, object, command, data_len, data);
321                         break;
322
323                 case TNOTI_SAT:
324                         dbus_plugin_sat_notification(ctx, cp_name, object, command, data_len, data);
325                         break;
326                 case TNOTI_CUSTOM:
327                         break;
328
329                 case TNOTI_NETWORK:
330                         dbus_plugin_network_notification(ctx, cp_name, object, command, data_len, data);
331                         break;
332
333                 case TNOTI_GPS:
334                         dbus_plugin_gps_notification(ctx, cp_name, object, command, data_len, data);
335                         break;
336
337                 case TNOTI_SERVER:
338                         dbg("Server Notification");
339                         if (command == TNOTI_SERVER_ADDED_PLUGIN) {
340                                 dbg("Plug-in is added... Refresh the context");
341                                 refresh_object(ctx);
342                         }
343                         break;
344
345                 default:
346                         warn("unknown command (0x%x)", command);
347                         break;
348         }
349
350         return FALSE;
351 }
352
353
354 static gboolean
355 on_manager_getmodems (TelephonyManager *mgr,
356                 GDBusMethodInvocation  *invocation,
357                 gpointer                user_data)
358 {
359         struct custom_data *ctx = user_data;
360         GSList *cp_name_list;
361         gchar **list;
362         char *name;
363         int count;
364         dbg("Entry");
365
366         cp_name_list = tcore_server_get_cp_name_list(ctx->server);
367         if (cp_name_list == NULL) {
368                 telephony_manager_complete_get_modems(mgr, invocation, NULL);
369                 return TRUE;
370         }
371
372         count = g_slist_length(cp_name_list);
373         if (count == 0) {
374                 err("No Modems present");
375                 telephony_manager_complete_get_modems(mgr, invocation, NULL);
376                 return TRUE;
377         }
378
379         dbg("count: %d", count);
380         list = g_try_malloc0(sizeof(gchar *) * (count+1));
381         if (list == NULL) {
382                 err("Failed to allocate memory");
383                 g_slist_free_full(cp_name_list, g_free);
384
385                 telephony_manager_complete_get_modems(mgr, invocation, NULL);
386                 return TRUE;
387         }
388
389         count = 0;
390         for ( ; cp_name_list ; cp_name_list = cp_name_list->next) {
391                 name = cp_name_list->data;
392                 if (name == NULL)
393                         continue;
394
395                 list[count] = g_strdup(name);
396                 dbg("list[%d]: %s", count, list[count]);
397                 count++;
398         }
399
400         telephony_manager_complete_get_modems(mgr, invocation, (const gchar **)list);
401
402         /* Free memory */
403         for (;count >= 0; count--)
404                 g_free(list[count]);
405
406         g_free(list);
407
408         /* Freeing the received list of CP names */
409         g_slist_free_full(cp_name_list, g_free);
410
411         return TRUE;
412 }
413
414 static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
415 {
416         struct custom_data *ctx = user_data;
417         TelephonyManager *mgr;
418         info("DBUS Registered");
419
420         /* Add interface to default object path */
421         mgr = telephony_manager_skeleton_new();
422         g_signal_connect (mgr,
423                         "handle-get-modems",
424                         G_CALLBACK (on_manager_getmodems),
425                         ctx); /* user_data */
426
427         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(mgr), conn, MY_DBUS_PATH, NULL);
428
429         g_dbus_object_manager_server_set_connection (ctx->manager, conn);
430
431         dbg("Aquire DBUS - COMPLETE");
432
433         /* Refresh Object */
434         refresh_object(ctx);
435 }
436
437 struct tcore_communitor_operations ops = {
438         .send_response = send_response,
439         .send_notification = send_notification,
440 };
441
442 static gboolean on_load()
443 {
444         dbg("i'm load!");
445
446         return TRUE;
447 }
448
449 static gboolean on_init(TcorePlugin *p)
450 {
451         Communicator *comm;
452         struct custom_data *data;
453         guint id;
454
455         if (p == NULL)
456                 return FALSE;
457
458         dbg("i'm init!");
459
460         data = calloc(sizeof(struct custom_data), 1);
461         if (data == NULL) {
462                 return FALSE;
463         }
464
465         data->plugin = p;
466
467         comm = tcore_communicator_new(p, "dbus", &ops);
468         tcore_communicator_link_user_data(comm, data);
469
470         data->comm = comm;
471         data->server = tcore_plugin_ref_server(p);
472
473         data->objects = g_hash_table_new(g_str_hash, g_str_equal);
474         data->cached_sat_main_menu = NULL;
475
476         dbg("data = %p", data);
477
478         id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
479                         MY_DBUS_SERVICE,
480                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
481                         on_bus_acquired,
482                         NULL, NULL,
483                         data,
484                         NULL);
485
486         data->manager = g_dbus_object_manager_server_new (MY_DBUS_PATH);
487
488         refresh_object(data);
489
490         return TRUE;
491 }
492
493 static void on_unload(TcorePlugin *p)
494 {
495         struct custom_data *data;
496         Communicator *comm;
497
498         if (p == NULL)
499                 return;
500
501         dbg("i'm unload");
502
503         comm = tcore_server_find_communicator(tcore_plugin_ref_server(p), "dbus");
504         if (comm == NULL)
505                 return;
506
507         data = tcore_communicator_ref_user_data(comm);
508         if (data == NULL)
509                 return;
510
511         g_hash_table_destroy(data->objects);
512
513         free(data);
514 }
515
516 struct tcore_plugin_define_desc plugin_define_desc =
517 {
518         .name = "NEW_DBUS_COMMUNICATOR",
519         .priority = TCORE_PLUGIN_PRIORITY_HIGH,
520         .version = PLUGIN_VERSION,
521         .load = on_load,
522         .init = on_init,
523         .unload = on_unload
524 };