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:
@@ -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)) {
|
||||
|
Reference in New Issue
Block a user