aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-iface-modem.c140
-rw-r--r--src/mm-iface-modem.h9
2 files changed, 149 insertions, 0 deletions
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 9f9ad50d..86ecead7 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -1791,6 +1791,142 @@ handle_factory_reset (MmGdbusModem *skeleton,
}
/*****************************************************************************/
+/* Current capabilities setting */
+
+typedef struct {
+ MmGdbusModem *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModem *self;
+ MMModemCapability capabilities;
+} HandleSetCurrentCapabilitiesContext;
+
+static void
+handle_set_current_capabilities_context_free (HandleSetCurrentCapabilitiesContext *ctx)
+{
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->invocation);
+ g_object_unref (ctx->self);
+ g_slice_free (HandleSetCurrentCapabilitiesContext, ctx);
+}
+
+static void
+set_current_capabilities_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ HandleSetCurrentCapabilitiesContext *ctx)
+{
+ GError *error = NULL;
+
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_capabilities_finish (self, res, &error))
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ else
+ mm_gdbus_modem_complete_set_current_capabilities (ctx->skeleton, ctx->invocation);
+ handle_set_current_capabilities_context_free (ctx);
+}
+
+static void
+handle_set_current_capabilities_auth_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ HandleSetCurrentCapabilitiesContext *ctx)
+{
+ GError *error = NULL;
+ gchar *capabilities_string;
+ GArray *supported;
+ gboolean matched = FALSE;
+ guint i;
+
+ if (!mm_base_modem_authorize_finish (self, res, &error)) {
+ g_dbus_method_invocation_take_error (ctx->invocation, error);
+ handle_set_current_capabilities_context_free (ctx);
+ return;
+ }
+
+ /* Get list of supported capabilities */
+ supported = mm_common_capability_combinations_variant_to_garray (
+ mm_gdbus_modem_get_supported_capabilities (ctx->skeleton));
+
+ /* Don't allow capability switching if only one item given in the supported list */
+ if (supported->len == 1) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot change capabilities: only one combination supported");
+ handle_set_current_capabilities_context_free (ctx);
+ g_array_unref (supported);
+ return;
+ }
+
+ /* Check if the given combination is supported */
+ for (i = 0; !matched && i < supported->len; i++) {
+ MMModemCapability supported_capability;
+
+ supported_capability = g_array_index (supported, MMModemCapability, i);
+ if (supported_capability == ctx->capabilities)
+ matched = TRUE;
+ }
+ g_array_unref (supported);
+
+ if (!matched) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "The given combination of capabilities is not supported");
+ handle_set_current_capabilities_context_free (ctx);
+ return;
+ }
+
+ /* Check if we already are in the requested setup */
+ if (mm_gdbus_modem_get_current_capabilities (ctx->skeleton) == ctx->capabilities) {
+ /* Nothing to do */
+ mm_gdbus_modem_complete_set_current_capabilities (ctx->skeleton, ctx->invocation);
+ handle_set_current_capabilities_context_free (ctx);
+ return;
+ }
+
+ /* If setting current capabilities is not implemented, report an error */
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_capabilities ||
+ !MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_capabilities_finish) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Setting current capabilities not supported");
+ handle_set_current_capabilities_context_free (ctx);
+ return;
+ }
+
+ capabilities_string = mm_modem_capability_build_string_from_mask (ctx->capabilities);
+ mm_dbg ("Setting new list of capabilities: '%s'", capabilities_string);
+ g_free (capabilities_string);
+
+ MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_capabilities (
+ MM_IFACE_MODEM (self),
+ ctx->capabilities,
+ (GAsyncReadyCallback)set_current_capabilities_ready,
+ ctx);
+}
+
+static gboolean
+handle_set_current_capabilities (MmGdbusModem *skeleton,
+ GDBusMethodInvocation *invocation,
+ guint capabilities,
+ MMIfaceModem *self)
+{
+ HandleSetCurrentCapabilitiesContext *ctx;
+
+ ctx = g_slice_new (HandleSetCurrentCapabilitiesContext);
+ ctx->skeleton = g_object_ref (skeleton);
+ ctx->invocation = g_object_ref (invocation);
+ ctx->self = g_object_ref (self);
+ ctx->capabilities = capabilities;
+
+ mm_base_modem_authorize (MM_BASE_MODEM (self),
+ invocation,
+ MM_AUTHORIZATION_DEVICE_CONTROL,
+ (GAsyncReadyCallback)handle_set_current_capabilities_auth_ready,
+ ctx);
+ return TRUE;
+}
+
+/*****************************************************************************/
/* Current bands setting */
typedef struct {
@@ -4312,6 +4448,10 @@ interface_initialization_step (InitializationContext *ctx)
G_CALLBACK (handle_factory_reset),
ctx->self);
g_signal_connect (ctx->skeleton,
+ "handle-set-current-capabilities",
+ G_CALLBACK (handle_set_current_capabilities),
+ ctx->self);
+ g_signal_connect (ctx->skeleton,
"handle-set-current-bands",
G_CALLBACK (handle_set_current_bands),
ctx->self);
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 8f87bc6b..cadf31eb 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -217,6 +217,15 @@ struct _MMIfaceModem {
GAsyncResult *res,
GError **error);
+ /* Asynchronous capabilities setting operation */
+ void (*set_current_capabilities) (MMIfaceModem *self,
+ MMModemCapability,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*set_current_capabilities_finish) (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
+
/* Asynchronous current band setting operation */
void (*set_current_bands) (MMIfaceModem *self,
GArray *bands_array,