diff options
-rw-r--r-- | marshallers/mm-marshal.list | 2 | ||||
-rw-r--r-- | src/mm-generic-cdma.c | 50 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 35 | ||||
-rw-r--r-- | src/mm-generic-gsm.h | 3 | ||||
-rw-r--r-- | src/mm-modem-base.c | 11 | ||||
-rw-r--r-- | src/mm-modem.c | 65 | ||||
-rw-r--r-- | src/mm-modem.h | 30 |
7 files changed, 186 insertions, 10 deletions
diff --git a/marshallers/mm-marshal.list b/marshallers/mm-marshal.list index ccf8605b..12c22c22 100644 --- a/marshallers/mm-marshal.list +++ b/marshallers/mm-marshal.list @@ -3,3 +3,5 @@ VOID:STRING,STRING,UINT VOID:OBJECT,UINT VOID:UINT,BOOLEAN VOID:UINT,UINT +VOID:UINT,UINT,UINT + diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index e07c81e9..0653e708 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -292,6 +292,18 @@ mm_generic_cdma_evdo_get_registration_state_sync (MMGenericCdma *self) /*****************************************************************************/ static void +set_state_enabled (MMGenericCdma *self, MMModemStateReason reason) +{ + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + + if ( priv->cdma_1x_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN + || priv->evdo_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_REGISTERED, reason); + else + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_ENABLED, reason); +} + +static void registration_cleanup (MMGenericCdma *self, GQuark error_class, guint32 error_num) { MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); @@ -337,6 +349,8 @@ enable_error_reporting_done (MMSerialPort *port, g_assert (info->error); } + set_state_enabled (MM_GENERIC_CDMA (info->modem), MM_MODEM_STATE_REASON_NONE); + /* Ignore errors, see FIXME in init_done() */ mm_callback_info_schedule (info); } @@ -406,8 +420,12 @@ disable_flash_done (MMSerialPort *port, if (error) info->error = g_error_copy (error); - else + else { mm_serial_port_close (port); + mm_modem_set_state (MM_MODEM (info->modem), + MM_MODEM_STATE_DISABLED, + MM_MODEM_STATE_REASON_NONE); + } mm_callback_info_schedule (info); } @@ -445,13 +463,15 @@ dial_done (MMSerialPort *port, MMGenericCdma *self = MM_GENERIC_CDMA (info->modem); MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);; - if (error) + if (error) { info->error = g_error_copy (error); - else { + mm_modem_set_state (info->modem, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE); + } else { /* Clear reg tries; we're obviously registered by this point */ registration_cleanup (self, 0, 0); mm_port_set_connected (priv->data, TRUE); + mm_modem_set_state (info->modem, MM_MODEM_STATE_CONNECTED, MM_MODEM_STATE_REASON_NONE); } mm_callback_info_schedule (info); @@ -467,6 +487,8 @@ connect (MMModem *modem, MMCallbackInfo *info; char *command; + mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE); + info = mm_callback_info_new (modem, callback, user_data); command = g_strconcat ("DT", number, NULL); mm_serial_port_queue_command (priv->primary, command, 60, dial_done, info); @@ -488,6 +510,9 @@ disconnect_flash_done (MMSerialPort *port, } mm_port_set_connected (priv->data, FALSE); + + set_state_enabled (MM_GENERIC_CDMA (info->modem), MM_MODEM_STATE_REASON_NONE); + mm_callback_info_schedule (info); } @@ -1260,6 +1285,12 @@ reg_state_changed (MMModemCdma *self, } static void +set_simple_state (MMCallbackInfo *info, SimpleState state) +{ + mm_callback_info_set_data (info, "simple-connect-state", GUINT_TO_POINTER (state), NULL); +} + +static void simple_state_machine (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; @@ -1275,11 +1306,11 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) switch (state) { case SIMPLE_STATE_BEGIN: - state = SIMPLE_STATE_ENABLE; + set_simple_state (info, SIMPLE_STATE_ENABLE); mm_modem_enable (modem, simple_state_machine, info); break; case SIMPLE_STATE_ENABLE: - state = SIMPLE_STATE_REGISTER; + set_simple_state (info, SIMPLE_STATE_REGISTER); mm_modem_cdma_get_registration_state (MM_MODEM_CDMA (modem), simple_reg_callback, info); @@ -1291,12 +1322,14 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) break; case SIMPLE_STATE_REGISTER: registration_cleanup (MM_GENERIC_CDMA (modem), 0, 0); - state = SIMPLE_STATE_CONNECT; + set_simple_state (info, SIMPLE_STATE_CONNECT); + mm_modem_set_state (modem, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE); + str = simple_get_string_property (info, "number", &info->error); mm_modem_connect (modem, str, simple_state_machine, info); break; case SIMPLE_STATE_CONNECT: - state = SIMPLE_STATE_DONE; + set_simple_state (info, SIMPLE_STATE_DONE); break; case SIMPLE_STATE_DONE: break; @@ -1306,8 +1339,7 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) if (info->error || state == SIMPLE_STATE_DONE) { registration_cleanup (MM_GENERIC_CDMA (modem), 0, 0); mm_callback_info_schedule (info); - } else - mm_callback_info_set_data (info, "simple-connect-state", GUINT_TO_POINTER (state), NULL); + } } static void diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index f08097f6..eb712aba 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -159,6 +159,8 @@ mm_generic_gsm_set_reg_status (MMGenericGsm *modem, mm_modem_gsm_network_registration_info (MM_MODEM_GSM_NETWORK (modem), priv->reg_status, priv->oper_code, priv->oper_name); } + + mm_generic_gsm_update_enabled_state (modem, MM_MODEM_STATE_REASON_NONE); } } @@ -209,6 +211,28 @@ mm_generic_gsm_check_pin (MMGenericGsm *modem, /*****************************************************************************/ +void +mm_generic_gsm_update_enabled_state (MMGenericGsm *self, MMModemStateReason reason) +{ + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); + + switch (priv->reg_status) { + case MM_MODEM_GSM_NETWORK_REG_STATUS_HOME: + case MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING: + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_REGISTERED, reason); + break; + case MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING: + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_SEARCHING, reason); + break; + case MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE: + case MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED: + case MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN: + default: + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_ENABLED, reason); + break; + } +} + static void check_valid (MMGenericGsm *self) { @@ -348,6 +372,10 @@ enable_done (MMSerialPort *port, * on the phone and let the subclass decided whether it wants to handle * errors or ignore them. */ + + mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (info->modem), + MM_MODEM_STATE_REASON_NONE); + mm_callback_info_schedule (info); } @@ -432,8 +460,13 @@ disable_done (MMSerialPort *port, GError *error, gpointer user_data) { + MMCallbackInfo *info = user_data; + mm_serial_port_close (port); - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + mm_modem_set_state (MM_MODEM (info->modem), + MM_MODEM_STATE_DISABLED, + MM_MODEM_STATE_REASON_NONE); + mm_callback_info_schedule (info); } static void diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h index 7cfd6253..af71b17b 100644 --- a/src/mm-generic-gsm.h +++ b/src/mm-generic-gsm.h @@ -85,4 +85,7 @@ MMPort *mm_generic_gsm_grab_port (MMGenericGsm *modem, MMPortType ptype, GError **error); +void mm_generic_gsm_update_enabled_state (MMGenericGsm *modem, + MMModemStateReason reason); + #endif /* MM_GENERIC_GSM_H */ diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index 1df965f8..8398f936 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -40,6 +40,7 @@ typedef struct { char *device; guint32 ip_method; gboolean valid; + MMModemState state; GHashTable *ports; } MMModemBasePrivate; @@ -181,6 +182,9 @@ set_property (GObject *object, guint prop_id, MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (object); switch (prop_id) { + case MM_MODEM_PROP_STATE: + priv->state = g_value_get_uint (value); + break; case MM_MODEM_PROP_DRIVER: /* Construct only */ priv->driver = g_value_dup_string (value); @@ -212,6 +216,9 @@ get_property (GObject *object, guint prop_id, MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (object); switch (prop_id) { + case MM_MODEM_PROP_STATE: + g_value_set_uint (value, priv->state); + break; case MM_MODEM_PROP_MASTER_DEVICE: g_value_set_string (value, priv->device); break; @@ -266,6 +273,10 @@ mm_modem_base_class_init (MMModemBaseClass *klass) object_class->finalize = finalize; g_object_class_override_property (object_class, + MM_MODEM_PROP_STATE, + MM_MODEM_STATE); + + g_object_class_override_property (object_class, MM_MODEM_PROP_MASTER_DEVICE, MM_MODEM_MASTER_DEVICE); diff --git a/src/mm-modem.c b/src/mm-modem.c index ca2afbd7..11934a20 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,9 +58,18 @@ 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) { + /* Already enabled */ + callback (self, NULL, user_data); + return; + } + if (MM_MODEM_GET_INTERFACE (self)->enable) MM_MODEM_GET_INTERFACE (self)->enable (self, callback, user_data); else @@ -71,9 +81,18 @@ 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); + state = mm_modem_get_state (self); + if (state <= MM_MODEM_STATE_DISABLED) { + /* Already disabled */ + callback (self, NULL, user_data); + return; + } + if (MM_MODEM_GET_INTERFACE (self)->disable) MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data); else @@ -381,11 +400,37 @@ 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; +} + +void +mm_modem_set_state (MMModem *self, + MMModemState new_state, + MMModemStateReason reason) +{ + MMModemState old_state = MM_MODEM_STATE_UNKNOWN; + + 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); +g_message ("%s: state %d -> %d", __func__, old_state, 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 +495,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; } diff --git a/src/mm-modem.h b/src/mm-modem.h index 29f72b43..f771f3ad 100644 --- a/src/mm-modem.h +++ b/src/mm-modem.h @@ -21,6 +21,22 @@ #include "mm-port.h" +typedef enum { + MM_MODEM_STATE_UNKNOWN = 0, + MM_MODEM_STATE_DISABLED = 10, + MM_MODEM_STATE_ENABLED = 20, + MM_MODEM_STATE_SEARCHING = 30, + MM_MODEM_STATE_REGISTERED = 40, + MM_MODEM_STATE_CONNECTING = 50, + MM_MODEM_STATE_CONNECTED = 60, + + MM_MODEM_STATE_LAST = MM_MODEM_STATE_CONNECTED +} MMModemState; + +typedef enum { + MM_MODEM_STATE_REASON_NONE = 0 +} MMModemStateReason; + #define MM_TYPE_MODEM (mm_modem_get_type ()) #define MM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM, MMModem)) #define MM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM)) @@ -33,6 +49,7 @@ #define MM_MODEM_IP_METHOD "ip-method" #define MM_MODEM_VALID "valid" /* not exported */ #define MM_MODEM_PLUGIN "plugin" /* not exported */ +#define MM_MODEM_STATE "state" /* not exported */ #define MM_MODEM_TYPE_UNKNOWN 0 #define MM_MODEM_TYPE_GSM 1 @@ -52,6 +69,7 @@ typedef enum { MM_MODEM_PROP_IP_METHOD, MM_MODEM_PROP_VALID, /* Not exported */ MM_MODEM_PROP_PLUGIN, /* Not exported */ + MM_MODEM_PROP_STATE, /* Not exported */ } MMModemProp; typedef struct _MMModem MMModem; @@ -126,6 +144,12 @@ struct _MMModem { void (*get_info) (MMModem *self, MMModemInfoFn callback, gpointer user_data); + + /* Signals */ + void (*state_changed) (MMModem *self, + MMModemState new_state, + MMModemState old_state, + MMModemStateReason reason); }; GType mm_modem_get_type (void); @@ -174,5 +198,11 @@ gboolean mm_modem_get_valid (MMModem *self); char *mm_modem_get_device (MMModem *self); +MMModemState mm_modem_get_state (MMModem *self); + +void mm_modem_set_state (MMModem *self, + MMModemState new_state, + MMModemStateReason reason); + #endif /* MM_MODEM_H */ |