summaryrefslogtreecommitdiff
path: root/plugins/icera/mm-broadband-modem-icera.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/icera/mm-broadband-modem-icera.c')
-rw-r--r--plugins/icera/mm-broadband-modem-icera.c973
1 files changed, 668 insertions, 305 deletions
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
index 730a79fb..e60d4bd5 100644
--- a/plugins/icera/mm-broadband-modem-icera.c
+++ b/plugins/icera/mm-broadband-modem-icera.c
@@ -25,27 +25,33 @@
#include "ModemManager.h"
#include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
#include "mm-modem-helpers.h"
#include "mm-errors-types.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
+#include "mm-iface-modem-3gpp-profile-manager.h"
#include "mm-iface-modem-time.h"
+#include "mm-common-helpers.h"
#include "mm-base-modem-at.h"
#include "mm-bearer-list.h"
#include "mm-broadband-bearer-icera.h"
#include "mm-broadband-modem-icera.h"
+#include "mm-modem-helpers-icera.h"
-static void iface_modem_init (MMIfaceModem *iface);
-static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
-static void iface_modem_time_init (MMIfaceModemTime *iface);
+static void iface_modem_init (MMIfaceModem *iface);
+static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
+static void iface_modem_3gpp_profile_manager_init (MMIfaceModem3gppProfileManager *iface);
+static void iface_modem_time_init (MMIfaceModemTime *iface);
-static MMIfaceModem *iface_modem_parent;
-static MMIfaceModem3gpp *iface_modem_3gpp_parent;
+static MMIfaceModem *iface_modem_parent;
+static MMIfaceModem3gpp *iface_modem_3gpp_parent;
+static MMIfaceModem3gppProfileManager *iface_modem_3gpp_profile_manager_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIcera, mm_broadband_modem_icera, MM_TYPE_BROADBAND_MODEM, 0,
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_3GPP_PROFILE_MANAGER, iface_modem_3gpp_profile_manager_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init))
enum {
@@ -71,38 +77,38 @@ struct _MMBroadbandModemIceraPrivate {
/* Load supported modes (Modem interface) */
static void
-add_supported_mode (GArray **combinations,
- guint mode)
+add_supported_mode (MMBroadbandModemIcera *self,
+ GArray **combinations,
+ guint mode)
{
MMModemModeCombination combination;
switch (mode) {
case 0:
- mm_dbg ("Modem supports 2G-only mode");
+ mm_obj_dbg (self, "2G-only mode supported");
combination.allowed = MM_MODEM_MODE_2G;
combination.preferred = MM_MODEM_MODE_NONE;
break;
case 1:
- mm_dbg ("Modem supports 3G-only mode");
+ mm_obj_dbg (self, "3G-only mode supported");
combination.allowed = MM_MODEM_MODE_3G;
combination.preferred = MM_MODEM_MODE_NONE;
break;
case 2:
- mm_dbg ("Modem supports 2G/3G mode with 2G preferred");
+ mm_obj_dbg (self, "2G/3G mode with 2G preferred supported");
combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
combination.preferred = MM_MODEM_MODE_2G;
break;
case 3:
- mm_dbg ("Modem supports 2G/3G mode with 3G preferred");
+ mm_obj_dbg (self, "2G/3G mode with 3G preferred supported");
combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
combination.preferred = MM_MODEM_MODE_3G;
break;
case 5:
- mm_dbg ("Modem supports 'any', but not explicitly listing it");
/* Any, no need to add it to the list */
return;
default:
- mm_warn ("Unsupported Icera mode found: %u", mode);
+ mm_obj_warn (self, "unsupported mode found in %%IPSYS=?: %u", mode);
return;
}
@@ -182,18 +188,18 @@ load_supported_modes_finish (MMIfaceModem *self,
guint j;
for (j = modefirst; j <= modelast; j++)
- add_supported_mode (&combinations, j);
+ add_supported_mode (MM_BROADBAND_MODEM_ICERA (self), &combinations, j);
} else
- mm_warn ("Couldn't parse mode interval (%s) in %%IPSYS=? response", split[i]);
+ mm_obj_warn (self, "couldn't parse mode interval in %%IPSYS=? response: %s", split[i]);
g_free (first);
} else {
guint mode;
/* Add single */
if (mm_get_uint_from_str (split[i], &mode))
- add_supported_mode (&combinations, mode);
+ add_supported_mode (MM_BROADBAND_MODEM_ICERA (self), &combinations, mode);
else
- mm_warn ("Couldn't parse mode (%s) in %%IPSYS=? response", split[i]);
+ mm_obj_warn (self, "couldn't parse mode in %%IPSYS=? response: %s", split[i]);
}
}
@@ -305,24 +311,24 @@ modem_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 (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
GError *error = NULL;
mm_base_modem_at_command_finish (MM_BASE_MODEM (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
@@ -332,14 +338,11 @@ modem_set_current_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
gchar *command;
gint icera_mode = -1;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_set_current_modes);
+ task = g_task_new (self, NULL, callback, user_data);
/*
* The core has checked the following:
@@ -366,18 +369,16 @@ modem_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;
}
@@ -388,7 +389,7 @@ modem_set_current_modes (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)allowed_mode_update_ready,
- result);
+ task);
g_free (command);
}
@@ -404,12 +405,21 @@ static void
bearer_list_report_status_foreach (MMBaseBearer *bearer,
BearerListReportStatusForeachContext *ctx)
{
- if (mm_broadband_bearer_get_3gpp_cid (MM_BROADBAND_BEARER (bearer)) != ctx->cid)
- return;
+ gint profile_id;
+ gint connecting_profile_id;
if (!MM_IS_BROADBAND_BEARER_ICERA (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 icera bearer is available during the connecting phase */
+ connecting_profile_id = mm_broadband_bearer_icera_get_connecting_profile_id (MM_BROADBAND_BEARER_ICERA (bearer));
+
+ if ((profile_id != (gint)ctx->cid) && (connecting_profile_id != (gint)ctx->cid))
+ return;
+
mm_base_bearer_report_connection_status (bearer, ctx->status);
}
@@ -446,7 +456,7 @@ ipdpact_received (MMPortSerialAt *port,
ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED;
break;
default:
- mm_warn ("Unknown Icera connect status %d", status);
+ mm_obj_warn (self, "unknown %%IPDPACT connect status %d", status);
break;
}
@@ -555,7 +565,7 @@ set_unsolicited_events_handlers (MMBroadbandModemIcera *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;
@@ -597,12 +607,16 @@ modem_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;
+ }
- *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_MODEM_ACCESS_TECHNOLOGY_ANY;
return TRUE;
}
@@ -610,26 +624,22 @@ modem_load_access_technologies_finish (MMIfaceModem *self,
static void
nwstate_query_ready (MMBroadbandModemIcera *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
GError *error = NULL;
mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
- if (error) {
- mm_dbg ("Couldn't query access technology: '%s'", error->message);
- g_simple_async_result_take_error (operation_result, error);
- } else {
+ if (error)
+ g_task_return_error (task, error);
+ else {
/*
* The unsolicited message handler will already have run and
* removed the NWSTATE response, so we use the result from there.
*/
- g_simple_async_result_set_op_res_gpointer (operation_result,
- GUINT_TO_POINTER (self->priv->last_act),
- NULL);
+ g_task_return_int (task, self->priv->last_act);
}
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_object_unref (task);
}
static void
@@ -637,12 +647,9 @@ modem_load_access_technologies (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_load_access_technologies);
+ task = g_task_new (self, NULL, callback, user_data);
mm_base_modem_at_command (
MM_BASE_MODEM (self),
@@ -650,7 +657,7 @@ modem_load_access_technologies (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)nwstate_query_ready,
- result);
+ task);
}
/*****************************************************************************/
@@ -661,26 +668,24 @@ 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_ICERA (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
@@ -692,25 +697,21 @@ modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *self,
iface_modem_3gpp_parent->setup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_setup_unsolicited_events_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_setup_unsolicited_events));
+ 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
@@ -718,13 +719,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_ICERA (self), FALSE);
@@ -732,7 +726,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));
}
/*****************************************************************************/
@@ -743,35 +737,33 @@ modem_3gpp_enable_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 void
own_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (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
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);
return;
}
@@ -782,7 +774,7 @@ parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
3,
FALSE,
(GAsyncReadyCallback)own_enable_unsolicited_events_ready,
- simple);
+ task);
}
static void
@@ -794,38 +786,33 @@ modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self,
iface_modem_3gpp_parent->enable_unsolicited_events (
self,
(GAsyncReadyCallback)parent_enable_unsolicited_events_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_enable_unsolicited_events));
+ g_task_new (self, NULL, callback, user_data));
}
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 (MMIfaceModem3gpp *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (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);
return;
}
@@ -833,7 +820,7 @@ own_disable_unsolicited_events_ready (MMIfaceModem3gpp *self,
iface_modem_3gpp_parent->disable_unsolicited_events (
MM_IFACE_MODEM_3GPP (self),
(GAsyncReadyCallback)parent_disable_unsolicited_events_ready,
- simple);
+ task);
}
static void
@@ -847,10 +834,7 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
3,
FALSE,
(GAsyncReadyCallback)own_disable_unsolicited_events_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_disable_unsolicited_events));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -861,84 +845,72 @@ modem_create_bearer_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return MM_BASE_BEARER (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
broadband_bearer_icera_new_ready (GObject *source,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
MMBaseBearer *bearer = NULL;
GError *error = NULL;
bearer = mm_broadband_bearer_icera_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_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
-modem_create_bearer (MMIfaceModem *self,
- MMBearerProperties *properties,
- GAsyncReadyCallback callback,
- gpointer user_data)
+modem_create_bearer (MMIfaceModem *self,
+ MMBearerProperties *props,
+ 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 we get a NET port, create Icera bearer */
if (mm_base_modem_peek_best_data_port (MM_BASE_MODEM (self), MM_PORT_TYPE_NET)) {
mm_broadband_bearer_icera_new (
MM_BROADBAND_MODEM (self),
MM_BROADBAND_MODEM_ICERA (self)->priv->default_ip_method,
- properties,
+ props,
NULL, /* cancellable */
(GAsyncReadyCallback)broadband_bearer_icera_new_ready,
- result);
+ task);
return;
}
/* Otherwise, plain generic broadband bearer */
mm_broadband_bearer_new (
MM_BROADBAND_MODEM (self),
- properties,
+ props,
NULL, /* cancellable */
(GAsyncReadyCallback)broadband_bearer_new_ready,
- result);
+ task);
}
/*****************************************************************************/
@@ -949,13 +921,13 @@ modem_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 void
cfun_enable_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
@@ -964,13 +936,14 @@ cfun_enable_ready (MMBaseModem *self,
if (g_error_matches (error,
MM_MOBILE_EQUIPMENT_ERROR,
MM_MOBILE_EQUIPMENT_ERROR_NOT_ALLOWED))
- g_simple_async_result_take_error (simple, error);
- else
+ g_task_return_error (task, error);
+ else {
g_error_free (error);
+ g_task_return_boolean (task, TRUE);
+ }
}
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -978,19 +951,12 @@ modem_power_up (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_power_up);
-
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CFUN=1",
10,
FALSE,
(GAsyncReadyCallback)cfun_enable_ready,
- result);
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -1056,16 +1022,13 @@ modem_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;
@@ -1073,10 +1036,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;
}
@@ -1088,18 +1049,15 @@ load_unlock_retries_ready (MMBaseModem *self,
mm_unlock_retries_set (retries, MM_MODEM_LOCK_SIM_PUK, puk1);
mm_unlock_retries_set (retries, MM_MODEM_LOCK_SIM_PIN2, pin2);
mm_unlock_retries_set (retries, MM_MODEM_LOCK_SIM_PUK2, puk2);
- 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
@@ -1113,10 +1071,7 @@ modem_load_unlock_retries (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)load_unlock_retries_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_load_unlock_retries));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -1137,20 +1092,20 @@ band_free (Band *b)
static const Band modem_bands[] = {
/* Sort 3G first since it's preferred */
- { MM_MODEM_BAND_U2100, "FDD_BAND_I", FALSE },
- { MM_MODEM_BAND_U1900, "FDD_BAND_II", FALSE },
- { MM_MODEM_BAND_U1800, "FDD_BAND_III", FALSE },
- { MM_MODEM_BAND_U17IV, "FDD_BAND_IV", FALSE },
- { MM_MODEM_BAND_U800, "FDD_BAND_VI", FALSE },
- { MM_MODEM_BAND_U850, "FDD_BAND_V", FALSE },
- { MM_MODEM_BAND_U900, "FDD_BAND_VIII", FALSE },
+ { MM_MODEM_BAND_UTRAN_1, (gchar *) "FDD_BAND_I", FALSE },
+ { MM_MODEM_BAND_UTRAN_2, (gchar *) "FDD_BAND_II", FALSE },
+ { MM_MODEM_BAND_UTRAN_3, (gchar *) "FDD_BAND_III", FALSE },
+ { MM_MODEM_BAND_UTRAN_4, (gchar *) "FDD_BAND_IV", FALSE },
+ { MM_MODEM_BAND_UTRAN_5, (gchar *) "FDD_BAND_V", FALSE },
+ { MM_MODEM_BAND_UTRAN_6, (gchar *) "FDD_BAND_VI", FALSE },
+ { MM_MODEM_BAND_UTRAN_8, (gchar *) "FDD_BAND_VIII", FALSE },
/* 2G second */
- { MM_MODEM_BAND_G850, "G850", FALSE },
- { MM_MODEM_BAND_DCS, "DCS", FALSE },
- { MM_MODEM_BAND_EGSM, "EGSM", FALSE },
- { MM_MODEM_BAND_PCS, "PCS", FALSE },
+ { MM_MODEM_BAND_G850, (gchar *) "G850", FALSE },
+ { MM_MODEM_BAND_DCS, (gchar *) "DCS", FALSE },
+ { MM_MODEM_BAND_EGSM, (gchar *) "EGSM", FALSE },
+ { MM_MODEM_BAND_PCS, (gchar *) "PCS", FALSE },
/* And ANY last since it's most inclusive */
- { MM_MODEM_BAND_ANY, "ANY", FALSE },
+ { MM_MODEM_BAND_ANY, (gchar *) "ANY", FALSE },
};
static const guint modem_band_any_bit = 1 << (G_N_ELEMENTS (modem_bands) - 1);
@@ -1158,7 +1113,7 @@ static const guint modem_band_any_bit = 1 << (G_N_ELEMENTS (modem_bands) - 1);
static MMModemBand
icera_band_to_mm (const char *icera)
{
- int i;
+ guint i;
for (i = 0 ; i < G_N_ELEMENTS (modem_bands); i++) {
if (g_strcmp0 (icera, modem_bands[i].name) == 0)
@@ -1219,7 +1174,7 @@ parse_bands (const gchar *response, guint32 *out_len)
/* Load supported bands (Modem interface) */
typedef struct {
- MMBaseModemAtCommand *cmds;
+ MMBaseModemAtCommandAlloc *cmds;
GSList *check_bands;
GSList *enabled_bands;
guint32 idx;
@@ -1231,7 +1186,7 @@ supported_bands_context_free (SupportedBandsContext *ctx)
guint i;
for (i = 0; ctx->cmds[i].command; i++)
- g_free (ctx->cmds[i].command);
+ mm_base_modem_at_command_alloc_clear (&ctx->cmds[i]);
g_free (ctx->cmds);
g_slist_free_full (ctx->check_bands, (GDestroyNotify) band_free);
g_slist_free_full (ctx->enabled_bands, (GDestroyNotify) band_free);
@@ -1243,17 +1198,13 @@ modem_load_supported_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return (GArray *) 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
load_supported_bands_ready (MMBaseModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *simple)
+ GTask *task)
{
GError *error = NULL;
SupportedBandsContext *ctx = NULL;
@@ -1262,7 +1213,7 @@ load_supported_bands_ready (MMBaseModem *self,
mm_base_modem_at_sequence_finish (self, res, (gpointer) &ctx, &error);
if (error)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else {
bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), ctx->idx);
@@ -1282,26 +1233,26 @@ load_supported_bands_ready (MMBaseModem *self,
g_array_prepend_val (bands, b->band);
}
- g_simple_async_result_set_op_res_gpointer (simple,
- bands,
- (GDestroyNotify) g_array_unref);
+ g_task_return_pointer (task, bands, (GDestroyNotify) g_array_unref);
}
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
-static gboolean
-load_supported_bands_response_processor (MMBaseModem *self,
- gpointer context,
- const gchar *command,
- const gchar *response,
- gboolean last_command,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- SupportedBandsContext *ctx = context;
- Band *b = g_slist_nth_data (ctx->check_bands, ctx->idx++);
+static MMBaseModemAtResponseProcessorResult
+load_supported_bands_response_processor (MMBaseModem *self,
+ gpointer context,
+ const gchar *command,
+ const gchar *response,
+ gboolean last_command,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
+{
+ SupportedBandsContext *ctx;
+ Band *b;
+
+ ctx = context;
+ b = g_slist_nth_data (ctx->check_bands, ctx->idx++);
/* If there was no error setting the band, that band is supported. We
* abuse the 'enabled' item to mean supported/unsupported.
@@ -1309,13 +1260,13 @@ load_supported_bands_response_processor (MMBaseModem *self,
b->enabled = !error;
/* Continue to next band */
- return FALSE;
+ return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE;
}
static void
load_supported_bands_get_current_bands_ready (MMIfaceModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
SupportedBandsContext *ctx;
const gchar *response;
@@ -1325,10 +1276,8 @@ load_supported_bands_get_current_bands_ready (MMIfaceModem *self,
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
- mm_dbg ("Couldn't query current bands: '%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;
}
@@ -1338,7 +1287,7 @@ load_supported_bands_get_current_bands_ready (MMIfaceModem *self,
* to its current enabled/disabled state.
*/
iter = ctx->check_bands = parse_bands (response, &len);
- ctx->cmds = g_new0 (MMBaseModemAtCommand, len + 1);
+ ctx->cmds = g_new0 (MMBaseModemAtCommandAlloc, len + 1);
while (iter) {
Band *b = iter->data;
@@ -1362,11 +1311,11 @@ load_supported_bands_get_current_bands_ready (MMIfaceModem *self,
}
mm_base_modem_at_sequence (MM_BASE_MODEM (self),
- ctx->cmds,
+ (const MMBaseModemAtCommand *)ctx->cmds,
ctx,
(GDestroyNotify) supported_bands_context_free,
(GAsyncReadyCallback) load_supported_bands_ready,
- operation_result);
+ task);
}
static void
@@ -1385,10 +1334,7 @@ modem_load_supported_bands (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)load_supported_bands_get_current_bands_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_load_supported_bands));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
@@ -1399,17 +1345,13 @@ modem_load_current_bands_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return (GArray *) 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
load_current_bands_ready (MMIfaceModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GTask *task)
{
GArray *bands;
const gchar *response;
@@ -1419,10 +1361,7 @@ load_current_bands_ready (MMIfaceModem *self,
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
- mm_dbg ("Couldn't query current bands: '%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);
} else {
/* Parse bands from Icera response into MM band numbers */
parsed = parse_bands (response, &len);
@@ -1435,12 +1374,9 @@ load_current_bands_ready (MMIfaceModem *self,
}
g_slist_free_full (parsed, (GDestroyNotify) band_free);
- g_simple_async_result_set_op_res_gpointer (operation_result,
- bands,
- (GDestroyNotify)g_array_unref);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref);
}
+ g_object_unref (task);
}
static void
@@ -1454,17 +1390,13 @@ modem_load_current_bands (MMIfaceModem *self,
3,
FALSE,
(GAsyncReadyCallback)load_current_bands_ready,
- g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_load_current_bands));
+ g_task_new (self, NULL, callback, user_data));
}
/*****************************************************************************/
/* Set current bands (Modem interface) */
typedef struct {
- GSimpleAsyncResult *result;
guint bandbits;
guint enablebits;
guint disablebits;
@@ -1482,43 +1414,37 @@ modem_set_current_bands_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 set_one_band (MMIfaceModem *self, SetCurrentBandsContext *ctx);
-
-static void
-set_current_bands_context_complete_and_free (SetCurrentBandsContext *ctx)
-{
- g_simple_async_result_complete (ctx->result);
- g_object_unref (ctx->result);
- g_slice_free (SetCurrentBandsContext, ctx);
-}
+static void set_one_band (MMIfaceModem *self, GTask *task);
static void
set_current_bands_next (MMIfaceModem *self,
GAsyncResult *res,
- SetCurrentBandsContext *ctx)
+ GTask *task)
{
GError *error = NULL;
if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
- mm_dbg ("Couldn't set current bands: '%s'", error->message);
- g_simple_async_result_take_error (ctx->result, error);
- set_current_bands_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- set_one_band (self, ctx);
+ set_one_band (self, task);
}
static void
set_one_band (MMIfaceModem *self,
- SetCurrentBandsContext *ctx)
+ GTask *task)
{
+ SetCurrentBandsContext *ctx;
guint enable, band;
gchar *command;
+ ctx = g_task_get_task_data (task);
+
/* Find the next band to enable or disable, always doing enables first */
enable = 1;
band = ffs (ctx->enablebits);
@@ -1528,22 +1454,22 @@ set_one_band (MMIfaceModem *self,
}
if (band == 0) {
/* Both enabling and disabling are done */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- set_current_bands_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
/* Note that ffs() returning 2 corresponds to 1 << 1, not 1 << 2 */
band--;
- mm_dbg("1. enablebits %x disablebits %x band %d enable %d",
- ctx->enablebits, ctx->disablebits, band, enable);
+ mm_obj_dbg (self, "preparing %%IPBM command (1/2): enablebits %x, disablebits %x, band %d, enable %d",
+ ctx->enablebits, ctx->disablebits, band, enable);
if (enable)
ctx->enablebits &= ~(1 << band);
else
ctx->disablebits &= ~(1 << band);
- mm_dbg("2. enablebits %x disablebits %x",
- ctx->enablebits, ctx->disablebits);
+ mm_obj_dbg (self, "preparing %%IPBM command (2/2): enablebits %x, disablebits %x",
+ ctx->enablebits, ctx->disablebits);
command = g_strdup_printf ("%%IPBM=\"%s\",%d",
modem_bands[band].name,
@@ -1554,7 +1480,7 @@ set_one_band (MMIfaceModem *self,
10,
FALSE,
(GAsyncReadyCallback)set_current_bands_next,
- ctx);
+ task);
g_free (command);
}
@@ -1582,24 +1508,26 @@ band_array_to_bandbits (GArray *bands)
static void
set_current_bands_got_current_bands (MMIfaceModem *self,
GAsyncResult *res,
- SetCurrentBandsContext *ctx)
+ GTask *task)
{
+ SetCurrentBandsContext *ctx;
GArray *bands;
GError *error = NULL;
guint currentbits;
bands = modem_load_current_bands_finish (self, res, &error);
if (!bands) {
- g_simple_async_result_take_error (ctx->result, error);
- set_current_bands_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ ctx = g_task_get_task_data (task);
currentbits = band_array_to_bandbits (bands);
ctx->enablebits = ctx->bandbits & ~currentbits;
ctx->disablebits = currentbits & ~ctx->bandbits;
- set_one_band (self, ctx);
+ set_one_band (self, task);
}
static void
@@ -1609,27 +1537,27 @@ modem_set_current_bands (MMIfaceModem *self,
gpointer user_data)
{
SetCurrentBandsContext *ctx;
+ GTask *task;
- ctx = g_slice_new0 (SetCurrentBandsContext);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_set_current_bands);
+ ctx = g_new0 (SetCurrentBandsContext, 1);
ctx->bandbits = band_array_to_bandbits (bands_array);
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, g_free);
+
/*
* If ANY is requested, simply enable ANY to activate all bands except for
* those forbidden. */
if (ctx->bandbits & modem_band_any_bit) {
ctx->enablebits = modem_band_any_bit;
ctx->disablebits = 0;
- set_one_band (self, ctx);
+ set_one_band (self, task);
return;
}
modem_load_current_bands (self,
(GAsyncReadyCallback)set_current_bands_got_current_bands,
- ctx);
+ task);
}
/*****************************************************************************/
@@ -1763,6 +1691,424 @@ modem_time_load_network_timezone (MMIfaceModemTime *self,
}
/*****************************************************************************/
+/* List profiles (3GPP profile management interface) */
+
+typedef struct {
+ GList *profiles;
+} ListProfilesContext;
+
+static void
+list_profiles_context_free (ListProfilesContext *ctx)
+{
+ mm_3gpp_profile_list_free (ctx->profiles);
+ g_slice_free (ListProfilesContext, ctx);
+}
+
+static gboolean
+modem_3gpp_profile_manager_list_profiles_finish (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GList **out_profiles,
+ GError **error)
+{
+ ListProfilesContext *ctx;
+
+ if (!g_task_propagate_boolean (G_TASK (res), error))
+ return FALSE;
+
+ ctx = g_task_get_task_data (G_TASK (res));
+ if (out_profiles)
+ *out_profiles = g_steal_pointer (&ctx->profiles);
+ return TRUE;
+}
+
+static void
+profile_manager_ipdpcfg_query_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ ListProfilesContext *ctx;
+ const gchar *response;
+ g_autoptr(GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ response = mm_base_modem_at_command_finish (self, res, &error);
+ if (!response)
+ mm_obj_warn (self, "couldn't load PDP context auth settings: %s", error->message);
+ else if (!mm_icera_parse_ipdpcfg_query_response (response, ctx->profiles, self, &error))
+ mm_obj_warn (self, "couldn't update profile list with PDP context auth settings: %s", error->message);
+
+ /* complete successfully anyway */
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+profile_manager_parent_list_profiles_ready (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ ListProfilesContext *ctx;
+ GError *error = NULL;
+
+ ctx = g_slice_new0 (ListProfilesContext);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) list_profiles_context_free);
+
+ if (!iface_modem_3gpp_profile_manager_parent->list_profiles_finish (self, res, &ctx->profiles, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!ctx->profiles) {
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self),
+ "%IPDPCFG?",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)profile_manager_ipdpcfg_query_ready,
+ task);
+}
+
+static void
+modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ iface_modem_3gpp_profile_manager_parent->list_profiles (
+ self,
+ (GAsyncReadyCallback)profile_manager_parent_list_profiles_ready,
+ task);
+}
+
+typedef struct {
+ gboolean new_id;
+ gint min_profile_id;
+ gint max_profile_id;
+ GEqualFunc apn_cmp;
+ MM3gppProfileCmpFlags profile_cmp_flags;
+} CheckFormatContext;
+
+static void
+check_format_context_free (CheckFormatContext *ctx)
+{
+ g_slice_free (CheckFormatContext, ctx);
+}
+
+static gboolean
+modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ gboolean *new_id,
+ gint *min_profile_id,
+ gint *max_profile_id,
+ GEqualFunc *apn_cmp,
+ MM3gppProfileCmpFlags *profile_cmp_flags,
+ GError **error)
+{
+ CheckFormatContext *ctx;
+
+ if (!g_task_propagate_boolean (G_TASK (res), error))
+ return FALSE;
+
+ ctx = g_task_get_task_data (G_TASK (res));
+ if (new_id)
+ *new_id = ctx->new_id;
+ if (min_profile_id)
+ *min_profile_id = (gint) ctx->min_profile_id;
+ if (max_profile_id)
+ *max_profile_id = (gint) ctx->max_profile_id;
+ if (apn_cmp)
+ *apn_cmp = ctx->apn_cmp;
+ if (profile_cmp_flags)
+ *profile_cmp_flags = ctx->profile_cmp_flags;
+ return TRUE;
+}
+
+static void
+profile_manager_parent_check_format_ready (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ CheckFormatContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!iface_modem_3gpp_profile_manager_parent->check_format_finish (self,
+ res,
+ &ctx->new_id,
+ &ctx->min_profile_id,
+ &ctx->max_profile_id,
+ &ctx->apn_cmp,
+ &ctx->profile_cmp_flags,
+ &error)) {
+ g_task_return_error (task, error);
+ } else {
+ /* the icera implementation supports AUTH, so unset that cmp flag */
+ ctx->profile_cmp_flags &= ~MM_3GPP_PROFILE_CMP_FLAGS_NO_AUTH;
+ g_task_return_boolean (task, TRUE);
+ }
+ g_object_unref (task);
+}
+
+static void
+modem_3gpp_profile_manager_check_format (MMIfaceModem3gppProfileManager *self,
+ MMBearerIpFamily ip_type,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ CheckFormatContext *ctx;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ ctx = g_slice_new0 (CheckFormatContext);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)check_format_context_free);
+
+ iface_modem_3gpp_profile_manager_parent->check_format (
+ self,
+ ip_type,
+ (GAsyncReadyCallback)profile_manager_parent_check_format_ready,
+ task);
+}
+
+/*****************************************************************************/
+/* Deactivate profile (3GPP profile management interface) */
+
+static gboolean
+modem_3gpp_profile_manager_deactivate_profile_finish (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+deactivate_profile_ipdpact_set_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+
+ if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+modem_3gpp_profile_manager_deactivate_profile (MMIfaceModem3gppProfileManager *self,
+ MM3gppProfile *profile,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ g_autofree gchar *cmd = NULL;
+ gint profile_id;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ profile_id = mm_3gpp_profile_get_profile_id (profile);
+ mm_obj_dbg (self, "deactivating profile '%d'...", profile_id);
+
+ cmd = g_strdup_printf ("%%IPDPACT=%d,0", profile_id);
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self),
+ cmd,
+ MM_BASE_BEARER_DEFAULT_DISCONNECTION_TIMEOUT,
+ FALSE,
+ (GAsyncReadyCallback)deactivate_profile_ipdpact_set_ready,
+ task);
+}
+
+/*****************************************************************************/
+/* Set profile (3GPP profile management interface) */
+
+#define IPDPCFG_SET_MAX_ATTEMPTS 3
+#define IPDPCFG_SET_RETRY_TIMEOUT_SECS 1
+
+typedef struct {
+ MM3gppProfile *profile;
+ gchar *cmd;
+ gint profile_id;
+ guint n_attempts;
+} StoreProfileContext;
+
+static void
+store_profile_context_free (StoreProfileContext *ctx)
+{
+ g_free (ctx->cmd);
+ g_clear_object (&ctx->profile);
+ g_slice_free (StoreProfileContext, ctx);
+}
+
+static gint
+modem_3gpp_profile_manager_store_profile_finish (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ StoreProfileContext *ctx;
+
+ if (!g_task_propagate_boolean (G_TASK (res), error))
+ return MM_3GPP_PROFILE_ID_UNKNOWN;
+
+ ctx = g_task_get_task_data (G_TASK (res));
+ return ctx->profile_id;
+}
+
+static void profile_manager_store_profile_auth_settings (GTask *task);
+
+static gboolean
+profile_manager_ipdpcfg_set_retry (GTask *task)
+{
+ profile_manager_store_profile_auth_settings (task);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+profile_manager_ipdpcfg_set_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ StoreProfileContext *ctx;
+ g_autoptr(GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!mm_base_modem_at_command_finish (self, res, &error)) {
+ /* Retry configuring the context. It sometimes fails with a 583
+ * error ["a profile (CID) is currently active"] if a connect
+ * is attempted too soon after a disconnect. */
+ if (ctx->n_attempts < IPDPCFG_SET_MAX_ATTEMPTS) {
+ mm_obj_dbg (self, "couldn't store auth settings in profile '%d': %s; retrying...",
+ ctx->profile_id, error->message);
+ g_timeout_add_seconds (IPDPCFG_SET_RETRY_TIMEOUT_SECS, (GSourceFunc)profile_manager_ipdpcfg_set_retry, task);
+ return;
+ }
+ g_task_return_error (task, g_steal_pointer (&error));
+ } else
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+profile_manager_store_profile_auth_settings (GTask *task)
+{
+ MMIfaceModem3gppProfileManager *self;
+ StoreProfileContext *ctx;
+ g_autofree gchar *cmd = NULL;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ if (!ctx->cmd) {
+ const gchar *user;
+ const gchar *password;
+ MMBearerAllowedAuth allowed_auth;
+
+ user = mm_3gpp_profile_get_user (ctx->profile);
+ password = mm_3gpp_profile_get_password (ctx->profile);
+ allowed_auth = mm_3gpp_profile_get_allowed_auth (ctx->profile);
+
+ /* Both user and password are required; otherwise firmware returns an error */
+ if (!user || !password || allowed_auth == MM_BEARER_ALLOWED_AUTH_NONE) {
+ mm_obj_dbg (self, "not using authentication");
+ ctx->cmd = g_strdup_printf ("%%IPDPCFG=%d,0,0,\"\",\"\"", ctx->profile_id);
+ } else {
+ g_autofree gchar *quoted_user = NULL;
+ g_autofree gchar *quoted_password = NULL;
+ guint icera_auth;
+
+ if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
+ mm_obj_dbg (self, "using default (CHAP) authentication method");
+ icera_auth = 2;
+ } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
+ mm_obj_dbg (self, "using CHAP authentication method");
+ icera_auth = 2;
+ } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
+ mm_obj_dbg (self, "using PAP authentication method");
+ icera_auth = 1;
+ } else {
+ g_autofree gchar *str = NULL;
+
+ str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
+ 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);
+ return;
+ }
+
+ quoted_user = mm_port_serial_at_quote_string (user);
+ quoted_password = mm_port_serial_at_quote_string (password);
+ ctx->cmd = g_strdup_printf ("%%IPDPCFG=%d,0,%u,%s,%s",
+ ctx->profile_id,
+ icera_auth,
+ quoted_user,
+ quoted_password);
+ }
+ }
+
+ ctx->n_attempts++;
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ ctx->cmd,
+ 6,
+ FALSE,
+ (GAsyncReadyCallback)profile_manager_ipdpcfg_set_ready,
+ task);
+}
+
+static void
+profile_manager_parent_store_profile_ready (MMIfaceModem3gppProfileManager *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+
+ if (iface_modem_3gpp_profile_manager_parent->store_profile_finish (self, res, &error) == MM_3GPP_PROFILE_ID_UNKNOWN) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ profile_manager_store_profile_auth_settings (task);
+}
+
+static void
+modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self,
+ MM3gppProfile *profile,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ StoreProfileContext *ctx;
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ ctx = g_slice_new0 (StoreProfileContext);
+ ctx->profile = g_object_ref (profile);
+ ctx->profile_id = mm_3gpp_profile_get_profile_id (ctx->profile);
+ g_assert (ctx->profile_id != MM_3GPP_PROFILE_ID_UNKNOWN);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) store_profile_context_free);
+
+ iface_modem_3gpp_profile_manager_parent->store_profile (
+ self,
+ profile,
+ (GAsyncReadyCallback)profile_manager_parent_store_profile_ready,
+ task);
+}
+
+/*****************************************************************************/
/* Load network time (Time interface) */
static gchar *
@@ -1801,11 +2147,7 @@ modem_time_check_support_finish (MMIfaceModemTime *self,
GAsyncResult *res,
GError **error)
{
- /* We assume Icera devices always support *TLTS, since they appear
- * to return ERROR if the modem is not powered up, and thus we cannot
- * check for *TLTS support during modem initialization.
- */
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (res), error);
}
static void
@@ -1813,15 +2155,16 @@ modem_time_check_support (MMIfaceModemTime *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_time_check_support);
+ task = g_task_new (self, NULL, callback, user_data);
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
+ /* We assume Icera devices always support *TLTS, since they appear
+ * to return ERROR if the modem is not powered up, and thus we cannot
+ * check for *TLTS support during modem initialization.
+ */
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
/*****************************************************************************/
@@ -1852,6 +2195,9 @@ mm_broadband_modem_icera_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) or Icera bearer (NET) supported */
+ MM_BASE_MODEM_DATA_NET_SUPPORTED, TRUE,
+ MM_BASE_MODEM_DATA_TTY_SUPPORTED, TRUE,
NULL);
}
@@ -1971,6 +2317,23 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
}
static void
+iface_modem_3gpp_profile_manager_init (MMIfaceModem3gppProfileManager *iface)
+{
+ iface_modem_3gpp_profile_manager_parent = g_type_interface_peek_parent (iface);
+
+ iface->list_profiles = modem_3gpp_profile_manager_list_profiles;
+ iface->list_profiles_finish = modem_3gpp_profile_manager_list_profiles_finish;
+ iface->check_format = modem_3gpp_profile_manager_check_format;
+ iface->check_format_finish = modem_3gpp_profile_manager_check_format_finish;
+ /* note: the parent check_activated_profile() implementation using +CGACT? seems to
+ * be perfectly valid. */
+ iface->deactivate_profile = modem_3gpp_profile_manager_deactivate_profile;
+ iface->deactivate_profile_finish = modem_3gpp_profile_manager_deactivate_profile_finish;
+ iface->store_profile = modem_3gpp_profile_manager_store_profile;
+ iface->store_profile_finish = modem_3gpp_profile_manager_store_profile_finish;
+}
+
+static void
iface_modem_time_init (MMIfaceModemTime *iface)
{
iface->check_support = modem_time_check_support;