00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023 #include <osso-ic-dbus.h>
00024 #include <osso-log.h>
00025 #include "rpc-dbus.h"
00026 #include "rpc-ic.h"
00027 #include "debug.h"
00028
00029 #define ICD_CONNECTED_SIGNAL "type='signal',interface='" ICD_DBUS_INTERFACE "',path='" ICD_DBUS_PATH "',member='" ICD_STATUS_CHANGED_SIG "',arg2='CONNECTED'"
00030
00031 static DBusHandlerResult _ic_connected(DBusConnection *connection, DBusMessage *message, void *user_data);
00032
00033 typedef struct _ICNotify {
00034 ICConnectedNotifyCb cb;
00035 gpointer user_data;
00036 } ICNotify;
00037
00038 static GSList *connection_notifies = NULL;
00039 static DBusConnection *system_bus = NULL;
00040 static GStaticMutex notify_mutex = G_STATIC_MUTEX_INIT;
00041
00042 static gboolean _ic_get_connected_bus(DBusConnection *bus) {
00043 DBusMessage *msg = NULL;
00044 ENTER_FUNC;
00045
00046 if (!bus) {
00047 LEAVE_FUNC;
00048 return FALSE;
00049 }
00050
00051 dbus_uint32_t state = 0;
00052 dbus_do_call(bus, &msg, FALSE, ICD_DBUS_SERVICE, ICD_DBUS_PATH,
00053 ICD_DBUS_INTERFACE, ICD_GET_STATE_REQ,
00054 DBUS_TYPE_INVALID);
00055
00056 if (msg != NULL) {
00057 dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &state,
00058 DBUS_TYPE_INVALID);
00059 dbus_message_unref(msg);
00060 }
00061
00062 LEAVE_FUNC;
00063 return state;
00064 }
00065
00066 gboolean ic_get_connected(void)
00067 {
00068 DBusConnection *conn;
00069 gboolean state;
00070 ENTER_FUNC;
00071 conn = get_dbus_connection(DBUS_BUS_SYSTEM);
00072
00073 if (!conn) {
00074 DEBUG("No connection.");
00075 LEAVE_FUNC;
00076 return FALSE;
00077 }
00078
00079 state = _ic_get_connected_bus(conn);
00080 dbus_connection_unref(conn);
00081
00082 DEBUG("Is connection: %d", state);
00083 LEAVE_FUNC;
00084 return state;
00085 }
00086
00087 void ic_wait_connection(ICConnectedNotifyCb cb, gpointer user_data)
00088 {
00089 ENTER_FUNC;
00090 gboolean connected;
00091 g_static_mutex_lock(¬ify_mutex);
00092
00093 if (system_bus == NULL) {
00094 DEBUG("Adding match %s and filter.", ICD_CONNECTED_SIGNAL);
00095 system_bus = get_dbus_connection(DBUS_BUS_SYSTEM);
00096 dbus_bus_add_match(system_bus, ICD_CONNECTED_SIGNAL, NULL);
00097 dbus_connection_add_filter(system_bus,
00098 _ic_connected, NULL,
00099 NULL);
00100 }
00101 connected = _ic_get_connected_bus(system_bus);
00102 if (!connected) {
00103 ICNotify *notify = g_new0(ICNotify, 1);
00104 notify->cb = cb;
00105 notify->user_data = user_data;
00106 connection_notifies = g_slist_append(connection_notifies,
00107 notify);
00108 }
00109
00110 if (connection_notifies == NULL && system_bus != NULL) {
00111 DEBUG("No notifies, removing match and filter.");
00112 dbus_connection_remove_filter(system_bus, _ic_connected, NULL);
00113 dbus_bus_remove_match(system_bus, ICD_CONNECTED_SIGNAL, NULL);
00114 dbus_connection_unref(system_bus);
00115 system_bus = NULL;
00116 } else {
00117 DLOG_DEBUG("Waiting for internet connection.");
00118 }
00119 g_static_mutex_unlock(¬ify_mutex);
00120
00121 if (connected) {
00122 cb(user_data);
00123 }
00124 LEAVE_FUNC;
00125 }
00126
00127 void ic_unwait_connection(ICConnectedNotifyCb cb, gpointer user_data)
00128 {
00129 GSList *iter;
00130 ENTER_FUNC;
00131 g_static_mutex_lock(¬ify_mutex);
00132 for (iter = connection_notifies; iter != NULL; iter = iter->next) {
00133 ICNotify *notify = iter->data;
00134
00135 if (notify->cb == cb &&
00136 notify->user_data == user_data) {
00137 g_free(notify);
00138 connection_notifies = g_slist_delete_link(connection_notifies,
00139 iter);
00140 break;
00141 }
00142 }
00143
00144 if (connection_notifies == NULL && system_bus != NULL) {
00145 dbus_connection_remove_filter(system_bus, _ic_connected, NULL);
00146 dbus_bus_remove_match(system_bus, ICD_CONNECTED_SIGNAL, NULL);
00147 dbus_connection_unref(system_bus);
00148 system_bus = NULL;
00149 }
00150 g_static_mutex_unlock(¬ify_mutex);
00151 LEAVE_FUNC;
00152 }
00153
00154 static DBusHandlerResult _ic_connected(DBusConnection *connection, DBusMessage *message, void *user_data)
00155 {
00156 (void)connection;
00157 (void)user_data;
00158
00159 ENTER_FUNC;
00160 if (dbus_message_is_signal(message, ICD_DBUS_INTERFACE, ICD_STATUS_CHANGED_SIG)) {
00161 GSList *notifies;
00162 const gchar *name;
00163 const gchar *type;
00164 const gchar *event;
00165
00166 DEBUG("%s signal from %d", ICD_STATUS_CHANGED_SIG, ICD_DBUS_INTERFACE);
00167
00168 dbus_message_get_args(message, NULL,
00169 DBUS_TYPE_STRING, &name,
00170 DBUS_TYPE_STRING, &type,
00171 DBUS_TYPE_STRING, &event,
00172 DBUS_TYPE_INVALID);
00173
00174 DEBUG("Args: %s, %s, %s", name, type, event);
00175
00176 if (strcmp(event, "CONNECTED") != 0) {
00177 LEAVE_FUNC;
00178 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00179 }
00180
00181 DLOG_DEBUG("Got connection, no longer waiting.");
00182
00183 g_static_mutex_lock(¬ify_mutex);
00184
00185 notifies = connection_notifies;
00186 connection_notifies = NULL;
00187
00188 dbus_connection_remove_filter(system_bus, _ic_connected, NULL);
00189 dbus_bus_remove_match(system_bus, ICD_CONNECTED_SIGNAL, NULL);
00190 dbus_connection_unref(system_bus);
00191 system_bus = NULL;
00192
00193 g_static_mutex_unlock(¬ify_mutex);
00194
00195 while (notifies) {
00196 ICNotify *notify = notifies->data;
00197 notify->cb(notify->user_data);
00198 g_free(notify);
00199 notifies = g_slist_delete_link(notifies, notifies);
00200 }
00201 }
00202 LEAVE_FUNC;
00203 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00204 }