aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-bearer-qmi.c367
1 files changed, 183 insertions, 184 deletions
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 151b20f5..5ab2dc2c 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -581,135 +581,6 @@ complete_connect (GTask *task,
static void connect_context_step (GTask *task);
static void
-start_network_ready (QmiClientWds *client,
- GAsyncResult *res,
- GTask *task)
-{
- MMBearerQmi *self;
- ConnectContext *ctx;
- GError *error = NULL;
- QmiMessageWdsStartNetworkOutput *output;
-
- self = g_task_get_source_object (task);
- ctx = g_task_get_task_data (task);
-
- g_assert (ctx->running_ipv4 || ctx->running_ipv6);
- g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
-
- output = qmi_client_wds_start_network_finish (client, res, &error);
- if (output &&
- !qmi_message_wds_start_network_output_get_result (output, &error)) {
- /* No-effect errors should be ignored. The modem will keep the
- * connection active as long as there is a WDS client which requested
- * to start the network. If ModemManager crashed while a connection was
- * active, we would be leaving an unreleased WDS client around and the
- * modem would just keep connected. */
- if (g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
- g_error_free (error);
- error = NULL;
- if (ctx->running_ipv4)
- ctx->packet_data_handle_ipv4 = GLOBAL_PACKET_DATA_HANDLE;
- else
- ctx->packet_data_handle_ipv6 = GLOBAL_PACKET_DATA_HANDLE;
-
- /* Fall down to a successful connection */
- } else {
- mm_obj_info (self, "couldn't start network: %s", error->message);
- if (g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_CALL_FAILED)) {
- QmiWdsCallEndReason cer;
- QmiWdsVerboseCallEndReasonType verbose_cer_type;
- gint16 verbose_cer_reason;
-
- if (qmi_message_wds_start_network_output_get_call_end_reason (
- output,
- &cer,
- NULL))
- mm_obj_info (self, "call end reason (%u): %s", cer, qmi_wds_call_end_reason_get_string (cer));
-
- if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
- output,
- &verbose_cer_type,
- &verbose_cer_reason,
- NULL))
- mm_obj_info (self, "verbose call end reason (%u,%d): [%s] %s",
- verbose_cer_type,
- verbose_cer_reason,
- qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
- qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
- }
- }
- }
-
- if (error) {
- if (ctx->running_ipv4)
- ctx->error_ipv4 = error;
- else
- ctx->error_ipv6 = error;
- } else {
- if (ctx->running_ipv4)
- qmi_message_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle_ipv4, NULL);
- else
- qmi_message_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle_ipv6, NULL);
- }
-
- if (output)
- qmi_message_wds_start_network_output_unref (output);
-
- /* Keep on */
- ctx->step++;
- connect_context_step (task);
-}
-
-static QmiMessageWdsStartNetworkInput *
-build_start_network_input (ConnectContext *ctx)
-{
- QmiMessageWdsStartNetworkInput *input;
- gboolean has_user, has_password;
-
- g_assert (ctx->running_ipv4 || ctx->running_ipv6);
- g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
-
- input = qmi_message_wds_start_network_input_new ();
-
- if (ctx->apn && ctx->apn[0])
- qmi_message_wds_start_network_input_set_apn (input, ctx->apn, NULL);
-
- has_user = (ctx->user && ctx->user[0]);
- has_password = (ctx->password && ctx->password[0]);
-
- /* Need to add auth info? */
- if (has_user || has_password || ctx->auth != QMI_WDS_AUTHENTICATION_NONE) {
- /* We define a valid auth preference if we have either user or password, or an explicit
- * request for one to be set. If no explicit one was given, default to CHAP. */
- qmi_message_wds_start_network_input_set_authentication_preference (
- input,
- (ctx->auth != QMI_WDS_AUTHENTICATION_NONE) ? ctx->auth : QMI_WDS_AUTHENTICATION_CHAP,
- NULL);
-
- if (has_user)
- qmi_message_wds_start_network_input_set_username (input, ctx->user, NULL);
- if (has_password)
- qmi_message_wds_start_network_input_set_password (input, ctx->password, NULL);
- }
-
- /* Only add the IP family preference TLV if explicitly requested a given
- * family. This TLV may be newer than the Start Network command itself, so
- * we'll just allow the case where none is specified. */
- if (!ctx->no_ip_family_preference) {
- qmi_message_wds_start_network_input_set_ip_family_preference (
- input,
- (ctx->running_ipv6 ? QMI_WDS_IP_FAMILY_IPV6 : QMI_WDS_IP_FAMILY_IPV4),
- NULL);
- }
-
- return input;
-}
-
-static void
qmi_inet4_ntop (guint32 address, char *buf, const gsize buflen)
{
struct in_addr a = { .s_addr = GUINT32_TO_BE (address) };
@@ -1019,87 +890,132 @@ get_current_settings (GTask *task, QmiClientWds *client)
}
static void
-bind_data_port_ready (QmiClientWds *client,
- GAsyncResult *res,
- GTask *task)
+start_network_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
{
- ConnectContext *ctx;
- GError *error = NULL;
- g_autoptr(QmiMessageWdsBindDataPortOutput) output = NULL;
+ MMBearerQmi *self;
+ ConnectContext *ctx;
+ GError *error = NULL;
+ QmiMessageWdsStartNetworkOutput *output;
+ self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
g_assert (ctx->running_ipv4 || ctx->running_ipv6);
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
- output = qmi_client_wds_bind_data_port_finish (client, res, &error);
- if (!output || !qmi_message_wds_bind_data_port_output_get_result (output, &error)) {
- g_prefix_error (&error, "Couldn't bind data port: ");
- complete_connect (task, NULL, error);
- return;
- }
-
- /* Keep on */
- ctx->step++;
- connect_context_step (task);
-}
+ output = qmi_client_wds_start_network_finish (client, res, &error);
+ if (output &&
+ !qmi_message_wds_start_network_output_get_result (output, &error)) {
+ /* No-effect errors should be ignored. The modem will keep the
+ * connection active as long as there is a WDS client which requested
+ * to start the network. If ModemManager crashed while a connection was
+ * active, we would be leaving an unreleased WDS client around and the
+ * modem would just keep connected. */
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ g_error_free (error);
+ error = NULL;
+ if (ctx->running_ipv4)
+ ctx->packet_data_handle_ipv4 = GLOBAL_PACKET_DATA_HANDLE;
+ else
+ ctx->packet_data_handle_ipv6 = GLOBAL_PACKET_DATA_HANDLE;
-static void
-bind_mux_data_port_ready (QmiClientWds *client,
- GAsyncResult *res,
- GTask *task)
-{
- ConnectContext *ctx;
- GError *error = NULL;
- g_autoptr(QmiMessageWdsBindMuxDataPortOutput) output = NULL;
+ /* Fall down to a successful connection */
+ } else {
+ mm_obj_info (self, "couldn't start network: %s", error->message);
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_CALL_FAILED)) {
+ QmiWdsCallEndReason cer;
+ QmiWdsVerboseCallEndReasonType verbose_cer_type;
+ gint16 verbose_cer_reason;
- ctx = g_task_get_task_data (task);
+ if (qmi_message_wds_start_network_output_get_call_end_reason (
+ output,
+ &cer,
+ NULL))
+ mm_obj_info (self, "call end reason (%u): %s", cer, qmi_wds_call_end_reason_get_string (cer));
- g_assert (ctx->running_ipv4 || ctx->running_ipv6);
- g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
+ if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
+ output,
+ &verbose_cer_type,
+ &verbose_cer_reason,
+ NULL))
+ mm_obj_info (self, "verbose call end reason (%u,%d): [%s] %s",
+ verbose_cer_type,
+ verbose_cer_reason,
+ qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
+ qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+ }
+ }
+ }
- output = qmi_client_wds_bind_mux_data_port_finish (client, res, &error);
- if (!output || !qmi_message_wds_bind_mux_data_port_output_get_result (output, &error)) {
- g_prefix_error (&error, "Couldn't bind mux data port: ");
- complete_connect (task, NULL, error);
- return;
+ if (error) {
+ if (ctx->running_ipv4)
+ ctx->error_ipv4 = error;
+ else
+ ctx->error_ipv6 = error;
+ } else {
+ if (ctx->running_ipv4)
+ qmi_message_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle_ipv4, NULL);
+ else
+ qmi_message_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle_ipv6, NULL);
}
+ if (output)
+ qmi_message_wds_start_network_output_unref (output);
+
/* Keep on */
ctx->step++;
connect_context_step (task);
}
-static void
-set_ip_family_ready (QmiClientWds *client,
- GAsyncResult *res,
- GTask *task)
+static QmiMessageWdsStartNetworkInput *
+build_start_network_input (ConnectContext *ctx)
{
- MMBearerQmi *self;
- ConnectContext *ctx;
- GError *error = NULL;
- QmiMessageWdsSetIpFamilyOutput *output;
-
- self = g_task_get_source_object (task);
- ctx = g_task_get_task_data (task);
+ QmiMessageWdsStartNetworkInput *input;
+ gboolean has_user, has_password;
g_assert (ctx->running_ipv4 || ctx->running_ipv6);
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
- output = qmi_client_wds_set_ip_family_finish (client, res, &error);
- if (output) {
- qmi_message_wds_set_ip_family_output_get_result (output, &error);
- qmi_message_wds_set_ip_family_output_unref (output);
+ input = qmi_message_wds_start_network_input_new ();
+
+ if (ctx->apn && ctx->apn[0])
+ qmi_message_wds_start_network_input_set_apn (input, ctx->apn, NULL);
+
+ has_user = (ctx->user && ctx->user[0]);
+ has_password = (ctx->password && ctx->password[0]);
+
+ /* Need to add auth info? */
+ if (has_user || has_password || ctx->auth != QMI_WDS_AUTHENTICATION_NONE) {
+ /* We define a valid auth preference if we have either user or password, or an explicit
+ * request for one to be set. If no explicit one was given, default to CHAP. */
+ qmi_message_wds_start_network_input_set_authentication_preference (
+ input,
+ (ctx->auth != QMI_WDS_AUTHENTICATION_NONE) ? ctx->auth : QMI_WDS_AUTHENTICATION_CHAP,
+ NULL);
+
+ if (has_user)
+ qmi_message_wds_start_network_input_set_username (input, ctx->user, NULL);
+ if (has_password)
+ qmi_message_wds_start_network_input_set_password (input, ctx->password, NULL);
}
- if (error) {
- mm_obj_dbg (self, "couldn't set IP family preference: %s", error->message);
- g_error_free (error);
+ /* Only add the IP family preference TLV if explicitly requested a given
+ * family. This TLV may be newer than the Start Network command itself, so
+ * we'll just allow the case where none is specified. */
+ if (!ctx->no_ip_family_preference) {
+ qmi_message_wds_start_network_input_set_ip_family_preference (
+ input,
+ (ctx->running_ipv6 ? QMI_WDS_IP_FAMILY_IPV6 : QMI_WDS_IP_FAMILY_IPV4),
+ NULL);
}
- /* Keep on */
- ctx->step++;
- connect_context_step (task);
+ return input;
}
static void
@@ -1303,6 +1219,90 @@ cleanup_event_report_unsolicited_events (MMBearerQmi *self,
}
static void
+set_ip_family_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBearerQmi *self;
+ ConnectContext *ctx;
+ GError *error = NULL;
+ QmiMessageWdsSetIpFamilyOutput *output;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+ g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
+
+ output = qmi_client_wds_set_ip_family_finish (client, res, &error);
+ if (output) {
+ qmi_message_wds_set_ip_family_output_get_result (output, &error);
+ qmi_message_wds_set_ip_family_output_unref (output);
+ }
+
+ if (error) {
+ mm_obj_dbg (self, "couldn't set IP family preference: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* Keep on */
+ ctx->step++;
+ connect_context_step (task);
+}
+
+static void
+bind_data_port_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ ConnectContext *ctx;
+ GError *error = NULL;
+ g_autoptr(QmiMessageWdsBindDataPortOutput) output = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+ g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
+
+ output = qmi_client_wds_bind_data_port_finish (client, res, &error);
+ if (!output || !qmi_message_wds_bind_data_port_output_get_result (output, &error)) {
+ g_prefix_error (&error, "Couldn't bind data port: ");
+ complete_connect (task, NULL, error);
+ return;
+ }
+
+ /* Keep on */
+ ctx->step++;
+ connect_context_step (task);
+}
+
+static void
+bind_mux_data_port_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ ConnectContext *ctx;
+ GError *error = NULL;
+ g_autoptr(QmiMessageWdsBindMuxDataPortOutput) output = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+ g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
+
+ output = qmi_client_wds_bind_mux_data_port_finish (client, res, &error);
+ if (!output || !qmi_message_wds_bind_mux_data_port_output_get_result (output, &error)) {
+ g_prefix_error (&error, "Couldn't bind mux data port: ");
+ complete_connect (task, NULL, error);
+ return;
+ }
+
+ /* Keep on */
+ ctx->step++;
+ connect_context_step (task);
+}
+
+static void
qmi_port_allocate_client_ready (MMPortQmi *qmi,
GAsyncResult *res,
GTask *task)
@@ -1560,7 +1560,6 @@ connect_context_step (GTask *task)
}
case CONNECT_STEP_SETUP_LINK:
-
/* if muxing has been enabled in the port, we need to create a new link
* interface. */
if (MM_PORT_QMI_DAP_IS_SUPPORTED_QMAP (ctx->dap)) {