diff options
author | Dan Williams <dcbw@redhat.com> | 2017-02-06 20:53:39 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-10-16 17:09:21 +0000 |
commit | 627303a748cce7274b05a6861a1dc0c779d9263a (patch) | |
tree | 52acb186721f9c48ccf1c042e620a86a06a7265c | |
parent | 16162a5033593e017775eab640a3b9bf1b805c39 (diff) |
api/libmm-glib/cli: add AudioPort and AudioFormat properties to the Call object
-rw-r--r-- | cli/mmcli-call.c | 23 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 32 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Call.xml | 39 | ||||
-rw-r--r-- | libmm-glib/Makefile.am | 3 | ||||
-rw-r--r-- | libmm-glib/mm-call-audio-format.c | 276 | ||||
-rw-r--r-- | libmm-glib/mm-call-audio-format.h | 88 | ||||
-rw-r--r-- | libmm-glib/mm-call.c | 188 | ||||
-rw-r--r-- | libmm-glib/mm-call.h | 10 | ||||
-rw-r--r-- | src/mm-base-call.c | 15 | ||||
-rw-r--r-- | src/mm-base-call.h | 6 |
10 files changed, 678 insertions, 2 deletions
diff --git a/cli/mmcli-call.c b/cli/mmcli-call.c index 5991d073..09cf0871 100644 --- a/cli/mmcli-call.c +++ b/cli/mmcli-call.c @@ -145,6 +145,12 @@ mmcli_call_shutdown (void) static void print_call_info (MMCall *call) { + const gchar *audio_port; + MMCallAudioFormat *audio_format; + + audio_port = mm_call_get_audio_port (call); + audio_format = mm_call_peek_audio_format (call); + /* Not the best thing to do, as we may be doing _get() calls twice, but * easiest to maintain */ #undef VALIDATE @@ -161,6 +167,23 @@ print_call_info (MMCall *call) if (mm_call_get_state_reason(call) != MM_CALL_STATE_REASON_UNKNOWN) g_print (" | state reason: '%s'\n", mm_call_state_reason_get_string(mm_call_get_state_reason (call))); + + if (audio_port) + g_print (" | audio port: '%s'\n", VALIDATE (audio_port)); + + if (audio_format) { + guint rate = mm_call_audio_format_get_rate (audio_format); + gchar *rate_str = rate ? g_strdup_printf ("%u", rate) : NULL; + + g_print (" -------------------------\n" + " Audio Format | encoding: '%s'\n" + " | resolution: '%s'\n" + " | rate: '%s'\n", + VALIDATE (mm_call_audio_format_get_encoding (audio_format)), + VALIDATE (mm_call_audio_format_get_resolution (audio_format)), + VALIDATE (rate_str)); + g_free (rate_str); + } } static void diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index f41f4a7e..65d8e364 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -1257,6 +1257,10 @@ mm_call_dup_number mm_call_get_direction mm_call_get_state mm_call_get_state_reason +mm_call_get_audio_port +mm_call_dup_audio_port +mm_call_get_audio_format +mm_call_peek_audio_format <SUBSECTION Methods> mm_call_start mm_call_start_finish @@ -1342,6 +1346,34 @@ mm_pco_get_type </SECTION> <SECTION> +<FILE>mm-call-audio-format</FILE> +<TITLE>MMCallAudioFormat</TITLE> +MMCallAudioFormat +<SUBSECTION Getters> +mm_call_audio_format_get_encoding +mm_call_audio_format_get_resolution +mm_call_audio_format_get_rate +<SUBSECTION Private> +mm_call_audio_format_get_dictionary +mm_call_audio_format_new +mm_call_audio_format_new_from_dictionary +mm_call_audio_format_set_encoding +mm_call_audio_format_set_resolution +mm_call_audio_format_set_rate +mm_call_audio_format_dup +<SUBSECTION Standard> +MMCallAudioFormatClass +MMCallAudioFormatPrivate +MM_CALL_AUDIO_FORMAT +MM_CALL_AUDIO_FORMAT_CLASS +MM_CALL_AUDIO_FORMAT_GET_CLASS +MM_IS_CALL_AUDIO_FORMAT +MM_IS_CALL_AUDIO_FORMAT_CLASS +MM_TYPE_CALL_AUDIO_FORMAT +mm_call_audio_format_get_type +</SECTION> + +<SECTION> <FILE>mm-enums-types</FILE> <TITLE>Flags and Enumerations</TITLE> mm_bearer_ip_method_get_string diff --git a/introspection/org.freedesktop.ModemManager1.Call.xml b/introspection/org.freedesktop.ModemManager1.Call.xml index f095726b..f53f5b7b 100644 --- a/introspection/org.freedesktop.ModemManager1.Call.xml +++ b/introspection/org.freedesktop.ModemManager1.Call.xml @@ -111,5 +111,44 @@ The remote phone number. --> <property name="Number" type="s" access="read" /> + + <!-- + AudioPort: + + If call audio is routed via the host, the name of the kernel device that + provides the audio. For example, with certain Huawei USB modems, this + property might be "ttyUSB2" indicating audio is available via ttyUSB2 in + the format described by the AudioFormat property. + --> + <property name="AudioPort" type="s" access="read" /> + + <!-- + AudioFormat: + + If call audio is routed via the host, a description of the audio format + supported by the audio port. + + This property may include the following items: + <variablelist> + <varlistentry><term><literal>"encoding"</literal></term> + <listitem> + The audio encoding format. For example, "pcm" for PCM audio. + </listitem> + </varlistentry> + <varlistentry><term><literal>"resolution"</literal></term> + <listitem> + The sampling precision and its encoding format. For example, + "s16le" for signed 16-bit little-endian samples. + </listitem> + </varlistentry> + <varlistentry><term><literal>"rate"</literal></term> + <listitem> + The sampling rate as an unsigned integer. For example, 8000 for + 8000hz. + </listitem> + </varlistentry> + </variablelist> + --> + <property name="AudioFormat" type="a{sv}" access="read" /> </interface> </node> diff --git a/libmm-glib/Makefile.am b/libmm-glib/Makefile.am index 4c890592..0ebfd7e2 100644 --- a/libmm-glib/Makefile.am +++ b/libmm-glib/Makefile.am @@ -85,6 +85,8 @@ libmm_glib_la_SOURCES = \ mm-kernel-event-properties.c \ mm-pco.h \ mm-pco.c \ + mm-call-audio-format.h \ + mm-call-audio-format.c \ $(NULL) libmm_glib_la_CPPFLAGS = \ @@ -155,6 +157,7 @@ include_HEADERS = \ mm-signal.h \ mm-kernel-event-properties.h \ mm-pco.h \ + mm-call-audio-format.h \ $(NULL) CLEANFILES = diff --git a/libmm-glib/mm-call-audio-format.c b/libmm-glib/mm-call-audio-format.c new file mode 100644 index 00000000..a5e5126a --- /dev/null +++ b/libmm-glib/mm-call-audio-format.c @@ -0,0 +1,276 @@ +/* -*- 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 (C) 2017 Red Hat, Inc. + */ + +#include <string.h> + +#include "mm-errors-types.h" +#include "mm-call-audio-format.h" + +/** + * SECTION: mm-call-audio-format + * @title: MMCallAudioFormat + * @short_description: Helper object to handle voice call audio formats. + * + * The #MMCallAudioFormat is an object handling the voice call audio format + * which describes how to send/receive voice call audio from the host. + * + * This object is retrieved with either mm_call_get_audio_format() or + * mm_call_peek_audio_format(). + */ + +G_DEFINE_TYPE (MMCallAudioFormat, mm_call_audio_format, G_TYPE_OBJECT) + +#define PROPERTY_ENCODING "encoding" +#define PROPERTY_RESOLUTION "resolution" +#define PROPERTY_RATE "rate" + +struct _MMCallAudioFormatPrivate { + gchar *encoding; + gchar *resolution; + guint rate; +}; + +/*****************************************************************************/ + +/** + * mm_call_audio_format_get_encoding: + * @self: a #MMCallAudioFormat. + * + * Gets the encoding of the audio format. For example, "pcm" for PCM-encoded + * audio. + * + * Returns: a string with the encoding, or #NULL if unknown. Do not free the returned value, it is owned by @self. + */ +const gchar * +mm_call_audio_format_get_encoding (MMCallAudioFormat *self) +{ + g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), NULL); + + return self->priv->encoding; +} + +void +mm_call_audio_format_set_encoding (MMCallAudioFormat *self, + const gchar *encoding) +{ + g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self)); + + g_free (self->priv->encoding); + self->priv->encoding = g_strdup (encoding); +} + +/*****************************************************************************/ + +/** + * mm_call_audio_format_get_resolution: + * @self: a #MMCallAudioFormat. + * + * Gets the resolution of the audio format. For example, "s16le" for signed + * 16-bit little-endian audio sampling resolution. + * + * Returns: a string with the resolution, or #NULL if unknown. Do not free the returned value, it is owned by @self. + */ +const gchar * +mm_call_audio_format_get_resolution (MMCallAudioFormat *self) +{ + g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), NULL); + + return self->priv->resolution; +} + +void +mm_call_audio_format_set_resolution (MMCallAudioFormat *self, + const gchar *resolution) +{ + g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self)); + + g_free (self->priv->resolution); + self->priv->resolution = g_strdup (resolution); +} + +/*****************************************************************************/ + +/** + * mm_call_audio_format_get_rate: + * @self: a #MMCallAudioFormat. + * + * Gets the sampling rate of the audio format. For example, 8000 for an 8000hz + * sampling rate. + * + * Returns: the sampling rate, or 0 if unknown. + */ +guint +mm_call_audio_format_get_rate (MMCallAudioFormat *self) +{ + g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), 0); + + return self->priv->rate; +} + +void +mm_call_audio_format_set_rate (MMCallAudioFormat *self, + guint rate) +{ + g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self)); + + self->priv->rate = rate; +} + +/*****************************************************************************/ + +GVariant * +mm_call_audio_format_get_dictionary (MMCallAudioFormat *self) +{ + GVariantBuilder builder; + + /* We do allow NULL */ + if (!self) + return NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + if (self) { + if (self->priv->encoding) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_ENCODING, + g_variant_new_string (self->priv->encoding)); + + if (self->priv->resolution) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RESOLUTION, + g_variant_new_string (self->priv->resolution)); + + if (self->priv->rate) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RATE, + g_variant_new_uint32 (self->priv->rate)); + } + + return g_variant_builder_end (&builder); +} + +/*****************************************************************************/ + +MMCallAudioFormat * +mm_call_audio_format_new_from_dictionary (GVariant *dictionary, + GError **error) +{ + GVariantIter iter; + gchar *key; + GVariant *value; + MMCallAudioFormat *self; + + self = mm_call_audio_format_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 call audio format 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_ENCODING)) + mm_call_audio_format_set_encoding ( + self, + g_variant_get_string (value, NULL)); + else if (g_str_equal (key, PROPERTY_RESOLUTION)) + mm_call_audio_format_set_resolution ( + self, + g_variant_get_string (value, NULL)); + else if (g_str_equal (key, PROPERTY_RATE)) + mm_call_audio_format_set_rate ( + self, + g_variant_get_uint32 (value)); + + g_free (key); + g_variant_unref (value); + } + + return self; +} + +/*****************************************************************************/ + +/** + * mm_call_audio_format_dup: + * @orig: a #MMCallAudioFormat + * + * Creates a copy of @orig. + * + * Returns: (transfer full): a newly created #MMCallAudioFormat + */ +MMCallAudioFormat * +mm_call_audio_format_dup (MMCallAudioFormat *orig) +{ + GVariant *dict; + MMCallAudioFormat *copy; + GError *error = NULL; + + g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (orig), NULL); + + dict = mm_call_audio_format_get_dictionary (orig); + copy = mm_call_audio_format_new_from_dictionary (dict, &error); + g_assert_no_error (error); + g_variant_unref (dict); + + return copy; +} + +/*****************************************************************************/ + +MMCallAudioFormat * +mm_call_audio_format_new (void) +{ + return (MM_CALL_AUDIO_FORMAT ( + g_object_new (MM_TYPE_CALL_AUDIO_FORMAT, NULL))); +} + +static void +mm_call_audio_format_init (MMCallAudioFormat *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), + MM_TYPE_CALL_AUDIO_FORMAT, + MMCallAudioFormatPrivate); +} + +static void +finalize (GObject *object) +{ + MMCallAudioFormat *self = MM_CALL_AUDIO_FORMAT (object); + + g_free (self->priv->encoding); + g_free (self->priv->resolution); + + G_OBJECT_CLASS (mm_call_audio_format_parent_class)->finalize (object); +} + +static void +mm_call_audio_format_class_init (MMCallAudioFormatClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMCallAudioFormatPrivate)); + + object_class->finalize = finalize; +} diff --git a/libmm-glib/mm-call-audio-format.h b/libmm-glib/mm-call-audio-format.h new file mode 100644 index 00000000..f6da710a --- /dev/null +++ b/libmm-glib/mm-call-audio-format.h @@ -0,0 +1,88 @@ +/* -*- 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 (C) 2017 Red Hat, Inc. + */ + +#ifndef MM_CALL_AUDIO_FORMAT_H +#define MM_CALL_AUDIO_FORMAT_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_CALL_AUDIO_FORMAT (mm_call_audio_format_get_type ()) +#define MM_CALL_AUDIO_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormat)) +#define MM_CALL_AUDIO_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormatClass)) +#define MM_IS_CALL_AUDIO_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_CALL_AUDIO_FORMAT)) +#define MM_IS_CALL_AUDIO_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_CALL_AUDIO_FORMAT)) +#define MM_CALL_AUDIO_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormatClass)) + +typedef struct _MMCallAudioFormat MMCallAudioFormat; +typedef struct _MMCallAudioFormatClass MMCallAudioFormatClass; +typedef struct _MMCallAudioFormatPrivate MMCallAudioFormatPrivate; + +/** + * MMCallAudioFormat: + * + * The #MMCallAudioFormat structure contains private data and should + * only be accessed using the provided API. + */ +struct _MMCallAudioFormat { + /*< private >*/ + GObject parent; + MMCallAudioFormatPrivate *priv; +}; + +struct _MMCallAudioFormatClass { + /*< private >*/ + GObjectClass parent; +}; + +GType mm_call_audio_format_get_type (void); + +const gchar *mm_call_audio_format_get_encoding (MMCallAudioFormat *self); +const gchar *mm_call_audio_format_get_resolution (MMCallAudioFormat *self); +guint mm_call_audio_format_get_rate (MMCallAudioFormat *self); + +/*****************************************************************************/ +/* ModemManager/libmm-glib/mmcli specific methods */ + +#if defined (_LIBMM_INSIDE_MM) || \ + defined (_LIBMM_INSIDE_MMCLI) || \ + defined (LIBMM_GLIB_COMPILATION) + +MMCallAudioFormat *mm_call_audio_format_new (void); +MMCallAudioFormat *mm_call_audio_format_new_from_dictionary (GVariant *dictionary, + GError **error); + +MMCallAudioFormat *mm_call_audio_format_dup (MMCallAudioFormat *orig); + +void mm_call_audio_format_set_encoding (MMCallAudioFormat *self, + const gchar *encoding); +void mm_call_audio_format_set_resolution (MMCallAudioFormat *self, + const gchar *resolution); +void mm_call_audio_format_set_rate (MMCallAudioFormat *self, + guint rate); + +GVariant *mm_call_audio_format_get_dictionary (MMCallAudioFormat *self); + +#endif + +G_END_DECLS + +#endif /* MM_CALL_AUDIO_FORMAT_H */ diff --git a/libmm-glib/mm-call.c b/libmm-glib/mm-call.c index 92689f85..af1d8f12 100644 --- a/libmm-glib/mm-call.c +++ b/libmm-glib/mm-call.c @@ -36,6 +36,13 @@ G_DEFINE_TYPE (MMCall, mm_call, MM_GDBUS_TYPE_CALL_PROXY) +struct _MMCallPrivate { + /* Audio Format */ + GMutex audio_format_mutex; + guint audio_format_id; + MMCallAudioFormat *audio_format; +}; + /*****************************************************************************/ /** @@ -177,6 +184,156 @@ mm_call_get_state_reason (MMCall *self) /*****************************************************************************/ /** + * mm_call_get_audio_port: + * @self: A #MMCall. + * + * Gets the kernel device used for audio (if any). + * + * Returns: (transfer none): The audio port, or %NULL if call audio is not + * routed via the host or couldn't be retrieved. + */ +const gchar * +mm_call_get_audio_port (MMCall *self) +{ + g_return_val_if_fail (MM_IS_CALL (self), NULL); + + RETURN_NON_EMPTY_CONSTANT_STRING ( + mm_gdbus_call_get_audio_port (MM_GDBUS_CALL (self))); +} + +/** + * mm_call_dup_audio_port: + * @self: A #MMCall. + * + * Gets the kernel device used for audio (if any). + * + * Returns: (transfer full): The audio port, or %NULL if call audio is not + * routed via the host or couldn't be retrieved. + */ +gchar * +mm_call_dup_audio_port (MMCall *self) +{ + g_return_val_if_fail (MM_IS_CALL (self), NULL); + + RETURN_NON_EMPTY_STRING ( + mm_gdbus_call_dup_audio_port (MM_GDBUS_CALL (self))); +} + +/*****************************************************************************/ + +static void +audio_format_updated (MMCall *self, + GParamSpec *pspec) +{ + g_mutex_lock (&self->priv->audio_format_mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->audio_format); + + /* TODO: update existing object instead of re-creating? */ + dictionary = mm_gdbus_call_get_audio_format (MM_GDBUS_CALL (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->audio_format = mm_call_audio_format_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid audio format update received: %s", error->message); + g_error_free (error); + } + } + } + g_mutex_unlock (&self->priv->audio_format_mutex); +} + +static void +ensure_internal_audio_format (MMCall *self, + MMCallAudioFormat **dup) +{ + g_mutex_lock (&self->priv->audio_format_mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->audio_format_id) { + GVariant *dictionary; + + dictionary = mm_gdbus_call_dup_audio_format (MM_GDBUS_CALL (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->audio_format = mm_call_audio_format_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid initial audio format: %s", error->message); + g_error_free (error); + } + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->audio_format_id = + g_signal_connect (self, + "notify::audio-format", + G_CALLBACK (audio_format_updated), + NULL); + } + + if (dup && self->priv->audio_format) + *dup = g_object_ref (self->priv->audio_format); + } + g_mutex_unlock (&self->priv->audio_format_mutex); +} + +/** + * mm_call_get_audio_format: + * @self: A #MMCall. + * + * Gets a #MMCallAudioFormat object specifying the audio format used by the + * audio port if call audio is routed via the host. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_call_get_audio_format() again to get a new #MMCallAudioFormat with the + * new values.</warning> + * + * Returns: (transfer full): A #MMCallAudioFormat that must be freed with g_object_unref() or %NULL if unknown. + */ +MMCallAudioFormat * +mm_call_get_audio_format (MMCall *self) +{ + MMCallAudioFormat *format = NULL; + + g_return_val_if_fail (MM_IS_CALL (self), NULL); + + ensure_internal_audio_format (self, &format); + return format; +} + +/** + * mm_call_peek_audio_format: + * @self: A #MMCall. + * + * Gets a #MMCallAudioFormat object specifying the audio format used by the + * audio port if call audio is routed via the host. + * + * <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_call_get_audio_format() if on another + * thread.</warning> + * + * Returns: (transfer none): A #MMCallAudioFormat. Do not free the returned value, it belongs to @self. + */ +MMCallAudioFormat * +mm_call_peek_audio_format (MMCall *self) +{ + g_return_val_if_fail (MM_IS_CALL (self), NULL); + + ensure_internal_audio_format (self, NULL); + return self->priv->audio_format; +} + +/*****************************************************************************/ + +/** * mm_call_start_finish: * @self: A #MMCall. * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_call_start(). @@ -500,9 +657,40 @@ mm_call_send_dtmf_sync (MMCall *self, static void mm_call_init (MMCall *self) { + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_CALL, + MMCallPrivate); + g_mutex_init (&self->priv->audio_format_mutex); +} + +static void +finalize (GObject *object) +{ + MMCall *self = MM_CALL (object); + + g_mutex_clear (&self->priv->audio_format_mutex); + + G_OBJECT_CLASS (mm_call_parent_class)->finalize (object); +} + +static void +dispose (GObject *object) +{ + MMCall *self = MM_CALL (object); + + g_clear_object (&self->priv->audio_format); + + G_OBJECT_CLASS (mm_call_parent_class)->dispose (object); } static void mm_call_class_init (MMCallClass *call_class) { + GObjectClass *object_class = G_OBJECT_CLASS (call_class); + + g_type_class_add_private (object_class, sizeof (MMCallPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; } diff --git a/libmm-glib/mm-call.h b/libmm-glib/mm-call.h index a5aeb730..baf51cc4 100644 --- a/libmm-glib/mm-call.h +++ b/libmm-glib/mm-call.h @@ -26,7 +26,7 @@ #include <ModemManager.h> #include "mm-gdbus-call.h" -#include "mm-call-properties.h" +#include "mm-call-audio-format.h" G_BEGIN_DECLS @@ -39,6 +39,7 @@ G_BEGIN_DECLS typedef struct _MMCall MMCall; typedef struct _MMCallClass MMCallClass; +typedef struct _MMCallPrivate MMCallPrivate; /** * MMCall: @@ -49,7 +50,7 @@ typedef struct _MMCallClass MMCallClass; struct _MMCall { /*< private >*/ MmGdbusCallProxy parent; - gpointer unused; + MMCallPrivate *priv; }; struct _MMCallClass { @@ -71,6 +72,11 @@ MMCallStateReason mm_call_get_state_reason (MMCall *self); MMCallDirection mm_call_get_direction (MMCall *self); +const gchar *mm_call_get_audio_port (MMCall *self); +gchar *mm_call_dup_audio_port (MMCall *self); + +MMCallAudioFormat *mm_call_get_audio_format (MMCall *self); +MMCallAudioFormat *mm_call_peek_audio_format(MMCall *self); void mm_call_start (MMCall *self, diff --git a/src/mm-base-call.c b/src/mm-base-call.c index c0fada6e..5637ddcf 100644 --- a/src/mm-base-call.c +++ b/src/mm-base-call.c @@ -724,6 +724,21 @@ mm_base_call_received_dtmf (MMBaseCall *self, mm_gdbus_call_emit_dtmf_received (MM_GDBUS_CALL (self), dtmf); } +void +mm_base_call_set_audio_port (MMBaseCall *self, const gchar *port) +{ + mm_gdbus_call_set_audio_port (MM_GDBUS_CALL (self), port); +} + +void +mm_base_call_set_audio_format (MMBaseCall *self, + MMCallAudioFormat *audio_format) +{ + mm_gdbus_call_set_audio_format ( + MM_GDBUS_CALL (self), + mm_call_audio_format_get_dictionary (audio_format)); +} + /*****************************************************************************/ /* Start the CALL */ diff --git a/src/mm-base-call.h b/src/mm-base-call.h index 0ef3ffcf..f68e9f6b 100644 --- a/src/mm-base-call.h +++ b/src/mm-base-call.h @@ -23,6 +23,7 @@ #include <libmm-glib.h> #include "mm-base-modem.h" +#include "mm-call-audio-format.h" #define MM_TYPE_BASE_CALL (mm_base_call_get_type ()) #define MM_BASE_CALL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BASE_CALL, MMBaseCall)) @@ -104,6 +105,11 @@ void mm_base_call_change_state (MMBaseCall *self, MMCallState new_state, MMCallStateReason reason); +void mm_base_call_set_audio_port (MMBaseCall *self, + const gchar *port); +void mm_base_call_set_audio_format (MMBaseCall *self, + MMCallAudioFormat *audio_format); + void mm_base_call_received_dtmf (MMBaseCall *self, const gchar *dtmf); |