huawei: port connect_3gpp to use GTask
This commit is contained in:
committed by
Aleksander Morgado
parent
1ada2d23a5
commit
d6d52b95c7
@@ -72,12 +72,9 @@ typedef enum {
|
||||
} Connect3gppContextStep;
|
||||
|
||||
typedef struct {
|
||||
MMBroadbandBearerHuawei *self;
|
||||
MMBaseModem *modem;
|
||||
MMPortSerialAt *primary;
|
||||
MMPort *data;
|
||||
GCancellable *cancellable;
|
||||
GSimpleAsyncResult *result;
|
||||
Connect3gppContextStep step;
|
||||
guint check_count;
|
||||
guint failed_ndisstatqry_count;
|
||||
@@ -85,14 +82,9 @@ typedef struct {
|
||||
} Connect3gppContext;
|
||||
|
||||
static void
|
||||
connect_3gpp_context_complete_and_free (Connect3gppContext *ctx)
|
||||
connect_3gpp_context_free (Connect3gppContext *ctx)
|
||||
{
|
||||
g_simple_async_result_complete_in_idle (ctx->result);
|
||||
|
||||
g_object_unref (ctx->cancellable);
|
||||
g_object_unref (ctx->result);
|
||||
g_object_unref (ctx->modem);
|
||||
g_object_unref (ctx->self);
|
||||
|
||||
g_clear_object (&ctx->ipv4_config);
|
||||
g_clear_object (&ctx->data);
|
||||
@@ -106,25 +98,25 @@ connect_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_bearer_connect_result_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 connect_3gpp_context_step (Connect3gppContext *ctx);
|
||||
static void connect_3gpp_context_step (GTask *task);
|
||||
|
||||
static void
|
||||
connect_dhcp_check_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
MMBroadbandBearerHuawei *self)
|
||||
{
|
||||
GTask *task;
|
||||
Connect3gppContext *ctx;
|
||||
const gchar *response;
|
||||
GError *error = NULL;
|
||||
|
||||
ctx = self->priv->connect_pending;
|
||||
g_assert (ctx != NULL);
|
||||
task = self->priv->connect_pending;
|
||||
g_assert (task != NULL);
|
||||
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
/* Balance refcount */
|
||||
g_object_unref (self);
|
||||
@@ -189,23 +181,23 @@ connect_dhcp_check_ready (MMBaseModem *modem,
|
||||
|
||||
g_clear_error (&error);
|
||||
ctx->step++;
|
||||
connect_3gpp_context_step (ctx);
|
||||
connect_3gpp_context_step (task);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
connect_retry_ndisstatqry_check_cb (MMBroadbandBearerHuawei *self)
|
||||
{
|
||||
Connect3gppContext *ctx;
|
||||
GTask *task;
|
||||
|
||||
/* Recover context */
|
||||
ctx = self->priv->connect_pending;
|
||||
g_assert (ctx != NULL);
|
||||
task = self->priv->connect_pending;
|
||||
g_assert (task != NULL);
|
||||
|
||||
/* Balance refcount */
|
||||
g_object_unref (self);
|
||||
|
||||
/* Retry same step */
|
||||
connect_3gpp_context_step (ctx);
|
||||
connect_3gpp_context_step (task);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -215,6 +207,7 @@ connect_ndisstatqry_check_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
MMBroadbandBearerHuawei *self)
|
||||
{
|
||||
GTask *task;
|
||||
Connect3gppContext *ctx;
|
||||
const gchar *response;
|
||||
GError *error = NULL;
|
||||
@@ -223,8 +216,10 @@ connect_ndisstatqry_check_ready (MMBaseModem *modem,
|
||||
gboolean ipv6_available = FALSE;
|
||||
gboolean ipv6_connected = FALSE;
|
||||
|
||||
ctx = self->priv->connect_pending;
|
||||
g_assert (ctx != NULL);
|
||||
task = self->priv->connect_pending;
|
||||
g_assert (task != NULL);
|
||||
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
/* Balance refcount */
|
||||
g_object_unref (self);
|
||||
@@ -247,7 +242,7 @@ connect_ndisstatqry_check_ready (MMBaseModem *modem,
|
||||
if (ipv4_available && ipv4_connected) {
|
||||
/* Success! */
|
||||
ctx->step++;
|
||||
connect_3gpp_context_step (ctx);
|
||||
connect_3gpp_context_step (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -262,26 +257,29 @@ connect_ndisdup_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
MMBroadbandBearerHuawei *self)
|
||||
{
|
||||
GTask *task;
|
||||
Connect3gppContext *ctx;
|
||||
GError *error = NULL;
|
||||
|
||||
ctx = self->priv->connect_pending;
|
||||
g_assert (ctx != NULL);
|
||||
task = self->priv->connect_pending;
|
||||
g_assert (task != NULL);
|
||||
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
/* Balance refcount */
|
||||
g_object_unref (self);
|
||||
|
||||
if (!mm_base_modem_at_command_full_finish (modem, res, &error)) {
|
||||
/* Clear context */
|
||||
/* Clear task */
|
||||
self->priv->connect_pending = NULL;
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Go to next step */
|
||||
ctx->step++;
|
||||
connect_3gpp_context_step (ctx);
|
||||
connect_3gpp_context_step (task);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -310,12 +308,18 @@ huawei_parse_auth_type (MMBearerAllowedAuth mm_auth)
|
||||
}
|
||||
|
||||
static void
|
||||
connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
connect_3gpp_context_step (GTask *task)
|
||||
{
|
||||
MMBroadbandBearerHuawei *self;
|
||||
Connect3gppContext *ctx;
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
/* Check for cancellation */
|
||||
if (g_cancellable_is_cancelled (ctx->cancellable)) {
|
||||
/* Clear context */
|
||||
ctx->self->priv->connect_pending = NULL;
|
||||
if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) {
|
||||
/* Clear task */
|
||||
self->priv->connect_pending = NULL;
|
||||
|
||||
/* If we already sent the connetion command, send the disconnection one */
|
||||
if (ctx->step > CONNECT_3GPP_CONTEXT_STEP_NDISDUP)
|
||||
@@ -329,29 +333,29 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
NULL, /* Do not care the AT response */
|
||||
NULL);
|
||||
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_CANCELLED,
|
||||
"Huawei connection operation has been cancelled");
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
g_task_return_new_error (task,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_CANCELLED,
|
||||
"Huawei connection operation has been cancelled");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Network-initiated disconnect should not be outstanding at this point,
|
||||
* because it interferes with the connect attempt.
|
||||
*/
|
||||
g_assert (ctx->self->priv->network_disconnect_pending_id == 0);
|
||||
g_assert (self->priv->network_disconnect_pending_id == 0);
|
||||
|
||||
switch (ctx->step) {
|
||||
case CONNECT_3GPP_CONTEXT_STEP_FIRST: {
|
||||
MMBearerIpFamily ip_family;
|
||||
|
||||
ip_family = mm_bearer_properties_get_ip_type (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
|
||||
ip_family = mm_bearer_properties_get_ip_type (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
|
||||
if (ip_family == MM_BEARER_IP_FAMILY_NONE ||
|
||||
ip_family == MM_BEARER_IP_FAMILY_ANY) {
|
||||
gchar *ip_family_str;
|
||||
|
||||
ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (ctx->self));
|
||||
ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (self));
|
||||
ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
|
||||
mm_dbg ("No specific IP family requested, defaulting to %s",
|
||||
ip_family_str);
|
||||
@@ -359,16 +363,16 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
}
|
||||
|
||||
if (ip_family != MM_BEARER_IP_FAMILY_IPV4) {
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Only IPv4 is supported by this modem");
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
g_task_return_new_error (task,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Only IPv4 is supported by this modem");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the context */
|
||||
ctx->self->priv->connect_pending = ctx;
|
||||
/* Store the task */
|
||||
self->priv->connect_pending = task;
|
||||
|
||||
ctx->step++;
|
||||
/* Fall down to the next step */
|
||||
@@ -382,10 +386,10 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
gint encoded_auth = MM_BEARER_HUAWEI_AUTH_UNKNOWN;
|
||||
gchar *command;
|
||||
|
||||
apn = mm_bearer_properties_get_apn (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
|
||||
user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
|
||||
passwd = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
|
||||
auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
|
||||
apn = mm_bearer_properties_get_apn (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
|
||||
user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
|
||||
passwd = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
|
||||
auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
|
||||
encoded_auth = huawei_parse_auth_type (auth);
|
||||
|
||||
/* Default to no authentication if not specified */
|
||||
@@ -415,7 +419,7 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
FALSE,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)connect_ndisdup_ready,
|
||||
g_object_ref (ctx->self));
|
||||
g_object_ref (self));
|
||||
g_free (command);
|
||||
return;
|
||||
}
|
||||
@@ -427,24 +431,24 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
*/
|
||||
if (ctx->check_count > 60) {
|
||||
/* Clear context */
|
||||
ctx->self->priv->connect_pending = NULL;
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_MOBILE_EQUIPMENT_ERROR,
|
||||
MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
|
||||
"Connection attempt timed out");
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
self->priv->connect_pending = NULL;
|
||||
g_task_return_new_error (task,
|
||||
MM_MOBILE_EQUIPMENT_ERROR,
|
||||
MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
|
||||
"Connection attempt timed out");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Give up if too many unexpected responses to NIDSSTATQRY are encountered. */
|
||||
if (ctx->failed_ndisstatqry_count > 10) {
|
||||
/* Clear context */
|
||||
ctx->self->priv->connect_pending = NULL;
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_MOBILE_EQUIPMENT_ERROR,
|
||||
MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
|
||||
"Connection attempt not supported.");
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
self->priv->connect_pending = NULL;
|
||||
g_task_return_new_error (task,
|
||||
MM_MOBILE_EQUIPMENT_ERROR,
|
||||
MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
|
||||
"Connection attempt not supported.");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -458,7 +462,7 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
FALSE,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)connect_ndisstatqry_check_ready,
|
||||
g_object_ref (ctx->self));
|
||||
g_object_ref (self));
|
||||
return;
|
||||
|
||||
case CONNECT_3GPP_CONTEXT_STEP_IP_CONFIG:
|
||||
@@ -470,26 +474,26 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
|
||||
FALSE,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)connect_dhcp_check_ready,
|
||||
g_object_ref (ctx->self));
|
||||
g_object_ref (self));
|
||||
return;
|
||||
|
||||
case CONNECT_3GPP_CONTEXT_STEP_LAST:
|
||||
/* Clear context */
|
||||
ctx->self->priv->connect_pending = NULL;
|
||||
self->priv->connect_pending = NULL;
|
||||
|
||||
/* Setup result */
|
||||
g_simple_async_result_set_op_res_gpointer (
|
||||
ctx->result,
|
||||
g_task_return_pointer (
|
||||
task,
|
||||
mm_bearer_connect_result_new (ctx->data, ctx->ipv4_config, NULL),
|
||||
(GDestroyNotify)mm_bearer_connect_result_unref);
|
||||
|
||||
connect_3gpp_context_complete_and_free (ctx);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connect_3gpp (MMBroadbandBearer *self,
|
||||
connect_3gpp (MMBroadbandBearer *_self,
|
||||
MMBroadbandModem *modem,
|
||||
MMPortSerialAt *primary,
|
||||
MMPortSerialAt *secondary,
|
||||
@@ -497,7 +501,9 @@ connect_3gpp (MMBroadbandBearer *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
Connect3gppContext *ctx;
|
||||
MMBroadbandBearerHuawei *self = MM_BROADBAND_BEARER_HUAWEI (_self);
|
||||
Connect3gppContext *ctx;
|
||||
GTask *task;
|
||||
MMPort *data;
|
||||
|
||||
g_assert (primary != NULL);
|
||||
@@ -505,39 +511,39 @@ connect_3gpp (MMBroadbandBearer *self,
|
||||
/* We need a net data port */
|
||||
data = mm_base_modem_peek_best_data_port (MM_BASE_MODEM (modem), MM_PORT_TYPE_NET);
|
||||
if (!data) {
|
||||
g_simple_async_report_error_in_idle (G_OBJECT (self),
|
||||
callback,
|
||||
user_data,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_NOT_FOUND,
|
||||
"No valid data port found to launch connection");
|
||||
g_task_report_new_error (self,
|
||||
callback,
|
||||
user_data,
|
||||
connect_3gpp,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_NOT_FOUND,
|
||||
"No valid data port found to launch connection");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup connection context */
|
||||
ctx = g_slice_new0 (Connect3gppContext);
|
||||
ctx->self = g_object_ref (self);
|
||||
ctx->modem = g_object_ref (modem);
|
||||
ctx->data = g_object_ref (data);
|
||||
ctx->result = g_simple_async_result_new (G_OBJECT (self),
|
||||
callback,
|
||||
user_data,
|
||||
connect_3gpp);
|
||||
ctx->cancellable = g_object_ref (cancellable);
|
||||
ctx->step = CONNECT_3GPP_CONTEXT_STEP_FIRST;
|
||||
|
||||
g_assert (ctx->self->priv->connect_pending == NULL);
|
||||
g_assert (ctx->self->priv->disconnect_pending == NULL);
|
||||
g_assert (self->priv->connect_pending == NULL);
|
||||
g_assert (self->priv->disconnect_pending == NULL);
|
||||
|
||||
/* Get correct dial port to use */
|
||||
ctx->primary = get_dial_port (MM_BROADBAND_MODEM_HUAWEI (ctx->modem), ctx->data, primary);
|
||||
|
||||
|
||||
/* Default to automatic/DHCP addressing */
|
||||
ctx->ipv4_config = mm_bearer_ip_config_new ();
|
||||
mm_bearer_ip_config_set_method (ctx->ipv4_config, MM_BEARER_IP_METHOD_DHCP);
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
g_task_set_task_data (task, ctx, (GDestroyNotify)connect_3gpp_context_free);
|
||||
g_task_set_check_cancellable (task, FALSE);
|
||||
|
||||
/* Run! */
|
||||
connect_3gpp_context_step (ctx);
|
||||
connect_3gpp_context_step (task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user