[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