[PATCH v2] broadband-modem-huawei: implement Modem.Signal extended signal info interface

Aleksander Morgado aleksander at aleksander.es
Wed Aug 31 13:23:05 UTC 2016


On Tue, Aug 30, 2016 at 10:32 PM, Dan Williams <dcbw at redhat.com> wrote:
> Implement the detailed signal info interface for some Huawei 3GPP modems.
>

Some very minor thing, commented below. Other than that looks good to
me, go merge it :)

> ---
>  plugins/huawei/mm-broadband-modem-huawei.c       | 318 ++++++++++++++++++++++-
>  plugins/huawei/mm-modem-helpers-huawei.c         |  71 +++++
>  plugins/huawei/mm-modem-helpers-huawei.h         |  12 +
>  plugins/huawei/tests/test-modem-helpers-huawei.c |  61 +++++
>  src/mm-modem-helpers.c                           |  17 +-
>  5 files changed, 471 insertions(+), 8 deletions(-)
>
> diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
> index fe6c217..af560a4 100644
> --- a/plugins/huawei/mm-broadband-modem-huawei.c
> +++ b/plugins/huawei/mm-broadband-modem-huawei.c
> @@ -43,6 +43,7 @@
>  #include "mm-iface-modem-location.h"
>  #include "mm-iface-modem-time.h"
>  #include "mm-iface-modem-cdma.h"
> +#include "mm-iface-modem-signal.h"
>  #include "mm-iface-modem-voice.h"
>  #include "mm-broadband-modem-huawei.h"
>  #include "mm-broadband-bearer-huawei.h"
> @@ -58,6 +59,7 @@ static void iface_modem_location_init (MMIfaceModemLocation *iface);
>  static void iface_modem_cdma_init (MMIfaceModemCdma *iface);
>  static void iface_modem_time_init (MMIfaceModemTime *iface);
>  static void iface_modem_voice_init (MMIfaceModemVoice *iface);
> +static void iface_modem_signal_init (MMIfaceModemSignal *iface);
>
>  static MMIfaceModem *iface_modem_parent;
>  static MMIfaceModem3gpp *iface_modem_3gpp_parent;
> @@ -72,7 +74,8 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemHuawei, mm_broadband_modem_huawei, MM_TY
>                          G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)
>                          G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
>                          G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init)
> -                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init));
> +                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init)
> +                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIGNAL, iface_modem_signal_init));
>

The semicolon is not needed on the G_DEFINE_TYPE_* macros, you may
want to remove it before pushing.


>  typedef enum {
>      FEATURE_SUPPORT_UNKNOWN,
> @@ -80,6 +83,14 @@ typedef enum {
>      FEATURE_SUPPORTED
>  } FeatureSupport;
>
> +typedef struct {
> +    MMSignal *cdma;
> +    MMSignal *evdo;
> +    MMSignal *gsm;
> +    MMSignal *umts;
> +    MMSignal *lte;
> +} DetailedSignal;
> +
>  struct _MMBroadbandModemHuaweiPrivate {
>      /* Regex for signal quality related notifications */
>      GRegex *rssi_regex;
> @@ -134,6 +145,8 @@ struct _MMBroadbandModemHuaweiPrivate {
>      GArray *syscfg_supported_modes;
>      GArray *syscfgex_supported_modes;
>      GArray *prefmode_supported_modes;
> +
> +    DetailedSignal detailed_signal;
>  };
>
>  /*****************************************************************************/
> @@ -1740,6 +1753,136 @@ huawei_ndisstat_changed (MMPortSerialAt *port,
>  }
>
>  static void
> +detailed_signal_clear (DetailedSignal *signal)
> +{
> +    g_clear_object (&signal->cdma);
> +    g_clear_object (&signal->evdo);
> +    g_clear_object (&signal->gsm);
> +    g_clear_object (&signal->umts);
> +    g_clear_object (&signal->lte);
> +}
> +
> +static gboolean
> +get_rssi_dbm (guint rssi, gdouble *out_val)
> +{
> +    if (rssi <= 96) {
> +        *out_val = (double) (-121.0 + rssi);
> +        return TRUE;
> +    }
> +    return FALSE;
> +}
> +
> +static gboolean
> +get_ecio_db (guint ecio, gdouble *out_val)
> +{
> +    if (ecio <= 65) {
> +        *out_val = -32.5 + ((double) ecio / 2.0);
> +        return TRUE;
> +    }
> +    return FALSE;
> +}
> +
> +static gboolean
> +get_rsrp_dbm (guint rsrp, gdouble *out_val)
> +{
> +    if (rsrp <= 97) {
> +        *out_val = (double) (-141.0 + rsrp);
> +        return TRUE;
> +    }
> +    return FALSE;
> +}
> +
> +static gboolean
> +get_sinr_db (guint sinr, gdouble *out_val)
> +{
> +    if (sinr <= 251) {
> +        *out_val = -20.2 + (double) (sinr / 5.0);
> +        return TRUE;
> +    }
> +    return FALSE;
> +}
> +
> +static gboolean
> +get_rsrq_db (guint rsrq, gdouble *out_val)
> +{
> +    if (rsrq <= 34) {
> +        *out_val = -20 + (double) (rsrq / 2.0);
> +        return TRUE;
> +    }
> +    return FALSE;
> +}
> +
> +static void
> +huawei_hcsq_changed (MMPortSerialAt *port,
> +                     GMatchInfo *match_info,
> +                     MMBroadbandModemHuawei *self)
> +{
> +    gchar *str;
> +    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> +    guint value1 = 0;
> +    guint value2 = 0;
> +    guint value3 = 0;
> +    guint value4 = 0;
> +    guint value5 = 0;
> +    gdouble v;
> +    GError *error = NULL;
> +
> +    str = g_match_info_fetch (match_info, 1);
> +    if (!mm_huawei_parse_hcsq_response (str,
> +                                        &act,
> +                                        &value1,
> +                                        &value2,
> +                                        &value3,
> +                                        &value4,
> +                                        &value5,
> +                                        &error)) {
> +        mm_dbg ("Ignored invalid ^HCSQ message: %s (error %s)", str, error->message);
> +        g_error_free (error);
> +        g_free (str);
> +        return;
> +    }
> +
> +    detailed_signal_clear (&self->priv->detailed_signal);
> +
> +    switch (act) {
> +    case MM_MODEM_ACCESS_TECHNOLOGY_GSM:
> +        self->priv->detailed_signal.gsm = mm_signal_new ();
> +        /* value1: gsm_rssi */
> +        if (get_rssi_dbm (value1, &v))
> +            mm_signal_set_rssi (self->priv->detailed_signal.gsm, v);
> +        break;
> +    case MM_MODEM_ACCESS_TECHNOLOGY_UMTS:
> +        self->priv->detailed_signal.umts = mm_signal_new ();
> +        /* value1: wcdma_rssi */
> +        if (get_rssi_dbm (value1, &v))
> +            mm_signal_set_rssi (self->priv->detailed_signal.umts, v);
> +        /* value2: wcdma_rscp; unused */
> +        /* value3: wcdma_ecio */
> +        if (get_ecio_db (value3, &v))
> +            mm_signal_set_ecio (self->priv->detailed_signal.umts, v);
> +        break;
> +    case MM_MODEM_ACCESS_TECHNOLOGY_LTE:
> +        self->priv->detailed_signal.lte = mm_signal_new ();
> +        /* value1: lte_rssi */
> +        if (get_rssi_dbm (value1, &v))
> +            mm_signal_set_rssi (self->priv->detailed_signal.lte, v);
> +        /* value2: lte_rsrp */
> +        if (get_rsrp_dbm (value2, &v))
> +            mm_signal_set_rsrp (self->priv->detailed_signal.lte, v);
> +        /* value3: lte_sinr -> SNR? */
> +        if (get_sinr_db (value3, &v))
> +            mm_signal_set_snr (self->priv->detailed_signal.lte, v);
> +        /* value4: lte_rsrq */
> +        if (get_rsrq_db (value4, &v))
> +            mm_signal_set_rsrq (self->priv->detailed_signal.lte, v);
> +        break;
> +    default:
> +        /* CDMA and EVDO not yet supported */
> +        break;
> +    }
> +}
> +
> +static void
>  set_3gpp_unsolicited_events_handlers (MMBroadbandModemHuawei *self,
>                                        gboolean enable)
>  {
> @@ -1781,6 +1924,13 @@ set_3gpp_unsolicited_events_handlers (MMBroadbandModemHuawei *self,
>              enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_ndisstat_changed : NULL,
>              enable ? self : NULL,
>              NULL);
> +
> +        mm_port_serial_at_add_unsolicited_msg_handler (
> +            port,
> +            self->priv->hcsq_regex,
> +            enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_hcsq_changed : NULL,
> +            enable ? self : NULL,
> +            NULL);
>      }
>
>      g_list_free_full (ports, (GDestroyNotify)g_object_unref);
> @@ -3967,6 +4117,146 @@ modem_time_check_support (MMIfaceModemTime *self,
>  }
>
>  /*****************************************************************************/
> +/* Check support (Signal interface) */
> +
> +static void
> +hcsq_check_ready (MMBaseModem *_self,
> +                  GAsyncResult *res,
> +                  GTask *task)
> +{
> +    GError *error = NULL;
> +    const gchar *response;
> +
> +    response = mm_base_modem_at_command_finish (_self, res, &error);
> +    if (response)
> +        g_task_return_boolean (task, TRUE);
> +    else
> +        g_task_return_error (task, error);
> +
> +    g_object_unref (task);
> +}
> +
> +static gboolean
> +signal_check_support_finish (MMIfaceModemSignal *self,
> +                             GAsyncResult *res,
> +                             GError **error)
> +{
> +    return g_task_propagate_boolean (G_TASK (res), error);
> +}
> +
> +static void
> +signal_check_support (MMIfaceModemSignal *_self,
> +                      GAsyncReadyCallback callback,
> +                      gpointer user_data)
> +{
> +    MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
> +    GTask *task;
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +    mm_base_modem_at_command (MM_BASE_MODEM (self),
> +                              "^HCSQ?",
> +                              3,
> +                              FALSE,
> +                              (GAsyncReadyCallback)hcsq_check_ready,
> +                              task);
> +}
> +
> +/*****************************************************************************/
> +/* Load extended signal information */
> +
> +static void
> +detailed_signal_free (DetailedSignal *signal)
> +{
> +    g_clear_object (&signal->cdma);
> +    g_clear_object (&signal->evdo);
> +    g_clear_object (&signal->gsm);
> +    g_clear_object (&signal->umts);
> +    g_clear_object (&signal->lte);
> +    g_slice_free (DetailedSignal, signal);
> +}
> +
> +static gboolean
> +signal_load_values_finish (MMIfaceModemSignal *self,
> +                           GAsyncResult *res,
> +                           MMSignal **cdma,
> +                           MMSignal **evdo,
> +                           MMSignal **gsm,
> +                           MMSignal **umts,
> +                           MMSignal **lte,
> +                           GError **error)
> +{
> +    DetailedSignal *signals;
> +
> +    signals = g_task_propagate_pointer (G_TASK (res), error);
> +    if (!signals)
> +        return FALSE;
> +
> +    *cdma = signals->cdma ? g_object_ref (signals->cdma) : NULL;
> +    *evdo = signals->evdo ? g_object_ref (signals->evdo) : NULL;
> +    *gsm  = signals->gsm ? g_object_ref (signals->gsm) : NULL;
> +    *umts = signals->umts ? g_object_ref (signals->umts) : NULL;
> +    *lte  = signals->lte ? g_object_ref (signals->lte) : NULL;
> +
> +    detailed_signal_free (signals);
> +    return TRUE;
> +}
> +
> +static void
> +hcsq_get_ready (MMBaseModem *_self,
> +                GAsyncResult *res,
> +                GTask *task)
> +{
> +    MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
> +    DetailedSignal *signals;
> +    GError *error = NULL;
> +
> +    /* Don't care about the response; it will have been parsed by the HCSQ
> +     * unsolicited event handler and self->priv->detailed_signal will already
> +     * be updated.
> +     */
> +    if (!mm_base_modem_at_command_finish (_self, res, &error)) {
> +        mm_dbg ("^HCSQ failed: %s", error->message);
> +        g_task_return_error (task, error);
> +        g_object_unref (task);
> +        return;
> +    }
> +
> +    signals = g_slice_new0 (DetailedSignal);
> +    signals->cdma = self->priv->detailed_signal.cdma ? g_object_ref (self->priv->detailed_signal.cdma) : NULL;
> +    signals->evdo = self->priv->detailed_signal.evdo ? g_object_ref (self->priv->detailed_signal.evdo) : NULL;
> +    signals->gsm = self->priv->detailed_signal.gsm ? g_object_ref (self->priv->detailed_signal.gsm) : NULL;
> +    signals->umts = self->priv->detailed_signal.umts ? g_object_ref (self->priv->detailed_signal.umts) : NULL;
> +    signals->lte = self->priv->detailed_signal.lte ? g_object_ref (self->priv->detailed_signal.lte) : NULL;
> +
> +    g_task_return_pointer (task, signals, (GDestroyNotify)detailed_signal_free);
> +    g_object_unref (task);
> +}
> +
> +static void
> +signal_load_values (MMIfaceModemSignal *_self,
> +                    GCancellable *cancellable,
> +                    GAsyncReadyCallback callback,
> +                    gpointer user_data)
> +{
> +    MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
> +    GTask *task;
> +
> +    mm_dbg ("loading extended signal information...");
> +
> +    task = g_task_new (self, cancellable, callback, user_data);
> +
> +    /* Clear any previous detailed signal values to get new ones */
> +    detailed_signal_clear (&self->priv->detailed_signal);
> +
> +    mm_base_modem_at_command (MM_BASE_MODEM (self),
> +                              "^HCSQ?",
> +                              3,
> +                              FALSE,
> +                              (GAsyncReadyCallback)hcsq_get_ready,
> +                              task);
> +}
> +
> +/*****************************************************************************/
>  /* Setup ports (Broadband modem class) */
>
>  static void
> @@ -4018,10 +4308,6 @@ set_ignored_unsolicited_events_handlers (MMBroadbandModemHuawei *self)
>              NULL, NULL, NULL);
>          mm_port_serial_at_add_unsolicited_msg_handler (
>              port,
> -            self->priv->hcsq_regex,
> -            NULL, NULL, NULL);
> -        mm_port_serial_at_add_unsolicited_msg_handler (
> -            port,
>              self->priv->pdpdeact_regex,
>              NULL, NULL, NULL);
>          mm_port_serial_at_add_unsolicited_msg_handler (
> @@ -4152,7 +4438,7 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)
>                                             G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
>      self->priv->stin_regex = g_regex_new ("\\r\\n\\^STIN:.+\\r\\n",
>                                            G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
> -    self->priv->hcsq_regex = g_regex_new ("\\r\\n\\^HCSQ:.+\\r+\\n",
> +    self->priv->hcsq_regex = g_regex_new ("\\r\\n(\\^HCSQ:.+)\\r+\\n",
>                                            G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
>      self->priv->pdpdeact_regex = g_regex_new ("\\r\\n\\^PDPDEACT:.+\\r+\\n",
>                                                G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
> @@ -4210,6 +4496,16 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)
>  }
>
>  static void
> +dispose (GObject *object)
> +{
> +    MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (object);
> +
> +    detailed_signal_clear (&self->priv->detailed_signal);
> +
> +    G_OBJECT_CLASS (mm_broadband_modem_huawei_parent_class)->dispose (object);
> +}
> +
> +static void
>  finalize (GObject *object)
>  {
>      MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (object);
> @@ -4372,6 +4668,15 @@ iface_modem_voice_init (MMIfaceModemVoice *iface)
>  }
>
>  static void
> +iface_modem_signal_init (MMIfaceModemSignal *iface)
> +{
> +    iface->check_support = signal_check_support;
> +    iface->check_support_finish = signal_check_support_finish;
> +    iface->load_values = signal_load_values;
> +    iface->load_values_finish = signal_load_values_finish;
> +}
> +
> +static void
>  mm_broadband_modem_huawei_class_init (MMBroadbandModemHuaweiClass *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS (klass);
> @@ -4379,6 +4684,7 @@ mm_broadband_modem_huawei_class_init (MMBroadbandModemHuaweiClass *klass)
>
>      g_type_class_add_private (object_class, sizeof (MMBroadbandModemHuaweiPrivate));
>
> +    object_class->dispose = dispose;
>      object_class->finalize = finalize;
>
>      broadband_modem_class->setup_ports = setup_ports;
> diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c
> index 0e0e046..d3f13c2 100644
> --- a/plugins/huawei/mm-modem-helpers-huawei.c
> +++ b/plugins/huawei/mm-modem-helpers-huawei.c
> @@ -1329,3 +1329,74 @@ gboolean mm_huawei_parse_time_response (const gchar *response,
>
>      return ret;
>  }
> +
> +/*****************************************************************************/
> +/* ^HCSQ response parser */
> +
> +gboolean
> +mm_huawei_parse_hcsq_response (const gchar *response,
> +                               MMModemAccessTechnology *out_act,
> +                               guint *out_value1,
> +                               guint *out_value2,
> +                               guint *out_value3,
> +                               guint *out_value4,
> +                               guint *out_value5,
> +                               GError **error)
> +{
> +    GRegex *r;
> +    GMatchInfo *match_info = NULL;
> +    GError *match_error = NULL;
> +    gboolean ret = FALSE;
> +    char *s;
> +
> +    r = g_regex_new ("\\^HCSQ:\\s*\"([a-zA-Z]*)\",(\\d+),?(\\d+)?,?(\\d+)?,?(\\d+)?,?(\\d+)?$", 0, 0, NULL);
> +    g_assert (r != NULL);
> +
> +    if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) {
> +        if (match_error) {
> +            g_propagate_error (error, match_error);
> +            g_prefix_error (error, "Could not parse ^HCSQ results: ");
> +        } else {
> +            g_set_error_literal (error,
> +                                 MM_CORE_ERROR,
> +                                 MM_CORE_ERROR_FAILED,
> +                                 "Couldn't match ^HCSQ reply");
> +        }
> +        goto done;
> +    }
> +
> +    /* Remember that g_match_info_get_match_count() includes match #0 */
> +    if (g_match_info_get_match_count (match_info) < 3) {
> +        g_set_error_literal (error,
> +                             MM_CORE_ERROR,
> +                             MM_CORE_ERROR_FAILED,
> +                             "Not enough elements in ^HCSQ reply");
> +        goto done;
> +    }
> +
> +    if (out_act) {
> +        s = g_match_info_fetch (match_info, 1);
> +        *out_act = mm_string_to_access_tech (s);
> +        g_free (s);
> +    }
> +
> +    if (out_value1)
> +        mm_get_uint_from_match_info (match_info, 2, out_value1);
> +    if (out_value2)
> +        mm_get_uint_from_match_info (match_info, 3, out_value2);
> +    if (out_value3)
> +        mm_get_uint_from_match_info (match_info, 4, out_value3);
> +    if (out_value4)
> +        mm_get_uint_from_match_info (match_info, 5, out_value4);
> +    if (out_value5)
> +        mm_get_uint_from_match_info (match_info, 6, out_value5);
> +
> +    ret = TRUE;
> +
> +done:
> +    if (match_info)
> +        g_match_info_free (match_info);
> +    g_regex_unref (r);
> +
> +    return ret;
> +}
> diff --git a/plugins/huawei/mm-modem-helpers-huawei.h b/plugins/huawei/mm-modem-helpers-huawei.h
> index 62019e8..b4c7ac7 100644
> --- a/plugins/huawei/mm-modem-helpers-huawei.h
> +++ b/plugins/huawei/mm-modem-helpers-huawei.h
> @@ -139,4 +139,16 @@ gboolean mm_huawei_parse_time_response (const gchar *response,
>                                          MMNetworkTimezone **tzp,
>                                          GError **error);
>
> +/*****************************************************************************/
> +/* ^HCSQ response parser */
> +
> +gboolean mm_huawei_parse_hcsq_response (const gchar *response,
> +                                        MMModemAccessTechnology *out_act,
> +                                        guint *out_value1,
> +                                        guint *out_value2,
> +                                        guint *out_value3,
> +                                        guint *out_value4,
> +                                        guint *out_value5,
> +                                        GError **error);
> +
>  #endif  /* MM_MODEM_HELPERS_HUAWEI_H */
> diff --git a/plugins/huawei/tests/test-modem-helpers-huawei.c b/plugins/huawei/tests/test-modem-helpers-huawei.c
> index bd0a8a6..13601c4 100644
> --- a/plugins/huawei/tests/test-modem-helpers-huawei.c
> +++ b/plugins/huawei/tests/test-modem-helpers-huawei.c
> @@ -1192,6 +1192,66 @@ test_time (void)
>  }
>
>  /*****************************************************************************/
> +/* Test ^HCSQ responses */
> +
> +typedef struct {
> +    const gchar *str;
> +    gboolean ret;
> +    MMModemAccessTechnology act;
> +    guint value1;
> +    guint value2;
> +    guint value3;
> +    guint value4;
> +    guint value5;
> +} HcsqTest;
> +
> +static const HcsqTest hcsq_tests[] = {
> +    { "^HCSQ:\"LTE\",30,19,66,0\r\n",  TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_LTE,     30, 19,  66, 0, 0 },
> +    { "^HCSQ: \"WCDMA\",30,30,58\r\n", TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_UMTS,    30, 30,  58, 0, 0 },
> +    { "^HCSQ: \"GSM\",36,255\r\n",     TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_GSM,     36, 255,  0, 0, 0 },
> +    { "^HCSQ: \"NOSERVICE\"\r\n",      FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,  0, 0, 0 },
> +    { NULL,                            FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,  0, 0, 0 }
> +};
> +
> +static void
> +test_hcsq (void)
> +{
> +    guint i;
> +
> +    for (i = 0; hcsq_tests[i].str; i++) {
> +        GError *error = NULL;
> +        MMModemAccessTechnology act;
> +        guint value1 = 0;
> +        guint value2 = 0;
> +        guint value3 = 0;
> +        guint value4 = 0;
> +        guint value5 = 0;
> +        gboolean ret;
> +
> +        ret = mm_huawei_parse_hcsq_response (hcsq_tests[i].str,
> +                                             &act,
> +                                             &value1,
> +                                             &value2,
> +                                             &value3,
> +                                             &value4,
> +                                             &value5,
> +                                             &error);
> +        g_assert (ret == hcsq_tests[i].ret);
> +        if (ret) {
> +            g_assert_no_error (error);
> +            g_assert_cmpint (hcsq_tests[i].act, ==, act);
> +            g_assert_cmpint (hcsq_tests[i].value1, ==, value1);
> +            g_assert_cmpint (hcsq_tests[i].value2, ==, value2);
> +            g_assert_cmpint (hcsq_tests[i].value3, ==, value3);
> +            g_assert_cmpint (hcsq_tests[i].value4, ==, value4);
> +            g_assert_cmpint (hcsq_tests[i].value5, ==, value5);
> +        } else
> +            g_assert (error);
> +        g_clear_error (&error);
> +    }
> +}
> +
> +/*****************************************************************************/
>
>  void
>  _mm_log (const char *loc,
> @@ -1232,6 +1292,7 @@ int main (int argc, char **argv)
>      g_test_add_func ("/MM/huawei/syscfgex/response", test_syscfgex_response);
>      g_test_add_func ("/MM/huawei/nwtime", test_nwtime);
>      g_test_add_func ("/MM/huawei/time", test_time);
> +    g_test_add_func ("/MM/huawei/hcsq", test_hcsq);
>
>      return g_test_run ();
>  }
> diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
> index 9f71b24..01d0c79 100644
> --- a/src/mm-modem-helpers.c
> +++ b/src/mm-modem-helpers.c
> @@ -2089,6 +2089,7 @@ MMModemAccessTechnology
>  mm_string_to_access_tech (const gchar *string)
>  {
>      MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> +    gsize len;
>
>      g_return_val_if_fail (string != NULL, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
>
> @@ -2102,14 +2103,15 @@ mm_string_to_access_tech (const gchar *string)
>      else if (strcasestr (string, "HSPA"))
>          act |= MM_MODEM_ACCESS_TECHNOLOGY_HSPA;
>
> -
>      if (strcasestr (string, "HSUPA"))
>          act |= MM_MODEM_ACCESS_TECHNOLOGY_HSUPA;
>
>      if (strcasestr (string, "HSDPA"))
>          act |= MM_MODEM_ACCESS_TECHNOLOGY_HSDPA;
>
> -    if (strcasestr (string, "UMTS") || strcasestr (string, "3G"))
> +    if (strcasestr (string, "UMTS") ||
> +        strcasestr (string, "3G") ||
> +        strcasestr (string, "WCDMA"))
>          act |= MM_MODEM_ACCESS_TECHNOLOGY_UMTS;
>
>      if (strcasestr (string, "EDGE"))
> @@ -2133,6 +2135,17 @@ mm_string_to_access_tech (const gchar *string)
>      if (strcasestr (string, "1xRTT") || strcasestr (string, "CDMA2000 1X"))
>          act |= MM_MODEM_ACCESS_TECHNOLOGY_1XRTT;
>
> +    /* Check "EVDO" and "CDMA" as standalone strings since their characters
> +     * are included in other strings too.
> +     */
> +    len = strlen (string);
> +    if (strncmp (string, "EVDO", 4) && (len >= 4 && !isalnum (string[4])))
> +        act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
> +    if (strncmp (string, "CDMA", 4) && (len >= 4 && !isalnum (string[4])))
> +        act |= MM_MODEM_ACCESS_TECHNOLOGY_1XRTT;
> +    if (strncmp (string, "CDMA-EVDO", 9) && (len >= 9 && !isalnum (string[9])))
> +        act |= MM_MODEM_ACCESS_TECHNOLOGY_1XRTT | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
> +
>      return act;
>  }
>
> --
> 2.5.5



-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list