api,voice: new CallWaitingSetup() and CallWaitingQuery() methods
These new methods allow querying and updating the status of the call waiting network service, as per 3GPP TS 22.083. The status of the service is not a property because we don't want to unconditionally load it on every boot, given that the process involves talking to the network (i.e. it is not a device setting).
This commit is contained in:
@@ -54,6 +54,9 @@ static gboolean hold_and_accept_flag;
|
||||
static gboolean hangup_and_accept_flag;
|
||||
static gboolean hangup_all_flag;
|
||||
static gboolean transfer_flag;
|
||||
static gboolean call_waiting_enable_flag;
|
||||
static gboolean call_waiting_disable_flag;
|
||||
static gboolean call_waiting_query_flag;
|
||||
|
||||
static GOptionEntry entries[] = {
|
||||
{ "voice-list-calls", 0, 0, G_OPTION_ARG_NONE, &list_flag,
|
||||
@@ -84,6 +87,18 @@ static GOptionEntry entries[] = {
|
||||
"Joins active and held calls and disconnects from them",
|
||||
NULL
|
||||
},
|
||||
{ "voice-enable-call-waiting", 0, 0, G_OPTION_ARG_NONE, &call_waiting_enable_flag,
|
||||
"Enables the call waiting network service",
|
||||
NULL
|
||||
},
|
||||
{ "voice-disable-call-waiting", 0, 0, G_OPTION_ARG_NONE, &call_waiting_disable_flag,
|
||||
"Disables the call waiting network service",
|
||||
NULL
|
||||
},
|
||||
{ "voice-query-call-waiting", 0, 0, G_OPTION_ARG_NONE, &call_waiting_query_flag,
|
||||
"Queries the status of the call waiting network service",
|
||||
NULL
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -117,7 +132,10 @@ mmcli_modem_voice_options_enabled (void)
|
||||
hold_and_accept_flag +
|
||||
hangup_and_accept_flag +
|
||||
hangup_all_flag +
|
||||
transfer_flag);
|
||||
transfer_flag +
|
||||
call_waiting_enable_flag +
|
||||
call_waiting_disable_flag +
|
||||
call_waiting_query_flag);
|
||||
|
||||
if (n_actions > 1) {
|
||||
g_printerr ("error: too many Voice actions requested\n");
|
||||
@@ -199,6 +217,58 @@ output_call_info (MMCall *call)
|
||||
g_free (extra);
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_query_process_reply (const GError *error,
|
||||
gboolean status)
|
||||
{
|
||||
if (error) {
|
||||
g_printerr ("error: couldn't query call waiting network service status: '%s'\n",
|
||||
error->message);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_print ("call waiting service is %s\n", status ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_query_ready (MMModemVoice *modem,
|
||||
GAsyncResult *result,
|
||||
gpointer nothing)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean status = FALSE;
|
||||
|
||||
mm_modem_voice_call_waiting_query_finish (modem, result, &status, &error);
|
||||
call_waiting_query_process_reply (error, status);
|
||||
|
||||
mmcli_async_operation_done ();
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_setup_process_reply (const GError *error)
|
||||
{
|
||||
if (error) {
|
||||
g_printerr ("error: couldn't setup call waiting network service: '%s'\n",
|
||||
error->message);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_print ("operation successful\n");
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_setup_ready (MMModemVoice *modem,
|
||||
GAsyncResult *result,
|
||||
gpointer nothing)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
mm_modem_voice_call_waiting_setup_finish (modem, result, &error);
|
||||
call_waiting_setup_process_reply (error);
|
||||
|
||||
mmcli_async_operation_done ();
|
||||
}
|
||||
|
||||
static void
|
||||
transfer_process_reply (const GError *error)
|
||||
{
|
||||
@@ -498,6 +568,38 @@ get_modem_ready (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to enable call waiting? */
|
||||
if (call_waiting_enable_flag) {
|
||||
g_debug ("Asynchronously enabling call waiting...");
|
||||
mm_modem_voice_call_waiting_setup (ctx->modem_voice,
|
||||
TRUE,
|
||||
ctx->cancellable,
|
||||
(GAsyncReadyCallback)call_waiting_setup_ready,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to disable call waiting? */
|
||||
if (call_waiting_disable_flag) {
|
||||
g_debug ("Asynchronously enabling call waiting...");
|
||||
mm_modem_voice_call_waiting_setup (ctx->modem_voice,
|
||||
FALSE,
|
||||
ctx->cancellable,
|
||||
(GAsyncReadyCallback)call_waiting_setup_ready,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to query call waiting? */
|
||||
if (call_waiting_query_flag) {
|
||||
g_debug ("Asynchronously querying call waiting status...");
|
||||
mm_modem_voice_call_waiting_query (ctx->modem_voice,
|
||||
ctx->cancellable,
|
||||
(GAsyncReadyCallback)call_waiting_query_ready,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
|
||||
@@ -626,5 +728,31 @@ mmcli_modem_voice_run_synchronous (GDBusConnection *connection)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to enable call waiting? */
|
||||
if (call_waiting_enable_flag) {
|
||||
g_debug ("Synchronously enabling call waiting...");
|
||||
mm_modem_voice_call_waiting_setup_sync (ctx->modem_voice, TRUE, NULL, &error);
|
||||
call_waiting_setup_process_reply (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to disable call waiting? */
|
||||
if (call_waiting_disable_flag) {
|
||||
g_debug ("Synchronously disabling call waiting...");
|
||||
mm_modem_voice_call_waiting_setup_sync (ctx->modem_voice, FALSE, NULL, &error);
|
||||
call_waiting_setup_process_reply (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request to query call waiting? */
|
||||
if (call_waiting_query_flag) {
|
||||
gboolean status = FALSE;
|
||||
|
||||
g_debug ("Synchronously querying call waiting status...");
|
||||
mm_modem_voice_call_waiting_query_sync (ctx->modem_voice, NULL, &status, &error);
|
||||
call_waiting_query_process_reply (error, status);
|
||||
return;
|
||||
}
|
||||
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
|
@@ -123,6 +123,32 @@
|
||||
-->
|
||||
<method name="Transfer" />
|
||||
|
||||
<!--
|
||||
CallWaitingSetup:
|
||||
|
||||
Activates or deactivates the call waiting network service, as per
|
||||
3GPP TS 22.083.
|
||||
|
||||
This operation requires communication with the network in order to
|
||||
complete, so the modem must be successfully registered.
|
||||
-->
|
||||
<method name="CallWaitingSetup">
|
||||
<arg name="enable" type="b" direction="in" />
|
||||
</method>
|
||||
|
||||
<!--
|
||||
CallWaitingQuery:
|
||||
|
||||
Queries the status of the call waiting network service, as per
|
||||
3GPP TS 22.083.
|
||||
|
||||
This operation requires communication with the network in order to
|
||||
complete, so the modem must be successfully registered.
|
||||
-->
|
||||
<method name="CallWaitingQuery">
|
||||
<arg name="status" type="b" direction="out" />
|
||||
</method>
|
||||
|
||||
<!--
|
||||
CallAdded:
|
||||
@path: Object path of the new call.
|
||||
|
@@ -848,6 +848,175 @@ mm_modem_voice_transfer_sync (MMModemVoice *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_setup_finish:
|
||||
* @self: A #MMModemVoice.
|
||||
* @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_voice_call_waiting_setup().
|
||||
* @error: Return location for error or %NULL.
|
||||
*
|
||||
* Finishes an operation started with mm_modem_voice_call_waiting_setup().
|
||||
*
|
||||
* Returns: %TRUE if @status is set, %FALSE if @error is set.
|
||||
* Since: 1.12
|
||||
*/
|
||||
gboolean
|
||||
mm_modem_voice_call_waiting_setup_finish (MMModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||
|
||||
return mm_gdbus_modem_voice_call_call_waiting_setup_finish (MM_GDBUS_MODEM_VOICE (self), res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_setup:
|
||||
* @self: A #MMModemVoice.
|
||||
* @enable: Whether the call waiting service should be enabled.
|
||||
* @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 enables or disables the call waiting network service.
|
||||
*
|
||||
* 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_call_waiting_setup_finish() to get the result of the operation.
|
||||
*
|
||||
* See mm_modem_voice_call_waiting_setup_sync() for the synchronous, blocking version of this method.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
void
|
||||
mm_modem_voice_call_waiting_setup (MMModemVoice *self,
|
||||
gboolean enable,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (MM_IS_MODEM_VOICE (self));
|
||||
|
||||
mm_gdbus_modem_voice_call_call_waiting_setup (MM_GDBUS_MODEM_VOICE (self),
|
||||
enable,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_setup_sync:
|
||||
* @self: A #MMModemVoice.
|
||||
* @enable: Whether the call waiting service should be enabled.
|
||||
* @cancellable: (allow-none): A #GCancellable or %NULL.
|
||||
* @error: Return location for error or %NULL.
|
||||
*
|
||||
* Synchronously enables or disables the call waiting network service.
|
||||
*
|
||||
* The calling thread is blocked until a reply is received. See mm_modem_voice_call_waiting_setup()
|
||||
* for the asynchronous version of this method.
|
||||
*
|
||||
* Returns: %TRUE if the operation is successful, %FALSE if @error is set.
|
||||
* Since: 1.12
|
||||
*/
|
||||
gboolean
|
||||
mm_modem_voice_call_waiting_setup_sync (MMModemVoice *self,
|
||||
gboolean enable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||
|
||||
return mm_gdbus_modem_voice_call_call_waiting_setup_sync (MM_GDBUS_MODEM_VOICE (self),
|
||||
enable,
|
||||
cancellable,
|
||||
error);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_query_finish:
|
||||
* @self: A #MMModemVoice.
|
||||
* @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_voice_call_waiting_query().
|
||||
* @status: Output location where to store the status.
|
||||
* @error: Return location for error or %NULL.
|
||||
*
|
||||
* Finishes an operation started with mm_modem_voice_call_waiting_query().
|
||||
*
|
||||
* Returns: %TRUE if @status is set, %FALSE if @error is set.
|
||||
* Since: 1.12
|
||||
*/
|
||||
gboolean
|
||||
mm_modem_voice_call_waiting_query_finish (MMModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
gboolean *status,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||
|
||||
return mm_gdbus_modem_voice_call_call_waiting_query_finish (MM_GDBUS_MODEM_VOICE (self), status, res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_query:
|
||||
* @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 queries the status of the call waiting network service.
|
||||
*
|
||||
* 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_call_waiting_query_finish() to get the result of the operation.
|
||||
*
|
||||
* See mm_modem_voice_call_waiting_query_sync() for the synchronous, blocking version of this method.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
void
|
||||
mm_modem_voice_call_waiting_query (MMModemVoice *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (MM_IS_MODEM_VOICE (self));
|
||||
|
||||
mm_gdbus_modem_voice_call_call_waiting_query (MM_GDBUS_MODEM_VOICE (self),
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_voice_call_waiting_query_sync:
|
||||
* @self: A #MMModemVoice.
|
||||
* @cancellable: (allow-none): A #GCancellable or %NULL.
|
||||
* @status: Output location where to store the status.
|
||||
* @error: Return location for error or %NULL.
|
||||
*
|
||||
* Synchronously queries the status of the call waiting network service.
|
||||
*
|
||||
* The calling thread is blocked until a reply is received. See mm_modem_voice_call_waiting_query()
|
||||
* for the asynchronous version of this method.
|
||||
*
|
||||
* Returns: %TRUE if @status is set, %FALSE if @error is set.
|
||||
* Since: 1.12
|
||||
*/
|
||||
gboolean
|
||||
mm_modem_voice_call_waiting_query_sync (MMModemVoice *self,
|
||||
GCancellable *cancellable,
|
||||
gboolean *status,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM_VOICE (self), FALSE);
|
||||
|
||||
return mm_gdbus_modem_voice_call_call_waiting_query_sync (MM_GDBUS_MODEM_VOICE (self),
|
||||
status,
|
||||
cancellable,
|
||||
error);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_modem_voice_init (MMModemVoice *self)
|
||||
{
|
||||
|
@@ -154,6 +154,32 @@ gboolean mm_modem_voice_transfer_sync (MMModemVoice *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
void mm_modem_voice_call_waiting_setup (MMModemVoice *self,
|
||||
gboolean enable,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean mm_modem_voice_call_waiting_setup_finish (MMModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean mm_modem_voice_call_waiting_setup_sync (MMModemVoice *self,
|
||||
gboolean enable,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
void mm_modem_voice_call_waiting_query (MMModemVoice *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean mm_modem_voice_call_waiting_query_finish (MMModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
gboolean *status,
|
||||
GError **error);
|
||||
gboolean mm_modem_voice_call_waiting_query_sync (MMModemVoice *self,
|
||||
GCancellable *cancellable,
|
||||
gboolean *status,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _MM_MODEM_VOICE_H_ */
|
||||
|
@@ -1262,6 +1262,204 @@ handle_transfer (MmGdbusModemVoice *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
MmGdbusModemVoice *skeleton;
|
||||
GDBusMethodInvocation *invocation;
|
||||
MMIfaceModemVoice *self;
|
||||
gboolean enable;
|
||||
} HandleCallWaitingSetupContext;
|
||||
|
||||
static void
|
||||
handle_call_waiting_setup_context_free (HandleCallWaitingSetupContext *ctx)
|
||||
{
|
||||
g_object_unref (ctx->skeleton);
|
||||
g_object_unref (ctx->invocation);
|
||||
g_object_unref (ctx->self);
|
||||
g_slice_free (HandleCallWaitingSetupContext, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_setup_ready (MMIfaceModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
HandleCallWaitingSetupContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_setup_finish (self, res, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_call_waiting_setup_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
mm_gdbus_modem_voice_complete_call_waiting_setup (ctx->skeleton, ctx->invocation);
|
||||
handle_call_waiting_setup_context_free (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_call_waiting_setup_auth_ready (MMBaseModem *self,
|
||||
GAsyncResult *res,
|
||||
HandleCallWaitingSetupContext *ctx)
|
||||
{
|
||||
MMModemState modem_state = MM_MODEM_STATE_UNKNOWN;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!mm_base_modem_authorize_finish (self, res, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_call_waiting_setup_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 setup call waiting: device not yet enabled");
|
||||
handle_call_waiting_setup_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_setup ||
|
||||
!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_setup_finish) {
|
||||
g_dbus_method_invocation_return_error (ctx->invocation,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Cannot setup call waiting: unsupported");
|
||||
handle_call_waiting_setup_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_setup (MM_IFACE_MODEM_VOICE (self),
|
||||
ctx->enable,
|
||||
(GAsyncReadyCallback)call_waiting_setup_ready,
|
||||
ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_call_waiting_setup (MmGdbusModemVoice *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gboolean enable,
|
||||
MMIfaceModemVoice *self)
|
||||
{
|
||||
HandleCallWaitingSetupContext *ctx;
|
||||
|
||||
ctx = g_slice_new0 (HandleCallWaitingSetupContext);
|
||||
ctx->skeleton = g_object_ref (skeleton);
|
||||
ctx->invocation = g_object_ref (invocation);
|
||||
ctx->self = g_object_ref (self);
|
||||
ctx->enable = enable;
|
||||
|
||||
mm_base_modem_authorize (MM_BASE_MODEM (self),
|
||||
invocation,
|
||||
MM_AUTHORIZATION_VOICE,
|
||||
(GAsyncReadyCallback)handle_call_waiting_setup_auth_ready,
|
||||
ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
MmGdbusModemVoice *skeleton;
|
||||
GDBusMethodInvocation *invocation;
|
||||
MMIfaceModemVoice *self;
|
||||
gboolean enable;
|
||||
} HandleCallWaitingQueryContext;
|
||||
|
||||
static void
|
||||
handle_call_waiting_query_context_free (HandleCallWaitingQueryContext *ctx)
|
||||
{
|
||||
g_object_unref (ctx->skeleton);
|
||||
g_object_unref (ctx->invocation);
|
||||
g_object_unref (ctx->self);
|
||||
g_slice_free (HandleCallWaitingQueryContext, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
call_waiting_query_ready (MMIfaceModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
HandleCallWaitingQueryContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean status = FALSE;
|
||||
|
||||
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_query_finish (self, res, &status, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_call_waiting_query_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
mm_gdbus_modem_voice_complete_call_waiting_query (ctx->skeleton, ctx->invocation, status);
|
||||
handle_call_waiting_query_context_free (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_call_waiting_query_auth_ready (MMBaseModem *self,
|
||||
GAsyncResult *res,
|
||||
HandleCallWaitingQueryContext *ctx)
|
||||
{
|
||||
MMModemState modem_state = MM_MODEM_STATE_UNKNOWN;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!mm_base_modem_authorize_finish (self, res, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_call_waiting_query_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 query call waiting: device not yet enabled");
|
||||
handle_call_waiting_query_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_query ||
|
||||
!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_query_finish) {
|
||||
g_dbus_method_invocation_return_error (ctx->invocation,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Cannot query call waiting: unsupported");
|
||||
handle_call_waiting_query_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->call_waiting_query (MM_IFACE_MODEM_VOICE (self),
|
||||
(GAsyncReadyCallback)call_waiting_query_ready,
|
||||
ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_call_waiting_query (MmGdbusModemVoice *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
MMIfaceModemVoice *self)
|
||||
{
|
||||
HandleCallWaitingQueryContext *ctx;
|
||||
|
||||
ctx = g_slice_new0 (HandleCallWaitingQueryContext);
|
||||
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_call_waiting_query_auth_ready,
|
||||
ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Leave one of the calls from the multiparty call */
|
||||
|
||||
@@ -2773,13 +2971,15 @@ interface_initialization_step (GTask *task)
|
||||
case INITIALIZATION_STEP_LAST:
|
||||
/* Setup all method handlers */
|
||||
g_object_connect (ctx->skeleton,
|
||||
"signal::handle-create-call", G_CALLBACK (handle_create), self,
|
||||
"signal::handle-delete-call", G_CALLBACK (handle_delete), self,
|
||||
"signal::handle-list-calls", G_CALLBACK (handle_list), self,
|
||||
"signal::handle-hangup-and-accept", G_CALLBACK (handle_hangup_and_accept), self,
|
||||
"signal::handle-hold-and-accept", G_CALLBACK (handle_hold_and_accept), self,
|
||||
"signal::handle-hangup-all", G_CALLBACK (handle_hangup_all), self,
|
||||
"signal::handle-transfer", G_CALLBACK (handle_transfer), self,
|
||||
"signal::handle-create-call", G_CALLBACK (handle_create), self,
|
||||
"signal::handle-delete-call", G_CALLBACK (handle_delete), self,
|
||||
"signal::handle-list-calls", G_CALLBACK (handle_list), self,
|
||||
"signal::handle-hangup-and-accept", G_CALLBACK (handle_hangup_and_accept), self,
|
||||
"signal::handle-hold-and-accept", G_CALLBACK (handle_hold_and_accept), self,
|
||||
"signal::handle-hangup-all", G_CALLBACK (handle_hangup_all), self,
|
||||
"signal::handle-transfer", G_CALLBACK (handle_transfer), self,
|
||||
"signal::handle-call-waiting-setup", G_CALLBACK (handle_call_waiting_setup), self,
|
||||
"signal::handle-call-waiting-query", G_CALLBACK (handle_call_waiting_query), self,
|
||||
NULL);
|
||||
|
||||
/* Finally, export the new interface */
|
||||
|
@@ -175,6 +175,24 @@ struct _MMIfaceModemVoice {
|
||||
gboolean (* transfer_finish) (MMIfaceModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
/* Call waiting setup */
|
||||
void (* call_waiting_setup) (MMIfaceModemVoice *self,
|
||||
gboolean enable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (* call_waiting_setup_finish) (MMIfaceModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
/* Call waiting query */
|
||||
void (* call_waiting_query) (MMIfaceModemVoice *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (* call_waiting_query_finish) (MMIfaceModemVoice *self,
|
||||
GAsyncResult *res,
|
||||
gboolean *status,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
GType mm_iface_modem_voice_get_type (void);
|
||||
|
Reference in New Issue
Block a user