api/libmm-glib/cli: add AudioPort and AudioFormat properties to the Call object

This commit is contained in:
Dan Williams
2017-02-06 20:53:39 -06:00
parent 16162a5033
commit 627303a748
10 changed files with 678 additions and 2 deletions

View File

@@ -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

View File

@@ -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
@@ -1341,6 +1345,34 @@ MM_TYPE_PCO
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>

View File

@@ -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>

View File

@@ -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 =

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
};
/*****************************************************************************/
/**
@@ -176,6 +183,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.
@@ -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;
}

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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);