Adding support to asynchronous connections to Maemo conic device
- From: Sergio Villar Senin <svillar igalia com>
- To: tinymail-devel-list gnome org
- Subject: Adding support to asynchronous connections to Maemo conic device
- Date: Fri, 09 Nov 2007 11:37:49 +0100
Hi,
find attached a patch that adds a new API to the Maemo conic device to
allow asynchronous connections. This patch comes from the initial work
by Philip and was lately modified by me. Basically I restored the old
sync connect API (Philip just threw it away) and renamed the new async
functions with the suffix _async like many other tinymail functions. I
had also to fix a problem with the linker that was not including the
conic symbols (due to they were not used inside libtinymail-maemo).
Br
Index: configure.ac
===================================================================
--- configure.ac (revision 2932)
+++ configure.ac (working copy)
@@ -67,6 +67,7 @@
build_tests=false
build_unittests=false
build_tp=false
+have_conic=false
PLATFORMDIR=libtinymail-gnome-desktop
PLATFORM=1
@@ -428,26 +429,23 @@
if $PKG_CONFIG --exists conic; then
PKG_CHECK_MODULES(LIBTINYMAIL_MAEMO_CONIC,conic,HAVE_CONIC=yes,HAVE_CONIC=no)
AC_MSG_RESULT(conic)
- MAEMO_DEVICE='tny-maemo-conic-device.$(OBJEXT)'
AC_SUBST(LIBYINYMAIL_MAEMO_CONIC_CFLAGS)
AC_SUBST(LIBTINYMAIL_MAEMO_CONIC_LIBS)
-dnl HACK: unless we are building for arm, make the device a 'dummy' assuming it is always online
-dnl this is because scratcbhox-Conic does not support ethernet, and will therefore never consider
-dnl itself 'online'
+ dnl HACK: unless we are building for arm, make the device a 'dummy' assuming it is always online
+ dnl this is because scratcbhox-Conic does not support ethernet, and will therefore never consider
+ dnl itself 'online'
if test -z "`sb-conf show -c | grep arm`"; then
+ use_conic_device_dummy=1
AC_DEFINE_UNQUOTED(MAEMO_CONIC_DUMMY,1,["Whether to hack the TnyMaemoConicDevice to somewhat work in sbox"])
fi
+ AM_CONDITIONAL(MAEMO_CONIC_DEVICE_DUMMY, test -n "$use_conic_device_dummy")
fi
- AC_SUBST([MAEMO_DEVICE])
AC_SUBST(LIBTINYMAIL_MAEMO_CFLAGS)
AC_SUBST(LIBTINYMAIL_MAEMO_LIBS)
fi
-
AM_CONDITIONAL(BUILD_MAEMO, test x$build_maemo = xtrue)
-
-
dnl ### libtinymail-gpe, a platform library implementation for the GPE platform ##
if test x$PLATFORMDIR = xlibtinymail-gpe; then
PKG_CHECK_MODULES(LIBTINYMAIL_GPE, glib-2.0 >= 2.8 gobject-2.0 gconf-2.0 gtk+-2.0)
Index: libtinymail-maemo/tny-maemo-conic-device.h
===================================================================
--- libtinymail-maemo/tny-maemo-conic-device.h (revision 2932)
+++ libtinymail-maemo/tny-maemo-conic-device.h (working copy)
@@ -55,6 +55,11 @@
TnyDevice* tny_maemo_conic_device_new (void);
gboolean tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id);
+typedef void (*TnyMaemoConicDeviceConnectCallback) (TnyMaemoConicDevice *self, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data);
+void tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self,
+ const gchar* iap_id,
+ TnyMaemoConicDeviceConnectCallback callback,
+ gpointer user_data);
gboolean tny_maemo_conic_device_disconnect (TnyMaemoConicDevice *self, const gchar* iap_id);
const gchar* tny_maemo_conic_device_get_current_iap_id (TnyMaemoConicDevice *self);
ConIcIap* tny_maemo_conic_device_get_iap (TnyMaemoConicDevice *self, const gchar *iap_id);
Index: libtinymail-maemo/Makefile.am
===================================================================
--- libtinymail-maemo/Makefile.am (revision 2932)
+++ libtinymail-maemo/Makefile.am (working copy)
@@ -10,7 +10,6 @@
-I$(top_srcdir)/libtinymail-gnomevfs \
-DDBUS_API_SUBJECT_TO_CHANGE
-
lib_LTLIBRARIES = libtinymail-maemo-1.0.la
libtinymail_maemo_1_0_headers = \
@@ -25,21 +24,20 @@
tny-maemo-device.c \
tny-maemo-platform-factory.c
-EXTRA_libtinymail_maemo_1_0_la_SOURCES = \
- tny-maemo-conic-device.c
-
+if MAEMO_CONIC_DEVICE_DUMMY
+libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-dummy-device.c
+else
+libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-device.c
+endif
+
libtinymail_maemo_1_0_la_LIBADD = \
$(LIBTINYMAIL_MAEMO_LIBS) \
$(LIBTINYMAIL_MAEMO_CONIC_LIBS) \
- @MAEMO_DEVICE@ \
$(top_builddir)/libtinymail/libtinymail-$(API_VERSION).la \
$(top_builddir)/libtinymailui/libtinymailui-$(API_VERSION).la \
$(top_builddir)/libtinymailui-gtk/libtinymailui-gtk-$(API_VERSION).la \
$(top_builddir)/libtinymail-camel/libtinymail-camel-$(API_VERSION).la
-libtinymail_maemo_1_0_la_DEPENDENCIES=\
- @MAEMO_DEVICE@
-
libtinymail_maemo_1_0_la_LDFLAGS = -export-dynamic \
-version-info $(LT_VERSION_INFO) $(LIBTOOL_EXPORT_OPTIONS)
Index: libtinymail-maemo/tny-maemo-conic-device.c
===================================================================
--- libtinymail-maemo/tny-maemo-conic-device.c (revision 2932)
+++ libtinymail-maemo/tny-maemo-conic-device.c (working copy)
@@ -1,4 +1,4 @@
-/* libtinymail-camel - The Tiny Mail base library for Camel
+/* libtinymail-camel - The Tiny Mail base library for Maemo
* Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof gnome org>
*
* This library is free software; you can redistribute it and/or
@@ -25,66 +25,34 @@
#include <coniciap.h>
#include <conicconnection.h>
#include <conicconnectionevent.h>
+#include <string.h>
+#include <tny-error.h>
#include <gdk/gdk.h> /* For GDK_THREAD_ENTER/LEAVE */
-#include <string.h> /* For strcmp() */
+static void stop_loop (TnyMaemoConicDevice *self);
-#ifdef MAEMO_CONIC_DUMMY
-#include <gtk/gtkmessagedialog.h>
-#endif
-
-
-
-static gboolean
-dnsmasq_has_resolv (void)
-{
- /* This is because silly Conic does not have a blocking API that tells
- * us immediately when the device is online. */
-
- if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS))
- if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS))
- if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS))
- return FALSE;
-
- return TRUE;
-}
-
-#ifdef MAEMO_CONIC_DUMMY
-/* #include "coniciap-private.h"
- * This is not installed, so we predeclare the struct instead. Of course, this
- * is a hack and could break if the private API changes. It would be better for
- * libconic to support scratchbox. */
-
-struct _ConIcIap
-{
- GObject parent_instance;
- gboolean dispose_has_run;
- gchar *id;
- gchar *name;
- gchar *bearer;
-};
-
-#define MAEMO_CONIC_DUMMY_IAP_ID_FILENAME "maemo_conic_dummy_id"
-#define MAEMO_CONIC_DUMMY_IAP_ID_NONE "none"
-static gboolean on_dummy_connection_check (gpointer user_data);
-#endif /* MAEMO_CONIC_DUMMY */
-
static gboolean tny_maemo_conic_device_is_online (TnyDevice *self);
static GObjectClass *parent_class = NULL;
typedef struct {
+ TnyMaemoConicDevice *self;
+ gchar* iap_id;
+ gpointer user_data;
+ TnyMaemoConicDeviceConnectCallback callback;
+} ConnectInfo;
+
+typedef struct {
ConIcConnection *cnx;
gboolean is_online;
gchar *iap;
gboolean forced; /* Whether the is_online value is forced rather than real. */
+ ConnectInfo *connect_slot;
/* When non-NULL, we are waiting for the success or failure signal. */
GMainLoop *loop;
-#ifdef MAEMO_CONIC_DUMMY
- gint dummy_env_check_timeout;
-#endif /* MAEMO_CONIC_DUMMY */
} TnyMaemoConicDevicePriv;
+
#define TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_MAEMO_CONIC_DEVICE, TnyMaemoConicDevicePriv))
@@ -94,12 +62,26 @@
} EmitStatusInfo;
static gboolean
+dnsmasq_has_resolv (void)
+{
+ /* This is because silly Conic does not have a blocking API that tells
+ * us immediately when the device is online. */
+
+ if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS))
+ if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS))
+ if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
conic_emit_status_idle (gpointer user_data)
{
EmitStatusInfo *info = (EmitStatusInfo *) user_data;
- /* We lock the gdk thread because tinymail wants implementations to do this
- * before emitting _any_ signals.
+ /* We lock the gdk thread because tinymail wants implementations to do
+ * this before emitting signals from within a g_idle_add_full callback.
* See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */
gdk_threads_enter ();
@@ -122,46 +104,19 @@
static void
conic_emit_status (TnyDevice *self, gboolean status)
{
- /* If there is a mainloop (if gtk_main() has been run, for instance),
- * then emit the signal via an idle callback, so that it is
- * always emitted in the main context as required by tinymail
- * (libconic does not give any guarantee
- * about this - it would be nice if libconic documented that).
- * But if there is no mainloop, then just emit it, as tinymail
- * requires when there is no mainloop: */
+ /* Emit it in an idle handler: */
+ EmitStatusInfo *info = g_slice_new (EmitStatusInfo);
+ guint time = 1000;
- /* TODO: We have no way to check for this now, and
- * at this time it's not even clear whether tinymail should/can really
- * demand this. murrayc. 15th Aug. 2007. */
+ info->self = g_object_ref (self);
+ info->status = status;
- if (TRUE) /* TODO: But NULL is not allowed here: g_main_loop_is_running (NULL)) */
- {
- /* Emit it in an idle handler: */
- EmitStatusInfo *info = g_slice_new (EmitStatusInfo);
- guint time = 5000;
+ if (!dnsmasq_has_resolv())
+ time = 5000;
- info->self = g_object_ref (self);
- info->status = status;
+ g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle,
+ info, conic_emit_status_destroy);
- if (!dnsmasq_has_resolv())
- time = 5000;
-
- g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle,
- info, conic_emit_status_destroy);
-
- } else {
- /* Emit it directly: */
-
- /* We lock the gdk thread because tinymail wants implementations
- * to do this before emitting _any_ signals.
- * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */
-
- gdk_threads_enter ();
- g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, status);
- gdk_threads_leave ();
- }
-
return;
}
@@ -185,17 +140,81 @@
return;
}
-#ifndef MAEMO_CONIC_DUMMY
-
-static void
-stop_loop (TnyMaemoConicDevice *self)
+static void
+handle_connect (TnyMaemoConicDevice *self, int con_err, int con_state)
{
TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
- if (priv->loop)
- g_main_loop_quit (priv->loop);
+
+ if (priv->connect_slot)
+ {
+ GError *err = NULL;
+ gboolean canceled = FALSE;
+ ConnectInfo *info = priv->connect_slot;
+
+ /* Mark it as handled (TODO, this needs a small lock) */
+ priv->connect_slot = NULL;
+
+ switch (con_err) {
+ case CON_IC_CONNECTION_ERROR_NONE:
+ break;
+ case CON_IC_CONNECTION_ERROR_INVALID_IAP:
+ g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC,
+ "IAP is invalid");
+ break;
+ case CON_IC_CONNECTION_ERROR_CONNECTION_FAILED:
+ g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC,
+ "Connection failed");
+ break;
+ case CON_IC_CONNECTION_ERROR_USER_CANCELED:
+ default:
+ canceled = TRUE;
+ break;
+ }
+
+ if (info->callback) {
+ /* We lock the gdk thread because tinymail wants implementations to do
+ * this before invoking callbacks from within a g_idle_add_full callback.
+ * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */
+
+ gdk_threads_enter ();
+ info->callback (info->self, info->iap_id, canceled, err, info->user_data);
+ gdk_threads_leave ();
+ }
+
+ if (err)
+ g_error_free (err);
+
+ g_object_unref (info->self);
+ g_free (info->self);
+ g_slice_free (ConnectInfo, info);
+ }
+
return;
}
+typedef struct {
+ TnyMaemoConicDevice *self;
+ int con_err;
+ int con_state;
+} HandleConnInfo;
+
+static gboolean
+handle_con_idle (gpointer data)
+{
+ HandleConnInfo *info = (HandleConnInfo *) data;
+ handle_connect (info->self, info->con_err, info->con_state);
+ return FALSE;
+}
+
+static void
+handle_con_idle_destroy (gpointer data)
+{
+ HandleConnInfo *info = (HandleConnInfo *) data;
+ g_object_unref (info->self);
+ g_slice_free (HandleConnInfo, data);
+}
+
+
static void
on_connection_event (ConIcConnection *cnx, ConIcConnectionEvent *event, gpointer user_data)
{
@@ -203,19 +222,18 @@
TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (device);
gboolean is_online = FALSE;
gboolean emit = FALSE;
+ HandleConnInfo *iinfo;
+ int con_err, con_state;
/* Don't emit nor make any changes in case of forced state */
+
if (priv->forced)
return;
- g_return_if_fail (CON_IC_IS_CONNECTION(cnx));
+ con_err = con_ic_connection_event_get_error (event);
+ con_state = con_ic_connection_event_get_status (event);
-#ifdef DEBUG
- g_message (__FUNCTION__);
-#endif
-
- switch (con_ic_connection_event_get_error(event))
- {
+ switch (con_err) {
case CON_IC_CONNECTION_ERROR_NONE:
break;
case CON_IC_CONNECTION_ERROR_INVALID_IAP:
@@ -231,8 +249,7 @@
g_return_if_reached ();
}
- switch (con_ic_connection_event_get_status(event))
- {
+ switch (con_state) {
case CON_IC_STATUS_CONNECTED:
if (priv->iap)
g_free (priv->iap);
@@ -261,135 +278,87 @@
priv->is_online = is_online;
-#ifdef DEBUG
- g_message ("DEBUG: %s: emitting signal CONNECTION_CHANGED: %s",
- __FUNCTION__, is_online ? "online" : "offline");
-#endif
+ if (priv->connect_slot &&
+ (con_err != CON_IC_CONNECTION_ERROR_NONE ||
+ con_state == CON_IC_STATUS_CONNECTED))
+ {
+ /* If there's an error or if we just connected, we call the
+ * callback for tny_maemo_conic_device_connect, if any */
+
+ iinfo = g_slice_new (HandleConnInfo);
+ iinfo->self = (TnyMaemoConicDevice *) g_object_ref (device);
+ iinfo->con_err = con_err;
+ iinfo->con_state = con_state;
+
+ g_idle_add_full (G_PRIORITY_HIGH, handle_con_idle, iinfo,
+ handle_con_idle_destroy);
+ }
+
if (emit)
conic_emit_status (TNY_DEVICE (device), is_online);
return;
}
-#endif /* MAEMO_CONIC_DUMMY */
-#ifdef MAEMO_CONIC_DUMMY
-static gchar*
-get_dummy_filename ()
-{
- gchar *filename = g_build_filename (
- g_get_home_dir (),
- MAEMO_CONIC_DUMMY_IAP_ID_FILENAME,
- NULL);
- return filename;
-}
-
-static gboolean
-dummy_con_ic_connection_connect_by_id (TnyMaemoConicDevice *self, const gchar* iap_id)
-{
- int response = 0;
-
- /* Show a dialog, because libconic would show a dialog here,
- * and give the user a chance to refuse a new connection, because libconic would allow that too.
- * This allows us to see roughly similar behaviour in scratchbox as on the device. */
- GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
- "TnyMaemoConicDevice fake scratchbox implementation:\nThe application requested a connection. Make a fake connection?"));
-
- response = gtk_dialog_run (dialog);
- gtk_widget_hide (GTK_WIDGET (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- if (response == GTK_RESPONSE_OK) {
- GError* error = NULL;
- /* Make a connection, by setting a name in our dummy text file,
- * which will be read later: */
- gchar *filename = get_dummy_filename ();
-
- g_file_set_contents (filename, "debug id0", -1, &error);
- if(error) {
- g_warning("%s: error from g_file_set_contents(): %s\n", __FUNCTION__, error->message);
- g_error_free (error);
- error = NULL;
- }
-
- g_free (filename);
-
- return TRUE;
- }
- else
- return FALSE;
-}
-
-#endif /* MAEMO_CONIC_DUMMY */
-
-
/**
* tny_maemo_conic_device_connect:
* @self: a #TnyDevice object
* @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any;
+ * @callback: a #TnyMaemoConicDeviceConnectCallback
+ * @user_data: user data for @callback
*
* Try to connect to a specific IAP, or to any if @iap_id == NULL
* this calls con_ic_connection_connect(_by_id).
* This may show a dialog to allow the user to select a connection, or
- * may otherwise take a significant amount of time. This function blocks until
- * the connection has either succeeded or failed.
- *
- * Returns TRUE if a connection was made, FALSE otherwise.
+ * may otherwise take a significant amount of time.
**/
-gboolean
-tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id)
+void
+tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self,
+ const gchar* iap_id,
+ TnyMaemoConicDeviceConnectCallback callback,
+ gpointer user_data)
{
-#ifdef MAEMO_CONIC_DUMMY
- return dummy_con_ic_connection_connect_by_id (self, iap_id);
-#else
TnyMaemoConicDevicePriv *priv = NULL;
gboolean request_failed = FALSE;
+ ConnectInfo *info;
+ GError *err = NULL;
- g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
- g_return_val_if_fail (priv->cnx, FALSE);
+ info = g_slice_new (ConnectInfo);
+ info->self = (TnyMaemoConicDevice *) g_object_ref (info);
+ info->callback = callback;
+ info->user_data = user_data;
+ info->iap_id = g_strdup (iap_id);
-#ifdef DEBUG
- g_message (__FUNCTION__);
- g_message ("connecting to %s", iap_id ? iap_id : "<any>");
-#endif
+ priv->connect_slot = info;
- priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */);
-
if (iap_id) {
if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) {
- g_warning ("could not send connect_by_id dbus message");
+ g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC,
+ "Could not send connect_by_id dbus message");
request_failed = TRUE;
}
} else {
if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) {
- g_warning ("could not send connect dbus message");
+ g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC,
+ "Could not send connect dbus message");
request_failed = TRUE;
}
}
if (request_failed) {
- g_object_unref (priv->loop);
- priv->loop = NULL;
+ priv->connect_slot = NULL;
+ if (info->callback)
+ info->callback (info->self, iap_id, FALSE, err, info->user_data);
+ g_free (info->iap_id);
+ g_object_unref (info->self);
+ g_slice_free (ConnectInfo, info);
}
-
- /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or
- * CON_IC_STATUS_DISCONNECTED event: */
-
- /* This is based on code found in gtk_dialog_run(): */
- GDK_THREADS_LEAVE();
- /* Run until g_main_loop_quit() is called by our signal handler. */
- g_main_loop_run (priv->loop);
- GDK_THREADS_ENTER();
-
- g_main_loop_unref (priv->loop);
- priv->loop = NULL;
-
- return priv->is_online;
-#endif /* MAEMO_CONIC_DUMMY */
+
+ return;
}
@@ -406,10 +375,6 @@
gboolean
tny_maemo_conic_device_disconnect (TnyMaemoConicDevice *self, const gchar* iap_id)
{
-/* don't try to disconnect if we're in dummy mode, as we're not "really"
- * connected in that case either
- */
-#ifndef MAEMO_CONIC_DUMMY
TnyMaemoConicDevicePriv *priv = NULL;
g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), FALSE);
@@ -417,93 +382,22 @@
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
g_return_val_if_fail (priv->cnx, FALSE);
-#ifdef DEBUG
- g_message (__FUNCTION__);
- g_message ("disconnecting from %s", iap_id ? iap_id : "<any>");
-#endif
-
if (iap_id) {
if (!con_ic_connection_disconnect_by_id (priv->cnx, iap_id)) {
- g_warning ("could not send disconnect_by_id dbus message");
+ g_warning ("Could not send disconnect_by_id dbus message");
return FALSE;
}
} else {
/* don't try to disconnect if iap_id==NULL, or conic will crash... */
- g_warning ("could not send disconnect dbus message");
+ g_warning ("Could not send disconnect dbus message");
return FALSE;
}
-#endif /* MAEMO_CONIC_DUMMY*/
return TRUE;
}
-#ifdef MAEMO_CONIC_DUMMY
-static gboolean
-on_dummy_connection_check (gpointer user_data)
-{
- TnyMaemoConicDevice *self = NULL;
- TnyMaemoConicDevicePriv *priv = NULL;
- gchar *filename = NULL;
- gchar *contents = NULL;
- GError* error = NULL;
- gboolean test = FALSE;
-
- self = TNY_MAEMO_CONIC_DEVICE (user_data);
- priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-
- /* Check whether the enviroment variable has changed,
- * so we can fake a connection change: */
- filename = get_dummy_filename ();
-
- test = g_file_get_contents (filename, &contents, NULL, &error);
-
- if(error) {
- /* g_debug("%s: error from g_file_get_contents(): %s\n", __FUNCTION__, error->message); */
- g_error_free (error);
- error = NULL;
- }
-
- if (!test || !contents) {
- /* g_debug ("DEBUG1: %s: priv->iap = %s\n", priv->iap); */
- /* Default to the first debug connection: */
- contents = g_strdup ("debug id0");
- }
-
- if (contents)
- g_strstrip(contents);
-
- if ((priv->iap == NULL) || (strcmp (contents, priv->iap) != 0)) {
- if (priv->iap) {
- g_free (priv->iap);
- priv->iap = NULL;
- }
-
- /* We store even the special "none" text, so we can detect changes. */
- priv->iap = g_strdup (contents);
-
- if (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0) {
- priv->is_online = FALSE;
- g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n Dummy connection changed to no connection.\n", __FUNCTION__);
- } else {
- priv->is_online = TRUE;
- g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n Dummy connection changed to '%s\n", __FUNCTION__, priv->iap);
- }
-
- g_debug ("DEBUG1: %s: emitting is_online=%d\n", __FUNCTION__, priv->is_online);
-
- conic_emit_status (TNY_DEVICE (self), priv->is_online);
-
- }
-
- g_free (contents);
- g_free (filename);
-
- return TRUE;
-}
-#endif /* MAEMO_CONIC_DUMMY */
-
/**
* tny_maemo_conic_device_get_current_iap_id:
* @self: a #TnyDevice object
@@ -523,13 +417,6 @@
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-#ifdef MAEMO_CONIC_DUMMY
- on_dummy_connection_check (self);
- /* Handle the special "none" text: */
- if (priv->iap && (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0))
- return NULL;
-#endif
-
return priv->iap;
}
@@ -550,33 +437,18 @@
ConIcIap*
tny_maemo_conic_device_get_iap (TnyMaemoConicDevice *self, const gchar *iap_id)
{
-#ifdef MAEMO_CONIC_DUMMY
- ConIcIap *iap = NULL;
-#else
TnyMaemoConicDevicePriv *priv = NULL;
-#endif
-
g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL);
g_return_val_if_fail (iap_id, NULL);
-
-#ifdef MAEMO_CONIC_DUMMY
- /* Note that we have re-declared the private struct so that we
- * can do this, which is very bad and fragile: */
- iap = g_object_new (CON_IC_TYPE_IAP, NULL);
- iap->id = g_strdup(iap_id);
- iap->name = g_strdup_printf("%s name", iap->id);
- return iap;
-#else
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
g_return_val_if_fail (priv->cnx, NULL);
- /* Note that it is very unusual to return a reference from a get_() function,
- * but we must do so because that mistake has already been made in
- * con_ic_connection_get_iap().
- * If we just unref immediately then libconic might destroy the object.
- */
+ /* Note that it is very unusual to return a reference from a get_()
+ * function, but we must do so because that mistake has already been
+ * made in con_ic_connection_get_iap (). If we just unref immediately
+ * then libconic might destroy the object. */
+
return con_ic_connection_get_iap (priv->cnx, iap_id);
-#endif
}
@@ -593,56 +465,21 @@
GSList*
tny_maemo_conic_device_get_iap_list (TnyMaemoConicDevice *self)
{
-#ifdef MAEMO_CONIC_DUMMY
- GSList* result = NULL;
- int i = 0;
-#else
TnyMaemoConicDevicePriv *priv = NULL;
-#endif /* MAEMO_CONIC_DUMMY */
-
- g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL);
-#ifdef MAEMO_CONIC_DUMMY
-
- /* libconic does not return a list of connections when running
- * in scratchbox, though it might do this in future when
- * "ethernet support" is implemented.
- * So we return a fake list so we can exercise funcationality
- * that uses connections: */
- for (i = 0; i < 10; ++i) {
- /* con_ic_iap_new (id) would checkc for a gconf dir and
- * fails, though _new() functions should just call g_object_new().
- *
- gchar *id = g_strdup_printf("debug id%d", i);
- ConIcIap *iap = con_ic_iap_new (id);
- g_free (id);
- */
-
- /* Note that we have re-declared the private struct so that we
- * can do this, which is very bad and fragile: */
- ConIcIap *iap = g_object_new (CON_IC_TYPE_IAP, NULL);
- iap->id = g_strdup_printf("debug id%d", i);
- iap->name = g_strdup_printf("%s name", iap->id);
-
- result = g_slist_append (result, iap);
- }
-
- return result;
-#else
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
g_return_val_if_fail (priv->cnx, NULL);
return con_ic_connection_get_all_iaps (priv->cnx);
-#endif
}
/**
* tny_maemo_conic_device_free_iap_list:
* @self: a #TnyDevice object
- *
+ * @cnx_list: a list of IAP objects
+ *
* free a list of IAP objects retrieved from tny_maemo_conic_device_get_iap_list
- *
**/
void
tny_maemo_conic_device_free_iap_list (TnyMaemoConicDevice *self, GSList* cnx_list)
@@ -653,10 +490,10 @@
cur = g_slist_next (cur);
}
g_slist_free (cnx_list);
+ return;
}
-
static void
tny_maemo_conic_device_force_online (TnyDevice *device)
{
@@ -666,20 +503,15 @@
g_return_if_fail (TNY_IS_DEVICE(device));
self = TNY_MAEMO_CONIC_DEVICE (device);
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-
+
already_online = tny_maemo_conic_device_is_online (device);
-#ifdef DEBUG
- g_message (__FUNCTION__);
- g_message ("force online, current status is: %s", already_online ? "online" : "offline");
-#endif
-
priv->forced = TRUE;
+ priv->is_online = TRUE;
/* Signal if it changed: */
if (!already_online)
- g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, TRUE);
+ g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
}
@@ -688,24 +520,21 @@
{
TnyMaemoConicDevice *self;
TnyMaemoConicDevicePriv *priv;
-#ifndef MAEMO_CONIC_DUMMY
gboolean already_offline = FALSE;
-#endif
g_return_if_fail (TNY_IS_DEVICE(device));
self = TNY_MAEMO_CONIC_DEVICE (device);
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-#ifdef MAEMO_CONIC_DUMMY
- return;
-#else
already_offline = !tny_maemo_conic_device_is_online (device);
priv->forced = TRUE;
+ priv->is_online = FALSE;
+
/* Signal if it changed: */
if (!already_offline)
conic_emit_status (device, FALSE);
+
return;
-#endif
}
static gboolean
@@ -713,10 +542,6 @@
{
g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
-#ifdef MAEMO_CONIC_DUMMY
- on_dummy_connection_check (self);
-#endif /* MAEMO_CONIC_DUMMY */
-
return TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self)->is_online;
}
@@ -728,45 +553,31 @@
TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
/* We should not have a real is_online, based on what libconic has told us: */
+
priv->forced = FALSE;
priv->iap = NULL;
priv->is_online = dnsmasq_has_resolv ();
-
-#ifndef MAEMO_CONIC_DUMMY
priv->cnx = con_ic_connection_new ();
- if (!priv->cnx) {
+
+ if (!priv->cnx)
g_warning ("con_ic_connection_new failed. The TnyMaemoConicDevice will be useless.");
- }
/* This might be necessary to make the connection object actually emit
* the signal, though the documentation says that they should be sent
* even when this is not set, when we explicitly try to connect. The
* signal still does not seem to be emitted. */
-
g_object_set (priv->cnx, "automatic-connection-events", TRUE, NULL);
g_signal_connect (priv->cnx, "connection-event",
G_CALLBACK(on_connection_event), self);
-
+
/* This will get us in connected state only if there is already a connection.
* thus, this will setup our state correctly when we receive the signals. */
-
if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED))
g_warning ("could not send connect dbus message");
-
-#endif /* MAEMO_CONIC_DUMMY */
-
-#ifdef MAEMO_CONIC_DUMMY
-
- /* Allow debuggers to fake a connection change by setting an environment
- * variable, which we check ever 1 second. This should match one of the
- * fake iap IDs that we created in tny_maemo_conic_device_get_iap_list().*/
-
- priv->dummy_env_check_timeout =
- g_timeout_add (1000, on_dummy_connection_check, self);
-#endif /* MAEMO_CONIC_DUMMY */
+ return;
}
@@ -779,6 +590,7 @@
tny_maemo_conic_device_new (void)
{
TnyMaemoConicDevice *self = g_object_new (TNY_TYPE_MAEMO_CONIC_DEVICE, NULL);
+
return TNY_DEVICE (self);
}
@@ -787,25 +599,16 @@
{
TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (obj);
-#ifndef MAEMO_CONIC_DUMMY
if (priv->cnx && CON_IC_IS_CONNECTION(priv->cnx)) {
- if (!tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap))
- g_warning ("failed to disconnect dbus message");
+ tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap);
g_object_unref (priv->cnx);
priv->cnx = NULL;
}
-#else
- if (priv->dummy_env_check_timeout) {
- g_source_remove (priv->dummy_env_check_timeout);
- priv->dummy_env_check_timeout = 0;
- }
-#endif /* MAEMO_CONIC_DUMMY */
if (priv->iap) {
g_free (priv->iap);
priv->iap = NULL;
}
-
(*parent_class->finalize) (obj);
}
@@ -823,7 +626,6 @@
}
-
static void
tny_maemo_conic_device_class_init (TnyMaemoConicDeviceClass *class)
{
@@ -874,3 +676,71 @@
}
return type;
}
+
+static void
+stop_loop (TnyMaemoConicDevice *self)
+{
+ TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
+ if (priv->loop)
+ g_main_loop_quit (priv->loop);
+ return;
+}
+
+
+/**
+ * tny_maemo_conic_device_connect:
+ * @self: a #TnyDevice object
+ * @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any;
+ *
+ * Try to connect to a specific IAP, or to any if @iap_id == NULL
+ * this calls con_ic_connection_connect(_by_id).
+ * This may show a dialog to allow the user to select a connection, or
+ * may otherwise take a significant amount of time. This function blocks until
+ * the connection has either succeeded or failed.
+ *
+ * Returns TRUE if a connection was made, FALSE otherwise.
+ **/
+gboolean
+tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id)
+{
+ TnyMaemoConicDevicePriv *priv = NULL;
+ gboolean request_failed = FALSE;
+
+ g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
+ priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
+
+ g_return_val_if_fail (priv->cnx, FALSE);
+ priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */);
+
+ if (iap_id) {
+ if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) {
+ g_warning ("could not send connect_by_id dbus message");
+ request_failed = TRUE;
+ }
+ } else {
+ if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) {
+ g_warning ("could not send connect dbus message");
+ request_failed = TRUE;
+ }
+ }
+
+ if (request_failed) {
+ g_object_unref (priv->loop);
+ priv->loop = NULL;
+ }
+
+ /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or
+ * CON_IC_STATUS_DISCONNECTED event: */
+
+ /* This is based on code found in gtk_dialog_run(): */
+ GDK_THREADS_LEAVE();
+ /* Run until g_main_loop_quit() is called by our signal handler. */
+ if (priv->loop)
+ g_main_loop_run (priv->loop);
+ GDK_THREADS_ENTER();
+
+ g_main_loop_unref (priv->loop);
+ priv->loop = NULL;
+
+ return priv->is_online;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]