diff options
author | Ben Chan <benchan@chromium.org> | 2018-08-13 12:27:37 -0700 |
---|---|---|
committer | Ben Chan <benchan@chromium.org> | 2018-08-18 13:29:46 -0700 |
commit | 28e64d00181c83fd6cd420c46b6040f7b1afe5fb (patch) | |
tree | 59ba372cd17c3248d7a8d901e2ba41f5a52619d2 | |
parent | 89ffcbdd8db4164a4a1cbea0224b0cc14a3f57b0 (diff) | |
download | ModemManager-28e64d00181c83fd6cd420c46b6040f7b1afe5fb.tar.gz |
libmm-glib: add MMPco for handling raw PCO data
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-docs.xml | 4 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 28 | ||||
-rw-r--r-- | libmm-glib/Makefile.am | 3 | ||||
-rw-r--r-- | libmm-glib/libmm-glib.h | 1 | ||||
-rw-r--r-- | libmm-glib/mm-pco.c | 259 | ||||
-rw-r--r-- | libmm-glib/mm-pco.h | 87 |
6 files changed, 382 insertions, 0 deletions
diff --git a/docs/reference/libmm-glib/libmm-glib-docs.xml b/docs/reference/libmm-glib/libmm-glib-docs.xml index 4b0a564c6..80b3ce57a 100644 --- a/docs/reference/libmm-glib/libmm-glib-docs.xml +++ b/docs/reference/libmm-glib/libmm-glib-docs.xml @@ -129,6 +129,10 @@ <title>Voice support</title> <xi:include href="xml/mm-modem-voice.xml"/> </section> + <section> + <title>PCO support</title> + <xi:include href="xml/mm-pco.xml"/> + </section> </chapter> <chapter> diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index bfa57f1cd..01a5de27a 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -1309,6 +1309,34 @@ mm_call_properties_get_type </SECTION> <SECTION> +<FILE>mm-pco</FILE> +<TITLE>MMPco</TITLE> +MMPco +<SUBSECTION New> +mm_pco_new +<SUBSECTION GettersSetters> +mm_pco_get_session_id +mm_pco_is_complete +mm_pco_get_data +<SUBSECTION Private> +mm_pco_from_variant +mm_pco_to_variant +mm_pco_set_session_id +mm_pco_set_complete +mm_pco_set_data +<SUBSECTION Standard> +MMPcoClass +MMPcoPrivate +MM_IS_PCO +MM_IS_PCO_CLASS +MM_PCO +MM_PCO_CLASS +MM_PCO_GET_CLASS +MM_TYPE_PCO +mm_pco_get_type +</SECTION> + +<SECTION> <FILE>mm-enums-types</FILE> <TITLE>Flags and Enumerations</TITLE> mm_bearer_ip_method_get_string diff --git a/libmm-glib/Makefile.am b/libmm-glib/Makefile.am index 7d554ad04..4c8905926 100644 --- a/libmm-glib/Makefile.am +++ b/libmm-glib/Makefile.am @@ -83,6 +83,8 @@ libmm_glib_la_SOURCES = \ mm-signal.c \ mm-kernel-event-properties.h \ mm-kernel-event-properties.c \ + mm-pco.h \ + mm-pco.c \ $(NULL) libmm_glib_la_CPPFLAGS = \ @@ -152,6 +154,7 @@ include_HEADERS = \ mm-cdma-manual-activation-properties.h \ mm-signal.h \ mm-kernel-event-properties.h \ + mm-pco.h \ $(NULL) CLEANFILES = diff --git a/libmm-glib/libmm-glib.h b/libmm-glib/libmm-glib.h index 81175ca90..d45a6b12b 100644 --- a/libmm-glib/libmm-glib.h +++ b/libmm-glib/libmm-glib.h @@ -78,6 +78,7 @@ #include <mm-cdma-manual-activation-properties.h> #include <mm-signal.h> #include <mm-kernel-event-properties.h> +#include <mm-pco.h> /* generated */ #include <mm-errors-types.h> diff --git a/libmm-glib/mm-pco.c b/libmm-glib/mm-pco.c new file mode 100644 index 000000000..07db363da --- /dev/null +++ b/libmm-glib/mm-pco.c @@ -0,0 +1,259 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details: + * + * Copyright 2018 Google LLC. + */ + +#include <string.h> +#include <glib.h> + +#include "mm-enums-types.h" +#include "mm-errors-types.h" +#include "mm-common-helpers.h" +#include "mm-pco.h" + +/** + * SECTION: mm-pco + * @title: MMPco + * @short_description: Helper object to handle 3GPP PCO. + * + * The #MMPco is an object handling the raw 3GPP Protocol Configuration Options + * (PCO) that the modem has received from the network. + * + * This object is retrieved with mm_modem_3gpp_get_pco(). + */ + +G_DEFINE_TYPE (MMPco, mm_pco, G_TYPE_OBJECT); + +struct _MMPcoPrivate { + /* Session ID, signature 'u' */ + guint32 session_id; + /* Flag indicating if the PCO data is complete or partial, signature 'b' */ + gboolean is_complete; + /* Raw PCO data, signature 'ay' */ + GBytes *data; +}; + +/*****************************************************************************/ + +static GBytes * +_g_variant_get_bytes (GVariant *variant) +{ + GByteArray *byte_array; + guint num_bytes; + GVariantIter iter; + guint8 byte; + + g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE ("ay"))); + + num_bytes = g_variant_n_children (variant); + if (num_bytes == 0) + return NULL; + + byte_array = g_byte_array_sized_new (num_bytes); + + g_variant_iter_init (&iter, variant); + while (g_variant_iter_loop (&iter, "y", &byte)) + g_byte_array_append (byte_array, &byte, sizeof (byte)); + + return g_byte_array_free_to_bytes (byte_array); +} + +/*****************************************************************************/ + +/** + * mm_pco_get_session_id: + * @self: a #MMPco. + * + * Gets the session ID associated with the PCO. + * + * Returns: the session ID. + */ +guint32 +mm_pco_get_session_id (MMPco *self) +{ + g_return_val_if_fail (MM_IS_PCO (self), G_MAXUINT32); + + return self->priv->session_id; +} + +void +mm_pco_set_session_id (MMPco *self, + guint32 session_id) +{ + g_return_if_fail (MM_IS_PCO (self)); + + self->priv->session_id = session_id; +} + +/*****************************************************************************/ + +/** + * mm_pco_is_complete: + * @self: a #MMPco. + * + * Gets the complete flag that indicates whether the PCO data contains the + * complete PCO structure received from the network. + * + * Returns: %TRUE if the PCO data contains the complete PCO structure, %FALSE otherwise. + */ +gboolean +mm_pco_is_complete (MMPco *self) +{ + g_return_val_if_fail (MM_IS_PCO (self), FALSE); + + return self->priv->is_complete; +} + +void +mm_pco_set_complete (MMPco *self, + gboolean is_complete) +{ + g_return_if_fail (MM_IS_PCO (self)); + + self->priv->is_complete = is_complete; +} + +/*****************************************************************************/ + +/** + * mm_pco_get_data: + * @self: a #MMPco. + * @data_size: (out): Size of the PCO data, if any given. + * + * Gets the PCO data in raw bytes. + * + * Returns: (transfer none): the PCO data, or %NULL if it doesn't contain any. + */ +const guint8 * +mm_pco_get_data (MMPco *self, + gsize *data_size) +{ + g_return_val_if_fail (MM_IS_PCO (self), NULL); + + return g_bytes_get_data (self->priv->data, data_size); +} + +void +mm_pco_set_data (MMPco *self, + const guint8 *data, + gsize data_size) +{ + g_return_if_fail (MM_IS_PCO (self)); + + g_bytes_unref (self->priv->data); + + self->priv->data = (data && data_size) ? g_bytes_new (data, data_size) + : NULL; +} + +/*****************************************************************************/ + +MMPco * +mm_pco_from_variant (GVariant *variant, + GError **error) +{ + MMPco *pco; + GVariant *pco_data = NULL; + + pco = mm_pco_new (); + if (!variant) + return pco; + + if (!g_variant_is_of_type (variant, G_VARIANT_TYPE ("(ubay)"))) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot create PCO from variant: " + "invalid variant type received"); + g_object_unref (pco); + return NULL; + } + + g_variant_get (variant, "(ub@ay)", + &pco->priv->session_id, + &pco->priv->is_complete, + &pco_data); + + g_bytes_unref (pco->priv->data); + pco->priv->data = _g_variant_get_bytes (pco_data); + g_variant_unref (pco_data); + + return pco; +} + +/*****************************************************************************/ + +GVariant * +mm_pco_to_variant (MMPco *self) +{ + GVariantBuilder builder; + gsize i, pco_data_size; + const guint8 *pco_data; + + /* Allow NULL */ + if (!self) + return NULL; + + g_return_val_if_fail (MM_IS_PCO (self), NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ubay)")); + + g_variant_builder_add (&builder, "u", self->priv->session_id); + g_variant_builder_add (&builder, "b", self->priv->is_complete); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("ay")); + if (self->priv->data) { + pco_data = g_bytes_get_data (self->priv->data, &pco_data_size); + for (i = 0; i < pco_data_size; ++i) + g_variant_builder_add (&builder, "y", pco_data[i]); + } + g_variant_builder_close (&builder); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +/*****************************************************************************/ + +MMPco * +mm_pco_new (void) +{ + return (MM_PCO (g_object_new (MM_TYPE_PCO, NULL))); +} + +static void +mm_pco_init (MMPco *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_PCO, MMPcoPrivate); + + self->priv->session_id = G_MAXUINT32; +} + +static void +finalize (GObject *object) +{ + MMPco *self = MM_PCO (object); + + g_bytes_unref (self->priv->data); + + G_OBJECT_CLASS (mm_pco_parent_class)->finalize (object); +} + +static void +mm_pco_class_init (MMPcoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMPcoPrivate)); + + object_class->finalize = finalize; +} diff --git a/libmm-glib/mm-pco.h b/libmm-glib/mm-pco.h new file mode 100644 index 000000000..e9c47445b --- /dev/null +++ b/libmm-glib/mm-pco.h @@ -0,0 +1,87 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details: + * + * Copyright 2018 Google LLC. + */ + +#ifndef MM_PCO_H +#define MM_PCO_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_PCO (mm_pco_get_type ()) +#define MM_PCO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PCO, MMPco)) +#define MM_PCO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PCO, MMPcoClass)) +#define MM_IS_PCO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PCO)) +#define MM_IS_PCO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PCO)) +#define MM_PCO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PCO, MMPcoClass)) + +typedef struct _MMPco MMPco; +typedef struct _MMPcoClass MMPcoClass; +typedef struct _MMPcoPrivate MMPcoPrivate; + +/** + * MMPco: + * + * The #MMPco structure contains private data and should only be accessed + * using the provided API. + */ +struct _MMPco { + /*< private >*/ + GObject parent; + MMPcoPrivate *priv; +}; + +struct _MMPcoClass { + /*< private >*/ + GObjectClass parent; +}; + +GType mm_pco_get_type (void); + + +guint32 mm_pco_get_session_id (MMPco *self); +gboolean mm_pco_is_complete (MMPco *self); +const guint8 *mm_pco_get_data (MMPco *self, + gsize *data_size); + +/*****************************************************************************/ +/* ModemManager/libmm-glib/mmcli specific methods */ + +#if defined (_LIBMM_INSIDE_MM) || \ + defined (_LIBMM_INSIDE_MMCLI) || \ + defined (LIBMM_GLIB_COMPILATION) + +MMPco *mm_pco_new (void); +MMPco *mm_pco_from_variant (GVariant *variant, + GError **error); +GVariant *mm_pco_to_variant (MMPco *self); +void mm_pco_set_session_id (MMPco *self, + guint32 session_id); +void mm_pco_set_complete (MMPco *self, + gboolean is_complete); +void mm_pco_set_data (MMPco *self, + const guint8 *data, + gsize data_size); + +#endif + +G_END_DECLS + +#endif /* MM_PCO_H */ |