diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-generic-cdma.c | 238 | ||||
-rw-r--r-- | src/mm-generic-cdma.h | 36 | ||||
-rw-r--r-- | src/mm-modem-cdma.c | 48 | ||||
-rw-r--r-- | src/mm-modem-cdma.h | 16 |
4 files changed, 291 insertions, 47 deletions
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index 942834db..cfc7438d 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -40,17 +40,30 @@ typedef struct { guint32 signal_quality; guint32 ip_method; gboolean valid; - MMModemCdmaRegistrationState reg_state; + gboolean evdo_rev0; + gboolean evdo_revA; + + MMModemCdmaRegistrationState cdma_1x_reg_state; + MMModemCdmaRegistrationState evdo_reg_state; MMSerialPort *primary; MMSerialPort *secondary; MMPort *data; } MMGenericCdmaPrivate; +enum { + PROP_0, + PROP_EVDO_REV0, + PROP_EVDO_REVA, + LAST_PROP +}; + MMModem * mm_generic_cdma_new (const char *device, const char *driver, - const char *plugin) + const char *plugin, + gboolean evdo_rev0, + gboolean evdo_revA) { g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); @@ -60,6 +73,8 @@ mm_generic_cdma_new (const char *device, MM_MODEM_MASTER_DEVICE, device, MM_MODEM_DRIVER, driver, MM_MODEM_PLUGIN, plugin, + MM_GENERIC_CDMA_EVDO_REV0, evdo_rev0, + MM_GENERIC_CDMA_EVDO_REVA, evdo_revA, NULL)); } @@ -199,23 +214,67 @@ mm_generic_cdma_get_port (MMGenericCdma *modem, /*****************************************************************************/ void -mm_generic_cdma_set_registration_state (MMGenericCdma *self, - MMModemCdmaRegistrationState new_state) +mm_generic_cdma_set_1x_registration_state (MMGenericCdma *self, + MMModemCdmaRegistrationState new_state) { + MMGenericCdmaPrivate *priv; + g_return_if_fail (self != NULL); g_return_if_fail (MM_IS_GENERIC_CDMA (self)); - MM_GENERIC_CDMA_GET_PRIVATE (self)->reg_state = new_state; - mm_modem_cdma_emit_registration_state_changed (MM_MODEM_CDMA (self), new_state); + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + + if (priv->cdma_1x_reg_state != new_state) { + priv->cdma_1x_reg_state = new_state; + + mm_modem_cdma_emit_registration_state_changed (MM_MODEM_CDMA (self), + priv->cdma_1x_reg_state, + priv->evdo_reg_state); + } +} + +void +mm_generic_cdma_set_evdo_registration_state (MMGenericCdma *self, + MMModemCdmaRegistrationState new_state) +{ + MMGenericCdmaPrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_GENERIC_CDMA (self)); + + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + + if (priv->evdo_reg_state == new_state) + return; + + /* Don't update EVDO state if the card doesn't support it */ + if ( priv->evdo_rev0 + || priv->evdo_revA + || (new_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)) { + priv->evdo_reg_state = new_state; + + mm_modem_cdma_emit_registration_state_changed (MM_MODEM_CDMA (self), + priv->cdma_1x_reg_state, + priv->evdo_reg_state); + } +} + +MMModemCdmaRegistrationState +mm_generic_cdma_1x_get_registration_state_sync (MMGenericCdma *self) +{ + g_return_val_if_fail (self != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); + g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); + + return MM_GENERIC_CDMA_GET_PRIVATE (self)->cdma_1x_reg_state; } MMModemCdmaRegistrationState -mm_generic_cdma_get_registration_state_sync (MMGenericCdma *self) +mm_generic_cdma_evdo_get_registration_state_sync (MMGenericCdma *self) { g_return_val_if_fail (self != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); - return MM_GENERIC_CDMA_GET_PRIVATE (self)->reg_state; + return MM_GENERIC_CDMA_GET_PRIVATE (self)->evdo_reg_state; } /*****************************************************************************/ @@ -817,16 +876,110 @@ get_serving_system (MMModemCdma *modem, serving_system_done, info); } +#define CDMA_1X_STATE_TAG "cdma-1x-reg-state" +#define EVDO_STATE_TAG "evdo-reg-state" + +void +mm_generic_cdma_query_reg_state_set_callback_1x_state (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state) +{ + g_return_if_fail (info != NULL); + g_return_if_fail (info->modem != NULL); + g_return_if_fail (MM_IS_GENERIC_CDMA (info->modem)); + + mm_callback_info_set_data (info, CDMA_1X_STATE_TAG, GUINT_TO_POINTER (new_state), NULL); +} + +void +mm_generic_cdma_query_reg_state_set_callback_evdo_state (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state) +{ + g_return_if_fail (info != NULL); + g_return_if_fail (info->modem != NULL); + g_return_if_fail (MM_IS_GENERIC_CDMA (info->modem)); + + mm_callback_info_set_data (info, EVDO_STATE_TAG, GUINT_TO_POINTER (new_state), NULL); +} + static void -reg_state_query_done (MMModem *modem, guint32 reg_state, GError *error, gpointer user_data) +registration_state_invoke (MMCallbackInfo *info) +{ + MMModemCdmaRegistrationStateFn callback = (MMModemCdmaRegistrationStateFn) info->callback; + + /* note: This is the MMModemCdma interface callback */ + callback (MM_MODEM_CDMA (info->modem), + GPOINTER_TO_UINT (mm_callback_info_get_data (info, CDMA_1X_STATE_TAG)), + GPOINTER_TO_UINT (mm_callback_info_get_data (info, EVDO_STATE_TAG)), + info->error, + info->user_data); +} + +MMCallbackInfo * +mm_generic_cdma_query_reg_state_callback_info_new (MMGenericCdma *self, + MMModemCdmaRegistrationStateFn callback, + gpointer user_data) +{ + MMGenericCdmaPrivate *priv; + MMCallbackInfo *info; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), NULL); + g_return_val_if_fail (callback != NULL, NULL); + + info = mm_callback_info_new_full (MM_MODEM (self), + registration_state_invoke, + G_CALLBACK (callback), + user_data); + + /* Fill with current state */ + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + mm_callback_info_set_data (info, + CDMA_1X_STATE_TAG, + GUINT_TO_POINTER (priv->cdma_1x_reg_state), + NULL); + mm_callback_info_set_data (info, + EVDO_STATE_TAG, + GUINT_TO_POINTER (priv->evdo_reg_state), + NULL); + return info; +} + +static void +set_callback_1x_state_helper (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state) +{ + MMGenericCdma *self = MM_GENERIC_CDMA (info->modem); + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem); + + mm_generic_cdma_set_1x_registration_state (self, new_state); + mm_generic_cdma_query_reg_state_set_callback_1x_state (info, priv->cdma_1x_reg_state); +} + +static void +set_callback_evdo_state_helper (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state) +{ + MMGenericCdma *self = MM_GENERIC_CDMA (info->modem); + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem); + + mm_generic_cdma_set_evdo_registration_state (self, new_state); + mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, priv->evdo_reg_state); +} + +static void +reg_state_query_done (MMModemCdma *cdma, + MMModemCdmaRegistrationState cdma_1x_reg_state, + MMModemCdmaRegistrationState evdo_reg_state, + GError *error, + gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; if (error) info->error = g_error_copy (error); else { - mm_callback_info_set_result (info, GUINT_TO_POINTER (reg_state), NULL); - mm_generic_cdma_set_registration_state (MM_GENERIC_CDMA (info->modem), reg_state); + set_callback_1x_state_helper (info, cdma_1x_reg_state); + set_callback_evdo_state_helper (info, evdo_reg_state); } mm_callback_info_schedule (info); @@ -849,11 +1002,8 @@ reg_state_css_response (MMModemCdma *cdma, if (error) { if ( (error->domain == MM_MOBILE_ERROR) && (error->code == MM_MOBILE_ERROR_NO_NETWORK)) { - mm_callback_info_set_result (info, - GUINT_TO_POINTER (MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN), - NULL); - mm_generic_cdma_set_registration_state (MM_GENERIC_CDMA (modem), - MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); + set_callback_1x_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); + set_callback_evdo_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); } else { /* Some other error parsing CSS results */ info->error = g_error_copy (error); @@ -863,12 +1013,14 @@ reg_state_css_response (MMModemCdma *cdma, } /* SID is valid; let subclasses figure out roaming and detailed registration */ - if (MM_GENERIC_CDMA_GET_CLASS (modem)->query_registration_state) { - MM_GENERIC_CDMA_GET_CLASS (modem)->query_registration_state (MM_GENERIC_CDMA (modem), - reg_state_query_done, - info); + if (MM_GENERIC_CDMA_GET_CLASS (modem)->query_registration_state) { + MM_GENERIC_CDMA_GET_CLASS (modem)->query_registration_state (MM_GENERIC_CDMA (modem), + reg_state_query_done, + info); } else { - reg_state_query_done (modem, + /* Otherwise, success; we're registered */ + reg_state_query_done (cdma, + MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED, MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED, NULL, info); @@ -893,9 +1045,9 @@ get_analog_digital_done (MMSerialPort *port, /* Strip any leading command tag and spaces */ reply = strip_response (response->str, "+CAD:"); - errno = 0; - int_cad = strtol (reply, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) { + errno = 0; + int_cad = strtol (reply, NULL, 10); + if ((errno == EINVAL) || (errno == ERANGE)) { info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Failed to parse +CAD response"); @@ -904,7 +1056,7 @@ get_analog_digital_done (MMSerialPort *port, if (int_cad == 1) { /* 1 == CDMA service */ /* Now that we have some sort of service, check if the the device is - * registered on some network. + * registered on the network. */ get_serving_system (MM_MODEM_CDMA (info->modem), reg_state_css_response, @@ -923,7 +1075,7 @@ error: static void get_registration_state (MMModemCdma *modem, - MMModemUIntFn callback, + MMModemCdmaRegistrationStateFn callback, gpointer user_data) { MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); @@ -932,12 +1084,14 @@ get_registration_state (MMModemCdma *modem, connected = mm_port_get_connected (MM_PORT (priv->primary)); if (connected && !priv->secondary) { - g_message ("Returning saved registration state %d", priv->reg_state); - callback (MM_MODEM (modem), priv->reg_state, NULL, user_data); + g_message ("Returning saved registration states: 1x: %d EVDO: %d", + priv->cdma_1x_reg_state, priv->evdo_reg_state); + callback (MM_MODEM_CDMA (modem), priv->cdma_1x_reg_state, priv->evdo_reg_state, NULL, user_data); return; } - info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); + info = mm_generic_cdma_query_reg_state_callback_info_new (MM_GENERIC_CDMA (modem), callback, user_data); + /* Prefer secondary port for registration state */ mm_serial_port_queue_command (priv->secondary ? priv->secondary : priv->primary, "+CAD?", @@ -1154,6 +1308,12 @@ set_property (GObject *object, guint prop_id, case MM_MODEM_PROP_TYPE: case MM_MODEM_PROP_VALID: break; + case PROP_EVDO_REV0: + priv->evdo_rev0 = g_value_get_boolean (value); + break; + case PROP_EVDO_REVA: + priv->evdo_revA = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1191,6 +1351,12 @@ get_property (GObject *object, guint prop_id, case MM_MODEM_PROP_VALID: g_value_set_boolean (value, priv->valid); break; + case PROP_EVDO_REV0: + g_value_set_boolean (value, priv->evdo_rev0); + break; + case PROP_EVDO_REVA: + g_value_set_boolean (value, priv->evdo_revA); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1248,6 +1414,20 @@ mm_generic_cdma_class_init (MMGenericCdmaClass *klass) g_object_class_override_property (object_class, MM_MODEM_PROP_VALID, MM_MODEM_VALID); + + g_object_class_install_property (object_class, PROP_EVDO_REV0, + g_param_spec_boolean (MM_GENERIC_CDMA_EVDO_REV0, + "EVDO rev0", + "Supports EVDO rev0", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_EVDO_REVA, + g_param_spec_boolean (MM_GENERIC_CDMA_EVDO_REVA, + "EVDO revA", + "Supports EVDO revA", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } GType diff --git a/src/mm-generic-cdma.h b/src/mm-generic-cdma.h index d7b82250..a1200c36 100644 --- a/src/mm-generic-cdma.h +++ b/src/mm-generic-cdma.h @@ -21,6 +21,7 @@ #include "mm-modem-base.h" #include "mm-modem-cdma.h" #include "mm-serial-port.h" +#include "mm-callback-info.h" #define MM_TYPE_GENERIC_CDMA (mm_generic_cdma_get_type ()) #define MM_GENERIC_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_GENERIC_CDMA, MMGenericCdma)) @@ -29,6 +30,9 @@ #define MM_IS_GENERIC_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_GENERIC_CDMA)) #define MM_GENERIC_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_GENERIC_CDMA, MMGenericCdmaClass)) +#define MM_GENERIC_CDMA_EVDO_REV0 "evdo-rev0" +#define MM_GENERIC_CDMA_EVDO_REVA "evdo-revA" + typedef struct { MMModemBase parent; } MMGenericCdma; @@ -37,7 +41,7 @@ typedef struct { MMModemBaseClass parent; void (*query_registration_state) (MMGenericCdma *self, - MMModemUIntFn callback, + MMModemCdmaRegistrationStateFn callback, gpointer user_data); } MMGenericCdmaClass; @@ -45,7 +49,9 @@ GType mm_generic_cdma_get_type (void); MMModem *mm_generic_cdma_new (const char *device, const char *driver, - const char *plugin); + const char *plugin, + gboolean evdo_rev0, + gboolean evdo_revA); /* Private, for subclasses */ @@ -58,11 +64,29 @@ MMPort * mm_generic_cdma_grab_port (MMGenericCdma *self, MMSerialPort *mm_generic_cdma_get_port (MMGenericCdma *modem, MMPortType ptype); -void mm_generic_cdma_set_registration_state (MMGenericCdma *self, - MMModemCdmaRegistrationState new_state); +void mm_generic_cdma_update_signal_quality (MMGenericCdma *self, guint32 quality); + +/* For unsolicited 1x registration state changes */ +void mm_generic_cdma_set_1x_registration_state (MMGenericCdma *self, + MMModemCdmaRegistrationState new_state); -MMModemCdmaRegistrationState mm_generic_cdma_get_registration_state_sync (MMGenericCdma *self); +/* For unsolicited EVDO registration state changes */ +void mm_generic_cdma_set_evdo_registration_state (MMGenericCdma *self, + MMModemCdmaRegistrationState new_state); -void mm_generic_cdma_update_signal_quality (MMGenericCdma *self, guint32 quality); +MMModemCdmaRegistrationState mm_generic_cdma_1x_get_registration_state_sync (MMGenericCdma *self); + +MMModemCdmaRegistrationState mm_generic_cdma_evdo_get_registration_state_sync (MMGenericCdma *self); + +/* query_registration_state class function helpers */ +MMCallbackInfo *mm_generic_cdma_query_reg_state_callback_info_new (MMGenericCdma *self, + MMModemCdmaRegistrationStateFn callback, + gpointer user_data); + +void mm_generic_cdma_query_reg_state_set_callback_1x_state (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state); + +void mm_generic_cdma_query_reg_state_set_callback_evdo_state (MMCallbackInfo *info, + MMModemCdmaRegistrationState new_state); #endif /* MM_GENERIC_CDMA_H */ diff --git a/src/mm-modem-cdma.c b/src/mm-modem-cdma.c index 0f5bc3d9..112b93fa 100644 --- a/src/mm-modem-cdma.c +++ b/src/mm-modem-cdma.c @@ -19,6 +19,7 @@ #include "mm-modem-cdma.h" #include "mm-errors.h" #include "mm-callback-info.h" +#include "mm-marshal.h" static void impl_modem_cdma_get_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context); static void impl_modem_cdma_get_esn (MMModemCdma *modem, DBusGMethodInvocation *context); @@ -221,9 +222,26 @@ mm_modem_cdma_emit_signal_quality_changed (MMModemCdma *self, guint32 quality) g_signal_emit (self, signals[SIGNAL_QUALITY], 0, quality); } +/*****************************************************************************/ + +static void +get_registration_state_call_done (MMModemCdma *self, + MMModemCdmaRegistrationState cdma_1x_reg_state, + MMModemCdmaRegistrationState evdo_reg_state, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context, cdma_1x_reg_state, evdo_reg_state); +} + void mm_modem_cdma_get_registration_state (MMModemCdma *self, - MMModemUIntFn callback, + MMModemCdmaRegistrationStateFn callback, gpointer user_data) { g_return_if_fail (MM_IS_MODEM_CDMA (self)); @@ -231,23 +249,37 @@ mm_modem_cdma_get_registration_state (MMModemCdma *self, if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_registration_state) MM_MODEM_CDMA_GET_INTERFACE (self)->get_registration_state (self, callback, user_data); - else - uint_op_not_supported (MM_MODEM (self), callback, user_data); + else { + GError *error; + + error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, + "Operation not supported"); + + callback (self, + MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN, + MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN, + error, + user_data); + + g_error_free (error); + } } static void impl_modem_cdma_get_registration_state (MMModemCdma *modem, DBusGMethodInvocation *context) { - mm_modem_cdma_get_registration_state (modem, uint_call_done, context); + mm_modem_cdma_get_registration_state (modem, get_registration_state_call_done, context); } void mm_modem_cdma_emit_registration_state_changed (MMModemCdma *self, - MMModemCdmaRegistrationState new_state) + MMModemCdmaRegistrationState cdma_1x_new_state, + MMModemCdmaRegistrationState evdo_new_state) { g_return_if_fail (MM_IS_MODEM_CDMA (self)); - g_signal_emit (self, signals[REGISTRATION_STATE_CHANGED], 0, new_state); + g_signal_emit (self, signals[REGISTRATION_STATE_CHANGED], 0, cdma_1x_new_state, evdo_new_state); } /*****************************************************************************/ @@ -277,8 +309,8 @@ mm_modem_cdma_init (gpointer g_iface) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MMModemCdma, registration_state_changed), NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); + mm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); initialized = TRUE; } diff --git a/src/mm-modem-cdma.h b/src/mm-modem-cdma.h index bd8dfa3f..a7a626f7 100644 --- a/src/mm-modem-cdma.h +++ b/src/mm-modem-cdma.h @@ -44,6 +44,12 @@ typedef void (*MMModemCdmaServingSystemFn) (MMModemCdma *modem, GError *error, gpointer user_data); +typedef void (*MMModemCdmaRegistrationStateFn) (MMModemCdma *modem, + MMModemCdmaRegistrationState cdma_1x_reg_state, + MMModemCdmaRegistrationState evdo_reg_state, + GError *error, + gpointer user_data); + struct _MMModemCdma { GTypeInterface g_iface; @@ -61,7 +67,7 @@ struct _MMModemCdma { gpointer user_data); void (*get_registration_state) (MMModemCdma *self, - MMModemUIntFn callback, + MMModemCdmaRegistrationStateFn callback, gpointer user_data); /* Signals */ @@ -69,7 +75,8 @@ struct _MMModemCdma { guint32 quality); void (*registration_state_changed) (MMModemCdma *self, - MMModemCdmaRegistrationState new_state); + MMModemCdmaRegistrationState cdma_1x_new_state, + MMModemCdmaRegistrationState evdo_new_state); }; GType mm_modem_cdma_get_type (void); @@ -87,7 +94,7 @@ void mm_modem_cdma_get_serving_system (MMModemCdma *self, gpointer user_data); void mm_modem_cdma_get_registration_state (MMModemCdma *self, - MMModemUIntFn callback, + MMModemCdmaRegistrationStateFn callback, gpointer user_data); /* Protected */ @@ -95,6 +102,7 @@ void mm_modem_cdma_get_registration_state (MMModemCdma *self, void mm_modem_cdma_emit_signal_quality_changed (MMModemCdma *self, guint32 new_quality); void mm_modem_cdma_emit_registration_state_changed (MMModemCdma *self, - MMModemCdmaRegistrationState new_state); + MMModemCdmaRegistrationState cdma_1x_new_state, + MMModemCdmaRegistrationState evdo_new_state); #endif /* MM_MODEM_CDMA_H */ |