api,voice: new HangupAll() method
This method will terminate all ongoing calls.
This commit is contained in:
@@ -52,6 +52,7 @@ static gchar *create_str;
|
|||||||
static gchar *delete_str;
|
static gchar *delete_str;
|
||||||
static gboolean hold_and_accept_flag;
|
static gboolean hold_and_accept_flag;
|
||||||
static gboolean hangup_and_accept_flag;
|
static gboolean hangup_and_accept_flag;
|
||||||
|
static gboolean hangup_all_flag;
|
||||||
|
|
||||||
static GOptionEntry entries[] = {
|
static GOptionEntry entries[] = {
|
||||||
{ "voice-list-calls", 0, 0, G_OPTION_ARG_NONE, &list_flag,
|
{ "voice-list-calls", 0, 0, G_OPTION_ARG_NONE, &list_flag,
|
||||||
@@ -74,6 +75,10 @@ static GOptionEntry entries[] = {
|
|||||||
"Hangs up all active calls and accepts the next waiting or held call",
|
"Hangs up all active calls and accepts the next waiting or held call",
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
|
{ "voice-hangup-all", 0, 0, G_OPTION_ARG_NONE, &hangup_all_flag,
|
||||||
|
"Hangs up all ongoing (active, waiting, held) calls",
|
||||||
|
NULL
|
||||||
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +110,8 @@ mmcli_modem_voice_options_enabled (void)
|
|||||||
!!create_str +
|
!!create_str +
|
||||||
!!delete_str +
|
!!delete_str +
|
||||||
hold_and_accept_flag +
|
hold_and_accept_flag +
|
||||||
hangup_and_accept_flag);
|
hangup_and_accept_flag +
|
||||||
|
hangup_all_flag);
|
||||||
|
|
||||||
if (n_actions > 1) {
|
if (n_actions > 1) {
|
||||||
g_printerr ("error: too many Voice actions requested\n");
|
g_printerr ("error: too many Voice actions requested\n");
|
||||||
@@ -187,6 +193,31 @@ output_call_info (MMCall *call)
|
|||||||
g_free (extra);
|
g_free (extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hangup_all_process_reply (const GError *error)
|
||||||
|
{
|
||||||
|
if (error) {
|
||||||
|
g_printerr ("error: couldn't hangup all: '%s'\n",
|
||||||
|
error->message);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("operation successful\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hangup_all_ready (MMModemVoice *modem,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer nothing)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
mm_modem_voice_hangup_all_finish (modem, result, &error);
|
||||||
|
hangup_all_process_reply (error);
|
||||||
|
|
||||||
|
mmcli_async_operation_done ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hangup_and_accept_process_reply (const GError *error)
|
hangup_and_accept_process_reply (const GError *error)
|
||||||
{
|
{
|
||||||
@@ -416,6 +447,16 @@ get_modem_ready (GObject *source,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Request to hangup all? */
|
||||||
|
if (hangup_all_flag) {
|
||||||
|
g_debug ("Asynchronously hanging up all calls...");
|
||||||
|
mm_modem_voice_hangup_all (ctx->modem_voice,
|
||||||
|
ctx->cancellable,
|
||||||
|
(GAsyncReadyCallback)hangup_all_ready,
|
||||||
|
NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,5 +569,13 @@ mmcli_modem_voice_run_synchronous (GDBusConnection *connection)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Request to hangup all? */
|
||||||
|
if (hangup_all_flag) {
|
||||||
|
g_debug ("Synchronously hanging up all calls...");
|
||||||
|
mm_modem_voice_hangup_all_sync (ctx->modem_voice, NULL, &error);
|
||||||
|
hangup_all_process_reply (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
|
@@ -1018,6 +1018,9 @@ mm_modem_voice_hangup_and_accept_sync
|
|||||||
mm_modem_voice_hold_and_accept
|
mm_modem_voice_hold_and_accept
|
||||||
mm_modem_voice_hold_and_accept_finish
|
mm_modem_voice_hold_and_accept_finish
|
||||||
mm_modem_voice_hold_and_accept_sync
|
mm_modem_voice_hold_and_accept_sync
|
||||||
|
mm_modem_voice_hangup_all
|
||||||
|
mm_modem_voice_hangup_all_finish
|
||||||
|
mm_modem_voice_hangup_all_sync
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
MMModemVoiceClass
|
MMModemVoiceClass
|
||||||
MMModemVoicePrivate
|
MMModemVoicePrivate
|
||||||
@@ -2847,6 +2850,9 @@ mm_gdbus_modem_voice_call_hangup_and_accept_sync
|
|||||||
mm_gdbus_modem_voice_call_hold_and_accept
|
mm_gdbus_modem_voice_call_hold_and_accept
|
||||||
mm_gdbus_modem_voice_call_hold_and_accept_finish
|
mm_gdbus_modem_voice_call_hold_and_accept_finish
|
||||||
mm_gdbus_modem_voice_call_hold_and_accept_sync
|
mm_gdbus_modem_voice_call_hold_and_accept_sync
|
||||||
|
mm_gdbus_modem_voice_call_hangup_all
|
||||||
|
mm_gdbus_modem_voice_call_hangup_all_finish
|
||||||
|
mm_gdbus_modem_voice_call_hangup_all_sync
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
mm_gdbus_modem_voice_set_calls
|
mm_gdbus_modem_voice_set_calls
|
||||||
mm_gdbus_modem_voice_emit_call_added
|
mm_gdbus_modem_voice_emit_call_added
|
||||||
@@ -2856,6 +2862,7 @@ mm_gdbus_modem_voice_complete_delete_call
|
|||||||
mm_gdbus_modem_voice_complete_list_calls
|
mm_gdbus_modem_voice_complete_list_calls
|
||||||
mm_gdbus_modem_voice_complete_hangup_and_accept
|
mm_gdbus_modem_voice_complete_hangup_and_accept
|
||||||
mm_gdbus_modem_voice_complete_hold_and_accept
|
mm_gdbus_modem_voice_complete_hold_and_accept
|
||||||
|
mm_gdbus_modem_voice_complete_hangup_all
|
||||||
mm_gdbus_modem_voice_interface_info
|
mm_gdbus_modem_voice_interface_info
|
||||||
mm_gdbus_modem_voice_override_properties
|
mm_gdbus_modem_voice_override_properties
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
|
@@ -99,6 +99,18 @@
|
|||||||
-->
|
-->
|
||||||
<method name="HangupAndAccept" />
|
<method name="HangupAndAccept" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
HangupAll:
|
||||||
|
|
||||||
|
Hangup all active calls.
|
||||||
|
|
||||||
|
Depending on how the device implements the action, calls on
|
||||||
|
hold or in waiting state may also be terminated.
|
||||||
|
|
||||||
|
No error is returned if there are no ongoing calls.
|
||||||
|
-->
|
||||||
|
<method name="HangupAll" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
CallAdded:
|
CallAdded:
|
||||||
@path: Object path of the new call.
|
@path: Object path of the new call.
|
||||||
|
@@ -690,6 +690,85 @@ mm_modem_voice_hangup_and_accept_sync (MMModemVoice *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mm_modem_voice_hangup_all_finish:
|
||||||
|
* @self: A #MMModemVoice.
|
||||||
|
* @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_voice_hangup_all().
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Finishes an operation started with mm_modem_voice_hangup_all().
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the operation was successful, %FALSE if @error is set.
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
mm_modem_voice_hangup_all_finish (MMModemVoice *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||||
|
|
||||||
|
return mm_gdbus_modem_voice_call_hangup_all_finish (MM_GDBUS_MODEM_VOICE (self), res, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mm_modem_voice_hangup_all:
|
||||||
|
* @self: A #MMModemVoice.
|
||||||
|
* @cancellable: (allow-none): A #GCancellable or %NULL.
|
||||||
|
* @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
|
||||||
|
* @user_data: User data to pass to @callback.
|
||||||
|
*
|
||||||
|
* Asynchronously hangs up all ongoing (active, waiting, held) calls.
|
||||||
|
*
|
||||||
|
* When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
|
||||||
|
* You can then call mm_modem_voice_hangup_all_finish() to get the result of the operation.
|
||||||
|
*
|
||||||
|
* See mm_modem_voice_hangup_all_sync() for the synchronous, blocking version of this method.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mm_modem_voice_hangup_all (MMModemVoice *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_return_if_fail (MM_IS_MODEM_VOICE (self));
|
||||||
|
|
||||||
|
mm_gdbus_modem_voice_call_hangup_all (MM_GDBUS_MODEM_VOICE (self),
|
||||||
|
cancellable,
|
||||||
|
callback,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mm_modem_voice_hangup_all_sync:
|
||||||
|
* @self: A #MMModemVoice.
|
||||||
|
* @cancellable: (allow-none): A #GCancellable or %NULL.
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Synchronously hangs up all ongoing (active, waiting, held) calls.
|
||||||
|
*
|
||||||
|
* The calling thread is blocked until a reply is received. See mm_modem_voice_hangup_all()
|
||||||
|
* for the asynchronous version of this method.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the operation was successful, %FALSE if @error is set.
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
mm_modem_voice_hangup_all_sync (MMModemVoice *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||||
|
|
||||||
|
return mm_gdbus_modem_voice_call_hangup_all_sync (MM_GDBUS_MODEM_VOICE (self),
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_modem_voice_init (MMModemVoice *self)
|
mm_modem_voice_init (MMModemVoice *self)
|
||||||
{
|
{
|
||||||
|
@@ -132,6 +132,17 @@ gboolean mm_modem_voice_hangup_and_accept_sync (MMModemVoice *self,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
void mm_modem_voice_hangup_all (MMModemVoice *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
gboolean mm_modem_voice_hangup_all_finish (MMModemVoice *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
|
gboolean mm_modem_voice_hangup_all_sync (MMModemVoice *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* _MM_MODEM_VOICE_H_ */
|
#endif /* _MM_MODEM_VOICE_H_ */
|
||||||
|
@@ -826,6 +826,161 @@ handle_hangup_and_accept (MmGdbusModemVoice *skeleton,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MmGdbusModemVoice *skeleton;
|
||||||
|
GDBusMethodInvocation *invocation;
|
||||||
|
MMIfaceModemVoice *self;
|
||||||
|
GList *calls;
|
||||||
|
} HandleHangupAllContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_hangup_all_context_free (HandleHangupAllContext *ctx)
|
||||||
|
{
|
||||||
|
g_list_free_full (ctx->calls, g_object_unref);
|
||||||
|
g_object_unref (ctx->skeleton);
|
||||||
|
g_object_unref (ctx->invocation);
|
||||||
|
g_object_unref (ctx->self);
|
||||||
|
g_slice_free (HandleHangupAllContext, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hangup_all_ready (MMIfaceModemVoice *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
HandleHangupAllContext *ctx)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->hangup_all_finish (self, res, &error)) {
|
||||||
|
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = ctx->calls; l; l = g_list_next (l))
|
||||||
|
mm_base_call_change_state (MM_BASE_CALL (l->data), MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_TERMINATED);
|
||||||
|
|
||||||
|
mm_gdbus_modem_voice_complete_hangup_all (ctx->skeleton, ctx->invocation);
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_hangup_all_foreach (MMBaseCall *call,
|
||||||
|
HandleHangupAllContext *ctx)
|
||||||
|
{
|
||||||
|
/* The implementation of this operation will usually be done with +CHUP, and we
|
||||||
|
* know that +CHUP is implemented in different ways by different manufacturers.
|
||||||
|
*
|
||||||
|
* The 3GPP TS27.007 spec for +CHUP states that the "Execution command causes
|
||||||
|
* the TA to hangup the current call of the MT." This sentence leaves a bit of open
|
||||||
|
* interpretation to the implementors, because a current call can be considered only
|
||||||
|
* the active ones, or otherwise any call (active, held or waiting).
|
||||||
|
*
|
||||||
|
* And so, the u-blox TOBY-L4 takes one interpretation and "In case of multiple
|
||||||
|
* calls, all active calls will be released, while waiting and held calls are not".
|
||||||
|
*
|
||||||
|
* And the Cinterion PLS-8 takes a different interpretation and cancels all calls,
|
||||||
|
* including the waiting and held ones.
|
||||||
|
*
|
||||||
|
* In this logic, we're going to terminate exclusively the ACTIVE calls only, and we
|
||||||
|
* will leave the possible termination of waiting/held calls to be reported via
|
||||||
|
* call state updates, e.g. +CLCC polling or other plugin-specific method. In the
|
||||||
|
* case of the Cinterion PLS-8, we'll detect the termination of the waiting and
|
||||||
|
* held calls via ^SLCC URCs.
|
||||||
|
*/
|
||||||
|
switch (mm_base_call_get_state (call)) {
|
||||||
|
case MM_CALL_STATE_DIALING:
|
||||||
|
case MM_CALL_STATE_RINGING_OUT:
|
||||||
|
case MM_CALL_STATE_RINGING_IN:
|
||||||
|
case MM_CALL_STATE_ACTIVE:
|
||||||
|
ctx->calls = g_list_append (ctx->calls, g_object_ref (call));
|
||||||
|
break;
|
||||||
|
case MM_CALL_STATE_WAITING:
|
||||||
|
case MM_CALL_STATE_HELD:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_hangup_all_auth_ready (MMBaseModem *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
HandleHangupAllContext *ctx)
|
||||||
|
{
|
||||||
|
MMModemState modem_state = MM_MODEM_STATE_UNKNOWN;
|
||||||
|
GError *error = NULL;
|
||||||
|
MMCallList *list = NULL;
|
||||||
|
|
||||||
|
if (!mm_base_modem_authorize_finish (self, res, &error)) {
|
||||||
|
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (self,
|
||||||
|
MM_IFACE_MODEM_STATE, &modem_state,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (modem_state < MM_MODEM_STATE_ENABLED) {
|
||||||
|
g_dbus_method_invocation_return_error (ctx->invocation,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_WRONG_STATE,
|
||||||
|
"Cannot hangup all: device not yet enabled");
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->hangup_all ||
|
||||||
|
!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->hangup_all_finish) {
|
||||||
|
g_dbus_method_invocation_return_error (ctx->invocation,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_UNSUPPORTED,
|
||||||
|
"Cannot hangup all: unsupported");
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (self,
|
||||||
|
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
|
||||||
|
NULL);
|
||||||
|
if (!list) {
|
||||||
|
g_dbus_method_invocation_return_error (ctx->invocation,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_WRONG_STATE,
|
||||||
|
"Cannot hangup all: missing call list");
|
||||||
|
handle_hangup_all_context_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mm_call_list_foreach (list, (MMCallListForeachFunc)prepare_hangup_all_foreach, ctx);
|
||||||
|
g_object_unref (list);
|
||||||
|
|
||||||
|
MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->hangup_all (MM_IFACE_MODEM_VOICE (self),
|
||||||
|
(GAsyncReadyCallback)hangup_all_ready,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_hangup_all (MmGdbusModemVoice *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
MMIfaceModemVoice *self)
|
||||||
|
{
|
||||||
|
HandleHangupAllContext *ctx;
|
||||||
|
|
||||||
|
ctx = g_slice_new0 (HandleHangupAllContext);
|
||||||
|
ctx->skeleton = g_object_ref (skeleton);
|
||||||
|
ctx->invocation = g_object_ref (invocation);
|
||||||
|
ctx->self = g_object_ref (self);
|
||||||
|
|
||||||
|
mm_base_modem_authorize (MM_BASE_MODEM (self),
|
||||||
|
invocation,
|
||||||
|
MM_AUTHORIZATION_VOICE,
|
||||||
|
(GAsyncReadyCallback)handle_hangup_all_auth_ready,
|
||||||
|
ctx);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Call list polling logic
|
/* Call list polling logic
|
||||||
*
|
*
|
||||||
@@ -1516,6 +1671,10 @@ interface_initialization_step (GTask *task)
|
|||||||
"handle-hold-and-accept",
|
"handle-hold-and-accept",
|
||||||
G_CALLBACK (handle_hold_and_accept),
|
G_CALLBACK (handle_hold_and_accept),
|
||||||
self);
|
self);
|
||||||
|
g_signal_connect (ctx->skeleton,
|
||||||
|
"handle-hangup-all",
|
||||||
|
G_CALLBACK (handle_hangup_all),
|
||||||
|
self);
|
||||||
|
|
||||||
/* Finally, export the new interface */
|
/* Finally, export the new interface */
|
||||||
mm_gdbus_object_skeleton_set_modem_voice (MM_GDBUS_OBJECT_SKELETON (self),
|
mm_gdbus_object_skeleton_set_modem_voice (MM_GDBUS_OBJECT_SKELETON (self),
|
||||||
|
@@ -107,6 +107,14 @@ struct _MMIfaceModemVoice {
|
|||||||
gboolean (* hangup_and_accept_finish) (MMIfaceModemVoice *self,
|
gboolean (* hangup_and_accept_finish) (MMIfaceModemVoice *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/* Hangup all */
|
||||||
|
void (* hangup_all) (MMIfaceModemVoice *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
gboolean (* hangup_all_finish) (MMIfaceModemVoice *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType mm_iface_modem_voice_get_type (void);
|
GType mm_iface_modem_voice_get_type (void);
|
||||||
|
Reference in New Issue
Block a user