diff options
-rw-r--r-- | plugins/mm-modem-huawei-cdma.c | 67 | ||||
-rw-r--r-- | src/mm-generic-cdma.c | 39 | ||||
-rw-r--r-- | src/mm-generic-cdma.h | 3 |
3 files changed, 88 insertions, 21 deletions
diff --git a/plugins/mm-modem-huawei-cdma.c b/plugins/mm-modem-huawei-cdma.c index 25c7b373..cc0aa4ef 100644 --- a/plugins/mm-modem-huawei-cdma.c +++ b/plugins/mm-modem-huawei-cdma.c @@ -56,25 +56,53 @@ mm_modem_huawei_cdma_new (const char *device, /* Unsolicited message handlers */ -static void -handle_signal_quality_change (MMSerialPort *port, - GMatchInfo *match_info, - gpointer user_data) +static gint +parse_quality (const char *str, const char *detail) { - MMModemHuaweiCdma *self = MM_MODEM_HUAWEI_CDMA (user_data); - char *str; - long int quality; - - str = g_match_info_fetch (match_info, 1); + long int quality = 0; errno = 0; quality = strtol (str, NULL, 10); if (errno == 0) { quality = CLAMP (quality, 0, 100); - g_debug ("Signal quality: %ld", quality); - mm_generic_cdma_update_signal_quality (MM_GENERIC_CDMA (self), (guint32) quality); + g_debug ("%s: %ld", detail, quality); + return (gint) quality; } + return -1; +} + +static void +handle_1x_quality_change (MMSerialPort *port, + GMatchInfo *match_info, + gpointer user_data) +{ + MMModemHuaweiCdma *self = MM_MODEM_HUAWEI_CDMA (user_data); + char *str; + gint quality; + + str = g_match_info_fetch (match_info, 1); + quality = parse_quality (str, "1X signal quality"); + g_free (str); + + if (quality >= 0) + mm_generic_cdma_update_cdma1x_quality (MM_GENERIC_CDMA (self), (guint32) quality); +} + +static void +handle_evdo_quality_change (MMSerialPort *port, + GMatchInfo *match_info, + gpointer user_data) +{ + MMModemHuaweiCdma *self = MM_MODEM_HUAWEI_CDMA (user_data); + char *str; + gint quality; + + str = g_match_info_fetch (match_info, 1); + quality = parse_quality (str, "EVDO signal quality"); g_free (str); + + if (quality >= 0) + mm_generic_cdma_update_evdo_quality (MM_GENERIC_CDMA (self), (guint32) quality); } /*****************************************************************************/ @@ -233,11 +261,26 @@ grab_port (MMModem *modem, port = mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error); if (port && MM_IS_SERIAL_PORT (port)) { + gboolean evdo0 = FALSE, evdoA = FALSE; + g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); + /* 1x signal level */ regex = g_regex_new ("\\r\\n\\^RSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_signal_quality_change, modem, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_1x_quality_change, modem, NULL); g_regex_unref (regex); + + g_object_get (G_OBJECT (modem), + MM_GENERIC_CDMA_EVDO_REV0, &evdo0, + MM_GENERIC_CDMA_EVDO_REVA, &evdoA, + NULL); + + if (evdo0 || evdoA) { + /* EVDO signal level */ + regex = g_regex_new ("\\r\\n\\^HRSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_evdo_quality_change, modem, NULL); + g_regex_unref (regex); + } } return !!port; diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index e07c81e9..be4e0524 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -48,7 +48,8 @@ G_DEFINE_TYPE_EXTENDED (MMGenericCdma, mm_generic_cdma, MM_TYPE_MODEM_BASE, 0, #define MM_GENERIC_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_GENERIC_CDMA, MMGenericCdmaPrivate)) typedef struct { - guint32 signal_quality; + guint32 cdma1x_quality; + guint32 evdo_quality; gboolean valid; gboolean evdo_rev0; gboolean evdo_revA; @@ -608,13 +609,33 @@ get_card_info (MMModem *modem, /*****************************************************************************/ void -mm_generic_cdma_update_signal_quality (MMGenericCdma *self, guint32 quality) +mm_generic_cdma_update_cdma1x_quality (MMGenericCdma *self, guint32 quality) { + MMGenericCdmaPrivate *priv; + g_return_if_fail (MM_IS_GENERIC_CDMA (self)); g_return_if_fail (quality >= 0 && quality <= 100); - MM_GENERIC_CDMA_GET_PRIVATE (self)->signal_quality = quality; - mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (self), quality); + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + if (priv->cdma1x_quality != quality) { + priv->cdma1x_quality = quality; + mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (self), quality); + } +} + +void +mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality) +{ + MMGenericCdmaPrivate *priv; + + g_return_if_fail (MM_IS_GENERIC_CDMA (self)); + g_return_if_fail (quality >= 0 && quality <= 100); + + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + if (priv->evdo_quality != quality) { + priv->evdo_quality = quality; + // FIXME: emit a signal + } } static void @@ -646,9 +667,11 @@ get_signal_quality_done (MMSerialPort *port, quality = CLAMP (quality, 0, 31) * 100 / 31; priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem); - priv->signal_quality = quality; mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL); - mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (info->modem), quality); + if (priv->cdma1x_quality != quality) { + priv->cdma1x_quality = quality; + mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (info->modem), quality); + } } } else info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, @@ -669,8 +692,8 @@ get_signal_quality (MMModemCdma *modem, connected = mm_port_get_connected (MM_PORT (priv->primary)); if (connected && !priv->secondary) { - g_message ("Returning saved signal quality %d", priv->signal_quality); - callback (MM_MODEM (modem), priv->signal_quality, NULL, user_data); + g_message ("Returning saved signal quality %d", priv->cdma1x_quality); + callback (MM_MODEM (modem), priv->cdma1x_quality, NULL, user_data); return; } diff --git a/src/mm-generic-cdma.h b/src/mm-generic-cdma.h index a1200c36..8d85cb38 100644 --- a/src/mm-generic-cdma.h +++ b/src/mm-generic-cdma.h @@ -64,7 +64,8 @@ MMPort * mm_generic_cdma_grab_port (MMGenericCdma *self, MMSerialPort *mm_generic_cdma_get_port (MMGenericCdma *modem, MMPortType ptype); -void mm_generic_cdma_update_signal_quality (MMGenericCdma *self, guint32 quality); +void mm_generic_cdma_update_cdma1x_quality (MMGenericCdma *self, guint32 quality); +void mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality); /* For unsolicited 1x registration state changes */ void mm_generic_cdma_set_1x_registration_state (MMGenericCdma *self, |