const gchar * mm_simple_connect_properties_get_user (MMSimpleConnectProperties *self) { g_return_val_if_fail (MM_IS_SIMPLE_CONNECT_PROPERTIES (self), NULL); return mm_bearer_properties_get_user (self->priv->bearer_properties); }
static gboolean cmp_properties (MMBearer *self, MMBearerProperties *properties) { MMBroadbandBearerHso *hso = MM_BROADBAND_BEARER_HSO (self); return ((mm_broadband_bearer_get_allow_roaming (MM_BROADBAND_BEARER (self)) == mm_bearer_properties_get_allow_roaming (properties)) && (!g_strcmp0 (mm_broadband_bearer_get_ip_type (MM_BROADBAND_BEARER (self)), mm_bearer_properties_get_ip_type (properties))) && (!g_strcmp0 (mm_broadband_bearer_get_3gpp_apn (MM_BROADBAND_BEARER (self)), mm_bearer_properties_get_apn (properties))) && (!g_strcmp0 (hso->priv->user, mm_bearer_properties_get_user (properties))) && (!g_strcmp0 (hso->priv->password, mm_bearer_properties_get_password (properties)))); }
void mm_broadband_bearer_hso_new (MMBroadbandModemHso *modem, MMBearerProperties *properties, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async ( MM_TYPE_BROADBAND_BEARER_HSO, G_PRIORITY_DEFAULT, cancellable, callback, user_data, MM_BEARER_MODEM, modem, MM_BROADBAND_BEARER_3GPP_APN, mm_bearer_properties_get_apn (properties), MM_BROADBAND_BEARER_IP_TYPE, mm_bearer_properties_get_ip_type (properties), MM_BROADBAND_BEARER_ALLOW_ROAMING, mm_bearer_properties_get_allow_roaming (properties), MM_BROADBAND_BEARER_HSO_USER, mm_bearer_properties_get_user (properties), MM_BROADBAND_BEARER_HSO_PASSWORD, mm_bearer_properties_get_password (properties), NULL); }
static void _connect (MMBearer *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { MMBearerProperties *properties = NULL; ConnectContext *ctx; MMBaseModem *modem = NULL; MMPort *data; MMQmiPort *qmi; GError *error = NULL; g_object_get (self, MM_BEARER_MODEM, &modem, NULL); g_assert (modem); /* Grab a data port */ data = mm_base_modem_get_best_data_port (modem); 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_object_unref (modem); return; } /* Each data port has a single QMI port associated */ qmi = mm_base_modem_get_port_qmi_for_data (modem, data, &error); if (!qmi) { g_simple_async_report_take_gerror_in_idle ( G_OBJECT (self), callback, user_data, error); g_object_unref (data); g_object_unref (modem); return; } g_object_unref (modem); mm_dbg ("Launching connection with QMI port (%s/%s) and data port (%s/%s)", mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (qmi))), mm_port_get_device (MM_PORT (qmi)), mm_port_subsys_get_string (mm_port_get_subsys (data)), mm_port_get_device (data)); ctx = g_slice_new0 (ConnectContext); ctx->self = g_object_ref (self); ctx->qmi = qmi; ctx->data = data; ctx->cancellable = g_object_ref (cancellable); ctx->step = CONNECT_STEP_FIRST; ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, connect); g_object_get (self, MM_BEARER_CONFIG, &properties, NULL); if (properties) { MMBearerAllowedAuth auth; ctx->apn = g_strdup (mm_bearer_properties_get_apn (properties)); ctx->user = g_strdup (mm_bearer_properties_get_user (properties)); ctx->password = g_strdup (mm_bearer_properties_get_password (properties)); switch (mm_bearer_properties_get_ip_type (properties)) { case MM_BEARER_IP_FAMILY_IPV4: ctx->ipv4 = TRUE; ctx->ipv6 = FALSE; break; case MM_BEARER_IP_FAMILY_IPV6: ctx->ipv4 = FALSE; ctx->ipv6 = TRUE; break; case MM_BEARER_IP_FAMILY_IPV4V6: ctx->ipv4 = TRUE; ctx->ipv6 = TRUE; break; case MM_BEARER_IP_FAMILY_UNKNOWN: default: mm_dbg ("No specific IP family requested, defaulting to IPv4"); ctx->no_ip_family_preference = TRUE; ctx->ipv4 = TRUE; ctx->ipv6 = FALSE; break; } auth = mm_bearer_properties_get_allowed_auth (properties); g_object_unref (properties); if (auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) { mm_dbg ("Using default (PAP) authentication method"); ctx->auth = QMI_WDS_AUTHENTICATION_PAP; } else if (auth & (MM_BEARER_ALLOWED_AUTH_PAP | MM_BEARER_ALLOWED_AUTH_CHAP | MM_BEARER_ALLOWED_AUTH_NONE)) { /* Only PAP and/or CHAP or NONE are supported */ ctx->auth = mm_bearer_allowed_auth_to_qmi_authentication (auth); } else { gchar *str; str = mm_bearer_allowed_auth_build_string_from_mask (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_free (str); connect_context_complete_and_free (ctx); return; } } /* Run! */ connect_context_step (ctx); }
static void connect_3gpp_context_step (Connect3gppContext *ctx) { /* Check for cancellation */ if (g_cancellable_is_cancelled (ctx->cancellable)) { /* Clear context */ ctx->self->priv->connect_pending = NULL; /* If we already sent the connetion command, send the disconnection one */ if (ctx->step > CONNECT_3GPP_CONTEXT_STEP_NDISDUP) mm_base_modem_at_command_full (ctx->modem, ctx->primary, "^NDISDUP=1,0", 3, FALSE, FALSE, NULL, 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); 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); 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))); 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_str = mm_bearer_ip_family_build_string_from_mask (ip_family); mm_dbg ("No specific IP family requested, defaulting to %s", ip_family_str); g_free (ip_family_str); } 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); return; } /* Store the context */ ctx->self->priv->connect_pending = ctx; ctx->step++; /* Fall down to the next step */ } case CONNECT_3GPP_CONTEXT_STEP_NDISDUP: { const gchar *apn; const gchar *user; const gchar *passwd; MMBearerAllowedAuth auth; 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))); encoded_auth = huawei_parse_auth_type (auth); /* Default to no authentication if not specified */ if ((encoded_auth = huawei_parse_auth_type (auth)) == MM_BEARER_HUAWEI_AUTH_UNKNOWN) encoded_auth = MM_BEARER_HUAWEI_AUTH_NONE; if (!user && !passwd) command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\"", apn == NULL ? "" : apn); else if (encoded_auth == MM_BEARER_HUAWEI_AUTH_NONE) command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\",\"%s\",\"%s\"", apn == NULL ? "" : apn, user == NULL ? "" : user, passwd == NULL ? "" : passwd); else command = g_strdup_printf ("AT^NDISDUP=1,1,\"%s\",\"%s\",\"%s\",%d", apn == NULL ? "" : apn, user == NULL ? "" : user, passwd == NULL ? "" : passwd, encoded_auth); mm_base_modem_at_command_full (ctx->modem, ctx->primary, command, 3, FALSE, FALSE, NULL, (GAsyncReadyCallback)connect_ndisdup_ready, g_object_ref (ctx->self)); g_free (command); return; } case CONNECT_3GPP_CONTEXT_STEP_NDISSTATQRY: /* Wait for dial up timeout, retries for 60 times * (1s between the retries, so it means 1 minute). * If too many retries, failed */ 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); 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); return; } /* Check if connected */ ctx->check_count++; mm_base_modem_at_command_full (ctx->modem, ctx->primary, "^NDISSTATQRY?", 3, FALSE, FALSE, NULL, (GAsyncReadyCallback)connect_ndisstatqry_check_ready, g_object_ref (ctx->self)); return; case CONNECT_3GPP_CONTEXT_STEP_LAST: /* Clear context */ ctx->self->priv->connect_pending = NULL; /* Setup result */ { MMBearerIpConfig *ipv4_config; ipv4_config = mm_bearer_ip_config_new (); mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_DHCP); g_simple_async_result_set_op_res_gpointer ( ctx->result, mm_bearer_connect_result_new (ctx->data, ipv4_config, NULL), (GDestroyNotify)mm_bearer_connect_result_unref); g_object_unref (ipv4_config); } connect_3gpp_context_complete_and_free (ctx); return; } }