aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-iface-modem-3gpp-ussd.c205
-rw-r--r--src/mm-iface-modem-3gpp-ussd.h17
2 files changed, 222 insertions, 0 deletions
diff --git a/src/mm-iface-modem-3gpp-ussd.c b/src/mm-iface-modem-3gpp-ussd.c
index 6ec282bb..75907369 100644
--- a/src/mm-iface-modem-3gpp-ussd.c
+++ b/src/mm-iface-modem-3gpp-ussd.c
@@ -42,6 +42,197 @@ mm_iface_modem_3gpp_ussd_bind_simple_status (MMIfaceModem3gppUssd *self,
/*****************************************************************************/
+typedef struct {
+ MmGdbusModem3gppUssd *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModem3gppUssd *self;
+} DbusCallContext;
+
+static void
+dbus_call_context_free (DbusCallContext *ctx)
+{
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->invocation);
+ g_object_unref (ctx->self);
+ g_free (ctx);
+}
+
+static DbusCallContext *
+dbus_call_context_new (MmGdbusModem3gppUssd *skeleton,
+ GDBusMethodInvocation *invocation,
+ MMIfaceModem3gppUssd *self)
+{
+ DbusCallContext *ctx;
+
+ ctx = g_new (DbusCallContext, 1);
+ ctx->skeleton = g_object_ref (skeleton);
+ ctx->invocation = g_object_ref (invocation);
+ ctx->self = g_object_ref (self);
+ return ctx;
+}
+
+/*****************************************************************************/
+
+static void
+cancel_ready (MMIfaceModem3gppUssd *self,
+ GAsyncResult *res,
+ DbusCallContext *ctx)
+{
+ GError *error = NULL;
+
+ if (!MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->cancel_finish (self,
+ res,
+ &error))
+ g_dbus_method_invocation_take_error (ctx->invocation,
+ error);
+ else
+ mm_gdbus_modem3gpp_ussd_complete_cancel (ctx->skeleton,
+ ctx->invocation);
+ dbus_call_context_free (ctx);
+}
+
+static gboolean
+handle_cancel (MmGdbusModem3gppUssd *skeleton,
+ GDBusMethodInvocation *invocation,
+ const gchar *command,
+ MMIfaceModem3gppUssd *self)
+{
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->cancel != NULL);
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->cancel_finish != NULL);
+
+ MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->cancel (
+ self,
+ (GAsyncReadyCallback)cancel_ready,
+ dbus_call_context_new (skeleton,
+ invocation,
+ self));
+ return TRUE;
+}
+
+static void
+respond_send_ready (MMIfaceModem3gppUssd *self,
+ GAsyncResult *res,
+ DbusCallContext *ctx)
+{
+ GError *error = NULL;
+ const gchar *reply;
+
+ reply = MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send_finish (self,
+ res,
+ &error);
+ if (!reply)
+ g_dbus_method_invocation_take_error (ctx->invocation,
+ error);
+ else
+ mm_gdbus_modem3gpp_ussd_complete_respond (ctx->skeleton,
+ ctx->invocation,
+ reply);
+ dbus_call_context_free (ctx);
+}
+
+static gboolean
+handle_respond (MmGdbusModem3gppUssd *skeleton,
+ GDBusMethodInvocation *invocation,
+ const gchar *command,
+ MMIfaceModem3gppUssd *self)
+{
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send != NULL);
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send_finish != NULL);
+
+ switch (mm_gdbus_modem3gpp_ussd_get_state (skeleton)) {
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_ACTIVE:
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE:
+ g_dbus_method_invocation_return_error (invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_WRONG_STATE,
+ "Cannot respond USSD: "
+ "no active session");
+ break;
+
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE:
+ MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send (
+ self,
+ command,
+ (GAsyncReadyCallback)respond_send_ready,
+ dbus_call_context_new (skeleton,
+ invocation,
+ self));
+ break;
+
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_UNKNOWN:
+ default:
+ /* We should never have a DBus request when in UNKNOWN state */
+ g_assert_not_reached ();
+ break;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+static void
+initiate_send_ready (MMIfaceModem3gppUssd *self,
+ GAsyncResult *res,
+ DbusCallContext *ctx)
+{
+ GError *error = NULL;
+ const gchar *reply;
+
+ reply = MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send_finish (self,
+ res,
+ &error);
+ if (!reply)
+ g_dbus_method_invocation_take_error (ctx->invocation,
+ error);
+ else
+ mm_gdbus_modem3gpp_ussd_complete_initiate (ctx->skeleton,
+ ctx->invocation,
+ reply);
+ dbus_call_context_free (ctx);
+}
+
+static gboolean
+handle_initiate (MmGdbusModem3gppUssd *skeleton,
+ GDBusMethodInvocation *invocation,
+ const gchar *command,
+ MMIfaceModem3gppUssd *self)
+{
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send != NULL);
+ g_assert (MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send_finish != NULL);
+
+ switch (mm_gdbus_modem3gpp_ussd_get_state (skeleton)) {
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_ACTIVE:
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE:
+ g_dbus_method_invocation_return_error (invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_WRONG_STATE,
+ "Cannot initiate USSD: "
+ "a session is already active");
+ break;
+
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE:
+ MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->send (
+ self,
+ command,
+ (GAsyncReadyCallback)initiate_send_ready,
+ dbus_call_context_new (skeleton,
+ invocation,
+ self));
+ break;
+
+ case MM_MODEM_3GPP_USSD_SESSION_STATE_UNKNOWN:
+ default:
+ /* We should never have a DBus request when in UNKNOWN state */
+ g_assert_not_reached ();
+ break;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
gchar *
mm_iface_modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
const gchar *command,
@@ -542,6 +733,20 @@ interface_initialization_step (InitializationContext *ctx)
case INITIALIZATION_STEP_LAST:
/* We are done without errors! */
+ /* Handle method invocations */
+ g_signal_connect (ctx->skeleton,
+ "handle-initiate",
+ G_CALLBACK (handle_initiate),
+ ctx->self);
+ g_signal_connect (ctx->skeleton,
+ "handle-respond",
+ G_CALLBACK (handle_respond),
+ ctx->self);
+ g_signal_connect (ctx->skeleton,
+ "handle-cancel",
+ G_CALLBACK (handle_cancel),
+ ctx->self);
+
/* Finally, export the new interface */
mm_gdbus_object_skeleton_set_modem3gpp_ussd (MM_GDBUS_OBJECT_SKELETON (ctx->self),
MM_GDBUS_MODEM3GPP_USSD (ctx->skeleton));
diff --git a/src/mm-iface-modem-3gpp-ussd.h b/src/mm-iface-modem-3gpp-ussd.h
index abba6850..ce419088 100644
--- a/src/mm-iface-modem-3gpp-ussd.h
+++ b/src/mm-iface-modem-3gpp-ussd.h
@@ -85,6 +85,23 @@ struct _MMIfaceModem3gppUssd {
guint *scheme);
gchar * (*decode) (MMIfaceModem3gppUssd *self,
const gchar *reply);
+
+ /* Send command */
+ void (* send) (MMIfaceModem3gppUssd *self,
+ const gchar *command,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ const gchar * (* send_finish) (MMIfaceModem3gppUssd *self,
+ GAsyncResult *res,
+ GError **error);
+
+ /* Cancel */
+ void (* cancel) (MMIfaceModem3gppUssd *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (* cancel_finish) (MMIfaceModem3gppUssd *self,
+ GAsyncResult *res,
+ GError **error);
};
GType mm_iface_modem_3gpp_ussd_get_type (void);