diff options
author | Teijo Kinnunen <teijo.kinnunen@uros.com> | 2021-02-26 13:26:53 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-03-01 13:37:03 +0000 |
commit | 7b8427c8fdd4cd879c97aa680fd95908fab3e2c7 (patch) | |
tree | f72baeac423cdd0d7716a98bc4808eb3de7bbbe4 | |
parent | e0900654d60dedab83a9dc1a2f4a74aa73b6e4b2 (diff) |
qmicli,nas: add --nas-get-preferred-networks/--nas-set-preferred-networks
-rw-r--r-- | src/qmicli/qmicli-helpers.h | 5 | ||||
-rw-r--r-- | src/qmicli/qmicli-nas.c | 248 |
2 files changed, 251 insertions, 2 deletions
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h index 077047e..446e4ec 100644 --- a/src/qmicli/qmicli-helpers.h +++ b/src/qmicli/qmicli-helpers.h @@ -58,8 +58,9 @@ QMICLI_ENUM_LIST /* Common helpers to read flags from strings */ #define QMICLI_FLAGS_LIST \ - QMICLI_FLAGS_LIST_ITEM (QmiDeviceOpenFlags, device_open_flags, "device open flags") \ - QMICLI_FLAGS_LIST_ITEM (QmiLocNmeaType, loc_nmea_type, "NMEA type") + QMICLI_FLAGS_LIST_ITEM (QmiDeviceOpenFlags, device_open_flags, "device open flags") \ + QMICLI_FLAGS_LIST_ITEM (QmiLocNmeaType, loc_nmea_type, "NMEA type") \ + QMICLI_FLAGS_LIST_ITEM (QmiNasPlmnAccessTechnologyIdentifier, nas_plmn_access_technology_identifier, "PLMN access technology") #define QMICLI_FLAGS_LIST_ITEM(TYPE,TYPE_UNDERSCORE,DESCR) \ gboolean qmicli_read_## TYPE_UNDERSCORE ##_from_string (const gchar *str, TYPE *out); diff --git a/src/qmicli/qmicli-nas.c b/src/qmicli/qmicli-nas.c index 70371e6..b78a5b4 100644 --- a/src/qmicli/qmicli-nas.c +++ b/src/qmicli/qmicli-nas.c @@ -51,6 +51,8 @@ static gboolean get_home_network_flag; static gboolean get_serving_system_flag; static gboolean get_system_info_flag; static gboolean get_technology_preference_flag; +static gboolean get_preferred_networks_flag; +static gchar *set_preferred_networks_str; static gboolean get_system_selection_preference_flag; static gchar *set_system_selection_preference_str; static gchar *get_plmn_name_str; @@ -109,6 +111,18 @@ static GOptionEntry entries[] = { NULL }, #endif +#if defined HAVE_QMI_MESSAGE_NAS_GET_PREFERRED_NETWORKS + { "nas-get-preferred-networks", 0, 0, G_OPTION_ARG_NONE, &get_preferred_networks_flag, + "Get preferred networks", + NULL + }, +#endif +#if defined HAVE_QMI_MESSAGE_NAS_SET_PREFERRED_NETWORKS + { "nas-set-preferred-networks", 0, 0, G_OPTION_ARG_STRING, &set_preferred_networks_str, + "Set preferred networks list", + "[[MCCMNC,access_tech],...]" + }, +#endif #if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE { "nas-get-system-selection-preference", 0, 0, G_OPTION_ARG_NONE, &get_system_selection_preference_flag, "Get system selection preference", @@ -225,6 +239,8 @@ qmicli_nas_options_enabled (void) get_serving_system_flag + get_system_info_flag + get_technology_preference_flag + + get_preferred_networks_flag + + !!set_preferred_networks_str + get_system_selection_preference_flag + !!set_system_selection_preference_str + !!get_plmn_name_str + @@ -1004,6 +1020,203 @@ get_home_network_ready (QmiClientNas *client, #endif /* HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK */ +#if defined HAVE_QMI_MESSAGE_NAS_GET_PREFERRED_NETWORKS + +static void +get_preferred_networks_ready (QmiClientNas *client, + GAsyncResult *res) +{ + QmiMessageNasGetPreferredNetworksOutput *output; + GError *error = NULL; + GArray *preferred_networks_array; + GArray *pcs_digit_array; + + output = qmi_client_nas_get_preferred_networks_finish (client, res, &error); + if (!output) { + g_printerr ("error: operation failed: %s\n", error->message); + g_error_free (error); + operation_shutdown (FALSE); + return; + } + + if (!qmi_message_nas_get_preferred_networks_output_get_result (output, &error)) { + g_printerr ("error: couldn't get preferred networks: %s\n", error->message); + g_error_free (error); + qmi_message_nas_get_preferred_networks_output_unref (output); + operation_shutdown (FALSE); + return; + } + + g_print ("[%s] Successfully got preferred networks:\n", + qmi_device_get_path_display (ctx->device)); + + if (qmi_message_nas_get_preferred_networks_output_get_preferred_networks (output, &preferred_networks_array, NULL)) { + guint i; + gchar *access_tech_string; + + g_print ("Preferred PLMN list:\n"); + if (preferred_networks_array->len == 0) + g_print ("\t<empty>\n"); + for (i = 0; i < preferred_networks_array->len; i++) { + QmiMessageNasGetPreferredNetworksOutputPreferredNetworksElement *element; + + element = &g_array_index (preferred_networks_array, QmiMessageNasGetPreferredNetworksOutputPreferredNetworksElement, i); + access_tech_string = qmi_nas_plmn_access_technology_identifier_build_string_from_mask (element->radio_access_technology); + g_print ("[%u]:\n" + "\tMCC: '%" G_GUINT16_FORMAT "'\n" + "\tMNC: '%" G_GUINT16_FORMAT "'\n" + "\tAccess Technology: '%s'\n", + i, + element->mcc, + element->mnc, + access_tech_string); + g_free (access_tech_string); + } + } + + if (qmi_message_nas_get_preferred_networks_output_get_mnc_pcs_digit_include_status (output, &pcs_digit_array, NULL)) { + guint i; + + g_print ("PCS digit status:\n"); + if (pcs_digit_array->len == 0) + g_print ("\t<empty>\n"); + for (i = 0; i < pcs_digit_array->len; i++) { + QmiMessageNasGetPreferredNetworksOutputMncPcsDigitIncludeStatusElement *element; + + element = &g_array_index (pcs_digit_array, QmiMessageNasGetPreferredNetworksOutputMncPcsDigitIncludeStatusElement, i); + g_print ("[%u]:\n" + "\tMCC: '%" G_GUINT16_FORMAT "'\n" + "\tMNC: '%" G_GUINT16_FORMAT "'\n" + "\tMCC with PCS digit: '%s'\n", + i, + element->mcc, + element->mnc, + element->includes_pcs_digit ? "yes" : "no"); + } + } + + qmi_message_nas_get_preferred_networks_output_unref (output); + operation_shutdown (TRUE); +} + +#endif /* HAVE_QMI_MESSAGE_NAS_GET_PREFERRED_NETWORKS */ + +#if defined HAVE_QMI_MESSAGE_NAS_SET_PREFERRED_NETWORKS + +static QmiMessageNasSetPreferredNetworksInput * +set_preferred_networks_input_create (const gchar *str) +{ + QmiMessageNasSetPreferredNetworksInput *input = NULL; + GError *error = NULL; + gchar **parts = NULL; + gint i; + gint num_parts; + const gchar *part; + guint16 mcc = 0; + guint16 mnc = 0; + gboolean pcs_digit = FALSE; + QmiNasPlmnAccessTechnologyIdentifier access_tech = QMI_NAS_PLMN_ACCESS_TECHNOLOGY_IDENTIFIER_UNSPECIFIED; + GArray *preferred_nets_array; + GArray *pcs_digit_array; + QmiMessageNasSetPreferredNetworksInputPreferredNetworksElement preferred_nets_element; + QmiMessageNasSetPreferredNetworksInputMncPcsDigitIncludeStatusElement pcs_digit_element; + + preferred_nets_array = g_array_new (FALSE, FALSE, sizeof (QmiMessageNasSetPreferredNetworksInputPreferredNetworksElement)); + pcs_digit_array = g_array_new (FALSE, FALSE, sizeof (QmiMessageNasSetPreferredNetworksInputMncPcsDigitIncludeStatusElement)); + + parts = g_strsplit (str, ",", -1); + num_parts = g_strv_length (parts); + for (i = 0; i < num_parts; i += 2) { + part = parts[i]; + /* Parse MCCMNC, if it's found, also read the access technology in numeric format */ + if (qmicli_read_parse_3gpp_mcc_mnc (part, &mcc, &mnc, &pcs_digit)) { + access_tech = QMI_NAS_PLMN_ACCESS_TECHNOLOGY_IDENTIFIER_UNSPECIFIED; + if (i + 1 < num_parts) { + const gchar *access_tech_str = parts[i + 1]; + + if (!qmicli_read_nas_plmn_access_technology_identifier_from_string (access_tech_str, &access_tech)) + goto out; + + memset (&preferred_nets_element, 0, sizeof (preferred_nets_element)); + preferred_nets_element.mcc = mcc; + preferred_nets_element.mnc = mnc; + preferred_nets_element.radio_access_technology = access_tech; + g_array_append_val (preferred_nets_array, preferred_nets_element); + memset (&pcs_digit_element, 0, sizeof (pcs_digit_element)); + pcs_digit_element.mcc = mcc; + pcs_digit_element.mnc = mnc; + pcs_digit_element.includes_pcs_digit = pcs_digit; + g_array_append_val (pcs_digit_array, pcs_digit_element); + } else { + g_printerr ("error: access technology missing for MCCMNC: '%s'\n", part); + goto out; + } + } else + goto out; + } + + input = qmi_message_nas_set_preferred_networks_input_new (); + + if (!qmi_message_nas_set_preferred_networks_input_set_preferred_networks (input, preferred_nets_array, &error)) + goto out; + + if (!qmi_message_nas_set_preferred_networks_input_set_mnc_pcs_digit_include_status (input, pcs_digit_array, &error)) + goto out; + + /* Always set the clear previous flag, leaving any previously configured networks is not desired */ + if (!qmi_message_nas_set_preferred_networks_input_set_clear_previous_preferred_networks (input, TRUE, &error)) + goto out; + +out: + g_strfreev (parts); + + if (preferred_nets_array) + g_array_unref (preferred_nets_array); + if (pcs_digit_array) + g_array_unref (pcs_digit_array); + + if (error) { + g_printerr ("error: couldn't create preferred networks input data bundle: '%s'\n", error->message); + g_error_free (error); + qmi_message_nas_set_preferred_networks_input_unref (input); + return NULL; + } + + return input; +} + +static void +set_preferred_networks_ready (QmiClientNas *client, + GAsyncResult *res) +{ + QmiMessageNasSetPreferredNetworksOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_nas_set_preferred_networks_finish (client, res, &error); + if (!output) { + g_printerr ("error: operation failed: %s\n", error->message); + g_error_free (error); + operation_shutdown (FALSE); + return; + } + + if (!qmi_message_nas_set_preferred_networks_output_get_result (output, &error)) { + g_printerr ("error: couldn't set preferred networks: %s\n", error->message); + g_error_free (error); + qmi_message_nas_set_preferred_networks_output_unref (output); + operation_shutdown (FALSE); + return; + } + + g_print ("[%s] Preferred networks set successfully.\n", + qmi_device_get_path_display (ctx->device)); + + qmi_message_nas_set_preferred_networks_output_unref (output); + operation_shutdown (TRUE); +} + +#endif /* HAVE_QMI_MESSAGE_NAS_SET_PREFERRED_NETWORKS */ + #if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM static void @@ -4057,6 +4270,41 @@ qmicli_nas_run (QmiDevice *device, } #endif +#if defined HAVE_QMI_MESSAGE_NAS_GET_PREFERRED_NETWORKS + if (get_preferred_networks_flag) { + g_debug ("Asynchronously getting preferred networks..."); + qmi_client_nas_get_preferred_networks (ctx->client, + NULL, + 10, + ctx->cancellable, + (GAsyncReadyCallback)get_preferred_networks_ready, + NULL); + return; + } +#endif + +#if defined HAVE_QMI_MESSAGE_NAS_SET_PREFERRED_NETWORKS + if (set_preferred_networks_str) { + QmiMessageNasSetPreferredNetworksInput *input; + g_debug ("Asynchronously setting preferred networks..."); + + input = set_preferred_networks_input_create (set_preferred_networks_str); + if (!input) { + operation_shutdown (FALSE); + return; + } + + qmi_client_nas_set_preferred_networks (ctx->client, + input, + 10, + ctx->cancellable, + (GAsyncReadyCallback)set_preferred_networks_ready, + NULL); + qmi_message_nas_set_preferred_networks_input_ref (input); + return; + } +#endif + #if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM if (get_serving_system_flag) { g_debug ("Asynchronously getting serving system..."); |