bearer-qmi: reorder methods in connection state machine

The "ready" methods for each step in the state machine must be ordered
from bottom to top, so that the readers can read the methods in that
order when following the logic.
This commit is contained in:
Aleksander Morgado
2021-04-23 22:26:45 +02:00
parent e7c1eb8287
commit 26243e7ed7

View File

@@ -580,135 +580,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)
{
@@ -1019,66 +890,14 @@ get_current_settings (GTask *task, QmiClientWds *client)
}
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
set_ip_family_ready (QmiClientWds *client,
start_network_ready (QmiClientWds *client,
GAsyncResult *res,
GTask *task)
{
MMBearerQmi *self;
ConnectContext *ctx;
GError *error = NULL;
QmiMessageWdsSetIpFamilyOutput *output;
QmiMessageWdsStartNetworkOutput *output;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
@@ -1086,22 +905,119 @@ set_ip_family_ready (QmiClientWds *client,
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);
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) {
mm_obj_dbg (self, "couldn't set IP family preference: %s", error->message);
g_error_free (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
packet_service_status_indication_cb (QmiClientWds *client,
QmiIndicationWdsPacketServiceStatusOutput *output,
@@ -1302,6 +1218,90 @@ cleanup_event_report_unsolicited_events (MMBearerQmi *self,
qmi_message_wds_set_event_report_input_unref (input);
}
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,
@@ -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)) {