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