diff options
Diffstat (limited to 'plugins/option')
-rw-r--r-- | plugins/option/mm-broadband-bearer-hso.c | 597 | ||||
-rw-r--r-- | plugins/option/mm-broadband-bearer-hso.h | 2 | ||||
-rw-r--r-- | plugins/option/mm-broadband-modem-hso.c | 337 | ||||
-rw-r--r-- | plugins/option/mm-broadband-modem-option.c | 316 | ||||
-rw-r--r-- | plugins/option/mm-plugin-hso.c | 39 | ||||
-rw-r--r-- | plugins/option/mm-plugin-option.c | 18 | ||||
-rw-r--r-- | plugins/option/mm-shared-option.c | 77 | ||||
-rw-r--r-- | plugins/option/mm-shared-option.h | 49 | ||||
-rw-r--r-- | plugins/option/mm-shared.c | 20 | ||||
-rw-r--r-- | plugins/option/mm-sim-option.c | 84 | ||||
-rw-r--r-- | plugins/option/mm-sim-option.h | 51 |
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 */ |