cdma: handle 1x and EVDO quality separately
This commit is contained in:
@@ -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;
|
||||
|
||||
+31
-8
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user