diff options
author | Dan Williams <dcbw@redhat.com> | 2009-12-07 22:04:28 -0800 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2009-12-07 22:04:28 -0800 |
commit | dd057d28e4ab3812eebd41a7df1c2f80d90d8600 (patch) | |
tree | 46fa937720de3305ccc093f4741f0a25680fcba0 /src/mm-modem.c | |
parent | f715e0d498930409d97a8097b37731aadbc11a72 (diff) | |
parent | a9e0624426632a38c2d208e7a28fac3bca51d857 (diff) |
Merge commit 'origin/states'
Diffstat (limited to 'src/mm-modem.c')
-rw-r--r-- | src/mm-modem.c | 219 |
1 files changed, 215 insertions, 4 deletions
diff --git a/src/mm-modem.c b/src/mm-modem.c index ca2afbd7..af67864d 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -19,6 +19,7 @@ #include "mm-modem.h" #include "mm-errors.h" #include "mm-callback-info.h" +#include "mm-marshal.h" static void impl_modem_enable (MMModem *modem, gboolean enable, DBusGMethodInvocation *context); static void impl_modem_connect (MMModem *modem, const char *number, DBusGMethodInvocation *context); @@ -57,27 +58,109 @@ mm_modem_enable (MMModem *self, MMModemFn callback, gpointer user_data) { + MMModemState state; + g_return_if_fail (MM_IS_MODEM (self)); g_return_if_fail (callback != NULL); + state = mm_modem_get_state (self); + if (state >= MM_MODEM_STATE_ENABLED) { + MMCallbackInfo *info; + + info = mm_callback_info_new (self, callback, user_data); + + if (state == MM_MODEM_STATE_ENABLING) { + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_OPERATION_IN_PROGRESS, + "The device is already being enabled."); + } else { + /* Already enabled */ + } + + mm_callback_info_schedule (info); + return; + } + if (MM_MODEM_GET_INTERFACE (self)->enable) MM_MODEM_GET_INTERFACE (self)->enable (self, callback, user_data); else async_op_not_supported (self, callback, user_data); } +static void +finish_disable (MMModem *self, + MMModemFn callback, + gpointer user_data) +{ + + if (MM_MODEM_GET_INTERFACE (self)->disable) + MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data); + else + async_op_not_supported (self, callback, user_data); +} + +typedef struct { + MMModemFn callback; + gpointer user_data; +} DisableDisconnectInfo; + +static void +disable_disconnect_done (MMModem *self, + GError *error, + gpointer user_data) +{ + DisableDisconnectInfo *cb_data = user_data; + + /* ignore errors */ + if (error) { + g_warning ("%s: (%s): error disconnecting the modem while disabling: (%d) %s", + __func__, + mm_modem_get_device (self), + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + } + finish_disable (self, cb_data->callback, cb_data->user_data); + g_free (cb_data); +} + void mm_modem_disable (MMModem *self, MMModemFn callback, gpointer user_data) { + MMModemState state; + g_return_if_fail (MM_IS_MODEM (self)); g_return_if_fail (callback != NULL); - if (MM_MODEM_GET_INTERFACE (self)->disable) - MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data); - else - async_op_not_supported (self, callback, user_data); + state = mm_modem_get_state (self); + if (state <= MM_MODEM_STATE_DISABLING) { + MMCallbackInfo *info; + + info = mm_callback_info_new (self, callback, user_data); + + if (state == MM_MODEM_STATE_DISABLING) { + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_OPERATION_IN_PROGRESS, + "The device is already being disabled."); + } else { + /* Already disabled */ + } + + mm_callback_info_schedule (info); + return; + } + + /* If the modem is connected, disconnect it */ + if (state >= MM_MODEM_STATE_CONNECTING) { + DisableDisconnectInfo *cb_data; + + cb_data = g_malloc0 (sizeof (DisableDisconnectInfo)); + cb_data->callback = callback; + cb_data->user_data = user_data; + mm_modem_disconnect (self, disable_disconnect_done, cb_data); + } else + finish_disable (self, callback, user_data); } static void @@ -97,10 +180,30 @@ mm_modem_connect (MMModem *self, MMModemFn callback, gpointer user_data) { + MMModemState state; + g_return_if_fail (MM_IS_MODEM (self)); g_return_if_fail (callback != NULL); g_return_if_fail (number != NULL); + state = mm_modem_get_state (self); + if (state >= MM_MODEM_STATE_CONNECTING) { + MMCallbackInfo *info; + + /* Already connecting */ + info = mm_callback_info_new (self, callback, user_data); + if (state == MM_MODEM_STATE_CONNECTING) { + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_OPERATION_IN_PROGRESS, + "The device is already being connected."); + } else { + /* already connected */ + } + + mm_callback_info_schedule (info); + return; + } + if (MM_MODEM_GET_INTERFACE (self)->connect) MM_MODEM_GET_INTERFACE (self)->connect (self, number, callback, user_data); else @@ -211,9 +314,30 @@ mm_modem_disconnect (MMModem *self, MMModemFn callback, gpointer user_data) { + MMModemState state; + g_return_if_fail (MM_IS_MODEM (self)); g_return_if_fail (callback != NULL); + state = mm_modem_get_state (self); + if (state <= MM_MODEM_STATE_DISCONNECTING) { + MMCallbackInfo *info; + + /* Already connecting */ + info = mm_callback_info_new (self, callback, user_data); + if (state == MM_MODEM_STATE_DISCONNECTING) { + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_OPERATION_IN_PROGRESS, + "The device is already being disconnected."); + } else { + /* already disconnected */ + } + + mm_callback_info_schedule (info); + return; + } + + if (MM_MODEM_GET_INTERFACE (self)->disconnect) MM_MODEM_GET_INTERFACE (self)->disconnect (self, callback, user_data); else @@ -381,11 +505,78 @@ mm_modem_get_device (MMModem *self) return device; } +MMModemState +mm_modem_get_state (MMModem *self) +{ + MMModemState state = MM_MODEM_STATE_UNKNOWN; + + g_object_get (G_OBJECT (self), MM_MODEM_STATE, &state, NULL); + return state; +} + +static const char * +state_to_string (MMModemState state) +{ + switch (state) { + case MM_MODEM_STATE_UNKNOWN: + return "unknown"; + case MM_MODEM_STATE_DISABLED: + return "disabled"; + case MM_MODEM_STATE_DISABLING: + return "disabling"; + case MM_MODEM_STATE_ENABLING: + return "enabling"; + case MM_MODEM_STATE_ENABLED: + return "enabled"; + case MM_MODEM_STATE_SEARCHING: + return "searching"; + case MM_MODEM_STATE_REGISTERED: + return "registered"; + case MM_MODEM_STATE_DISCONNECTING: + return "disconnecting"; + case MM_MODEM_STATE_CONNECTING: + return "connecting"; + case MM_MODEM_STATE_CONNECTED: + return "connected"; + default: + g_assert_not_reached (); + break; + } + + g_assert_not_reached (); + return "(invalid)"; +} + +void +mm_modem_set_state (MMModem *self, + MMModemState new_state, + MMModemStateReason reason) +{ + MMModemState old_state = MM_MODEM_STATE_UNKNOWN; + const char *dbus_path; + + g_object_get (G_OBJECT (self), MM_MODEM_STATE, &old_state, NULL); + + if (new_state != old_state) { + g_object_set (G_OBJECT (self), MM_MODEM_STATE, new_state, NULL); + g_signal_emit_by_name (G_OBJECT (self), "state-changed", new_state, old_state, reason); + + dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); + if (dbus_path) { + g_message ("Modem %s: state changed (%s -> %s)", + dbus_path, + state_to_string (old_state), + state_to_string (new_state)); + } + } +} + /*****************************************************************************/ static void mm_modem_init (gpointer g_iface) { + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); static gboolean initialized = FALSE; if (initialized) @@ -450,6 +641,26 @@ mm_modem_init (gpointer g_iface) FALSE, G_PARAM_READABLE)); + g_object_interface_install_property + (g_iface, + g_param_spec_uint (MM_MODEM_STATE, + "State", + "State", + MM_MODEM_STATE_UNKNOWN, + MM_MODEM_STATE_LAST, + MM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE)); + + /* Signals */ + g_signal_new ("state-changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (MMModem, state_changed), + NULL, NULL, + mm_marshal_VOID__UINT_UINT_UINT, + G_TYPE_NONE, 3, + G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + initialized = TRUE; } |