[PATCH] qmicli: support auto/manual network with --nas-set-system-selection-preference

Dan Williams dcbw at redhat.com
Mon Jun 4 15:58:04 UTC 2018


On Sat, 2018-06-02 at 18:19 +0200, Aleksander Morgado wrote:
> On Thu, May 31, 2018 at 4:12 PM, Dan Williams <dcbw at redhat.com>
> wrote:
> > Support manual network selection by MCC/MNC via the
> > 
> 
> Via the.... ? :)
> 
> See other comments below.
> 
> Also, could we make all comments /* like this */ ? (instead of //
> like this)

That's what I get for sending a "please try this out" patch without 2
more looks :)  Will rework.

Dan

> > ---
> > 
> > diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-
> > helpers.c
> > index 00f7122..ad68573 100644
> > --- a/src/qmicli/qmicli-helpers.c
> > +++ b/src/qmicli/qmicli-helpers.c
> > @@ -263,6 +263,77 @@ qmicli_read_rat_mode_pref_from_string (const
> > gchar *str,
> >      return success && set;
> >  }
> > 
> > +static gboolean
> > +parse_3gpp_mcc_mnc (const gchar *str,
> > +                    guint16 *out_mcc,
> > +                    guint16 *out_mnc)
> > +{
> > +    guint len;
> > +    guint i;
> > +    gchar aux[4];
> > +    guint16 tmp;
> > +
> > +    len = strlen (str);
> > +    if (len != 5 && len != 6)
> > +        return FALSE;
> > +    for (i = 0; i < len; i++) {
> > +        if (!g_ascii_isdigit (str[i]))
> > +            return FALSE;
> > +    }
> > +
> > +    memcpy (&aux[0], str, 3);
> > +    aux[3] = '\0';
> > +    tmp = atoi (aux);
> > +    if (tmp == 0)
> > +        return FALSE;
> > +    *out_mcc = tmp;
> > +
> > +    if (len == 5) {
> > +        memcpy (&aux[0], &str[3], 2);
> > +        aux[2] = '\0';
> > +    } else
> > +        memcpy (&aux[0], &str[3], 3);
> > +    *out_mnc = atoi (aux);
> > +
> > +    return TRUE;
> > +}
> > +
> > +gboolean
> > +qmicli_read_net_selection_pref_from_string (const gchar *str,
> > +                                            QmiNasNetworkSelection
> > Preference *out,
> > +                                            guint16 *out_mcc,
> > +                                            guint16 *out_mnc)
> > +{
> > +    GType type;
> > +    GEnumClass *enum_class;
> > +    GEnumValue *enum_value;
> > +    gchar *equals = NULL;
> > +    guint16 mcc = 0, mnc = 0;
> > +
> > +    equals = strchr (str, '=');
> > +    if (equals) {
> > +        /* Parse MCC/MNC */
> > +        *equals++ = '\0';
> 
> This assignment above is abusing the assumption that the received
> "str" is modifiable, but we're receiving a "const gchar *" and so we
> shouldn't modify it. Wouldn't "equals++;" be enough?
> 
> 
> > +        if (!parse_3gpp_mcc_mnc (equals, &mcc, &mnc)) {
> > +            g_printerr ("error: invalid net selection MCC/MNC:
> > '%s'\n", equals);
> > +            return FALSE;
> > +        }
> > +    }
> > +
> > +    type = qmi_nas_network_selection_preference_get_type ();
> > +    enum_class = G_ENUM_CLASS (g_type_class_ref (type));
> > +    enum_value = g_enum_get_value_by_nick (enum_class, str);
> > +    if (enum_value) {
> > +        *out = (QmiNasNetworkSelectionPreference)enum_value-
> > >value;
> > +        *out_mcc = mcc;
> > +        *out_mnc = mnc;
> > +    } else
> > +        g_printerr ("error: invalid net selection preference value
> > given: '%s'\n", str);
> > +
> > +    g_type_class_unref (enum_class);
> > +    return !!enum_value;
> > +}
> > +
> >  gboolean
> >  qmicli_read_facility_from_string (const gchar *str,
> >                                    QmiDmsUimFacility *out)
> > diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-
> > helpers.h
> > index e8fac1d..6fd45d7 100644
> > --- a/src/qmicli/qmicli-helpers.h
> > +++ b/src/qmicli/qmicli-helpers.h
> > @@ -40,6 +40,10 @@ gboolean
> > qmicli_read_operating_mode_from_string              (const gchar
> > *str,
> >                                                                QmiD
> > msOperatingMode *out);
> >  gboolean
> > qmicli_read_rat_mode_pref_from_string               (const gchar
> > *str,
> >                                                                QmiN
> > asRatModePreference *out);
> > +gboolean
> > qmicli_read_net_selection_pref_from_string          (const gchar
> > *str,
> > +                                                              QmiN
> > asNetworkSelectionPreference *out,
> > +                                                              guin
> > t16 *out_mcc,
> > +                                                              guin
> > t16 *out_mnc);
> >  gboolean
> > qmicli_read_facility_from_string                    (const gchar
> > *str,
> >                                                                QmiD
> > msUimFacility *out);
> >  gboolean
> > qmicli_read_enable_disable_from_string              (const gchar
> > *str,
> > diff --git a/src/qmicli/qmicli-nas.c b/src/qmicli/qmicli-nas.c
> > index 2ea5a6b..d6cbe67 100644
> > --- a/src/qmicli/qmicli-nas.c
> > +++ b/src/qmicli/qmicli-nas.c
> > @@ -97,7 +97,7 @@ static GOptionEntry entries[] = {
> >      },
> >      { "nas-set-system-selection-preference", 0, 0,
> > G_OPTION_ARG_STRING, &set_system_selection_preference_str,
> >        "Set system selection preference",
> > -      "[cdma-1x|cdma-1xevdo|gsm|umts|lte|td-scdma]"
> > +      "[cdma-1x|cdma-1xevdo|gsm|umts|lte|td-
> > scdma][,[auto|manual=MCCMNC]]"
> >      },
> >      { "nas-network-scan", 0, 0, G_OPTION_ARG_NONE,
> > &network_scan_flag,
> >        "Scan networks",
> > @@ -2137,24 +2137,81 @@ static
> > QmiMessageNasSetSystemSelectionPreferenceInput *
> >  set_system_selection_preference_input_create (const gchar *str)
> >  {
> >      QmiMessageNasSetSystemSelectionPreferenceInput *input = NULL;
> > -    QmiNasRatModePreference pref;
> > +    QmiNasRatModePreference pref = 0;
> > +    QmiNasNetworkSelectionPreference net_pref = 0;
> > +    gchar *rat_pref_str = NULL;
> > +    gchar *net_pref_str = NULL;
> >      GError *error = NULL;
> > +    guint16 mcc = 0, mnc = 0;
> > 
> > -    if (!qmicli_read_rat_mode_pref_from_string (str, &pref)) {
> > -        g_printerr ("error: failed to parse mode pref\n");
> > -        return NULL;
> > +    if (strchr (str, ',')) {
> > +        gchar **parts;
> > +
> > +        // Both RAT mode preference and network selection
> > preference were given
> > +        parts = g_strsplit_set (str, ",", -1);
> > +        if (g_strv_length (parts) != 2) {
> > +            g_printerr ("error: failed to parse selection pref:
> > '%s'\n", str);
> > +            g_strfreev (parts);
> > +            return NULL;
> > +        }
> > +        rat_pref_str = g_strdup (parts[0]);
> > +        net_pref_str = g_strdup (parts[1]);
> > +        g_strfreev (parts);
> > +    } else if (g_str_has_prefix (str, "auto") || g_str_has_prefix
> > (str, "manual")) {
> > +        // Only network selection preference was given
> > +        net_pref_str = g_strdup (str);
> > +    } else {
> > +        // Only RAT mode preference was given
> > +        rat_pref_str = g_strdup (str);
> > +    }
> > +
> > +    if (net_pref_str &&
> > !qmicli_read_net_selection_pref_from_string (net_pref_str,
> > &net_pref, &mcc, &mnc)) {
> > +        g_printerr ("error: failed to parse net pref: '%s'\n",
> > net_pref_str);
> > +        goto error;
> > +    }
> > +
> > +    if (rat_pref_str && !qmicli_read_rat_mode_pref_from_string
> > (rat_pref_str, &pref)) {
> > +        g_printerr ("error: failed to parse mode pref: '%s'\n",
> > rat_pref_str);
> > +        goto error;
> >      }
> > 
> >      input =
> > qmi_message_nas_set_system_selection_preference_input_new ();
> > -    if
> > (!qmi_message_nas_set_system_selection_preference_input_set_mode_pr
> > eference (
> > -            input,
> > -            pref,
> > -            &error)) {
> > -        g_printerr ("error: couldn't create input data bundle:
> > '%s'\n",
> > -                    error->message);
> > -        g_error_free (error);
> > -        qmi_message_nas_set_system_selection_preference_input_unre
> > f (input);
> > -        return NULL;
> > +
> > +    if (rat_pref_str) {
> > +        if
> > (!qmi_message_nas_set_system_selection_preference_input_set_mode_pr
> > eference (
> > +                input,
> > +                pref,
> > +                &error)) {
> > +            g_printerr ("error: couldn't create input data bundle:
> > '%s'\n",
> > +                        error->message);
> > +            goto error;
> > +        }
> > +
> > +        if (pref & (QMI_NAS_RAT_MODE_PREFERENCE_GSM |
> > +                    QMI_NAS_RAT_MODE_PREFERENCE_UMTS |
> > +                    QMI_NAS_RAT_MODE_PREFERENCE_LTE)) {
> > +            if
> > (!qmi_message_nas_set_system_selection_preference_input_set_gsm_wcd
> > ma_acquisition_order_preference (
> > +                    input,
> > +                    QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE
> > _AUTOMATIC,
> > +                    &error)) {
> > +                g_printerr ("error: couldn't create input data
> > bundle: '%s'\n",
> > +                            error->message);
> > +                goto error;
> > +            }
> > +        }
> > +    }
> > +
> > +    if (net_pref_str) {
> > +        if
> > (!qmi_message_nas_set_system_selection_preference_input_set_network
> > _selection_preference (
> > +                input,
> > +                net_pref,
> > +                mcc,
> > +                mnc,
> > +                &error)) {
> > +            g_printerr ("error: couldn't create input data bundle:
> > '%s'\n",
> > +                        error->message);
> > +            goto error;
> > +        }
> >      }
> > 
> >      if
> > (!qmi_message_nas_set_system_selection_preference_input_set_change_
> > duration (
> > @@ -2163,27 +2220,20 @@
> > set_system_selection_preference_input_create (const gchar *str)
> >              &error)) {
> >          g_printerr ("error: couldn't create input data bundle:
> > '%s'\n",
> >                      error->message);
> > -        g_error_free (error);
> > -        qmi_message_nas_set_system_selection_preference_input_unre
> > f (input);
> > -        return NULL;
> > -    }
> > -
> > -    if (pref & (QMI_NAS_RAT_MODE_PREFERENCE_GSM |
> > -                QMI_NAS_RAT_MODE_PREFERENCE_UMTS |
> > -                QMI_NAS_RAT_MODE_PREFERENCE_LTE)) {
> > -        if
> > (!qmi_message_nas_set_system_selection_preference_input_set_gsm_wcd
> > ma_acquisition_order_preference (
> > -                input,
> > -                QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUT
> > OMATIC,
> > -                &error)) {
> > -            g_printerr ("error: couldn't create input data bundle:
> > '%s'\n",
> > -                        error->message);
> > -            g_error_free (error);
> > -            qmi_message_nas_set_system_selection_preference_input_
> > unref (input);
> > -            return NULL;
> > -        }
> > +        goto error;
> >      }
> > 
> > +    g_free (rat_pref_str);
> > +    g_free (net_pref_str);
> >      return input;
> > +
> > +error:
> > +    g_clear_error (&error);
> > +    if (input)
> > +        qmi_message_nas_set_system_selection_preference_input_unre
> > f (input);
> > +    g_free (rat_pref_str);
> > +    g_free (net_pref_str);
> > +    return NULL;
> >  }
> > 
> >  static void
> > _______________________________________________
> > libqmi-devel mailing list
> > libqmi-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/libqmi-devel
> 
> 
> 


More information about the libqmi-devel mailing list