Changeset 2933

Show
Ignore:
Timestamp:
11/09/07 12:12:26
Author:
svillar
Message:
  • New async API for connect into a maemo conic device
  • Fixed a linking error
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r2931 r2933  
     12007-11-09  Sergio Villar Senin  <svillar@igalia.com> 
     2 
     3        * libtinymail-maemo/tny-maemo-conic-device.c:  
     4        Added a new API to allow asynchronous connections 
     5        in the Maemo conic device. This patch is a new version of an initial 
     6        patch developed by pvanhoof with some changes. 
     7        Splitted the Maemo connic device in two files, one for the actual 
     8        device and the other one for a dummy device (useful for sbox devel) 
     9        Fixed a problem when linking the maemo conic device  
     10                                                         
    1112007-11-08  Jose Dapena Paz  <jdapena@igalia.com> 
    212 
     
    150160        * priv->folder_name in TnyCamelFolder sometimes is NULL, which 
    151161        doesn't seem right (and is racy). 
     162        * Improvements for the IDLE support. The Nonblocking read is now 
     163        actually used correctly, various racy situations should be fixed now 
     164        and instant event throwing is put in place (during IDLE state). 
     165        * Removed the (*read_idle) funcptr from CamelTcpStream, as this is no longer 
     166        required. This to reduce the complexity of the IDLE patch so that we 
     167        can later, perhaps, more easily bring this feature to upstream Camel. 
    152168 
    1531692007-10-19  Philip Van Hoof  <pvanhoof@gnome.org> 
  • trunk/libtinymail-maemo/Makefile.am

    r1834 r2933  
    1010        -I$(top_srcdir)/libtinymail-gnomevfs \ 
    1111        -DDBUS_API_SUBJECT_TO_CHANGE 
    12  
    1312 
    1413lib_LTLIBRARIES = libtinymail-maemo-1.0.la 
     
    2625        tny-maemo-platform-factory.c 
    2726 
    28 EXTRA_libtinymail_maemo_1_0_la_SOURCES = \ 
    29         tny-maemo-conic-device.c                                  
    30                                          
     27if MAEMO_CONIC_DEVICE_DUMMY 
     28libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-dummy-device.c 
     29else 
     30libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-device.c 
     31endif 
     32 
    3133libtinymail_maemo_1_0_la_LIBADD = \ 
    3234        $(LIBTINYMAIL_MAEMO_LIBS) \ 
    3335        $(LIBTINYMAIL_MAEMO_CONIC_LIBS) \ 
    34         @MAEMO_DEVICE@ \ 
    3536        $(top_builddir)/libtinymail/libtinymail-$(API_VERSION).la \ 
    3637        $(top_builddir)/libtinymailui/libtinymailui-$(API_VERSION).la \ 
    3738        $(top_builddir)/libtinymailui-gtk/libtinymailui-gtk-$(API_VERSION).la \ 
    3839        $(top_builddir)/libtinymail-camel/libtinymail-camel-$(API_VERSION).la 
    39  
    40 libtinymail_maemo_1_0_la_DEPENDENCIES=\ 
    41         @MAEMO_DEVICE@ 
    4240 
    4341libtinymail_maemo_1_0_la_LDFLAGS = -export-dynamic \ 
  • trunk/libtinymail-maemo/tny-maemo-conic-device.c

    r2825 r2933  
    1 /* libtinymail-camel - The Tiny Mail base library for Camel 
     1/* libtinymail-camel - The Tiny Mail base library for Maemo 
    22 * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org> 
    33 * 
     
    2626#include <conicconnection.h> 
    2727#include <conicconnectionevent.h> 
     28#include <string.h> 
     29#include <tny-error.h> 
    2830#include <gdk/gdk.h> /* For GDK_THREAD_ENTER/LEAVE */ 
    29 #include <string.h> /* For strcmp() */ 
    30  
    31  
    32 #ifdef MAEMO_CONIC_DUMMY  
    33 #include <gtk/gtkmessagedialog.h> 
    34 #endif 
    35  
    36  
    37  
    38 static gboolean 
    39 dnsmasq_has_resolv (void) 
    40 
    41         /* This is because silly Conic does not have a blocking API that tells 
    42          * us immediately when the device is online. */ 
    43  
    44         if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS)) 
    45                 if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS)) 
    46                         if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS)) 
    47                                 return FALSE; 
    48  
    49         return TRUE; 
    50 
    51  
    52 #ifdef MAEMO_CONIC_DUMMY 
    53 /* #include "coniciap-private.h" 
    54  * This is not installed, so we predeclare the struct instead. Of course, this  
    55  * is a hack and could break if the private API changes. It would be better for  
    56  * libconic to support scratchbox. */ 
    57  
    58 struct _ConIcIap  
    59 
    60         GObject parent_instance; 
    61         gboolean dispose_has_run; 
    62         gchar *id; 
    63         gchar *name; 
    64         gchar *bearer; 
    65 }; 
    66  
    67 #define MAEMO_CONIC_DUMMY_IAP_ID_FILENAME "maemo_conic_dummy_id" 
    68 #define MAEMO_CONIC_DUMMY_IAP_ID_NONE "none" 
    69 static gboolean on_dummy_connection_check (gpointer user_data); 
    70 #endif /* MAEMO_CONIC_DUMMY */ 
     31 
     32static void stop_loop (TnyMaemoConicDevice *self); 
    7133 
    7234static gboolean tny_maemo_conic_device_is_online (TnyDevice *self); 
    7335 
    7436static GObjectClass *parent_class = NULL; 
     37 
     38typedef struct { 
     39        TnyMaemoConicDevice *self; 
     40        gchar* iap_id; 
     41        gpointer user_data; 
     42        TnyMaemoConicDeviceConnectCallback callback; 
     43} ConnectInfo; 
    7544 
    7645typedef struct { 
     
    7948        gchar *iap; 
    8049        gboolean forced; /* Whether the is_online value is forced rather than real. */ 
     50        ConnectInfo *connect_slot; 
    8151        /* When non-NULL, we are waiting for the success or failure signal. */ 
    8252        GMainLoop *loop; 
    83 #ifdef MAEMO_CONIC_DUMMY 
    84         gint dummy_env_check_timeout; 
    85 #endif /* MAEMO_CONIC_DUMMY */ 
    8653} TnyMaemoConicDevicePriv; 
     54 
    8755 
    8856#define TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE(o)   \ 
     
    9563 
    9664static gboolean 
     65dnsmasq_has_resolv (void) 
     66{ 
     67        /* This is because silly Conic does not have a blocking API that tells 
     68         * us immediately when the device is online. */ 
     69 
     70        if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS)) 
     71                if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS)) 
     72                        if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS)) 
     73                                return FALSE; 
     74 
     75        return TRUE; 
     76} 
     77 
     78static gboolean 
    9779conic_emit_status_idle (gpointer user_data) 
    9880{ 
    9981        EmitStatusInfo *info = (EmitStatusInfo *) user_data; 
    10082 
    101         /* We lock the gdk thread because tinymail wants implementations to do this  
    102          * before emitting _any_ signals
     83        /* We lock the gdk thread because tinymail wants implementations to do 
     84         * this before emitting signals from within a g_idle_add_full callback
    10385         * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 
    10486 
     
    123105conic_emit_status (TnyDevice *self, gboolean status) 
    124106{ 
    125         /* If there is a mainloop (if gtk_main() has been run, for instance), 
    126          * then emit the signal via an idle callback, so that it is  
    127          * always emitted in the main context as required by tinymail 
    128          * (libconic does not give any guarantee  
    129          * about this - it would be nice if libconic documented that). 
    130          * But if there is no mainloop, then just emit it, as tinymail  
    131          * requires when there is no mainloop: */ 
    132  
    133          /* TODO: We have no way to check for this now, and  
    134           * at this time it's not even clear whether tinymail should/can really  
    135           * demand this. murrayc. 15th Aug. 2007. */ 
    136  
    137         if (TRUE) /* TODO: But NULL is not allowed here: g_main_loop_is_running (NULL)) */ 
    138         { 
    139                 /* Emit it in an idle handler: */ 
    140                 EmitStatusInfo *info = g_slice_new (EmitStatusInfo); 
    141                 guint time = 5000; 
    142  
    143                 info->self = g_object_ref (self); 
    144                 info->status = status; 
    145  
    146                 if (!dnsmasq_has_resolv()) 
    147                         time = 5000; 
    148  
    149                 g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle, 
    150                         info, conic_emit_status_destroy); 
    151  
    152         } else { 
    153                 /* Emit it directly: */ 
    154  
    155                 /* We lock the gdk thread because tinymail wants implementations 
    156                  *  to do this before emitting _any_ signals. 
    157                  * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 
    158  
    159                 gdk_threads_enter (); 
    160                 g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 
    161                         0, status); 
    162                 gdk_threads_leave (); 
    163         } 
     107        /* Emit it in an idle handler: */ 
     108        EmitStatusInfo *info = g_slice_new (EmitStatusInfo); 
     109        guint time = 1000; 
     110 
     111        info->self = g_object_ref (self); 
     112        info->status = status; 
     113 
     114        if (!dnsmasq_has_resolv()) 
     115                time = 5000; 
     116 
     117        g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle, 
     118                info, conic_emit_status_destroy); 
    164119 
    165120        return; 
     
    186141} 
    187142 
    188 #ifndef MAEMO_CONIC_DUMMY 
     143static void 
     144handle_connect (TnyMaemoConicDevice *self, int con_err, int con_state) 
     145
     146        TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
     147 
     148        if (priv->connect_slot)  
     149        { 
     150                GError *err = NULL; 
     151                gboolean canceled = FALSE; 
     152                ConnectInfo *info = priv->connect_slot; 
     153 
     154                /* Mark it as handled (TODO, this needs a small lock) */ 
     155                priv->connect_slot = NULL; 
     156 
     157                switch (con_err) { 
     158                        case CON_IC_CONNECTION_ERROR_NONE: 
     159                                break; 
     160                        case CON_IC_CONNECTION_ERROR_INVALID_IAP: 
     161                                g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 
     162                                        "IAP is invalid"); 
     163                                break; 
     164                        case CON_IC_CONNECTION_ERROR_CONNECTION_FAILED: 
     165                                g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 
     166                                        "Connection failed"); 
     167                                break; 
     168                        case CON_IC_CONNECTION_ERROR_USER_CANCELED: 
     169                        default: 
     170                                canceled = TRUE; 
     171                                break; 
     172                } 
     173 
     174                if (info->callback) { 
     175                        /* We lock the gdk thread because tinymail wants implementations to do 
     176                         * this before invoking callbacks from within a g_idle_add_full callback. 
     177                         * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 
     178 
     179                        gdk_threads_enter (); 
     180                        info->callback (info->self, info->iap_id, canceled, err, info->user_data); 
     181                        gdk_threads_leave (); 
     182                } 
     183 
     184                if (err) 
     185                        g_error_free (err); 
     186 
     187                g_object_unref (info->self); 
     188                g_free (info->self); 
     189                g_slice_free (ConnectInfo, info); 
     190        } 
     191 
     192        return; 
     193
     194 
     195typedef struct { 
     196        TnyMaemoConicDevice *self; 
     197        int con_err; 
     198        int con_state; 
     199} HandleConnInfo; 
     200 
     201static gboolean 
     202handle_con_idle (gpointer data) 
     203
     204        HandleConnInfo *info = (HandleConnInfo *) data; 
     205        handle_connect (info->self, info->con_err, info->con_state); 
     206        return FALSE; 
     207
    189208 
    190209static void  
    191 stop_loop (TnyMaemoConicDevice *self) 
    192 { 
    193         TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self)
    194         if (priv->loop) 
    195                g_main_loop_quit (priv->loop); 
    196         return; 
    197 
     210handle_con_idle_destroy (gpointer data)  
     211{  
     212        HandleConnInfo *info = (HandleConnInfo *) data
     213        g_object_unref (info->self); 
     214        g_slice_free (HandleConnInfo, data);  
     215
     216 
    198217 
    199218static void 
     
    204223        gboolean is_online = FALSE; 
    205224        gboolean emit = FALSE; 
     225        HandleConnInfo *iinfo; 
     226        int con_err, con_state; 
    206227 
    207228        /* Don't emit nor make any changes in case of forced state */ 
     229 
    208230        if (priv->forced) 
    209231                return; 
    210232 
    211         g_return_if_fail (CON_IC_IS_CONNECTION(cnx)); 
    212  
    213 #ifdef DEBUG 
    214         g_message (__FUNCTION__); 
    215 #endif 
    216  
    217         switch (con_ic_connection_event_get_error(event))  
    218         { 
     233        con_err = con_ic_connection_event_get_error (event); 
     234        con_state = con_ic_connection_event_get_status (event); 
     235 
     236        switch (con_err) { 
    219237                case CON_IC_CONNECTION_ERROR_NONE: 
    220238                        break; 
     
    232250        } 
    233251 
    234         switch (con_ic_connection_event_get_status(event))  
    235         { 
     252        switch (con_state) { 
    236253                case CON_IC_STATUS_CONNECTED: 
    237254                        if (priv->iap) 
     
    262279        priv->is_online = is_online; 
    263280 
    264 #ifdef DEBUG 
    265         g_message ("DEBUG: %s: emitting signal CONNECTION_CHANGED: %s",  
    266                    __FUNCTION__, is_online ? "online" : "offline"); 
    267 #endif 
     281        if (priv->connect_slot &&  
     282                (con_err != CON_IC_CONNECTION_ERROR_NONE ||  
     283                 con_state == CON_IC_STATUS_CONNECTED))  
     284        { 
     285 
     286                /* If there's an error or if we just connected, we call the 
     287                 * callback for tny_maemo_conic_device_connect, if any */ 
     288 
     289                iinfo = g_slice_new (HandleConnInfo); 
     290                iinfo->self = (TnyMaemoConicDevice *) g_object_ref (device); 
     291                iinfo->con_err = con_err; 
     292                iinfo->con_state = con_state; 
     293 
     294                g_idle_add_full (G_PRIORITY_HIGH, handle_con_idle, iinfo,  
     295                        handle_con_idle_destroy); 
     296        } 
    268297 
    269298        if (emit) 
     
    272301        return; 
    273302} 
    274 #endif /* MAEMO_CONIC_DUMMY */ 
    275  
    276 #ifdef MAEMO_CONIC_DUMMY 
    277  
    278 static gchar* 
    279 get_dummy_filename () 
    280 { 
    281         gchar *filename = g_build_filename ( 
    282                 g_get_home_dir (),  
    283                 MAEMO_CONIC_DUMMY_IAP_ID_FILENAME, 
    284                 NULL); 
    285         return filename; 
    286 } 
    287  
    288 static gboolean  
    289 dummy_con_ic_connection_connect_by_id (TnyMaemoConicDevice *self, const gchar* iap_id) 
    290 { 
    291         int response = 0; 
    292  
    293         /* Show a dialog, because libconic would show a dialog here, 
    294          * and give the user a chance to refuse a new connection, because libconic would allow that too. 
    295          * This allows us to see roughly similar behaviour in scratchbox as on the device. */ 
    296         GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, 
    297                         GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,  
    298                         "TnyMaemoConicDevice fake scratchbox implementation:\nThe application requested a connection. Make a fake connection?")); 
    299  
    300         response = gtk_dialog_run (dialog); 
    301         gtk_widget_hide (GTK_WIDGET (dialog)); 
    302         gtk_widget_destroy (GTK_WIDGET (dialog)); 
    303          
    304         if (response == GTK_RESPONSE_OK) { 
    305                 GError* error = NULL; 
    306                 /* Make a connection, by setting a name in our dummy text file, 
    307                  * which will be read later: */ 
    308                 gchar *filename = get_dummy_filename (); 
    309  
    310                 g_file_set_contents (filename, "debug id0", -1, &error); 
    311                 if(error) { 
    312                         g_warning("%s: error from g_file_set_contents(): %s\n", __FUNCTION__, error->message); 
    313                         g_error_free (error); 
    314                         error = NULL; 
    315                 } 
    316  
    317                 g_free (filename); 
    318  
    319                 return TRUE; 
    320         } 
    321         else 
    322                 return FALSE; 
    323 } 
    324  
    325 #endif /* MAEMO_CONIC_DUMMY */ 
    326303 
    327304 
     
    330307 * @self: a #TnyDevice object 
    331308 * @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any; 
     309 * @callback: a #TnyMaemoConicDeviceConnectCallback 
     310 * @user_data: user data for @callback 
    332311 *  
    333312 * Try to connect to a specific IAP, or to any if @iap_id == NULL 
    334313 * this calls con_ic_connection_connect(_by_id). 
    335314 * This may show a dialog to allow the user to select a connection, or  
    336  * may otherwise take a significant amount of time. This function blocks until  
    337  * the connection has either succeeded or failed. 
    338  *  
    339  * Returns TRUE if a connection was made, FALSE otherwise. 
     315 * may otherwise take a significant amount of time.  
    340316 **/ 
    341 gboolean 
    342 tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id) 
    343 
    344 #ifdef MAEMO_CONIC_DUMMY  
    345         return dummy_con_ic_connection_connect_by_id (self, iap_id); 
    346 #else 
     317void  
     318tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self,  
     319                                      const gchar* iap_id,  
     320                                     TnyMaemoConicDeviceConnectCallback callback,  
     321                                     gpointer user_data) 
     322
    347323        TnyMaemoConicDevicePriv *priv = NULL; 
    348324        gboolean request_failed = FALSE; 
    349  
    350         g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE)
    351         priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    352  
    353         g_return_val_if_fail (priv->cnx, FALSE); 
    354  
    355 #ifdef DEBUG 
    356         g_message (__FUNCTION__)
    357         g_message ("connecting to %s", iap_id ? iap_id : "<any>")
    358 #endif 
    359  
    360         priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */)
     325        ConnectInfo *info; 
     326        GError *err = NULL
     327 
     328        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
     329 
     330        info = g_slice_new (ConnectInfo); 
     331        info->self = (TnyMaemoConicDevice *) g_object_ref (info); 
     332        info->callback = callback
     333        info->user_data = user_data
     334        info->iap_id = g_strdup (iap_id); 
     335 
     336        priv->connect_slot = info
    361337 
    362338        if (iap_id) { 
    363339                if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) { 
    364                         g_warning ("could not send connect_by_id dbus message"); 
     340                        g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 
     341                                "Could not send connect_by_id dbus message"); 
    365342                        request_failed = TRUE; 
    366343                } 
    367344        } else { 
    368345                if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) { 
    369                         g_warning ("could not send connect dbus message"); 
     346                        g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 
     347                                "Could not send connect dbus message"); 
    370348                        request_failed = TRUE; 
    371349                } 
     
    373351 
    374352        if (request_failed) { 
    375                 g_object_unref (priv->loop); 
    376                 priv->loop = NULL; 
    377         } 
    378          
    379         /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or  
    380          * CON_IC_STATUS_DISCONNECTED event: */ 
    381           
    382         /* This is based on code found in gtk_dialog_run(): */ 
    383         GDK_THREADS_LEAVE(); 
    384         /* Run until g_main_loop_quit() is called by our signal handler. */ 
    385         g_main_loop_run (priv->loop); 
    386         GDK_THREADS_ENTER(); 
    387  
    388         g_main_loop_unref (priv->loop); 
    389         priv->loop = NULL; 
    390  
    391         return priv->is_online; 
    392 #endif /* MAEMO_CONIC_DUMMY */ 
     353                priv->connect_slot = NULL; 
     354                if (info->callback) 
     355                        info->callback (info->self, iap_id, FALSE, err, info->user_data); 
     356                g_free (info->iap_id); 
     357                g_object_unref (info->self); 
     358                g_slice_free (ConnectInfo, info); 
     359        } 
     360  
     361        return; 
    393362} 
    394363 
     
    407376tny_maemo_conic_device_disconnect (TnyMaemoConicDevice *self, const gchar* iap_id) 
    408377{ 
    409 /* don't try to disconnect if we're in dummy mode, as we're not "really" 
    410  * connected in that case either 
    411  */ 
    412 #ifndef MAEMO_CONIC_DUMMY  
    413378        TnyMaemoConicDevicePriv *priv = NULL; 
    414379 
     
    417382        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    418383        g_return_val_if_fail (priv->cnx, FALSE); 
    419  
    420 #ifdef DEBUG 
    421         g_message (__FUNCTION__); 
    422         g_message ("disconnecting from %s", iap_id ? iap_id : "<any>"); 
    423 #endif 
    424384 
    425385        if (iap_id) { 
    426386                if (!con_ic_connection_disconnect_by_id (priv->cnx, iap_id)) { 
    427                         g_warning ("could not send disconnect_by_id dbus message"); 
     387                        g_warning ("Could not send disconnect_by_id dbus message"); 
    428388                        return FALSE; 
    429389                } 
    430390        } else { 
    431391                /* don't try to disconnect if iap_id==NULL, or conic will crash... */ 
    432                 g_warning ("could not send disconnect dbus message"); 
     392                g_warning ("Could not send disconnect dbus message"); 
    433393                return FALSE; 
    434394        } 
    435 #endif /* MAEMO_CONIC_DUMMY*/ 
    436395 
    437396        return TRUE; 
     
    439398 
    440399 
    441 #ifdef MAEMO_CONIC_DUMMY 
    442 static gboolean 
    443 on_dummy_connection_check (gpointer user_data) 
    444 { 
    445         TnyMaemoConicDevice *self = NULL; 
    446         TnyMaemoConicDevicePriv *priv = NULL; 
    447         gchar *filename = NULL; 
    448         gchar *contents = NULL; 
    449         GError* error = NULL; 
    450         gboolean test = FALSE; 
    451                  
    452         self = TNY_MAEMO_CONIC_DEVICE (user_data); 
    453  
    454         priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    455          
    456         /* Check whether the enviroment variable has changed,  
    457          * so we can fake a connection change: */ 
    458         filename = get_dummy_filename (); 
    459          
    460         test = g_file_get_contents (filename, &contents, NULL, &error); 
    461  
    462         if(error) { 
    463                 /* g_debug("%s: error from g_file_get_contents(): %s\n", __FUNCTION__, error->message); */ 
    464                 g_error_free (error); 
    465                 error = NULL; 
    466         } 
    467          
    468         if (!test || !contents) { 
    469                 /* g_debug ("DEBUG1: %s: priv->iap = %s\n", priv->iap); */ 
    470                 /* Default to the first debug connection: */ 
    471                 contents = g_strdup ("debug id0"); 
    472         } 
    473          
    474         if (contents) 
    475                 g_strstrip(contents); 
    476  
    477         if ((priv->iap == NULL) || (strcmp (contents, priv->iap) != 0)) { 
    478                 if (priv->iap) { 
    479                         g_free (priv->iap); 
    480                         priv->iap = NULL; 
    481                 } 
    482                          
    483                 /* We store even the special "none" text, so we can detect changes. */ 
    484                 priv->iap = g_strdup (contents); 
    485                  
    486                 if (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0) { 
    487                         priv->is_online = FALSE; 
    488                         g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n  Dummy connection changed to no connection.\n", __FUNCTION__); 
    489                 } else { 
    490                         priv->is_online = TRUE; 
    491                         g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n  Dummy connection changed to '%s\n", __FUNCTION__, priv->iap); 
    492                 } 
    493                  
    494                 g_debug ("DEBUG1: %s: emitting is_online=%d\n", __FUNCTION__, priv->is_online); 
    495  
    496                 conic_emit_status (TNY_DEVICE (self), priv->is_online); 
    497  
    498         } 
    499          
    500         g_free (contents); 
    501         g_free (filename); 
    502          
    503         return TRUE; 
    504 } 
    505 #endif /* MAEMO_CONIC_DUMMY */ 
    506400 
    507401/** 
     
    524418        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    525419 
    526 #ifdef MAEMO_CONIC_DUMMY 
    527         on_dummy_connection_check (self); 
    528         /* Handle the special "none" text: */ 
    529         if (priv->iap && (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0)) 
    530                 return NULL; 
    531 #endif 
    532  
    533420        return priv->iap; 
    534421} 
     
    551438tny_maemo_conic_device_get_iap (TnyMaemoConicDevice *self, const gchar *iap_id) 
    552439{ 
    553 #ifdef MAEMO_CONIC_DUMMY 
    554         ConIcIap *iap = NULL; 
    555 #else 
    556440        TnyMaemoConicDevicePriv *priv = NULL; 
    557 #endif 
    558  
    559441        g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL); 
    560442        g_return_val_if_fail (iap_id, NULL); 
    561  
    562 #ifdef MAEMO_CONIC_DUMMY  
    563         /* Note that we have re-declared the private struct so that we  
    564          * can do this, which is very bad and fragile: */ 
    565         iap = g_object_new (CON_IC_TYPE_IAP, NULL); 
    566         iap->id = g_strdup(iap_id); 
    567         iap->name = g_strdup_printf("%s name", iap->id); 
    568         return iap; 
    569 #else 
    570443        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    571444        g_return_val_if_fail (priv->cnx, NULL); 
    572445 
    573         /* Note that it is very unusual to return a reference from a get_() function,  
    574          * but we must do so because that mistake has already been made in  
    575          * con_ic_connection_get_iap(). 
    576          * If we just unref immediately then libconic might destroy the object. 
    577          */ 
     446        /* Note that it is very unusual to return a reference from a get_()  
     447         * function, but we must do so because that mistake has already been  
     448         * made in con_ic_connection_get_iap (). If we just unref immediately  
     449         * then libconic might destroy the object. */ 
     450 
    578451        return con_ic_connection_get_iap (priv->cnx, iap_id); 
    579 #endif 
    580452} 
    581453 
     
    594466tny_maemo_conic_device_get_iap_list (TnyMaemoConicDevice *self) 
    595467{ 
    596 #ifdef MAEMO_CONIC_DUMMY 
    597         GSList* result = NULL; 
    598         int i = 0; 
    599 #else 
    600468        TnyMaemoConicDevicePriv *priv = NULL; 
    601 #endif /* MAEMO_CONIC_DUMMY */ 
    602          
    603         g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL); 
    604  
    605 #ifdef MAEMO_CONIC_DUMMY 
    606  
    607         /* libconic does not return a list of connections when running  
    608          * in scratchbox, though it might do this in future when  
    609          * "ethernet support" is implemented. 
    610          * So we return a fake list so we can exercise funcationality  
    611          * that uses connections: */ 
    612         for (i = 0; i < 10; ++i) { 
    613                 /* con_ic_iap_new (id) would checkc for a gconf dir and  
    614                  * fails, though _new() functions should just call g_object_new(). 
    615                  * 
    616                 gchar *id = g_strdup_printf("debug id%d", i); 
    617                 ConIcIap *iap = con_ic_iap_new (id); 
    618                 g_free (id); 
    619                 */ 
    620                  
    621                 /* Note that we have re-declared the private struct so that we  
    622                  * can do this, which is very bad and fragile: */ 
    623                 ConIcIap *iap = g_object_new (CON_IC_TYPE_IAP, NULL); 
    624                 iap->id = g_strdup_printf("debug id%d", i); 
    625                 iap->name = g_strdup_printf("%s name", iap->id); 
    626  
    627                 result = g_slist_append (result, iap);   
    628         } 
    629          
    630         return result; 
    631 #else 
     469 
    632470        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    633471        g_return_val_if_fail (priv->cnx, NULL); 
    634472 
    635473        return con_ic_connection_get_all_iaps (priv->cnx); 
    636 #endif 
    637474} 
    638475 
     
    641478 * tny_maemo_conic_device_free_iap_list: 
    642479 * @self: a #TnyDevice object 
    643  *   
     480 * @cnx_list: a list of IAP objects 
     481 * 
    644482 * free a  list of IAP objects retrieved from tny_maemo_conic_device_get_iap_list 
    645  *   
    646483 **/ 
    647484void 
     
    654491        } 
    655492        g_slist_free (cnx_list); 
    656 
    657  
     493        return; 
     494
    658495 
    659496 
     
    667504        self = TNY_MAEMO_CONIC_DEVICE (device); 
    668505        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    669          
     506 
    670507        already_online = tny_maemo_conic_device_is_online (device); 
    671508 
    672 #ifdef DEBUG 
    673         g_message (__FUNCTION__); 
    674         g_message ("force online, current status is: %s", already_online ? "online" : "offline"); 
    675 #endif 
    676  
    677509        priv->forced = TRUE; 
     510        priv->is_online = TRUE; 
    678511 
    679512        /* Signal if it changed: */ 
    680513        if (!already_online) 
    681                 g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 
    682                        0, TRUE); 
     514                g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE); 
    683515} 
    684516 
     
    689521        TnyMaemoConicDevice *self; 
    690522        TnyMaemoConicDevicePriv *priv; 
    691 #ifndef MAEMO_CONIC_DUMMY 
    692523        gboolean already_offline = FALSE; 
    693 #endif 
    694524 
    695525        g_return_if_fail (TNY_IS_DEVICE(device)); 
     
    697527        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
    698528 
    699 #ifdef MAEMO_CONIC_DUMMY 
    700         return; 
    701 #else 
    702529        already_offline = !tny_maemo_conic_device_is_online (device); 
    703530        priv->forced = TRUE; 
     531        priv->is_online = FALSE; 
     532 
    704533        /* Signal if it changed: */ 
    705534        if (!already_offline) 
    706535                conic_emit_status (device, FALSE); 
    707         return; 
    708 #endif 
     536 
     537        return; 
    709538} 
    710539 
     
    714543        g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE); 
    715544 
    716 #ifdef MAEMO_CONIC_DUMMY 
    717         on_dummy_connection_check (self); 
    718 #endif /* MAEMO_CONIC_DUMMY */ 
    719  
    720545        return TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self)->is_online; 
    721546} 
     
    729554 
    730555        /* We should not have a real is_online, based on what libconic has told us: */ 
     556 
    731557        priv->forced = FALSE; 
    732558        priv->iap = NULL; 
    733559        priv->is_online = dnsmasq_has_resolv (); 
    734560 
    735  
    736 #ifndef MAEMO_CONIC_DUMMY 
    737561        priv->cnx = con_ic_connection_new (); 
    738         if (!priv->cnx) { 
     562 
     563        if (!priv->cnx) 
    739564                g_warning ("con_ic_connection_new failed. The TnyMaemoConicDevice will be useless."); 
    740         } 
    741565 
    742566        /* This might be necessary to make the connection object actually emit  
     
    744568         * even when this is not set, when we explicitly try to connect. The  
    745569         * signal still does not seem to be emitted. */ 
    746  
    747570        g_object_set (priv->cnx, "automatic-connection-events", TRUE, NULL); 
    748571 
    749572        g_signal_connect (priv->cnx, "connection-event", 
    750573                          G_CALLBACK(on_connection_event), self); 
    751          
     574 
    752575        /* This will get us in connected state only if there is already a connection. 
    753576         * thus, this will setup our state correctly when we receive the signals. */ 
    754  
    755577        if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED)) 
    756578                g_warning ("could not send connect dbus message"); 
    757                  
    758 #endif /* MAEMO_CONIC_DUMMY */ 
    759  
    760  
    761 #ifdef MAEMO_CONIC_DUMMY 
    762  
    763         /* Allow debuggers to fake a connection change by setting an environment  
    764          * variable, which we check ever 1 second. This should match one of the  
    765          * fake iap IDs that we created in tny_maemo_conic_device_get_iap_list().*/ 
    766  
    767         priv->dummy_env_check_timeout =  
    768                 g_timeout_add (1000, on_dummy_connection_check, self); 
    769 #endif /* MAEMO_CONIC_DUMMY */ 
     579 
     580        return; 
    770581} 
    771582 
     
    780591{ 
    781592        TnyMaemoConicDevice *self = g_object_new (TNY_TYPE_MAEMO_CONIC_DEVICE, NULL); 
     593 
    782594        return TNY_DEVICE (self); 
    783595} 
     
    788600        TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (obj); 
    789601 
    790 #ifndef MAEMO_CONIC_DUMMY 
    791602        if (priv->cnx && CON_IC_IS_CONNECTION(priv->cnx)) { 
    792                 if (!tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap)) 
    793                         g_warning ("failed to disconnect dbus message"); 
     603                tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap); 
    794604                g_object_unref (priv->cnx); 
    795605                priv->cnx = NULL; 
    796606        } 
    797 #else 
    798         if (priv->dummy_env_check_timeout) { 
    799                 g_source_remove (priv->dummy_env_check_timeout); 
    800                 priv->dummy_env_check_timeout = 0; 
    801         } 
    802 #endif /* MAEMO_CONIC_DUMMY */ 
    803607 
    804608        if (priv->iap) { 
     
    806610                priv->iap = NULL; 
    807611        } 
    808          
    809612 
    810613        (*parent_class->finalize) (obj); 
     
    822625        klass->force_online_func  = tny_maemo_conic_device_force_online; 
    823626} 
    824  
    825627 
    826628 
     
    875677        return type; 
    876678} 
     679 
     680static void  
     681stop_loop (TnyMaemoConicDevice *self) 
     682{ 
     683        TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
     684        if (priv->loop) 
     685                g_main_loop_quit (priv->loop); 
     686        return; 
     687} 
     688 
     689 
     690/** 
     691 * tny_maemo_conic_device_connect: 
     692 * @self: a #TnyDevice object 
     693 * @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any; 
     694 *  
     695 * Try to connect to a specific IAP, or to any if @iap_id == NULL 
     696 * this calls con_ic_connection_connect(_by_id). 
     697 * This may show a dialog to allow the user to select a connection, or  
     698 * may otherwise take a significant amount of time. This function blocks until  
     699 * the connection has either succeeded or failed. 
     700 *  
     701 * Returns TRUE if a connection was made, FALSE otherwise. 
     702 **/ 
     703gboolean 
     704tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id) 
     705{ 
     706        TnyMaemoConicDevicePriv *priv = NULL; 
     707        gboolean request_failed = FALSE; 
     708 
     709        g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE); 
     710        priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 
     711 
     712        g_return_val_if_fail (priv->cnx, FALSE); 
     713        priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */); 
     714 
     715        if (iap_id) { 
     716                if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) { 
     717                        g_warning ("could not send connect_by_id dbus message"); 
     718                        request_failed = TRUE; 
     719                } 
     720        } else { 
     721                if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) { 
     722                        g_warning ("could not send connect dbus message"); 
     723                        request_failed = TRUE; 
     724                } 
     725        } 
     726 
     727        if (request_failed) { 
     728                g_object_unref (priv->loop); 
     729                priv->loop = NULL; 
     730        } 
     731         
     732        /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or  
     733         * CON_IC_STATUS_DISCONNECTED event: */ 
     734          
     735        /* This is based on code found in gtk_dialog_run(): */ 
     736        GDK_THREADS_LEAVE(); 
     737        /* Run until g_main_loop_quit() is called by our signal handler. */ 
     738        if (priv->loop) 
     739                g_main_loop_run (priv->loop); 
     740        GDK_THREADS_ENTER(); 
     741 
     742        g_main_loop_unref (priv->loop); 
     743        priv->loop = NULL; 
     744 
     745        return priv->is_online; 
     746} 
  • trunk/libtinymail-maemo/tny-maemo-conic-device.h

    r2825 r2933  
    5656 
    5757gboolean tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id); 
     58typedef void (*TnyMaemoConicDeviceConnectCallback) (TnyMaemoConicDevice *self, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data); 
     59void tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self,  
     60                                           const gchar* iap_id,  
     61