aboutsummaryrefslogtreecommitdiff
path: root/libmm-glib
diff options
context:
space:
mode:
authorUjjwal Pande <ujjwalpande@google.com>2024-05-30 00:04:24 +0000
committerAleksander Morgado <aleksander@aleksander.es>2024-06-12 09:39:12 +0000
commit2904510e760fa1fdf491d1ef4574c29d05307b3b (patch)
tree999160f261639f947303ef96589e7d1a0bf497b0 /libmm-glib
parentdf8287bf6c2febd068d06f0f45194bc622118bd4 (diff)
api: new NetworkRejection property
When a modem is not able to register to the network, MBIM and QMI indications related to registration reports network rejection cause codes if request is rejected by the network. This information is currently logged in the ModemManager but not exposed outside of ModemManager. These are the changes to define interface to expose network reject cause codes over d-bus to the above layers which could be used by above layers to present this information in a user friendly way.
Diffstat (limited to 'libmm-glib')
-rw-r--r--libmm-glib/libmm-glib.h1
-rw-r--r--libmm-glib/meson.build2
-rw-r--r--libmm-glib/mm-modem-3gpp.c49
-rw-r--r--libmm-glib/mm-modem-3gpp.h4
-rw-r--r--libmm-glib/mm-network-rejection.c321
-rw-r--r--libmm-glib/mm-network-rejection.h97
6 files changed, 474 insertions, 0 deletions
diff --git a/libmm-glib/libmm-glib.h b/libmm-glib/libmm-glib.h
index 8c282562..c0fde6e0 100644
--- a/libmm-glib/libmm-glib.h
+++ b/libmm-glib/libmm-glib.h
@@ -93,6 +93,7 @@
#include <mm-cell-info-tdscdma.h>
#include <mm-cell-info-lte.h>
#include <mm-cell-info-nr5g.h>
+#include <mm-network-rejection.h>
#include <mm-compat.h>
/* generated */
diff --git a/libmm-glib/meson.build b/libmm-glib/meson.build
index de668dab..0871778c 100644
--- a/libmm-glib/meson.build
+++ b/libmm-glib/meson.build
@@ -61,6 +61,7 @@ headers = files(
'mm-sms.h',
'mm-sms-properties.h',
'mm-unlock-retries.h',
+ 'mm-network-rejection.h',
)
install_headers(
@@ -123,6 +124,7 @@ sources = files(
'mm-sms.c',
'mm-sms-properties.c',
'mm-unlock-retries.c',
+ 'mm-network-rejection.c',
)
deps = [include_dep]
diff --git a/libmm-glib/mm-modem-3gpp.c b/libmm-glib/mm-modem-3gpp.c
index cb228108..e86360d3 100644
--- a/libmm-glib/mm-modem-3gpp.c
+++ b/libmm-glib/mm-modem-3gpp.c
@@ -52,6 +52,7 @@ struct _MMModem3gppPrivate {
PROPERTY_OBJECT_DECLARE (initial_eps_bearer_settings, MMBearerProperties)
PROPERTY_OBJECT_DECLARE (nr5g_registration_settings, MMNr5gRegistrationSettings)
+ PROPERTY_OBJECT_DECLARE (network_rejection, MMNetworkRejection)
};
/*****************************************************************************/
@@ -696,6 +697,52 @@ PROPERTY_OBJECT_DEFINE_FAILABLE (initial_eps_bearer_settings,
MMBearerProperties,
mm_bearer_properties_new_from_dictionary)
+/**
+ * mm_modem_3gpp_get_network_rejection:
+ * @self: A #MMModem3gpp.
+ *
+ * Gets a #MMNetworkRejection object specifying the network rejection
+ * information received during registration failure.
+ *
+ * <warning>The values reported by @self are not updated when the values in the
+ * interface change. Instead, the client is expected to call
+ * mm_modem_3gpp_get_network_rejection() again to get a new
+ * #MMNetworkRejection with the new values.</warning>
+ *
+ * Returns: (transfer full): A #MMNetworkRejection that must be freed with
+ * g_object_unref() or %NULL if unknown.
+ *
+ * Since: 1.24
+ */
+
+/**
+ * mm_modem_3gpp_peek_network_rejection:
+ * @self: A #MMModem3gpp.
+ *
+ * Gets a #MMNetworkRejection object specifying the network rejection
+ * information received during registration failure.
+ *
+ * <warning>The returned value is only valid until the property changes so
+ * it is only safe to use this function on the thread where
+ * @self was constructed. Use mm_modem_3gpp_get_network_rejection()
+ * if on another thread.</warning>
+ *
+ * Returns: (transfer none): A #MMNetworkRejection. Do not free the returned
+ * value, it belongs to @self.
+ *
+ * Since: 1.24
+ */
+
+/* helpers to match the property substring name with the one in our API */
+#define mm_gdbus_modem_3gpp_dup_network_rejection mm_gdbus_modem3gpp_dup_network_rejection
+
+PROPERTY_OBJECT_DEFINE_FAILABLE (network_rejection,
+ Modem3gpp, modem_3gpp, MODEM_3GPP,
+ MMNetworkRejection,
+ mm_network_rejection_new_from_dictionary)
+
+/*****************************************************************************/
+
/*****************************************************************************/
static GList *
@@ -1613,6 +1660,7 @@ mm_modem_3gpp_init (MMModem3gpp *self)
PROPERTY_INITIALIZE (initial_eps_bearer_settings, "initial-eps-bearer-settings")
PROPERTY_INITIALIZE (nr5g_registration_settings, "nr5g-registration-settings")
+ PROPERTY_INITIALIZE (network_rejection, "network-rejection")
}
static void
@@ -1624,6 +1672,7 @@ finalize (GObject *object)
PROPERTY_OBJECT_FINALIZE (initial_eps_bearer_settings);
PROPERTY_OBJECT_FINALIZE (nr5g_registration_settings);
+ PROPERTY_OBJECT_FINALIZE (network_rejection);
G_OBJECT_CLASS (mm_modem_3gpp_parent_class)->finalize (object);
}
diff --git a/libmm-glib/mm-modem-3gpp.h b/libmm-glib/mm-modem-3gpp.h
index 8f137676..6a9ae8e9 100644
--- a/libmm-glib/mm-modem-3gpp.h
+++ b/libmm-glib/mm-modem-3gpp.h
@@ -32,6 +32,7 @@
#include "mm-bearer.h"
#include "mm-nr5g-registration-settings.h"
+#include "mm-network-rejection.h"
#include "mm-gdbus-modem.h"
G_BEGIN_DECLS
@@ -98,6 +99,9 @@ MMModem3gppPacketServiceState mm_modem_3gpp_get_packet_service_state (MMModem3gp
MMNr5gRegistrationSettings *mm_modem_3gpp_get_nr5g_registration_settings (MMModem3gpp *self);
MMNr5gRegistrationSettings *mm_modem_3gpp_peek_nr5g_registration_settings (MMModem3gpp *self);
+MMNetworkRejection *mm_modem_3gpp_get_network_rejection (MMModem3gpp *self);
+MMNetworkRejection *mm_modem_3gpp_peek_network_rejection (MMModem3gpp *self);
+
void mm_modem_3gpp_register (MMModem3gpp *self,
const gchar *network_id,
GCancellable *cancellable,
diff --git a/libmm-glib/mm-network-rejection.c b/libmm-glib/mm-network-rejection.c
new file mode 100644
index 00000000..7bea1475
--- /dev/null
+++ b/libmm-glib/mm-network-rejection.c
@@ -0,0 +1,321 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libmm-glib -- Access modem status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2024 Google, Inc.
+ */
+
+#include <string.h>
+
+#include "mm-errors-types.h"
+#include "mm-network-rejection.h"
+
+/**
+ * SECTION: mm-network-rejection
+ * @title: MMNetworkRejection
+ * @short_description: Helper object to handle network rejection.
+ *
+ * The #MMNetworkRejection is an object handling the network rejection
+ * related information.
+ *
+ * This object is retrieved with either mm_modem_3gpp_get_network_rejection(),
+ * or mm_modem_3gpp_peek_network_rejection().
+ */
+
+G_DEFINE_TYPE (MMNetworkRejection, mm_network_rejection, G_TYPE_OBJECT)
+
+#define PROPERTY_ERROR "error"
+#define PROPERTY_OPERATOR_ID "operator-id"
+#define PROPERTY_OPERATOR_NAME "operator-name"
+#define PROPERTY_ACCESS_TECHNOLOGY "access-technology"
+
+struct _MMNetworkRejectionPrivate {
+ gchar *operator_id;
+ gchar *operator_name;
+ MMModemAccessTechnology access_technology;
+ MMNetworkError error;
+};
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_get_operator_id:
+ * @self: a #MMNetworkRejection.
+ *
+ * Gets the operator id reported with network reject.
+ *
+ * Returns: a string with the operator id, or #NULL if unknown. Do not free the
+ * returned value, it is owned by @self.
+ *
+ * Since: 1.24
+ */
+const gchar *
+mm_network_rejection_get_operator_id (MMNetworkRejection *self)
+{
+ g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), NULL);
+
+ return self->priv->operator_id;
+}
+
+/**
+ * mm_network_rejection_set_operator_id: (skip)
+ */
+void
+mm_network_rejection_set_operator_id (MMNetworkRejection *self,
+ const gchar *operator_id)
+{
+ g_return_if_fail (MM_IS_NETWORK_REJECTION (self));
+
+ g_free (self->priv->operator_id);
+ self->priv->operator_id = g_strdup (operator_id);
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_get_operator_name:
+ * @self: a #MMNetworkRejection.
+ *
+ * Gets the operator name reported with network reject.
+ *
+ * Returns: a string with the operator name, or #NULL if unknown. Do not free the
+ * returned value, it is owned by @self.
+ *
+ * Since: 1.24
+ */
+const gchar *
+mm_network_rejection_get_operator_name (MMNetworkRejection *self)
+{
+ g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), NULL);
+
+ return self->priv->operator_name;
+}
+
+/**
+ * mm_network_rejection_set_operator_name: (skip)
+ */
+void
+mm_network_rejection_set_operator_name (MMNetworkRejection *self,
+ const gchar *operator_name)
+{
+ g_return_if_fail (MM_IS_NETWORK_REJECTION (self));
+
+ g_free (self->priv->operator_name);
+ self->priv->operator_name = g_strdup (operator_name);
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_get_error:
+ * @self: a #MMNetworkRejection.
+ *
+ * Gets the network error reported with network reject.
+ *
+ * Returns: the network error.
+ *
+ * Since: 1.24
+ */
+MMNetworkError
+mm_network_rejection_get_error (MMNetworkRejection *self)
+{
+ g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), 0);
+
+ return self->priv->error;
+}
+
+/**
+ * mm_network_rejection_set_error: (skip)
+ */
+void
+mm_network_rejection_set_error (MMNetworkRejection *self,
+ MMNetworkError error)
+{
+ g_return_if_fail (MM_IS_NETWORK_REJECTION (self));
+
+ self->priv->error = error;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_get_access_technology:
+ * @self: a #MMNetworkRejection.
+ *
+ * Gets the available class reported with network reject.
+ *
+ * Returns: the available class.
+ *
+ * Since: 1.24
+ */
+MMModemAccessTechnology
+mm_network_rejection_get_access_technology (MMNetworkRejection *self)
+{
+ g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), 0);
+
+ return self->priv->access_technology;
+}
+
+/**
+ * mm_network_rejection_set_access_technology: (skip)
+ */
+void
+mm_network_rejection_set_access_technology (MMNetworkRejection *self,
+ MMModemAccessTechnology access_technology)
+{
+ g_return_if_fail (MM_IS_NETWORK_REJECTION (self));
+
+ self->priv->access_technology = access_technology;
+}
+
+/*****************************************************************************/
+
+
+/**
+ * mm_network_rejection_get_dictionary: (skip)
+ */
+GVariant *
+mm_network_rejection_get_dictionary (MMNetworkRejection *self)
+{
+ GVariantBuilder builder;
+
+ if (!self)
+ return NULL;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&builder,
+ "{sv}",
+ PROPERTY_ERROR,
+ g_variant_new_uint32 (self->priv->error));
+
+ if (self->priv->operator_id)
+ g_variant_builder_add (&builder,
+ "{sv}",
+ PROPERTY_OPERATOR_ID,
+ g_variant_new_string (self->priv->operator_id));
+
+ if (self->priv->operator_name)
+ g_variant_builder_add (&builder,
+ "{sv}",
+ PROPERTY_OPERATOR_NAME,
+ g_variant_new_string (self->priv->operator_name));
+
+ if (self->priv->access_technology)
+ g_variant_builder_add (&builder,
+ "{sv}",
+ PROPERTY_ACCESS_TECHNOLOGY,
+ g_variant_new_uint32 (self->priv->access_technology));
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_new_from_dictionary: (skip)
+ */
+MMNetworkRejection *
+mm_network_rejection_new_from_dictionary (GVariant *dictionary,
+ GError **error)
+{
+ GVariantIter iter;
+ gchar *key;
+ GVariant *value;
+ MMNetworkRejection *self;
+
+ self = mm_network_rejection_new ();
+ if (!dictionary)
+ return self;
+
+ if (!g_variant_is_of_type (dictionary, G_VARIANT_TYPE ("a{sv}"))) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_INVALID_ARGS,
+ "Cannot create network rejection from dictionary: "
+ "invalid variant type received");
+ g_object_unref (self);
+ return NULL;
+ }
+
+ g_variant_iter_init (&iter, dictionary);
+ while (g_variant_iter_next (&iter, "{sv}", &key, &value)) {
+ if (g_str_equal (key, PROPERTY_ERROR)) {
+ mm_network_rejection_set_error (
+ self,
+ g_variant_get_uint32 (value));
+ } else if (g_str_equal (key, PROPERTY_OPERATOR_ID)) {
+ mm_network_rejection_set_operator_id (
+ self,
+ g_variant_get_string (value, NULL));
+ } else if (g_str_equal (key, PROPERTY_OPERATOR_NAME)) {
+ mm_network_rejection_set_operator_name (
+ self,
+ g_variant_get_string (value, NULL));
+ } else if (g_str_equal (key, PROPERTY_ACCESS_TECHNOLOGY)) {
+ mm_network_rejection_set_access_technology (
+ self,
+ g_variant_get_uint32 (value));
+ }
+
+ g_free (key);
+ g_variant_unref (value);
+ }
+
+ return self;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_network_rejection_new: (skip)
+ */
+MMNetworkRejection *
+mm_network_rejection_new (void)
+{
+ return (MM_NETWORK_REJECTION (
+ g_object_new (MM_TYPE_NETWORK_REJECTION, NULL)));
+}
+
+static void
+mm_network_rejection_init (MMNetworkRejection *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ MM_TYPE_NETWORK_REJECTION,
+ MMNetworkRejectionPrivate);
+}
+
+static void
+finalize (GObject *object)
+{
+ MMNetworkRejection *self = MM_NETWORK_REJECTION (object);
+
+ g_free (self->priv->operator_id);
+ g_free (self->priv->operator_name);
+
+ G_OBJECT_CLASS (mm_network_rejection_parent_class)->finalize (object);
+}
+
+static void
+mm_network_rejection_class_init (MMNetworkRejectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (MMNetworkRejectionPrivate));
+
+ object_class->finalize = finalize;
+}
diff --git a/libmm-glib/mm-network-rejection.h b/libmm-glib/mm-network-rejection.h
new file mode 100644
index 00000000..2142454a
--- /dev/null
+++ b/libmm-glib/mm-network-rejection.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libmm-glib -- Access modem status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2024 Google, Inc.
+ */
+
+#ifndef MM_NETWORK_REJECTION_H
+#define MM_NETWORK_REJECTION_H
+
+#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION)
+#error "Only <libmm-glib.h> can be included directly."
+#endif
+
+#include <ModemManager.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MM_TYPE_NETWORK_REJECTION (mm_network_rejection_get_type ())
+#define MM_NETWORK_REJECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_NETWORK_REJECTION, MMNetworkRejection))
+#define MM_NETWORK_REJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_NETWORK_REJECTION, MMNetworkRejectionClass))
+#define MM_IS_NETWORK_REJECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_NETWORK_REJECTION))
+#define MM_IS_NETWORK_REJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_NETWORK_REJECTION))
+#define MM_NETWORK_REJECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_NETWORK_REJECTION, MMNetworkRejectionClass))
+
+typedef struct _MMNetworkRejection MMNetworkRejection;
+typedef struct _MMNetworkRejectionClass MMNetworkRejectionClass;
+typedef struct _MMNetworkRejectionPrivate MMNetworkRejectionPrivate;
+
+/**
+ * MMNetworkRejection:
+ *
+ * The #MMNetworkRejection structure contains private data and should
+ * only be accessed using the provided API.
+ */
+struct _MMNetworkRejection {
+ /*< private >*/
+ GObject parent;
+ MMNetworkRejectionPrivate *priv;
+};
+
+struct _MMNetworkRejectionClass {
+ /*< private >*/
+ GObjectClass parent;
+};
+
+GType mm_network_rejection_get_type (void);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMNetworkRejection, g_object_unref)
+
+MMNetworkError mm_network_rejection_get_error (MMNetworkRejection *self);
+MMModemAccessTechnology mm_network_rejection_get_access_technology (MMNetworkRejection *self);
+const gchar *mm_network_rejection_get_operator_id (MMNetworkRejection *self);
+const gchar *mm_network_rejection_get_operator_name (MMNetworkRejection *self);
+
+/*****************************************************************************/
+/* ModemManager/libmm-glib/mmcli specific methods */
+
+#if defined (_LIBMM_INSIDE_MM) || \
+ defined (_LIBMM_INSIDE_MMCLI) || \
+ defined (LIBMM_GLIB_COMPILATION)
+
+MMNetworkRejection *mm_network_rejection_new (void);
+MMNetworkRejection *mm_network_rejection_new_from_dictionary (GVariant *dictionary,
+ GError **error);
+
+void mm_network_rejection_set_error (MMNetworkRejection *self,
+ MMNetworkError error);
+void mm_network_rejection_set_operator_id (MMNetworkRejection *self,
+ const gchar *operator_id);
+void mm_network_rejection_set_operator_name (MMNetworkRejection *self,
+ const gchar *operator_name);
+void mm_network_rejection_set_access_technology (MMNetworkRejection *self,
+ MMModemAccessTechnology access_technology);
+
+GVariant *mm_network_rejection_get_dictionary (MMNetworkRejection *self);
+
+#endif
+
+G_END_DECLS
+
+#endif /* MM_NETWORK_REJECTION_H */