summaryrefslogtreecommitdiff
path: root/plugins/option
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/option')
-rw-r--r--plugins/option/mm-broadband-bearer-hso.c597
-rw-r--r--plugins/option/mm-broadband-bearer-hso.h2
-rw-r--r--plugins/option/mm-broadband-modem-hso.c337
-rw-r--r--plugins/option/mm-broadband-modem-option.c316
-rw-r--r--plugins/option/mm-plugin-hso.c39
-rw-r--r--plugins/option/mm-plugin-option.c18
-rw-r--r--plugins/option/mm-shared-option.c77
-rw-r--r--plugins/option/mm-shared-option.h49
-rw-r--r--plugins/option/mm-shared.c20
-rw-r--r--plugins/option/mm-sim-option.c84
-rw-r--r--plugins/option/mm-sim-option.h51
11 files changed, 875 insertions, 715 deletions
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index f1c0445e..592b2804 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -30,17 +30,17 @@
#include "mm-base-modem-at.h"
#include "mm-broadband-bearer-hso.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
#include "mm-modem-helpers.h"
#include "mm-daemon-enums-types.h"
G_DEFINE_TYPE (MMBroadbandBearerHso, mm_broadband_bearer_hso, MM_TYPE_BROADBAND_BEARER);
struct _MMBroadbandBearerHsoPrivate {
- guint auth_idx;
- gpointer connect_pending;
- guint connect_pending_id;
- gulong connect_cancellable_id;
+ guint auth_idx;
+
+ GTask *connect_pending;
+ guint connect_pending_id;
gulong connect_port_closed_id;
};
@@ -48,21 +48,16 @@ struct _MMBroadbandBearerHsoPrivate {
/* 3GPP IP config retrieval (sub-step of the 3GPP Connection sequence) */
typedef struct {
- MMBroadbandBearerHso *self;
MMBaseModem *modem;
MMPortSerialAt *primary;
guint cid;
- GSimpleAsyncResult *result;
} GetIpConfig3gppContext;
static void
-get_ip_config_context_complete_and_free (GetIpConfig3gppContext *ctx)
+get_ip_config_context_free (GetIpConfig3gppContext *ctx)
{
- g_simple_async_result_complete (ctx->result);
- g_object_unref (ctx->result);
g_object_unref (ctx->primary);
g_object_unref (ctx->modem);
- g_object_unref (ctx->self);
g_slice_free (GetIpConfig3gppContext, ctx);
}
@@ -75,12 +70,12 @@ get_ip_config_3gpp_finish (MMBroadbandBearer *self,
{
MMBearerIpConfig *ip_config;
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ ip_config = g_task_propagate_pointer (G_TASK (res), error);
+ if (!ip_config)
return FALSE;
/* No IPv6 for now */
- ip_config = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
- *ipv4_config = g_object_ref (ip_config);
+ *ipv4_config = ip_config; /* Transfer ownership */
*ipv6_config = NULL;
return TRUE;
}
@@ -90,8 +85,9 @@ get_ip_config_3gpp_finish (MMBroadbandBearer *self,
static void
ip_config_ready (MMBaseModem *modem,
GAsyncResult *res,
- GetIpConfig3gppContext *ctx)
+ GTask *task)
{
+ GetIpConfig3gppContext *ctx;
MMBearerIpConfig *ip_config = NULL;
const gchar *response;
GError *error = NULL;
@@ -102,8 +98,8 @@ ip_config_ready (MMBaseModem *modem,
response = mm_base_modem_at_command_full_finish (modem, res, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- get_ip_config_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -111,23 +107,24 @@ ip_config_ready (MMBaseModem *modem,
/* Check result */
if (!g_str_has_prefix (response, OWANDATA_TAG)) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't get IP config: invalid response '%s'",
- response);
- get_ip_config_context_complete_and_free (ctx);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't get IP config: invalid response '%s'",
+ response);
+ g_object_unref (task);
return;
}
+ ctx = g_task_get_task_data (task);
response = mm_strip_tag (response, OWANDATA_TAG);
items = g_strsplit (response, ", ", 0);
for (i = 0, dns_i = 0; items[i]; i++) {
if (i == 0) { /* CID */
- gint num;
+ guint num;
- if (!mm_get_int_from_str (items[i], &num) ||
+ if (!mm_get_uint_from_str (items[i], &num) ||
num != ctx->cid) {
error = g_error_new (MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
@@ -159,24 +156,22 @@ ip_config_ready (MMBaseModem *modem,
if (!ip_config) {
if (error)
- g_simple_async_result_take_error (ctx->result, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't get IP config: couldn't parse response '%s'",
- response);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't get IP config: couldn't parse response '%s'",
+ response);
} else {
/* If we got DNS entries, set them in the IP config */
if (dns[0])
mm_bearer_ip_config_set_dns (ip_config, (const gchar **)dns);
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- ip_config,
- (GDestroyNotify)g_object_unref);
+ g_task_return_pointer (task, ip_config, g_object_unref);
}
- get_ip_config_context_complete_and_free (ctx);
+ g_object_unref (task);
g_strfreev (items);
}
@@ -192,17 +187,16 @@ get_ip_config_3gpp (MMBroadbandBearer *self,
gpointer user_data)
{
GetIpConfig3gppContext *ctx;
+ GTask *task;
gchar *command;
ctx = g_slice_new0 (GetIpConfig3gppContext);
- ctx->self = g_object_ref (self);
- ctx->modem = g_object_ref (modem);
+ ctx->modem = MM_BASE_MODEM (g_object_ref (modem));
ctx->primary = g_object_ref (primary);
ctx->cid = cid;
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- get_ip_config_3gpp);
+
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)get_ip_config_context_free);
command = g_strdup_printf ("AT_OWANDATA=%d", cid);
mm_base_modem_at_command_full (
@@ -214,7 +208,7 @@ get_ip_config_3gpp (MMBroadbandBearer *self,
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)ip_config_ready,
- ctx);
+ task);
g_free (command);
}
@@ -222,88 +216,72 @@ get_ip_config_3gpp (MMBroadbandBearer *self,
/* 3GPP Dialing (sub-step of the 3GPP Connection sequence) */
typedef struct {
- MMBroadbandBearerHso *self;
- MMBaseModem *modem;
+ MMBaseModem *modem;
MMPortSerialAt *primary;
- guint cid;
- GCancellable *cancellable;
- GSimpleAsyncResult *result;
- MMPort *data;
- guint auth_idx;
- GError *saved_error;
+ guint cid;
+ MMPort *data;
+ guint auth_idx;
+ GError *saved_error;
} Dial3gppContext;
static void
-dial_3gpp_context_complete_and_free (Dial3gppContext *ctx)
+dial_3gpp_context_free (Dial3gppContext *ctx)
{
- g_simple_async_result_complete_in_idle (ctx->result);
- if (ctx->data)
- g_object_unref (ctx->data);
- g_object_unref (ctx->cancellable);
- g_object_unref (ctx->result);
- g_object_unref (ctx->primary);
- g_object_unref (ctx->modem);
- g_object_unref (ctx->self);
+ g_assert (!ctx->saved_error);
+ g_clear_object (&ctx->data);
+ g_clear_object (&ctx->primary);
+ g_clear_object (&ctx->modem);
g_slice_free (Dial3gppContext, ctx);
}
-static gboolean
-dial_3gpp_context_set_error_if_cancelled (Dial3gppContext *ctx,
- GError **error)
+static guint
+dial_3gpp_get_connecting_cid (GTask *task)
{
- if (!g_cancellable_is_cancelled (ctx->cancellable))
- return FALSE;
-
- g_set_error (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_CANCELLED,
- "Dial operation has been cancelled");
- return TRUE;
-}
-
-static gboolean
-dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx)
-{
- GError *error = NULL;
-
- if (!dial_3gpp_context_set_error_if_cancelled (ctx, &error))
- return FALSE;
+ Dial3gppContext *ctx;
- g_simple_async_result_take_error (ctx->result, error);
- dial_3gpp_context_complete_and_free (ctx);
- return TRUE;
+ ctx = g_task_get_task_data (task);
+ return ctx->cid;
}
static MMPort *
-dial_3gpp_finish (MMBroadbandBearer *self,
- GAsyncResult *res,
- GError **error)
+dial_3gpp_finish (MMBroadbandBearer *self,
+ GAsyncResult *res,
+ GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))));
+ return MM_PORT (g_task_propagate_pointer (G_TASK (res), error));
}
static void
-connect_reset_ready (MMBaseModem *modem,
+connect_reset_ready (MMBaseModem *modem,
GAsyncResult *res,
- Dial3gppContext *ctx)
+ GTask *task)
{
+ Dial3gppContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
mm_base_modem_at_command_full_finish (modem, res, NULL);
- /* error should have already been set in the simple async result */
- dial_3gpp_context_complete_and_free (ctx);
+ /* When reset is requested, it was either cancelled or an error was stored */
+ if (!g_task_return_error_if_cancelled (task)) {
+ g_assert (ctx->saved_error);
+ g_task_return_error (task, ctx->saved_error);
+ ctx->saved_error = NULL;
+ }
+
+ g_object_unref (task);
}
static void
-connect_reset (Dial3gppContext *ctx)
+connect_reset (GTask *task)
{
- gchar *command;
+ Dial3gppContext *ctx;
+ gchar *command;
+
+ ctx = g_task_get_task_data (task);
/* Need to reset the connection attempt */
- command = g_strdup_printf ("AT_OWANCALL=%d,0,1",
- ctx->cid);
+ command = g_strdup_printf ("AT_OWANCALL=%d,0,1", ctx->cid);
mm_base_modem_at_command_full (ctx->modem,
ctx->primary,
command,
@@ -312,53 +290,29 @@ connect_reset (Dial3gppContext *ctx)
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)connect_reset_ready,
- ctx);
+ task);
g_free (command);
}
static void
-report_connection_status (MMBaseBearer *bearer,
- MMBearerConnectionStatus status)
+process_pending_connect_attempt (MMBroadbandBearerHso *self,
+ MMBearerConnectionStatus status)
{
- MMBroadbandBearerHso *self = MM_BROADBAND_BEARER_HSO (bearer);
+ GTask *task;
Dial3gppContext *ctx;
- g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
- status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED ||
- status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
-
- /* Recover context (if any) and remove both cancellation and timeout (if any)*/
- ctx = self->priv->connect_pending;
+ /* Recover task and remove both cancellation and timeout (if any)*/
+ g_assert (self->priv->connect_pending);
+ task = self->priv->connect_pending;
self->priv->connect_pending = NULL;
- /* Connection status reported but no connection attempt? */
- if (!ctx) {
- g_assert (self->priv->connect_pending_id == 0);
-
- mm_dbg ("Received spontaneous _OWANCALL (%s)",
- mm_bearer_connection_status_get_string (status));
-
- if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
- /* If no connection attempt on-going, make sure we mark ourselves as
- * disconnected */
- MM_BASE_BEARER_CLASS (mm_broadband_bearer_hso_parent_class)->report_connection_status (
- bearer,
- status);
- }
- return;
- }
+ ctx = g_task_get_task_data (task);
if (self->priv->connect_pending_id) {
g_source_remove (self->priv->connect_pending_id);
self->priv->connect_pending_id = 0;
}
- if (self->priv->connect_cancellable_id) {
- g_cancellable_disconnect (ctx->cancellable,
- self->priv->connect_cancellable_id);
- self->priv->connect_cancellable_id = 0;
- }
-
if (self->priv->connect_port_closed_id) {
g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
self->priv->connect_port_closed_id = 0;
@@ -366,105 +320,60 @@ report_connection_status (MMBaseBearer *bearer,
/* Reporting connected */
if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED) {
- /* If we wanted to get cancelled before, do it now */
- if (ctx->saved_error) {
- /* Keep error */
- g_simple_async_result_take_error (ctx->result, ctx->saved_error);
- ctx->saved_error = NULL;
- /* Cancel connection */
- connect_reset (ctx);
+ /* If we wanted to get cancelled before, do it now. */
+ if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) {
+ connect_reset (task);
return;
}
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- g_object_ref (ctx->data),
- (GDestroyNotify)g_object_unref);
- dial_3gpp_context_complete_and_free (ctx);
- return;
- }
-
- /* If we wanted to get cancelled before and now we couldn't connect,
- * use the cancelled error and return */
- if (ctx->saved_error) {
- g_simple_async_result_take_error (ctx->result, ctx->saved_error);
- ctx->saved_error = NULL;
- dial_3gpp_context_complete_and_free (ctx);
+ g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
+ g_object_unref (task);
return;
}
- /* Received CONNECTION_FAILED or DISCONNECTED during a connection attempt? */
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Call setup failed");
- dial_3gpp_context_complete_and_free (ctx);
+ /* Received CONNECTION_FAILED or DISCONNECTED during a connection attempt,
+ * so return a failed error. Note that if the cancellable has been cancelled
+ * already, a cancelled error would be returned instead. */
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Call setup failed");
+ g_object_unref (task);
}
static gboolean
connect_timed_out_cb (MMBroadbandBearerHso *self)
{
+ GTask *task;
Dial3gppContext *ctx;
- /* Recover context and remove it from the private info */
- ctx = self->priv->connect_pending;
+ /* Cleanup timeout ID */
+ self->priv->connect_pending_id = 0;
+
+ /* Recover task and own it */
+ task = self->priv->connect_pending;
self->priv->connect_pending = NULL;
+ g_assert (task);
- /* Remove cancellation, if found */
- if (self->priv->connect_cancellable_id) {
- g_cancellable_disconnect (ctx->cancellable,
- self->priv->connect_cancellable_id);
- self->priv->connect_cancellable_id = 0;
- }
+ ctx = g_task_get_task_data (task);
/* Remove closed port watch, if found */
- if (ctx && self->priv->connect_port_closed_id) {
+ if (self->priv->connect_port_closed_id) {
g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
self->priv->connect_port_closed_id = 0;
}
- /* Cleanup timeout ID */
- self->priv->connect_pending_id = 0;
-
- /* If we were cancelled, prefer that error */
- if (ctx->saved_error) {
- g_simple_async_result_take_error (ctx->result, ctx->saved_error);
- ctx->saved_error = NULL;
- } else
- g_simple_async_result_set_error (ctx->result,
- MM_MOBILE_EQUIPMENT_ERROR,
- MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
- "Connection attempt timed out");
+ /* Setup error to return after the reset */
+ g_assert (!ctx->saved_error);
+ ctx->saved_error = g_error_new (MM_MOBILE_EQUIPMENT_ERROR,
+ MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
+ "Connection attempt timed out");
/* It's probably pointless to try to reset this here, but anyway... */
- connect_reset (ctx);
+ connect_reset (task);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
static void
-connect_cancelled_cb (GCancellable *cancellable,
- MMBroadbandBearerHso *self)
-{
- Dial3gppContext *ctx;
-
- /* Recover context but DON'T remove it from the private info */
- ctx = self->priv->connect_pending;
-
- /* Remove the cancellable
- * NOTE: we shouldn't remove the timeout yet. We still need to wait
- * to get connected before running the explicit connection reset */
- self->priv->connect_cancellable_id = 0;
-
- /* Store cancelled error */
- g_assert (dial_3gpp_context_set_error_if_cancelled (ctx, &ctx->saved_error));
-
- /* We cannot reset right here, we need to wait for the connection
- * attempt to finish */
-}
-
-static void
-forced_close_cb (MMPortSerial *port,
- MMBroadbandBearerHso *self)
+forced_close_cb (MMBroadbandBearerHso *self)
{
/* Just treat the forced close event as any other unsolicited message */
mm_base_bearer_report_connection_status (MM_BASE_BEARER (self),
@@ -472,77 +381,89 @@ forced_close_cb (MMPortSerial *port,
}
static void
-activate_ready (MMBaseModem *modem,
- GAsyncResult *res,
+activate_ready (MMBaseModem *modem,
+ GAsyncResult *res,
MMBroadbandBearerHso *self)
{
+ GTask *task;
Dial3gppContext *ctx;
- GError *error = NULL;
+ GError *error = NULL;
- /* Try to recover the connection context. If none found, it means the
- * context was already completed and we have nothing else to do. */
- ctx = self->priv->connect_pending;
-
- /* Balance refcount with the extra ref we passed to command_full() */
- g_object_unref (self);
-
- if (!ctx) {
- mm_dbg ("Connection context was finished already by an unsolicited message");
+ task = g_steal_pointer (&self->priv->connect_pending);
+ /* Try to recover the connection task. If none found, it means the
+ * task was already completed and we have nothing else to do.
+ * But note that we won't take owneship of the task yet! */
+ if (!task) {
+ mm_obj_dbg (self, "connection context was finished already by an unsolicited message");
/* Run _finish() to finalize the async call, even if we don't care
- * the result */
+ * about the result */
mm_base_modem_at_command_full_finish (modem, res, NULL);
- return;
+ goto out;
}
/* From now on, if we get cancelled, we'll need to run the connection
* reset ourselves just in case */
+ /* Errors on the dial command are fatal */
if (!mm_base_modem_at_command_full_finish (modem, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- dial_3gpp_context_complete_and_free (ctx);
- return;
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ goto out;
}
- /* We will now setup a timeout so that we don't wait forever to get the
- * connection on */
- self->priv->connect_pending_id = g_timeout_add_seconds (30,
+ /* Track the task again */
+ self->priv->connect_pending = task;
+
+ /* We will now setup a timeout and keep the context in the bearer's private.
+ * Reports of modem being connected will arrive via unsolicited messages.
+ * This timeout should be long enough. Actually... ideally should never get
+ * reached. */
+ self->priv->connect_pending_id = g_timeout_add_seconds (MM_BASE_BEARER_DEFAULT_CONNECTION_TIMEOUT,
(GSourceFunc)connect_timed_out_cb,
self);
- self->priv->connect_cancellable_id = g_cancellable_connect (ctx->cancellable,
- G_CALLBACK (connect_cancelled_cb),
- self,
- NULL);
/* If we get the port closed, we treat as a connect error */
- self->priv->connect_port_closed_id = g_signal_connect (ctx->primary,
- "forced-close",
- G_CALLBACK (forced_close_cb),
- self);
+ ctx = g_task_get_task_data (task);
+ self->priv->connect_port_closed_id = g_signal_connect_swapped (ctx->primary,
+ "forced-close",
+ G_CALLBACK (forced_close_cb),
+ self);
+
+ out:
+ /* Balance refcount with the extra ref we passed to command_full() */
+ g_object_unref (self);
}
-static void authenticate (Dial3gppContext *ctx);
+static void authenticate (GTask *task);
static void
-authenticate_ready (MMBaseModem *modem,
+authenticate_ready (MMBaseModem *modem,
GAsyncResult *res,
- Dial3gppContext *ctx)
+ GTask *task)
{
- gchar *command;
+ MMBroadbandBearerHso *self;
+ Dial3gppContext *ctx;
+ gchar *command;
/* If cancelled, complete */
- if (dial_3gpp_context_complete_and_free_if_cancelled (ctx))
+ if (g_task_return_error_if_cancelled (task)) {
+ g_object_unref (task);
return;
+ }
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
if (!mm_base_modem_at_command_full_finish (modem, res, NULL)) {
/* Try the next auth command */
ctx->auth_idx++;
- authenticate (ctx);
+ authenticate (task);
return;
}
/* Store which auth command worked, for next attempts */
- ctx->self->priv->auth_idx = ctx->auth_idx;
+ self->priv->auth_idx = ctx->auth_idx;
/* The unsolicited response to AT_OWANCALL may come before the OK does.
* We will keep the connection context in the bearer private data so
@@ -550,12 +471,11 @@ authenticate_ready (MMBaseModem *modem,
* also that we do NOT pass the ctx to the GAsyncReadyCallback, as it
* may not be valid any more when the callback is called (it may be
* already completed in the unsolicited handling) */
- g_assert (ctx->self->priv->connect_pending == NULL);
- ctx->self->priv->connect_pending = ctx;
+ g_assert (self->priv->connect_pending == NULL);
+ self->priv->connect_pending = task;
/* Success, activate the PDP context and start the data session */
- command = g_strdup_printf ("AT_OWANCALL=%d,1,1",
- ctx->cid);
+ command = g_strdup_printf ("AT_OWANCALL=%d,1,1", ctx->cid);
mm_base_modem_at_command_full (ctx->modem,
ctx->primary,
command,
@@ -563,8 +483,8 @@ authenticate_ready (MMBaseModem *modem,
FALSE,
FALSE, /* raw */
NULL, /* cancellable */
- (GAsyncReadyCallback)activate_ready,
- g_object_ref (ctx->self)); /* we pass the bearer object! */
+ (GAsyncReadyCallback) activate_ready,
+ g_object_ref (self)); /* we pass the bearer object! */
g_free (command);
}
@@ -578,62 +498,66 @@ const gchar *auth_commands[] = {
};
static void
-authenticate (Dial3gppContext *ctx)
+authenticate (GTask *task)
{
- gchar *command;
- const gchar *user;
- const gchar *password;
- MMBearerAllowedAuth allowed_auth;
+ MMBroadbandBearerHso *self;
+ Dial3gppContext *ctx;
+ gchar *command;
+ const gchar *user;
+ const gchar *password;
+ MMBearerAllowedAuth allowed_auth;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
if (!auth_commands[ctx->auth_idx]) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't run HSO authentication");
- dial_3gpp_context_complete_and_free (ctx);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't run HSO authentication");
+ g_object_unref (task);
return;
}
- user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
- password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
- allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
+ user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
+ password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
+ allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
/* Both user and password are required; otherwise firmware returns an error */
if (!user || !password || allowed_auth == MM_BEARER_ALLOWED_AUTH_NONE) {
- mm_dbg ("Not using authentication");
+ mm_obj_dbg (self, "not using authentication");
command = g_strdup_printf ("%s=%d,0",
auth_commands[ctx->auth_idx],
ctx->cid);
} else {
gchar *quoted_user;
gchar *quoted_password;
- guint hso_auth;
+ guint hso_auth;
if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
- mm_dbg ("Using default (PAP) authentication method");
- hso_auth = 1;
- } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
- mm_dbg ("Using PAP authentication method");
- hso_auth = 1;
+ mm_obj_dbg (self, "using default (CHAP) authentication method");
+ hso_auth = 2;
} else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
- mm_dbg ("Using CHAP authentication method");
+ mm_obj_dbg (self, "using CHAP authentication method");
hso_auth = 2;
+ } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
+ mm_obj_dbg (self, "using PAP authentication method");
+ hso_auth = 1;
} else {
gchar *str;
str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
- g_simple_async_result_set_error (
- ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_UNSUPPORTED,
- "Cannot use any of the specified authentication methods (%s)",
- str);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot use any of the specified authentication methods (%s)",
+ str);
+ g_object_unref (task);
g_free (str);
- dial_3gpp_context_complete_and_free (ctx);
return;
}
- quoted_user = mm_port_serial_at_quote_string (user);
+ quoted_user = mm_port_serial_at_quote_string (user);
quoted_password = mm_port_serial_at_quote_string (password);
command = g_strdup_printf ("%s=%d,%u,%s,%s",
auth_commands[ctx->auth_idx],
@@ -653,70 +577,63 @@ authenticate (Dial3gppContext *ctx)
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)authenticate_ready,
- ctx);
+ task);
g_free (command);
}
static void
-dial_3gpp (MMBroadbandBearer *self,
- MMBaseModem *modem,
- MMPortSerialAt *primary,
- guint cid,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+dial_3gpp (MMBroadbandBearer *_self,
+ MMBaseModem *modem,
+ MMPortSerialAt *primary,
+ guint cid,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- Dial3gppContext *ctx;
+ MMBroadbandBearerHso *self = MM_BROADBAND_BEARER_HSO (_self);
+ GTask *task;
+ Dial3gppContext *ctx;
g_assert (primary != NULL);
+ task = g_task_new (self, cancellable, callback, user_data);
+
ctx = g_slice_new0 (Dial3gppContext);
- ctx->self = g_object_ref (self);
- ctx->modem = g_object_ref (modem);
+ ctx->modem = g_object_ref (modem);
ctx->primary = g_object_ref (primary);
- ctx->cid = cid;
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- dial_3gpp);
- ctx->cancellable = g_object_ref (cancellable);
+ ctx->cid = cid;
+ g_task_set_task_data (task, ctx, (GDestroyNotify)dial_3gpp_context_free);
/* Always start with the index that worked last time
* (will be 0 the first time)*/
- ctx->auth_idx = ctx->self->priv->auth_idx;
+ ctx->auth_idx = self->priv->auth_idx;
/* We need a net data port */
ctx->data = mm_base_modem_get_best_data_port (modem, MM_PORT_TYPE_NET);
if (!ctx->data) {
- g_simple_async_result_set_error (
- ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_NOT_FOUND,
- "No valid data port found to launch connection");
- dial_3gpp_context_complete_and_free (ctx);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_NOT_FOUND,
+ "No valid data port found to launch connection");
+ g_object_unref (task);
return;
}
- authenticate (ctx);
+ authenticate (task);
}
/*****************************************************************************/
/* 3GPP disconnect */
typedef struct {
- MMBroadbandBearerHso *self;
MMBaseModem *modem;
MMPortSerialAt *primary;
- GSimpleAsyncResult *result;
} DisconnectContext;
static void
-disconnect_context_complete_and_free (DisconnectContext *ctx)
+disconnect_context_free (DisconnectContext *ctx)
{
- g_simple_async_result_complete (ctx->result);
- g_object_unref (ctx->result);
g_object_unref (ctx->primary);
- g_object_unref (ctx->self);
g_object_unref (ctx->modem);
g_free (ctx);
}
@@ -726,25 +643,28 @@ disconnect_3gpp_finish (MMBroadbandBearer *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
-disconnect_owancall_ready (MMBaseModem *modem,
+disconnect_owancall_ready (MMBaseModem *modem,
GAsyncResult *res,
- DisconnectContext *ctx)
+ GTask *task)
{
- GError *error = NULL;
+ MMBroadbandBearerHso *self;
+ GError *error = NULL;
+
+ self = g_task_get_source_object (task);
/* Ignore errors for now */
mm_base_modem_at_command_full_finish (modem, res, &error);
if (error) {
- mm_dbg ("Disconnection failed (not fatal): %s", error->message);
+ mm_obj_dbg (self, "disconnection failed (not fatal): %s", error->message);
g_error_free (error);
}
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- disconnect_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static void
@@ -759,34 +679,72 @@ disconnect_3gpp (MMBroadbandBearer *self,
{
gchar *command;
DisconnectContext *ctx;
+ GTask *task;
g_assert (primary != NULL);
ctx = g_new0 (DisconnectContext, 1);
- ctx->self = g_object_ref (self);
ctx->modem = MM_BASE_MODEM (g_object_ref (modem));
ctx->primary = g_object_ref (primary);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- disconnect_3gpp);
+
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)disconnect_context_free);
/* Use specific CID */
command = g_strdup_printf ("AT_OWANCALL=%d,0,0", cid);
mm_base_modem_at_command_full (MM_BASE_MODEM (modem),
primary,
command,
- 3,
+ MM_BASE_BEARER_DEFAULT_DISCONNECTION_TIMEOUT,
FALSE,
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)disconnect_owancall_ready,
- ctx);
+ task);
g_free (command);
}
/*****************************************************************************/
+gint
+mm_broadband_bearer_hso_get_connecting_profile_id (MMBroadbandBearerHso *self)
+{
+ return (self->priv->connect_pending ?
+ (gint)dial_3gpp_get_connecting_cid (self->priv->connect_pending) :
+ MM_3GPP_PROFILE_ID_UNKNOWN);
+}
+
+/*****************************************************************************/
+
+static void
+report_connection_status (MMBaseBearer *_self,
+ MMBearerConnectionStatus status,
+ const GError *connection_error)
+{
+ MMBroadbandBearerHso *self = MM_BROADBAND_BEARER_HSO (_self);
+
+ g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
+ status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED ||
+ status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
+
+ /* Process pending connection attempt */
+ if (self->priv->connect_pending) {
+ process_pending_connect_attempt (self, status);
+ return;
+ }
+
+ mm_obj_dbg (self, "received spontaneous _OWANCALL (%s)",
+ mm_bearer_connection_status_get_string (status));
+
+ if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
+ /* If no connection attempt on-going, make sure we mark ourselves as
+ * disconnected */
+ MM_BASE_BEARER_CLASS (mm_broadband_bearer_hso_parent_class)->report_connection_status (_self, status,connection_error);
+ }
+}
+
+/*****************************************************************************/
+
MMBaseBearer *
mm_broadband_bearer_hso_new_finish (GAsyncResult *res,
GError **error)
@@ -844,6 +802,13 @@ mm_broadband_bearer_hso_class_init (MMBroadbandBearerHsoClass *klass)
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerHsoPrivate));
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
+
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
diff --git a/plugins/option/mm-broadband-bearer-hso.h b/plugins/option/mm-broadband-bearer-hso.h
index 7812d74d..def46ac3 100644
--- a/plugins/option/mm-broadband-bearer-hso.h
+++ b/plugins/option/mm-broadband-bearer-hso.h
@@ -56,4 +56,6 @@ void mm_broadband_bearer_hso_new (MMBroadbandModemHso *modem,
MMBaseBearer *mm_broadband_bearer_hso_new_finish (GAsyncResult *res,
GError **error);
+gint mm_broadband_bearer_hso_get_connecting_profile_id (MMBroadbandBearerHso *self);
+
#endif /* MM_BROADBAND_BEARER_HSO_H */
diff --git a/plugins/option/mm-broadband-modem-hso.c b/plugins/option/mm-broadband-modem-hso.c
index d2d46891..a2cc1770 100644
--- a/plugins/option/mm-broadband-modem-hso.c
+++ b/plugins/option/mm-broadband-modem-hso.c
@@ -25,7 +25,7 @@
#include "ModemManager.h"
#include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
#include "mm-errors-types.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
@@ -34,7 +34,9 @@
#include "mm-broadband-modem-hso.h"
#include "mm-broadband-bearer-hso.h"
#include "mm-bearer-list.h"
+#include "mm-shared-option.h"
+static void shared_option_init (MMSharedOption *iface);
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_location_init (MMIfaceModemLocation *iface);
@@ -43,6 +45,7 @@ static MMIfaceModem3gpp *iface_modem_3gpp_parent;
static MMIfaceModemLocation *iface_modem_location_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemHso, mm_broadband_modem_hso, MM_TYPE_BROADBAND_MODEM_OPTION, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_OPTION, shared_option_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init));
@@ -62,52 +65,41 @@ modem_create_bearer_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- MMBaseBearer *bearer;
-
- bearer = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
- mm_dbg ("New %s bearer created at DBus path '%s'",
- MM_IS_BROADBAND_BEARER_HSO (bearer) ? "HSO" : "Generic",
- mm_base_bearer_get_path (bearer));
-
- return g_object_ref (bearer);
+ return g_task_propagate_pointer (G_TASK (res), error);
}
static void
broadband_bearer_new_ready (GObject *source,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
MMBaseBearer *bearer = NULL;
GError *error = NULL;
bearer = mm_broadband_bearer_new_finish (res, &error);
if (!bearer)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gpointer (simple,
- bearer,
- (GDestroyNotify)g_object_unref);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_pointer (task, bearer, g_object_unref);
+
+ g_object_unref (task);
}
static void
broadband_bearer_hso_new_ready (GObject *source,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
MMBaseBearer *bearer = NULL;
GError *error = NULL;
bearer = mm_broadband_bearer_hso_new_finish (res, &error);
if (!bearer)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gpointer (simple,
- bearer,
- (GDestroyNotify)g_object_unref);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_pointer (task, bearer, g_object_unref);
+
+ g_object_unref (task);
}
static void
@@ -116,30 +108,27 @@ modem_create_bearer (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_create_bearer);
+ task = g_task_new (self, NULL, callback, user_data);
if (mm_bearer_properties_get_ip_type (properties) &
(MM_BEARER_IP_FAMILY_IPV6 | MM_BEARER_IP_FAMILY_IPV4V6)) {
- mm_dbg ("Creating generic bearer (IPv6 requested)...");
+ mm_obj_dbg (self, "creating generic bearer (IPv6 requested)...");
mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
properties,
NULL, /* cancellable */
(GAsyncReadyCallback)broadband_bearer_new_ready,
- result);
+ task);
return;
}
- mm_dbg ("Creating HSO bearer...");
+ mm_obj_dbg (self, "creating HSO bearer...");
mm_broadband_bearer_hso_new (MM_BROADBAND_MODEM_HSO (self),
properties,
NULL, /* cancellable */
(GAsyncReadyCallback)broadband_bearer_hso_new_ready,
- result);
+ task);
}
/*****************************************************************************/
@@ -150,16 +139,13 @@ load_unlock_retries_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
- return (MMUnlockRetries *) g_object_ref (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res)));
+ return g_task_propagate_pointer (G_TASK (res), error);
}
static void
load_unlock_retries_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
const gchar *response;
GError *error = NULL;
@@ -167,10 +153,8 @@ load_unlock_retries_ready (MMBaseModem *self,
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
- mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
- g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -180,18 +164,15 @@ load_unlock_retries_ready (MMBaseModem *self,
retries = mm_unlock_retries_new ();
mm_unlock_retries_set (retries, MM_MODEM_LOCK_SIM_PIN, pin1);
mm_unlock_retries_set (retries, MM_MODEM_LOCK_SIM_PUK, puk1);
- g_simple_async_result_set_op_res_gpointer (operation_result,
- retries,
- (GDestroyNotify)g_object_unref);
+ g_task_return_pointer (task, retries, g_object_unref);
} else {
- g_simple_async_result_set_error (operation_result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Invalid unlock retries response: '%s'",
- response);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Invalid unlock retries response: '%s'",
+ response);
}
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_object_unref (task);
}
static void
@@ -205,10 +186,7 @@ load_unlock_retries (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)load_unlock_retries_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- load_unlock_retries));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -223,7 +201,19 @@ static void
bearer_list_report_status_foreach (MMBaseBearer *bearer,
BearerListReportStatusForeachContext *ctx)
{
- if (mm_broadband_bearer_get_3gpp_cid (MM_BROADBAND_BEARER (bearer)) != ctx->cid)
+ gint profile_id;
+ gint connecting_profile_id;
+
+ if (!MM_IS_BROADBAND_BEARER_HSO (bearer))
+ return;
+
+ /* The profile ID in the base bearer is set only once the modem is connected */
+ profile_id = mm_base_bearer_get_profile_id (bearer);
+
+ /* The profile ID in the hso bearer is available during the connecting phase */
+ connecting_profile_id = mm_broadband_bearer_hso_get_connecting_profile_id (MM_BROADBAND_BEARER_HSO (bearer));
+
+ if ((profile_id != (gint)ctx->cid) && (connecting_profile_id != (gint)ctx->cid))
return;
mm_base_bearer_report_connection_status (MM_BASE_BEARER (bearer), ctx->status);
@@ -234,7 +224,7 @@ hso_connection_status_changed (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemHso *self)
{
- MMBearerList *list = NULL;
+ g_autoptr(MMBearerList) list = NULL;
BearerListReportStatusForeachContext ctx;
guint cid;
guint status;
@@ -270,14 +260,10 @@ hso_connection_status_changed (MMPortSerialAt *port,
g_object_get (self,
MM_IFACE_MODEM_BEARER_LIST, &list,
NULL);
- if (!list)
- return;
/* Will report status only in the bearer with the specific CID */
- mm_bearer_list_foreach (list,
- (MMBearerListForeachFunc)bearer_list_report_status_foreach,
- &ctx);
- g_object_unref (list);
+ if (list)
+ mm_bearer_list_foreach (list, (MMBearerListForeachFunc)bearer_list_report_status_foreach, &ctx);
}
static gboolean
@@ -285,18 +271,18 @@ modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
parent_setup_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->setup_unsolicited_events_finish (self, res, &error))
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else {
/* Our own setup now */
mm_port_serial_at_add_unsolicited_msg_handler (
@@ -306,11 +292,9 @@ parent_setup_unsolicited_events_ready (MMIfaceModem3gpp *self,
self,
NULL);
- g_simple_async_result_set_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res), TRUE);
+ g_task_return_boolean (task, TRUE);
}
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -318,33 +302,26 @@ modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_setup_unsolicited_events);
-
/* Chain up parent's setup */
iface_modem_3gpp_parent->setup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_setup_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
static void
parent_cleanup_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->cleanup_unsolicited_events_finish (self, res, &error))
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res), TRUE);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static void
@@ -352,13 +329,6 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_cleanup_unsolicited_events);
-
/* Our own cleanup first */
mm_port_serial_at_add_unsolicited_msg_handler (
mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)),
@@ -369,7 +339,7 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
iface_modem_3gpp_parent->cleanup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_cleanup_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -380,26 +350,29 @@ location_load_capabilities_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return MM_MODEM_LOCATION_SOURCE_NONE;
+ GError *inner_error = NULL;
+ gssize value;
- return (MMModemLocationSource) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res)));
+ value = g_task_propagate_int (G_TASK (res), &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return MM_MODEM_LOCATION_SOURCE_NONE;
+ }
+ return (MMModemLocationSource)value;
}
static void
parent_load_capabilities_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
MMModemLocationSource sources;
GError *error = NULL;
sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error);
if (error) {
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -423,11 +396,8 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED);
/* So we're done, complete */
- g_simple_async_result_set_op_res_gpointer (simple,
- GUINT_TO_POINTER (sources),
- NULL);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_int (task, sources);
+ g_object_unref (task);
}
static void
@@ -435,38 +405,20 @@ location_load_capabilities (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- location_load_capabilities);
-
/* Chain up parent's setup */
iface_modem_location_parent->load_capabilities (
self,
(GAsyncReadyCallback)parent_load_capabilities_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
/* Enable/Disable location gathering (Location interface) */
typedef struct {
- MMBroadbandModemHso *self;
- GSimpleAsyncResult *result;
MMModemLocationSource source;
} LocationGatheringContext;
-static void
-location_gathering_context_complete_and_free (LocationGatheringContext *ctx)
-{
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
- g_object_unref (ctx->self);
- g_slice_free (LocationGatheringContext, ctx);
-}
-
/******************************/
/* Disable location gathering */
@@ -475,21 +427,21 @@ disable_location_gathering_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
gps_disabled_ready (MMBaseModem *self,
GAsyncResult *res,
- LocationGatheringContext *ctx)
+ GTask *task)
{
+ LocationGatheringContext *ctx;
MMPortSerialGps *gps_port;
GError *error = NULL;
- if (!mm_base_modem_at_command_full_finish (self, res, &error))
- g_simple_async_result_take_error (ctx->result, error);
- else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ mm_base_modem_at_command_full_finish (self, res, &error);
+
+ ctx = g_task_get_task_data (task);
/* Only use the GPS port in NMEA/RAW setups */
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
@@ -500,7 +452,12 @@ gps_disabled_ready (MMBaseModem *self,
mm_port_serial_close (MM_PORT_SERIAL (gps_port));
}
- location_gathering_context_complete_and_free (ctx);
+ if (error)
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static void
@@ -512,15 +469,14 @@ disable_location_gathering (MMIfaceModemLocation *self,
MMBroadbandModemHso *hso = MM_BROADBAND_MODEM_HSO (self);
gboolean stop_gps = FALSE;
LocationGatheringContext *ctx;
+ GTask *task;
- ctx = g_slice_new (LocationGatheringContext);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- disable_location_gathering);
+ ctx = g_new (LocationGatheringContext, 1);
ctx->source = source;
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, g_free);
+
/* Only stop GPS engine if no GPS-related sources enabled */
if (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
@@ -543,13 +499,13 @@ disable_location_gathering (MMIfaceModemLocation *self,
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)gps_disabled_ready,
- ctx);
+ task);
return;
}
/* For any other location (e.g. 3GPP), or if still some GPS needed, just return */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- location_gathering_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
/*****************************/
@@ -560,22 +516,25 @@ enable_location_gathering_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
gps_enabled_ready (MMBaseModem *self,
GAsyncResult *res,
- LocationGatheringContext *ctx)
+ GTask *task)
{
+ LocationGatheringContext *ctx;
GError *error = NULL;
if (!mm_base_modem_at_command_full_finish (self, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- location_gathering_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ ctx = g_task_get_task_data (task);
+
/* Only use the GPS port in NMEA/RAW setups */
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
@@ -585,37 +544,41 @@ gps_enabled_ready (MMBaseModem *self,
if (!gps_port ||
!mm_port_serial_open (MM_PORT_SERIAL (gps_port), &error)) {
if (error)
- g_simple_async_result_take_error (ctx->result, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't open raw GPS serial port");
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't open raw GPS serial port");
} else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ g_task_return_boolean (task, TRUE);
}
else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ g_task_return_boolean (task, TRUE);
- location_gathering_context_complete_and_free (ctx);
+ g_object_unref (task);
}
static void
-parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
+parent_enable_location_gathering_ready (MMIfaceModemLocation *_self,
GAsyncResult *res,
- LocationGatheringContext *ctx)
+ GTask *task)
{
+ MMBroadbandModemHso *self = MM_BROADBAND_MODEM_HSO (_self);
+ LocationGatheringContext *ctx;
gboolean start_gps = FALSE;
GError *error = NULL;
- if (!iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- location_gathering_context_complete_and_free (ctx);
+ if (!iface_modem_location_parent->enable_location_gathering_finish (_self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
/* Now our own enabling */
+ ctx = g_task_get_task_data (task);
+
/* NMEA, RAW and UNMANAGED are all enabled in the same way */
if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
MM_MODEM_LOCATION_SOURCE_GPS_RAW |
@@ -623,11 +586,11 @@ parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
/* Only start GPS engine if not done already.
* NOTE: interface already takes care of making sure that raw/nmea and
* unmanaged are not enabled at the same time */
- if (!(ctx->self->priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
- MM_MODEM_LOCATION_SOURCE_GPS_RAW |
- MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)))
+ if (!(self->priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
+ MM_MODEM_LOCATION_SOURCE_GPS_RAW |
+ MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)))
start_gps = TRUE;
- ctx->self->priv->enabled_sources |= ctx->source;
+ self->priv->enabled_sources |= ctx->source;
}
if (start_gps) {
@@ -640,13 +603,13 @@ parent_enable_location_gathering_ready (MMIfaceModemLocation *self,
FALSE, /* raw */
NULL, /* cancellable */
(GAsyncReadyCallback)gps_enabled_ready,
- ctx);
+ task);
return;
}
/* For any other location (e.g. 3GPP), or if GPS already running just return */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- location_gathering_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static void
@@ -656,52 +619,30 @@ enable_location_gathering (MMIfaceModemLocation *self,
gpointer user_data)
{
LocationGatheringContext *ctx;
+ GTask *task;
- ctx = g_slice_new (LocationGatheringContext);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- enable_location_gathering);
+ ctx = g_new (LocationGatheringContext, 1);
ctx->source = source;
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, g_free);
+
/* Chain up parent's gathering enable */
iface_modem_location_parent->enable_location_gathering (
self,
source,
(GAsyncReadyCallback)parent_enable_location_gathering_ready,
- ctx);
+ task);
}
/*****************************************************************************/
/* Setup ports (Broadband modem class) */
static void
-trace_received (MMPortSerialGps *port,
- const gchar *trace,
+trace_received (MMPortSerialGps *port,
+ const gchar *trace,
MMIfaceModemLocation *self)
{
- /* Helper to debug GPS location related issues. Don't depend on a real GPS
- * fix for debugging, just use some random values to update */
-#if 0
- if (g_str_has_prefix (trace, "$GPGGA")) {
- GString *str;
- GDateTime *now;
-
- now = g_date_time_new_now_utc ();
- str = g_string_new ("");
- g_string_append_printf (str,
- "$GPGGA,%02u%02u%02u,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
- g_date_time_get_hour (now),
- g_date_time_get_minute (now),
- g_date_time_get_second (now));
- mm_iface_modem_location_gps_update (self, str->str);
- g_string_free (str, TRUE);
- g_date_time_unref (now);
- return;
- }
-#endif
-
mm_iface_modem_location_gps_update (self, trace);
}
@@ -761,6 +702,9 @@ mm_broadband_modem_hso_new (const gchar *device,
MM_BASE_MODEM_PLUGIN, plugin,
MM_BASE_MODEM_VENDOR_ID, vendor_id,
MM_BASE_MODEM_PRODUCT_ID, product_id,
+ /* Generic bearer (AT) and HSO bearer (NET) supported */
+ MM_BASE_MODEM_DATA_NET_SUPPORTED, TRUE,
+ MM_BASE_MODEM_DATA_TTY_SUPPORTED, TRUE,
NULL);
}
@@ -788,8 +732,15 @@ mm_broadband_modem_hso_init (MMBroadbandModemHso *self)
}
static void
+shared_option_init (MMSharedOption *iface)
+{
+}
+
+static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface->create_sim = mm_shared_option_create_sim;
+ iface->create_sim_finish = mm_shared_option_create_sim_finish;
iface->create_bearer = modem_create_bearer;
iface->create_bearer_finish = modem_create_bearer_finish;
iface->load_unlock_retries = load_unlock_retries;
diff --git a/plugins/option/mm-broadband-modem-option.c b/plugins/option/mm-broadband-modem-option.c
index cf02ba30..5919364d 100644
--- a/plugins/option/mm-broadband-modem-option.c
+++ b/plugins/option/mm-broadband-modem-option.c
@@ -25,13 +25,15 @@
#include "ModemManager.h"
#include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
#include "mm-errors-types.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
#include "mm-base-modem-at.h"
#include "mm-broadband-modem-option.h"
+#include "mm-shared-option.h"
+static void shared_option_init (MMSharedOption *iface);
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
@@ -39,6 +41,7 @@ static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemOption, mm_broadband_modem_option, MM_TYPE_BROADBAND_MODEM, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_OPTION, shared_option_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init))
@@ -65,16 +68,13 @@ load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+ return g_task_propagate_pointer (G_TASK (res), error);
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
GArray *all;
@@ -84,9 +84,8 @@ parent_load_supported_modes_ready (MMIfaceModem *self,
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -115,13 +114,12 @@ parent_load_supported_modes_ready (MMIfaceModem *self,
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
- filtered = mm_filter_supported_modes (all, combinations);
+ filtered = mm_filter_supported_modes (all, combinations, self);
g_array_unref (all);
g_array_unref (combinations);
- g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_pointer (task, filtered, (GDestroyNotify) g_array_unref);
+ g_object_unref (task);
}
static void
@@ -133,10 +131,7 @@ load_supported_modes (MMIfaceModem *self,
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- load_supported_modes));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -222,24 +217,24 @@ set_current_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
-allowed_mode_update_ready (MMBroadbandModemOption *self,
+allowed_mode_update_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
GError *error = NULL;
- mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
+ mm_base_modem_at_command_finish (self, res, &error);
if (error)
/* Let the error be critical. */
- g_simple_async_result_take_error (operation_result, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gboolean (operation_result, TRUE);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static void
@@ -249,14 +244,11 @@ set_current_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
gchar *command;
gint option_mode = -1;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- set_current_modes);
+ task = g_task_new (self, NULL, callback, user_data);
if (allowed == MM_MODEM_MODE_2G)
option_mode = 0;
@@ -278,18 +270,16 @@ set_current_modes (MMIfaceModem *self,
allowed_str = mm_modem_mode_build_string_from_mask (allowed);
preferred_str = mm_modem_mode_build_string_from_mask (preferred);
- g_simple_async_result_set_error (result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Requested mode (allowed: '%s', preferred: '%s') not "
- "supported by the modem.",
- allowed_str,
- preferred_str);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Requested mode (allowed: '%s', preferred: '%s') not "
+ "supported by the modem.",
+ allowed_str,
+ preferred_str);
+ g_object_unref (task);
g_free (allowed_str);
g_free (preferred_str);
-
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
return;
}
@@ -300,7 +290,7 @@ set_current_modes (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)allowed_mode_update_ready,
- result);
+ task);
g_free (command);
}
@@ -316,24 +306,13 @@ typedef enum {
} AccessTechnologiesStep;
typedef struct {
- MMBroadbandModemOption *self;
- GSimpleAsyncResult *result;
MMModemAccessTechnology access_technology;
gboolean check_2g;
gboolean check_3g;
AccessTechnologiesStep step;
} AccessTechnologiesContext;
-static void load_access_technologies_step (AccessTechnologiesContext *ctx);
-
-static void
-access_technologies_context_complete_and_free (AccessTechnologiesContext *ctx)
-{
- g_simple_async_result_complete (ctx->result);
- g_object_unref (ctx->result);
- g_object_unref (ctx->self);
- g_free (ctx);
-}
+static void load_access_technologies_step (GTask *task);
static gboolean
load_access_technologies_finish (MMIfaceModem *self,
@@ -342,12 +321,17 @@ load_access_technologies_finish (MMIfaceModem *self,
guint *mask,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ GError *inner_error = NULL;
+ gssize value;
+
+ value = g_task_propagate_int (G_TASK (res), &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
return FALSE;
+ }
/* We are reporting ALL 3GPP access technologies here */
- *access_technologies = (MMModemAccessTechnology) GPOINTER_TO_UINT (
- g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+ *access_technologies = (MMModemAccessTechnology) value;
*mask = MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK;
return TRUE;
}
@@ -407,10 +391,13 @@ parse_ossys_response (const gchar *response,
static void
ossys_query_ready (MMBaseModem *self,
GAsyncResult *res,
- AccessTechnologiesContext *ctx)
+ GTask *task)
{
+ AccessTechnologiesContext *ctx;
const gchar *response;
+ ctx = g_task_get_task_data (task);
+
/* If for some reason the OSSYS request failed, still try to check
* explicit 2G/3G mode with OCTI and OWCTI; maybe we'll get something.
*/
@@ -429,7 +416,7 @@ ossys_query_ready (MMBaseModem *self,
/* Go on to next step */
ctx->step++;
- load_access_technologies_step (ctx);
+ load_access_technologies_step (task);
}
static gboolean
@@ -487,11 +474,14 @@ parse_octi_response (const gchar *response,
static void
octi_query_ready (MMBaseModem *self,
GAsyncResult *res,
- AccessTechnologiesContext *ctx)
+ GTask *task)
{
+ AccessTechnologiesContext *ctx;
MMModemAccessTechnology octi = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
const gchar *response;
+ ctx = g_task_get_task_data (task);
+
response = mm_base_modem_at_command_finish (self, res, NULL);
if (response &&
parse_octi_response (response, &octi)) {
@@ -504,7 +494,7 @@ octi_query_ready (MMBaseModem *self,
/* Go on to next step */
ctx->step++;
- load_access_technologies_step (ctx);
+ load_access_technologies_step (task);
}
static gboolean
@@ -544,11 +534,14 @@ parse_owcti_response (const gchar *response,
static void
owcti_query_ready (MMBaseModem *self,
GAsyncResult *res,
- AccessTechnologiesContext *ctx)
+ GTask *task)
{
+ AccessTechnologiesContext *ctx;
MMModemAccessTechnology owcti = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
const gchar *response;
+ ctx = g_task_get_task_data (task);
+
response = mm_base_modem_at_command_finish (self, res, NULL);
if (response &&
parse_owcti_response (response, &owcti)) {
@@ -557,59 +550,66 @@ owcti_query_ready (MMBaseModem *self,
/* Go on to next step */
ctx->step++;
- load_access_technologies_step (ctx);
+ load_access_technologies_step (task);
}
static void
-load_access_technologies_step (AccessTechnologiesContext *ctx)
+load_access_technologies_step (GTask *task)
{
+ MMBroadbandModemOption *self;
+ AccessTechnologiesContext *ctx;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
switch (ctx->step) {
case ACCESS_TECHNOLOGIES_STEP_FIRST:
- /* Go on to next step */
ctx->step++;
+ /* fall through */
case ACCESS_TECHNOLOGIES_STEP_OSSYS:
- mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
"_OSSYS?",
3,
FALSE,
(GAsyncReadyCallback)ossys_query_ready,
- ctx);
+ task);
break;
case ACCESS_TECHNOLOGIES_STEP_OCTI:
if (ctx->check_2g) {
- mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
"_OCTI?",
3,
FALSE,
(GAsyncReadyCallback)octi_query_ready,
- ctx);
+ task);
return;
}
- /* Go on to next step */
ctx->step++;
+ /* fall through */
case ACCESS_TECHNOLOGIES_STEP_OWCTI:
if (ctx->check_3g) {
- mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
"_OWCTI?",
3,
FALSE,
(GAsyncReadyCallback)owcti_query_ready,
- ctx);
+ task);
return;
}
- /* Go on to next step */
ctx->step++;
+ /* fall through */
case ACCESS_TECHNOLOGIES_STEP_LAST:
/* All done, set result and complete */
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- GUINT_TO_POINTER (ctx->access_technology),
- NULL);
- access_technologies_context_complete_and_free (ctx);
+ g_task_return_int (task, ctx->access_technology);
+ g_object_unref (task);
break;
+
+ default:
+ g_assert_not_reached ();
}
}
@@ -622,19 +622,18 @@ run_access_technology_loading_sequence (MMIfaceModem *self,
gpointer user_data)
{
AccessTechnologiesContext *ctx;
+ GTask *task;
ctx = g_new (AccessTechnologiesContext, 1);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- run_access_technology_loading_sequence);
ctx->step = first;
ctx->check_2g = check_2g;
ctx->check_3g = check_3g;
ctx->access_technology = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
- load_access_technologies_step (ctx);
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, g_free);
+
+ load_access_technologies_step (task);
}
static void
@@ -658,46 +657,38 @@ modem_after_power_up_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static gboolean
-after_power_up_wait_cb (GSimpleAsyncResult *result)
+after_power_up_wait_cb (GTask *task)
{
- MMBroadbandModemOption *option;
-
- option = MM_BROADBAND_MODEM_OPTION (g_async_result_get_source_object (G_ASYNC_RESULT (result)));
+ MMBroadbandModemOption *self;
- g_simple_async_result_set_op_res_gboolean (result, TRUE);
- g_simple_async_result_complete (result);
- g_object_unref (result);
+ self = g_task_get_source_object (task);
+ self->priv->after_power_up_wait_id = 0;
- option->priv->after_power_up_wait_id = 0;
- g_object_unref (option);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
static void
-modem_after_power_up (MMIfaceModem *self,
+modem_after_power_up (MMIfaceModem *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- MMBroadbandModemOption *option = MM_BROADBAND_MODEM_OPTION (self);
- GSimpleAsyncResult *result;
+ MMBroadbandModemOption *self = MM_BROADBAND_MODEM_OPTION (_self);
/* Some Option devices return OK on +CFUN=1 right away but need some time
* to finish initialization.
*/
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_after_power_up);
- g_warn_if_fail (option->priv->after_power_up_wait_id == 0);
- option->priv->after_power_up_wait_id =
+ g_warn_if_fail (self->priv->after_power_up_wait_id == 0);
+ self->priv->after_power_up_wait_id =
g_timeout_add_seconds (10,
(GSourceFunc)after_power_up_wait_cb,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -724,7 +715,6 @@ modem_3gpp_load_imei_finish (MMIfaceModem3gpp *self,
if (comma)
*comma = '\0';
- mm_dbg ("loaded IMEI: %s", imei);
return imei;
}
@@ -733,7 +723,6 @@ modem_3gpp_load_imei (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- mm_dbg ("loading (Option) IMEI...");
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CGSN",
3,
@@ -820,7 +809,7 @@ option_signal_changed (MMPortSerialAt *port,
MMBroadbandModemOption *self)
{
gchar *str;
- gint quality = 0;
+ guint quality = 0;
str = g_match_info_fetch (match_info, 1);
if (str) {
@@ -833,10 +822,10 @@ option_signal_changed (MMPortSerialAt *port,
quality = 0;
} else {
/* Normalize the quality */
- quality = CLAMP (quality, 0, 31) * 100 / 31;
+ quality = MM_CLAMP_HIGH (quality, 31) * 100 / 31;
}
- mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), (guint)quality);
+ mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
}
static void
@@ -850,7 +839,7 @@ set_unsolicited_events_handlers (MMBroadbandModemOption *self,
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
/* Enable unsolicited events in given port */
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < G_N_ELEMENTS (ports); i++) {
if (!ports[i])
continue;
@@ -896,26 +885,25 @@ modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
parent_setup_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->setup_unsolicited_events_finish (self, res, &error))
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else {
/* Our own setup now */
set_unsolicited_events_handlers (MM_BROADBAND_MODEM_OPTION (self), TRUE);
- g_simple_async_result_set_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res), TRUE);
+ g_task_return_boolean (task, TRUE);
}
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -923,33 +911,26 @@ modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_setup_unsolicited_events);
-
/* Chain up parent's setup */
iface_modem_3gpp_parent->setup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_setup_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
static void
parent_cleanup_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->cleanup_unsolicited_events_finish (self, res, &error))
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res), TRUE);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static void
@@ -957,13 +938,6 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_cleanup_unsolicited_events);
-
/* Our own cleanup first */
set_unsolicited_events_handlers (MM_BROADBAND_MODEM_OPTION (self), FALSE);
@@ -971,7 +945,7 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
iface_modem_3gpp_parent->cleanup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_cleanup_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -982,23 +956,23 @@ modem_3gpp_enable_unsolicited_events_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
own_enable_unsolicited_events_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
mm_base_modem_at_sequence_full_finish (self, res, NULL, &error);
if (error)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static const MMBaseModemAtCommand unsolicited_enable_sequence[] = {
@@ -1012,14 +986,13 @@ static const MMBaseModemAtCommand unsolicited_enable_sequence[] = {
static void
parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (self, res, &error)) {
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_error (task, error);
+ g_object_unref (task);
}
/* Our own enable now */
@@ -1031,7 +1004,7 @@ parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
NULL, /* response_processor_context_free */
NULL, /* cancellable */
(GAsyncReadyCallback)own_enable_unsolicited_events_ready,
- simple);
+ task);
}
static void
@@ -1039,18 +1012,11 @@ modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_enable_unsolicited_events);
-
/* Chain up parent's enable */
iface_modem_3gpp_parent->enable_unsolicited_events (
self,
(GAsyncReadyCallback)parent_enable_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -1061,7 +1027,7 @@ modem_3gpp_disable_unsolicited_events_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static const MMBaseModemAtCommand unsolicited_disable_sequence[] = {
@@ -1075,30 +1041,29 @@ static const MMBaseModemAtCommand unsolicited_disable_sequence[] = {
static void
parent_disable_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!iface_modem_3gpp_parent->disable_unsolicited_events_finish (self, res, &error))
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
}
static void
own_disable_unsolicited_events_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
mm_base_modem_at_sequence_full_finish (self, res, NULL, &error);
if (error) {
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -1106,7 +1071,7 @@ own_disable_unsolicited_events_ready (MMBaseModem *self,
iface_modem_3gpp_parent->disable_unsolicited_events (
MM_IFACE_MODEM_3GPP (self),
(GAsyncReadyCallback)parent_disable_unsolicited_events_ready,
- simple);
+ task);
}
static void
@@ -1114,13 +1079,6 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_disable_unsolicited_events);
-
/* Our own disable first */
mm_base_modem_at_sequence_full (
MM_BASE_MODEM (self),
@@ -1130,7 +1088,7 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
NULL, /* response_processor_context_free */
NULL, /* cancellable */
(GAsyncReadyCallback)own_disable_unsolicited_events_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -1181,6 +1139,9 @@ mm_broadband_modem_option_new (const gchar *device,
MM_BASE_MODEM_PLUGIN, plugin,
MM_BASE_MODEM_VENDOR_ID, vendor_id,
MM_BASE_MODEM_PRODUCT_ID, product_id,
+ /* Generic bearer supports TTY only */
+ MM_BASE_MODEM_DATA_NET_SUPPORTED, FALSE,
+ MM_BASE_MODEM_DATA_TTY_SUPPORTED, TRUE,
MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS, ignored,
NULL);
}
@@ -1222,10 +1183,17 @@ mm_broadband_modem_option_init (MMBroadbandModemOption *self)
}
static void
+shared_option_init (MMSharedOption *iface)
+{
+}
+
+static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
+ iface->create_sim = mm_shared_option_create_sim;
+ iface->create_sim_finish = mm_shared_option_create_sim_finish;
iface->modem_after_power_up = modem_after_power_up;
iface->modem_after_power_up_finish = modem_after_power_up_finish;
iface->load_access_technologies = load_access_technologies;
diff --git a/plugins/option/mm-plugin-hso.c b/plugins/option/mm-plugin-hso.c
index 94400c15..dbc41c11 100644
--- a/plugins/option/mm-plugin-hso.c
+++ b/plugins/option/mm-plugin-hso.c
@@ -24,12 +24,12 @@
#include "mm-private-boxed-types.h"
#include "mm-plugin-hso.h"
#include "mm-broadband-modem-hso.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
G_DEFINE_TYPE (MMPluginHso, mm_plugin_hso, MM_TYPE_PLUGIN)
-int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION;
-int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
+MM_PLUGIN_DEFINE_MAJOR_VERSION
+MM_PLUGIN_DEFINE_MINOR_VERSION
/*****************************************************************************/
/* Custom init */
@@ -46,7 +46,7 @@ hso_custom_init_finish (MMPortProbe *probe,
GAsyncResult *result,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static void
@@ -56,13 +56,13 @@ hso_custom_init (MMPortProbe *probe,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GUdevDevice *udev_port;
- GSimpleAsyncResult *result;
+ MMKernelDevice *kernel_port;
+ GTask *task;
const gchar *subsys, *sysfs_path;
subsys = mm_port_probe_get_port_subsys (probe);
- udev_port = mm_port_probe_peek_port (probe);
- sysfs_path = g_udev_device_get_sysfs_path (udev_port);
+ kernel_port = mm_port_probe_peek_port (probe);
+ sysfs_path = mm_kernel_device_get_sysfs_path (kernel_port);
if (g_str_equal (subsys, "tty")) {
gchar *hsotype_path;
@@ -70,7 +70,7 @@ hso_custom_init (MMPortProbe *probe,
hsotype_path = g_build_filename (sysfs_path, "hsotype", NULL);
if (g_file_get_contents (hsotype_path, &contents, NULL, NULL)) {
- mm_dbg ("HSO port type %s: %s", hsotype_path, contents);
+ mm_obj_dbg (probe, "HSO port type %s: %s", hsotype_path, contents);
if (g_str_has_prefix (contents, "Control")) {
g_object_set_data (G_OBJECT (probe), TAG_HSO_AT_CONTROL, GUINT_TO_POINTER (TRUE));
mm_port_probe_set_result_at (probe, TRUE);
@@ -102,27 +102,23 @@ hso_custom_init (MMPortProbe *probe,
g_free (hsotype_path);
}
- result = g_simple_async_result_new (G_OBJECT (probe),
- callback,
- user_data,
- hso_custom_init);
- g_simple_async_result_set_op_res_gboolean (result, TRUE);
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
+ task = g_task_new (probe, NULL, callback, user_data);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
/*****************************************************************************/
static MMBaseModem *
create_modem (MMPlugin *self,
- const gchar *sysfs_path,
+ const gchar *uid,
const gchar **drivers,
guint16 vendor,
guint16 product,
GList *probes,
GError **error)
{
- return MM_BASE_MODEM (mm_broadband_modem_hso_new (sysfs_path,
+ return MM_BASE_MODEM (mm_broadband_modem_hso_new (uid,
drivers,
mm_plugin_get_name (self),
vendor,
@@ -160,9 +156,7 @@ grab_port (MMPlugin *self,
}
return mm_base_modem_grab_port (modem,
- subsys,
- mm_port_probe_get_port_name (probe),
- mm_port_probe_get_parent_path (probe),
+ mm_port_probe_peek_port (probe),
port_type,
pflags,
error);
@@ -182,12 +176,13 @@ mm_plugin_create (void)
return MM_PLUGIN (
g_object_new (MM_TYPE_PLUGIN_HSO,
- MM_PLUGIN_NAME, "Option High-Speed",
+ MM_PLUGIN_NAME, MM_MODULE_NAME,
MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
MM_PLUGIN_ALLOWED_DRIVERS, drivers,
MM_PLUGIN_ALLOWED_AT, TRUE,
MM_PLUGIN_ALLOWED_QCDM, TRUE,
MM_PLUGIN_CUSTOM_INIT, &custom_init,
+ MM_PLUGIN_SEND_DELAY, (guint64) 0,
NULL));
}
diff --git a/plugins/option/mm-plugin-option.c b/plugins/option/mm-plugin-option.c
index 010e597b..1f72325c 100644
--- a/plugins/option/mm-plugin-option.c
+++ b/plugins/option/mm-plugin-option.c
@@ -27,21 +27,21 @@
G_DEFINE_TYPE (MMPluginOption, mm_plugin_option, MM_TYPE_PLUGIN)
-int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION;
-int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
+MM_PLUGIN_DEFINE_MAJOR_VERSION
+MM_PLUGIN_DEFINE_MINOR_VERSION
/*****************************************************************************/
static MMBaseModem *
create_modem (MMPlugin *self,
- const gchar *sysfs_path,
+ const gchar *uid,
const gchar **drivers,
guint16 vendor,
guint16 product,
GList *probes,
GError **error)
{
- return MM_BASE_MODEM (mm_broadband_modem_option_new (sysfs_path,
+ return MM_BASE_MODEM (mm_broadband_modem_option_new (uid,
drivers,
mm_plugin_get_name (self),
vendor,
@@ -55,7 +55,7 @@ grab_port (MMPlugin *self,
GError **error)
{
MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE;
- GUdevDevice *port;
+ MMKernelDevice *port;
gint usbif;
/* The Option plugin cannot do anything with non-AT ports */
@@ -73,14 +73,12 @@ grab_port (MMPlugin *self,
* the modem/data port, per mail with Option engineers. Only this port
* will emit responses to dialing commands.
*/
- usbif = g_udev_device_get_property_as_int (port, "ID_USB_INTERFACE_NUM");
+ usbif = mm_kernel_device_get_interface_number (port);
if (usbif == 0)
pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY | MM_PORT_SERIAL_AT_FLAG_PPP;
return mm_base_modem_grab_port (modem,
- mm_port_probe_get_port_subsys (probe),
- mm_port_probe_get_port_name (probe),
- mm_port_probe_get_parent_path (probe),
+ port,
MM_PORT_TYPE_AT, /* we only allow AT ports here */
pflags,
error);
@@ -99,7 +97,7 @@ mm_plugin_create (void)
return MM_PLUGIN (
g_object_new (MM_TYPE_PLUGIN_OPTION,
- MM_PLUGIN_NAME, "Option",
+ MM_PLUGIN_NAME, MM_MODULE_NAME,
MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
MM_PLUGIN_ALLOWED_DRIVERS, drivers,
MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
diff --git a/plugins/option/mm-shared-option.c b/plugins/option/mm-shared-option.c
new file mode 100644
index 00000000..a06888a1
--- /dev/null
+++ b/plugins/option/mm-shared-option.c
@@ -0,0 +1,77 @@
+/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-log-object.h"
+#include "mm-iface-modem.h"
+#include "mm-sim-option.h"
+#include "mm-shared-option.h"
+
+/*****************************************************************************/
+/* Create SIM (Modem inteface) */
+
+MMBaseSim *
+mm_shared_option_create_sim_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return mm_sim_option_new_finish (res, error);
+}
+
+void
+mm_shared_option_create_sim (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ mm_sim_option_new (MM_BASE_MODEM (self),
+ NULL, /* cancellable */
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
+
+static void
+shared_option_init (gpointer g_iface)
+{
+}
+
+GType
+mm_shared_option_get_type (void)
+{
+ static GType shared_option_type = 0;
+
+ if (!G_UNLIKELY (shared_option_type)) {
+ static const GTypeInfo info = {
+ sizeof (MMSharedOption), /* class_size */
+ shared_option_init, /* base_init */
+ NULL, /* base_finalize */
+ };
+
+ shared_option_type = g_type_register_static (G_TYPE_INTERFACE, "MMSharedOption", &info, 0);
+ g_type_interface_add_prerequisite (shared_option_type, MM_TYPE_IFACE_MODEM);
+ }
+
+ return shared_option_type;
+}
diff --git a/plugins/option/mm-shared-option.h b/plugins/option/mm-shared-option.h
new file mode 100644
index 00000000..0d4baf60
--- /dev/null
+++ b/plugins/option/mm-shared-option.h
@@ -0,0 +1,49 @@
+/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#ifndef MM_SHARED_OPTION_H
+#define MM_SHARED_OPTION_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-broadband-modem.h"
+#include "mm-iface-modem.h"
+#include "mm-iface-modem-location.h"
+
+#define MM_TYPE_SHARED_OPTION (mm_shared_option_get_type ())
+#define MM_SHARED_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SHARED_OPTION, MMSharedOption))
+#define MM_IS_SHARED_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SHARED_OPTION))
+#define MM_SHARED_OPTION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_SHARED_OPTION, MMSharedOption))
+
+typedef struct _MMSharedOption MMSharedOption;
+
+struct _MMSharedOption {
+ GTypeInterface g_iface;
+};
+
+GType mm_shared_option_get_type (void);
+
+void mm_shared_option_create_sim (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+MMBaseSim *mm_shared_option_create_sim_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif /* MM_SHARED_OPTION_H */
diff --git a/plugins/option/mm-shared.c b/plugins/option/mm-shared.c
new file mode 100644
index 00000000..3f89d86a
--- /dev/null
+++ b/plugins/option/mm-shared.c
@@ -0,0 +1,20 @@
+/* -*- 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) 2019 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include "mm-shared.h"
+
+MM_SHARED_DEFINE_MAJOR_VERSION
+MM_SHARED_DEFINE_MINOR_VERSION
+MM_SHARED_DEFINE_NAME(Option)
diff --git a/plugins/option/mm-sim-option.c b/plugins/option/mm-sim-option.c
new file mode 100644
index 00000000..0871c4f2
--- /dev/null
+++ b/plugins/option/mm-sim-option.c
@@ -0,0 +1,84 @@
+/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <ModemManager.h>
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-sim-option.h"
+
+G_DEFINE_TYPE (MMSimOption, mm_sim_option, MM_TYPE_BASE_SIM)
+
+/*****************************************************************************/
+
+MMBaseSim *
+mm_sim_option_new_finish (GAsyncResult *res,
+ GError **error)
+{
+ GObject *source;
+ GObject *sim;
+
+ source = g_async_result_get_source_object (res);
+ sim = g_async_initable_new_finish (G_ASYNC_INITABLE (source), res, error);
+ g_object_unref (source);
+
+ if (!sim)
+ return NULL;
+
+ /* Only export valid SIMs */
+ mm_base_sim_export (MM_BASE_SIM (sim));
+
+ return MM_BASE_SIM (sim);
+}
+
+void
+mm_sim_option_new (MMBaseModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_async_initable_new_async (MM_TYPE_SIM_OPTION,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ callback,
+ user_data,
+ MM_BASE_SIM_MODEM, modem,
+ "active", TRUE, /* by default always active */
+ NULL);
+}
+
+static void
+mm_sim_option_init (MMSimOption *self)
+{
+}
+
+static void
+mm_sim_option_class_init (MMSimOptionClass *klass)
+{
+ MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass);
+
+ /* Skip managing preferred networks, not supported by Option modems */
+ base_sim_class->load_preferred_networks = NULL;
+ base_sim_class->load_preferred_networks_finish = NULL;
+ base_sim_class->set_preferred_networks = NULL;
+ base_sim_class->set_preferred_networks_finish = NULL;
+}
diff --git a/plugins/option/mm-sim-option.h b/plugins/option/mm-sim-option.h
new file mode 100644
index 00000000..c502a397
--- /dev/null
+++ b/plugins/option/mm-sim-option.h
@@ -0,0 +1,51 @@
+/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#ifndef MM_SIM_OPTION_H
+#define MM_SIM_OPTION_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "mm-base-sim.h"
+
+#define MM_TYPE_SIM_OPTION (mm_sim_option_get_type ())
+#define MM_SIM_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_OPTION, MMSimOption))
+#define MM_SIM_OPTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_SIM_OPTION, MMSimOptionClass))
+#define MM_IS_SIM_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SIM_OPTION))
+#define MM_IS_SIM_OPTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_SIM_OPTION))
+#define MM_SIM_OPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_SIM_OPTION, MMSimOptionClass))
+
+typedef struct _MMSimOption MMSimOption;
+typedef struct _MMSimOptionClass MMSimOptionClass;
+
+struct _MMSimOption {
+ MMBaseSim parent;
+};
+
+struct _MMSimOptionClass {
+ MMBaseSimClass parent;
+};
+
+GType mm_sim_option_get_type (void);
+
+void mm_sim_option_new (MMBaseModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+MMBaseSim *mm_sim_option_new_finish (GAsyncResult *res,
+ GError **error);
+
+#endif /* MM_SIM_OPTION_H */