4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
32 #include <communicator.h>
34 #include <user_request.h>
35 #include <co_network.h>
39 #include "generated-code.h"
40 #include "dtapi_common.h"
42 static void __dtapi_initialize_properties(CoreObject *source,
43 TelephonyObjectSkeleton *object)
45 TelephonyNetwork *network;
46 TelephonyModem *modem;
50 err("object is NULL");
54 /* initialize network dbus properties */
55 network = telephony_object_peek_network(TELEPHONY_OBJECT(object));
56 if (network == NULL) {
57 err("Network object is NULL!!!");
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);
76 /* initialize modem dbus properties */
77 modem = telephony_object_peek_modem(TELEPHONY_OBJECT(object));
79 err("Modem object is NULL!!!");
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);
86 /* initialize sim dbus properties */
87 sim = telephony_object_peek_sim(TELEPHONY_OBJECT(object));
89 err("Sim object is NULL!!!");
91 telephony_sim_set_cf_state(sim, FALSE);
94 static void __dtapi_add_modem(struct custom_data *ctx, TcorePlugin *p)
96 TelephonyObjectSkeleton *object;
102 cp_name = tcore_server_get_cp_name_by_plugin(p);
103 if (cp_name == NULL) {
104 err("CP Name is NULL");
108 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
110 object = g_hash_table_lookup(ctx->objects, path);
112 dbg("DBUS interface object(%p) already created (path: %s)", object, path);
120 object = telephony_object_skeleton_new(path);
121 if (object == NULL) {
122 err("New DBUS object is NULL");
130 info("New DBUS object(%p) created (path: %s)", object, path);
131 g_hash_table_insert(ctx->objects, g_strdup(path), object);
139 * Interfaces are exposed only if Core object is available (supported)
141 /* Modem interface */
142 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_MODEM);
144 dbus_plugin_setup_modem_interface(object, ctx);
147 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
149 dbus_plugin_setup_call_interface(object, ctx);
151 /* Network interface */
152 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_NETWORK);
154 dbus_plugin_setup_network_interface(object, ctx);
157 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
159 dbus_plugin_setup_ss_interface(object, ctx);
162 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SMS);
164 dbus_plugin_setup_sms_interface(object, ctx);
167 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAT);
169 dbus_plugin_setup_sat_interface(object, ctx);
171 /* Phonebook interface */
172 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PHONEBOOK);
174 dbus_plugin_setup_phonebook_interface(object, ctx);
177 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SAP);
179 dbus_plugin_setup_sap_interface(object, ctx);
182 co = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SIM);
184 dbus_plugin_setup_sim_interface(object, ctx);
187 dbus_plugin_setup_oem_interface(object, ctx);
189 /* Export the Object to Manager */
190 g_dbus_object_manager_server_export(ctx->manager,
191 G_DBUS_OBJECT_SKELETON(object));
194 static void __dtapi_refresh_object(struct custom_data *ctx)
196 GSList *modem_plg_list;
197 TcorePlugin *modem_plg;
201 dbg("Telephony not ready...");
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;
209 __dtapi_add_modem(ctx, modem_plg); /* Add modem */
211 g_slist_free(modem_plg_list);
214 static gboolean on_manager_getmodems(TelephonyManager *mgr,
215 GDBusMethodInvocation *invocation, gpointer user_data)
217 struct custom_data *ctx = user_data;
218 GSList *cp_name_list;
219 GSList *cp_name_list_temp;
221 const char *name = NULL;
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);
230 count = g_slist_length(cp_name_list);
231 list = g_try_malloc0(sizeof(gchar *) * (count + 1));
233 err("Failed to allocate list");
234 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
236 /* Freeing the received list of CP names */
237 g_slist_free_full(cp_name_list, g_free);
244 * - Shouldn't move directly GSList pointer which is allocated in g_slist_append().
245 * - It cause memory leak.
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)
251 list[index] = g_strdup(cp_name_list_temp->data);
252 dbg("list[%d]: %s", index, list[index]);
255 telephony_manager_complete_get_modems(mgr, invocation, (const gchar **)list);
259 g_slist_free_full(cp_name_list, g_free);
264 static void on_name_lost(GDBusConnection *conn,
265 const gchar *name, gpointer user_data)
267 info("Lost the name '%s' on the Session bus!!!", name);
270 static void on_name_acquired(GDBusConnection *conn,
271 const gchar *name, gpointer user_data)
273 struct custom_data *ctx = user_data;
277 ctx->name_acquired = TRUE; /* Setting Bus acquried flag after Bus name is acquired */
279 info("Acquired the name '%s' on the Session bus", name);
280 strg = tcore_server_find_storage(ctx->server, "vconf");
282 count = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT);
284 err("SIM slot count not yet set");
286 if (tcore_storage_get_bool(strg, STORAGE_KEY_TELEPHONY_READY) == FALSE) {
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");
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!!!");
297 #ifdef ENABLE_KPI_LOGS
298 TIME_CHECK("Setting VCONFKEY_TELEPHONY_READY to TRUE");
300 msg("Setting VCONFKEY_TELEPHONY_READY to TRUE");
307 static void on_bus_acquired(GDBusConnection *conn,
308 const gchar *name, gpointer user_data)
310 struct custom_data *ctx = user_data;
312 info("dbus registered");
317 __dtapi_refresh_object(ctx);
320 * Add interface to 'default' object path
322 ctx->mgr = telephony_manager_skeleton_new();
325 * Register Manager signal handler(s)
327 g_signal_connect(ctx->mgr,
329 G_CALLBACK(on_manager_getmodems),
330 ctx); /* user_data */
333 * Export interface onto Connection (conn) with 'path' (MY_DBUS_PATH)
335 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(ctx->mgr),
336 conn, MY_DBUS_PATH, NULL);
339 * Exports all objects managed by 'manager' on Connection (conn)
341 g_dbus_object_manager_server_set_connection(ctx->manager, conn);
343 dbg("Aquire DBUS - COMPLETE");
346 static TReturn dtapi_send_response(Communicator *comm, UserRequest *ur,
347 enum tcore_response_command command, unsigned int data_len, const void *data)
349 struct custom_data *ctx = NULL;
350 struct dbus_request_info *dbus_info;
351 gboolean ret = FALSE;
353 ctx = tcore_communicator_ref_user_data(comm);
355 err("user_data is NULL");
356 return TCORE_RETURN_EINVAL;
359 dbus_info = (struct dbus_request_info *)tcore_user_request_ref_user_info(ur);
361 err("dbus_info is NULL");
362 return TCORE_RETURN_EINVAL;
367 FAIL_RESPONSE(dbus_info->invocation, "Request failed");
369 return TCORE_RETURN_SUCCESS;
372 dbg("cmd[0x%x] len[%d]", command, data_len);
374 switch (command & (TCORE_RESPONSE | 0x0FF00000)) {
376 ret = dbus_plugin_call_response(ctx, ur, dbus_info, command, data_len, data);
380 ret = dbus_plugin_ss_response(ctx, ur, dbus_info, command, data_len, data);
384 warn("Unhandled command (0x%x)", command);
388 ret = dbus_plugin_sim_response(ctx, ur, dbus_info, command, data_len, data);
392 ret = dbus_plugin_sap_response(ctx, ur, dbus_info, command, data_len, data);
395 case TRESP_PHONEBOOK:
396 ret = dbus_plugin_phonebook_response(ctx, ur, dbus_info, command, data_len, data);
400 ret = dbus_plugin_modem_response(ctx, ur, dbus_info, command, data_len, data);
404 ret = dbus_plugin_sms_response(ctx, ur, dbus_info, command, data_len, data);
408 ret = dbus_plugin_sat_response(ctx, ur, dbus_info, command, data_len, data);
412 ret = dbus_plugin_oem_response(ctx, ur, dbus_info, command, data_len, data);
416 ret = dbus_plugin_network_response(ctx, ur, dbus_info, command, data_len, data);
420 warn("unknown command (0x%x)", command);
425 return TCORE_RETURN_SUCCESS;
427 return TCORE_RETURN_FAILURE;
430 static TReturn dtapi_send_notification(Communicator *comm, CoreObject *source,
431 enum tcore_notification_command command, unsigned int data_len, const void *data)
433 struct custom_data *ctx = NULL;
434 unsigned int noti = 0;
435 gboolean ret = FALSE;
437 ctx = tcore_communicator_ref_user_data(comm);
439 err("user_data is NULL");
440 return TCORE_RETURN_EINVAL;
443 noti = (command & (TCORE_NOTIFICATION | 0x0FF00000));
446 * Notifications are classified into -
447 * Server (System) notifications
448 * Module notifications
450 if (noti == TNOTI_SERVER) {
451 dbg("Server (System) Notification (0x%x)", command);
454 case TNOTI_SERVER_ADDED_MODEM_PLUGIN: {
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);
460 __dtapi_add_modem(ctx, (TcorePlugin *)data); /* Add modem */
466 case TNOTI_SERVER_ADDED_MODEM_PLUGIN_COMPLETED: {
477 dbg("[%d] Modem plug-ins are added...", *count);
479 strg = tcore_server_find_storage(ctx->server, "vconf");
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");
485 /* Reset STORAGE_KEY_TELEPHONY_READY */
486 b_set = tcore_storage_set_bool(strg, STORAGE_KEY_TELEPHONY_READY, FALSE);
487 warn("Reset TELEPHONY_READY!!!");
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");
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!!!");
499 #ifdef ENABLE_KPI_LOGS
500 TIME_CHECK("Setting VCONFKEY_TELEPHONY_READY to TRUE");
502 msg("Setting VCONFKEY_TELEPHONY_READY to TRUE");
506 dbg("Bus acquired...[%s]", (ctx->name_acquired) ? "YES" : "NO");
512 case TNOTI_SERVER_REMOVED_MODEM_PLUGIN: {
513 TcorePlugin *plugin = tcore_communicator_ref_plugin(comm);
514 TelephonyObjectSkeleton *object;
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;
525 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
527 /* Look-up Hash table for Object */
528 object = g_hash_table_lookup(ctx->objects, path);
530 __dtapi_initialize_properties(source, object);
536 case TNOTI_SERVER_RUN:
537 dbg("TNOTI_SERVER_RUN");
540 case TNOTI_SERVER_ADDED_PLUGIN:
541 dbg("TNOTI_SERVER_ADDED_PLUGIN");
544 case TNOTI_SERVER_ADDED_COMMUNICATOR:
545 dbg("TNOTI_SERVER_ADDED_COMMUNICATOR");
548 case TNOTI_SERVER_ADDED_HAL:
549 dbg("TNOTI_SERVER_ADDED_HAL");
552 case TNOTI_SERVER_EXIT: {
553 Storage *strg = NULL;
555 dbg("TNOTI_SERVER_EXIT");
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);
562 * Exit Telephony daemon
564 if (TCORE_RETURN_SUCCESS == tcore_server_exit(ctx->server))
570 warn("Unsupported System notification: (0x%x)", command);
574 TelephonyObjectSkeleton *object;
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;
584 path = g_strdup_printf("%s/%s", MY_DBUS_PATH, cp_name);
586 /* Look-up Hash table for Object */
587 object = g_hash_table_lookup(ctx->objects, path);
589 dbg("[%s]:(cmd[0x%x] len[%d])", cp_name, command, data_len);
592 if (object == NULL) {
593 err("Object is NOT defined!!!");
594 return TCORE_RETURN_FAILURE;
599 ret = dbus_plugin_call_notification(ctx, source, object, command, data_len, data);
603 ret = dbus_plugin_ss_notification(ctx, source, object, command, data_len, data);
607 /* dbg("PS Notification (0x%x)... Not handled!!!", noti); */
611 ret = dbus_plugin_sim_notification(ctx, source, object, command, data_len, data);
615 ret = dbus_plugin_sap_notification(ctx, source, object, command, data_len, data);
618 case TNOTI_PHONEBOOK:
619 ret = dbus_plugin_phonebook_notification(ctx, source, object, command, data_len, data);
623 ret = dbus_plugin_modem_notification(ctx, source, object, command, data_len, data);
627 ret = dbus_plugin_sms_notification(ctx, source, object, command, data_len, data);
631 ret = dbus_plugin_sat_notification(ctx, source, object, command, data_len, data);
635 ret = dbus_plugin_network_notification(ctx, source, object, command, data_len, data);
639 if ((command & (TCORE_NOTIFICATION | 0x0F000000)) == TNOTI_CUSTOM)
640 ret = dbus_plugin_oem_notification(ctx, source, object, command, data_len, data);
642 warn("Unknown/Unhandled Notification: [0x%x]", command);
649 return TCORE_RETURN_SUCCESS;
651 return TCORE_RETURN_FAILURE;
655 * DBUS communicator operations
657 struct tcore_communicator_operations dbus_ops = {
658 .send_response = dtapi_send_response,
659 .send_notification = dtapi_send_notification,
662 gboolean dtapi_init(TcorePlugin *p)
665 struct custom_data *data;
670 data = calloc(1, sizeof(struct custom_data));
676 comm = tcore_communicator_new(p, "dbus", &dbus_ops);
677 tcore_communicator_link_user_data(comm, data);
680 data->server = tcore_plugin_ref_server(p);
682 data->objects = g_hash_table_new(g_str_hash, g_str_equal);
683 data->cached_data = NULL;
685 dbg("data = %p", data);
687 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
689 G_BUS_NAME_OWNER_FLAGS_REPLACE,
691 on_name_acquired, on_name_lost,
696 dbg("owner id=[%d]", data->owner_id);
698 data->manager = g_dbus_object_manager_server_new(MY_DBUS_PATH);
699 __dtapi_refresh_object(data);
704 void dtapi_deinit(TcorePlugin *p)
706 struct custom_data *data = 0;
707 Communicator *comm = 0;
708 Server *s = tcore_plugin_ref_server(p);
710 struct cached_data *object = NULL;
714 comm = tcore_server_find_communicator(s, "dbus");
718 data = tcore_communicator_ref_user_data(comm);
722 g_bus_unown_name(data->owner_id);
723 g_object_unref(data->manager);
724 g_hash_table_destroy(data->objects);
726 for (list = data->cached_data; list; list = list->next) {
727 object = (struct cached_data *)list->data;
731 g_variant_unref(object->cached_sat_main_menu);
732 g_free(object->cp_name);
735 g_slist_free(data->cached_data);
739 tcore_server_remove_communicator(s, comm);