diff options
author | Teijo Kinnunen <teijo.kinnunen@uros.com> | 2021-03-03 16:27:32 +0200 |
---|---|---|
committer | Teijo Kinnunen <teijo.kinnunen@uros.com> | 2021-03-09 08:52:55 +0200 |
commit | 0919abaa2ffa6d3ca42fcd73d7ed2040fabd61be (patch) | |
tree | ecb1b44700f36295b7172aa9045e5e2b50bb507f | |
parent | 66e93751b802beb5072e72bc911df3edf64b9a37 (diff) |
mmcli,sim: implement --sim-set-preferred-networks function
-rw-r--r-- | cli/mmcli-sim.c | 110 | ||||
-rw-r--r-- | libmm-glib/mm-common-helpers.c | 70 | ||||
-rw-r--r-- | libmm-glib/mm-common-helpers.h | 5 |
3 files changed, 183 insertions, 2 deletions
diff --git a/cli/mmcli-sim.c b/cli/mmcli-sim.c index 68ae7f5d..3056783b 100644 --- a/cli/mmcli-sim.c +++ b/cli/mmcli-sim.c @@ -51,6 +51,7 @@ static gchar *puk_str; static gboolean enable_pin_flag; static gboolean disable_pin_flag; static gchar *change_pin_str; +static gchar *set_preferred_networks_str; static GOptionEntry entries[] = { { "pin", 0, 0, G_OPTION_ARG_STRING, &pin_str, @@ -73,6 +74,10 @@ static GOptionEntry entries[] = { "Change the PIN in a given SIM (must send the current PIN with --pin).", "[New PIN]" }, + { "sim-set-preferred-networks", 0, 0, G_OPTION_ARG_STRING, &set_preferred_networks_str, + "Set preferred network list stored in a given SIM.", + "[[MCCMNC[,access_tech]],...]" + }, { NULL } }; @@ -104,10 +109,11 @@ mmcli_sim_options_enabled (void) n_actions = (!!puk_str + enable_pin_flag + disable_pin_flag + - !!change_pin_str); + !!change_pin_str + + !!set_preferred_networks_str); if (n_actions == 1) { - if (!pin_str) { + if (!pin_str && !set_preferred_networks_str) { g_printerr ("error: action requires also the PIN code\n"); exit (EXIT_FAILURE); } @@ -310,6 +316,77 @@ change_pin_ready (MMSim *sim, } static void +parse_preferred_networks (GList **preferred_networks) +{ + gchar **parts; + GList *preferred_nets_list = NULL; + GError *error = NULL; + + parts = g_strsplit (set_preferred_networks_str, ",", -1); + if (parts) { + guint i; + + for (i = 0; parts[i]; i++) { + MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; + MMSimPreferredNetwork *preferred_net; + const gchar *mccmnc; + + mccmnc = parts[i]; + if (!mm_is_string_mccmnc (mccmnc)) { + g_printerr ("error: couldn't parse MCCMNC for preferred network: '%s'\n", + mccmnc); + exit (EXIT_FAILURE); + } + /* if the next item is MCCMNC or is missing, omit the access technology */ + if (parts[i + 1] && !mm_is_string_mccmnc (parts[i + 1])) { + i++; + access_tech = mm_common_get_access_technology_from_string (parts[i], &error); + if (error) { + g_printerr ("error: %s\n", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + } + + preferred_net = mm_sim_preferred_network_new (); + mm_sim_preferred_network_set_operator_code (preferred_net, mccmnc); + mm_sim_preferred_network_set_access_technology (preferred_net, access_tech); + preferred_nets_list = g_list_append (preferred_nets_list, preferred_net); + } + } + g_strfreev (parts); + + *preferred_networks = preferred_nets_list; +} + +static void +set_preferred_networks_process_reply (gboolean result, + const GError *error) +{ + if (!result) { + g_printerr ("error: couldn't set preferred networks: '%s'\n", + error ? error->message : "unknown error"); + exit (EXIT_FAILURE); + } + + g_print ("successfully set preferred networks\n"); +} + +static void +set_preferred_networks_ready (MMSim *sim, + GAsyncResult *result, + gpointer nothing) +{ + gboolean operation_result; + GError *error = NULL; + + operation_result = mm_sim_set_preferred_networks_finish (sim, result, &error); + set_preferred_networks_process_reply (operation_result, error); + + mmcli_async_operation_done (); +} + +static void get_sim_ready (GObject *source, GAsyncResult *result, gpointer none) @@ -366,6 +443,20 @@ get_sim_ready (GObject *source, return; } + /* Requesting to set preferred networks? */ + if (set_preferred_networks_str) { + GList *preferred_networks = NULL; + + parse_preferred_networks (&preferred_networks); + mm_sim_set_preferred_networks (ctx->sim, + preferred_networks, + ctx->cancellable, + (GAsyncReadyCallback)set_preferred_networks_ready, + NULL); + g_list_free_full (preferred_networks, (GDestroyNotify) mm_sim_preferred_network_free); + return; + } + /* Requesting to send PIN? (always LAST check!) */ if (pin_str) { mm_sim_send_pin (ctx->sim, @@ -468,6 +559,21 @@ mmcli_sim_run_synchronous (GDBusConnection *connection) return; } + /* Requesting to set preferred networks? */ + if (set_preferred_networks_str) { + gboolean operation_result; + GList *preferred_networks = NULL; + + parse_preferred_networks (&preferred_networks); + operation_result = mm_sim_set_preferred_networks_sync (ctx->sim, + preferred_networks, + NULL, + &error); + g_list_free_full (preferred_networks, (GDestroyNotify) mm_sim_preferred_network_free); + set_preferred_networks_process_reply (operation_result, error); + return; + } + /* Requesting to send PIN? (always LAST check!) */ if (pin_str) { gboolean operation_result; diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c index 43fff922..f2faf71c 100644 --- a/libmm-glib/mm-common-helpers.c +++ b/libmm-glib/mm-common-helpers.c @@ -1313,6 +1313,56 @@ mm_common_parse_key_value_string (const gchar *str, return TRUE; } +MMModemAccessTechnology +mm_common_get_access_technology_from_string (const gchar *str, + GError **error) +{ + GError *inner_error = NULL; + MMModemAccessTechnology technologies; + gchar **technology_strings; + GFlagsClass *flags_class; + + technologies = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; + + flags_class = G_FLAGS_CLASS (g_type_class_ref (MM_TYPE_MODEM_ACCESS_TECHNOLOGY)); + technology_strings = g_strsplit (str, "|", -1); + + if (technology_strings) { + guint i; + + for (i = 0; technology_strings[i]; i++) { + guint j; + gboolean found = FALSE; + + for (j = 0; flags_class->values[j].value_nick; j++) { + if (!g_ascii_strcasecmp (technology_strings[i], flags_class->values[j].value_nick)) { + technologies |= flags_class->values[j].value; + found = TRUE; + break; + } + } + + if (!found) { + inner_error = g_error_new ( + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Couldn't match '%s' with a valid MMModemAccessTechnology value", + technology_strings[i]); + break; + } + } + } + + if (inner_error) { + g_propagate_error (error, inner_error); + technologies = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; + } + + g_type_class_unref (flags_class); + g_strfreev (technology_strings); + return technologies; +} + /*****************************************************************************/ gboolean @@ -1612,6 +1662,26 @@ mm_get_string_unquoted_from_match_info (GMatchInfo *match_info, return str; } +gboolean +mm_is_string_mccmnc (const gchar *str) +{ + gsize len; + guint i; + + if (!str) + return FALSE; + + len = strlen (str); + if (len < 5 || len > 6) + return FALSE; + + for (i = 0; i < len; i++) + if (str[i] < '0' || str[i] > '9') + return FALSE; + + return TRUE; +} + /*****************************************************************************/ const gchar * diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h index 4e6d9784..960a1f52 100644 --- a/libmm-glib/mm-common-helpers.h +++ b/libmm-glib/mm-common-helpers.h @@ -79,6 +79,9 @@ MMOmaSessionType mm_common_get_oma_session_type_from_string (const gchar *s MMModem3gppEpsUeModeOperation mm_common_get_eps_ue_mode_operation_from_string (const gchar *str, GError **error); +MMModemAccessTechnology mm_common_get_access_technology_from_string (const gchar *str, + GError **error); + GArray *mm_common_ports_variant_to_garray (GVariant *variant); MMModemPortInfo *mm_common_ports_variant_to_array (GVariant *variant, guint *n_ports); @@ -178,6 +181,8 @@ gboolean mm_get_double_from_match_info (GMatchInfo *match_info, gchar *mm_get_string_unquoted_from_match_info (GMatchInfo *match_info, guint32 match_index); +gboolean mm_is_string_mccmnc (const gchar *str); + const gchar *mm_sms_delivery_state_get_string_extended (guint delivery_state); gint mm_utils_hex2byte (const gchar *hex); |