summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-07-16 00:04:20 +0200
committerDan Williams <dcbw@redhat.com>2018-09-12 17:25:19 +0000
commitac69466c9da7c553c7f4c4a4197614af560abc83 (patch)
tree72ca946e1758b0f6183ac3e72f709fe3f3fdaf2f
parent692d076ba68e09bcad146d78109d4a59e1563918 (diff)
downloadModemManager-ac69466c9da7c553c7f4c4a4197614af560abc83.tar.gz
shared-qmi: implement 3GPP network registration logic
Ported from the broadband modem QMI implementation, keeping the logic in place. We will need this to integrate mode/capability switching in MBIM devices, for nothing else really (as MBIM already supports this operation).
-rw-r--r--src/mm-broadband-modem-qmi.c110
-rw-r--r--src/mm-shared-qmi.c103
-rw-r--r--src/mm-shared-qmi.h12
3 files changed, 117 insertions, 108 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index 54082ae07..c63618f18 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -2838,112 +2838,6 @@ modem_3gpp_load_operator_code (MMIfaceModem3gpp *_self,
}
/*****************************************************************************/
-/* Register in network (3GPP interface) */
-
-static gboolean
-modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_boolean (G_TASK (res), error);
-}
-
-static void
-initiate_network_register_ready (QmiClientNas *client,
- GAsyncResult *res,
- GTask *task)
-{
- GError *error = NULL;
- QmiMessageNasInitiateNetworkRegisterOutput *output;
-
- output = qmi_client_nas_initiate_network_register_finish (client, res, &error);
- if (!output) {
- g_prefix_error (&error, "QMI operation failed: ");
- g_task_return_error (task, error);
- } else if (!qmi_message_nas_initiate_network_register_output_get_result (output, &error)) {
- /* NOFX is not an error, they actually play pretty well */
- if (g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
- g_error_free (error);
- g_task_return_boolean (task, TRUE);
- } else {
- g_prefix_error (&error, "Couldn't initiate network register: ");
- g_task_return_error (task, error);
- }
- } else
- g_task_return_boolean (task, TRUE);
-
- g_object_unref (task);
-
- if (output)
- qmi_message_nas_initiate_network_register_output_unref (output);
-}
-
-static void
-modem_3gpp_register_in_network (MMIfaceModem3gpp *self,
- const gchar *operator_id,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint16 mcc = 0;
- guint16 mnc = 0;
- QmiClient *client = NULL;
- QmiMessageNasInitiateNetworkRegisterInput *input;
- GError *error = NULL;
-
- /* Parse input MCC/MNC */
- if (operator_id && !mm_3gpp_parse_operator_id (operator_id, &mcc, &mnc, &error)) {
- g_assert (error != NULL);
- g_task_report_error (self,
- callback,
- user_data,
- modem_3gpp_register_in_network,
- error);
- return;
- }
-
- /* Get NAS client */
- if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
- QMI_SERVICE_NAS, &client,
- callback, user_data))
- return;
-
- input = qmi_message_nas_initiate_network_register_input_new ();
-
- if (mcc) {
- /* If the user sent a specific network to use, lock it in. */
- qmi_message_nas_initiate_network_register_input_set_action (
- input,
- QMI_NAS_NETWORK_REGISTER_TYPE_MANUAL,
- NULL);
- qmi_message_nas_initiate_network_register_input_set_manual_registration_info_3gpp (
- input,
- mcc,
- mnc,
- QMI_NAS_RADIO_INTERFACE_UNKNOWN,
- NULL);
- } else {
- /* Otherwise, automatic registration */
- qmi_message_nas_initiate_network_register_input_set_action (
- input,
- QMI_NAS_NETWORK_REGISTER_TYPE_AUTOMATIC,
- NULL);
- }
-
- qmi_client_nas_initiate_network_register (
- QMI_CLIENT_NAS (client),
- input,
- 120,
- cancellable,
- (GAsyncReadyCallback)initiate_network_register_ready,
- g_task_new (self, NULL, callback, user_data));
-
- qmi_message_nas_initiate_network_register_input_unref (input);
-}
-
-/*****************************************************************************/
/* Registration checks (3GPP interface) */
static gboolean
@@ -9073,8 +8967,8 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
/* Other actions */
iface->scan_networks = modem_3gpp_scan_networks;
iface->scan_networks_finish = modem_3gpp_scan_networks_finish;
- iface->register_in_network = modem_3gpp_register_in_network;
- iface->register_in_network_finish = modem_3gpp_register_in_network_finish;
+ iface->register_in_network = mm_shared_qmi_3gpp_register_in_network;
+ iface->register_in_network_finish = mm_shared_qmi_3gpp_register_in_network_finish;
iface->run_registration_checks = modem_3gpp_run_registration_checks;
iface->run_registration_checks_finish = modem_3gpp_run_registration_checks_finish;
iface->load_operator_code = modem_3gpp_load_operator_code;
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index 58645320a..cc73c9927 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -27,6 +27,7 @@
#include "mm-log.h"
#include "mm-iface-modem.h"
+#include "mm-iface-modem-3gpp.h"
#include "mm-iface-modem-location.h"
#include "mm-shared-qmi.h"
#include "mm-modem-helpers-qmi.h"
@@ -109,6 +110,107 @@ get_private (MMSharedQmi *self)
}
/*****************************************************************************/
+/* Register in network (3GPP interface) */
+
+gboolean
+mm_shared_qmi_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+initiate_network_register_ready (QmiClientNas *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ QmiMessageNasInitiateNetworkRegisterOutput *output;
+
+ output = qmi_client_nas_initiate_network_register_finish (client, res, &error);
+ if (!output || !qmi_message_nas_initiate_network_register_output_get_result (output, &error)) {
+ if (!g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ g_prefix_error (&error, "Couldn't initiate network register: ");
+ g_task_return_error (task, error);
+ goto out;
+ }
+ g_error_free (error);
+ }
+
+ g_task_return_boolean (task, TRUE);
+
+out:
+ g_object_unref (task);
+
+ if (output)
+ qmi_message_nas_initiate_network_register_output_unref (output);
+}
+
+void
+mm_shared_qmi_3gpp_register_in_network (MMIfaceModem3gpp *self,
+ const gchar *operator_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ QmiMessageNasInitiateNetworkRegisterInput *input;
+ guint16 mcc = 0;
+ guint16 mnc = 0;
+ QmiClient *client = NULL;
+ GError *error = NULL;
+
+ /* Get NAS client */
+ if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_NAS, &client,
+ callback, user_data))
+ return;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ /* Parse input MCC/MNC */
+ if (operator_id && !mm_3gpp_parse_operator_id (operator_id, &mcc, &mnc, &error)) {
+ g_assert (error != NULL);
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ input = qmi_message_nas_initiate_network_register_input_new ();
+
+ if (mcc) {
+ /* If the user sent a specific network to use, lock it in. */
+ qmi_message_nas_initiate_network_register_input_set_action (
+ input,
+ QMI_NAS_NETWORK_REGISTER_TYPE_MANUAL,
+ NULL);
+ qmi_message_nas_initiate_network_register_input_set_manual_registration_info_3gpp (
+ input,
+ mcc,
+ mnc,
+ QMI_NAS_RADIO_INTERFACE_UNKNOWN, /* don't change radio interface */
+ NULL);
+ } else {
+ /* Otherwise, automatic registration */
+ qmi_message_nas_initiate_network_register_input_set_action (
+ input,
+ QMI_NAS_NETWORK_REGISTER_TYPE_AUTOMATIC,
+ NULL);
+ }
+
+ qmi_client_nas_initiate_network_register (
+ QMI_CLIENT_NAS (client),
+ input,
+ 120,
+ cancellable,
+ (GAsyncReadyCallback)initiate_network_register_ready,
+ task);
+
+ qmi_message_nas_initiate_network_register_input_unref (input);
+}
+
+/*****************************************************************************/
/* Current capabilities setting (Modem interface) */
typedef enum {
@@ -3948,6 +4050,7 @@ mm_shared_qmi_get_type (void)
shared_qmi_type = g_type_register_static (G_TYPE_INTERFACE, "MMSharedQmi", &info, 0);
g_type_interface_add_prerequisite (shared_qmi_type, MM_TYPE_IFACE_MODEM);
+ g_type_interface_add_prerequisite (shared_qmi_type, MM_TYPE_IFACE_MODEM_3GPP);
g_type_interface_add_prerequisite (shared_qmi_type, MM_TYPE_IFACE_MODEM_LOCATION);
}
diff --git a/src/mm-shared-qmi.h b/src/mm-shared-qmi.h
index 9b3e10c53..11381de9b 100644
--- a/src/mm-shared-qmi.h
+++ b/src/mm-shared-qmi.h
@@ -25,6 +25,7 @@
#include <libqmi-glib.h>
#include "mm-iface-modem.h"
+#include "mm-iface-modem-3gpp.h"
#include "mm-iface-modem-location.h"
#include "mm-port-qmi.h"
@@ -60,6 +61,17 @@ gboolean mm_shared_qmi_ensure_client (MMSharedQmi *self,
GAsyncReadyCallback callback,
gpointer user_data);
+/* Shared QMI 3GPP operations */
+
+void mm_shared_qmi_3gpp_register_in_network (MMIfaceModem3gpp *self,
+ const gchar *operator_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_shared_qmi_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error);
+
/* Shared QMI device management support */
void mm_shared_qmi_load_supported_capabilities (MMIfaceModem *self,