bearer-qmi: if connection aborted, ensure network handles are released

If the connection attempt is aborted before finishing (either network
triggered or user triggered), we need to make sure that we run a 'Stop
Network' request for every 'Start Network' that had succeeded until
then, or otherwise we'll no longer be able to re-run a 'Start Network'
with the same settings and get a proper packet data handle.

E.g. in this sequence we attempt a IPv4v6 connection. The logic starts
setting up the IPv4 path:

    Wed Jul 29 14:44:06 2020 daemon.info [1567]: <info>  Modem /org/freedesktop/ModemManager1/Modem/0: state changed (registered -> connecting)
    Wed Jul 29 14:44:06 2020 daemon.debug [1567]: <debug> Launching connection with QMI port (usb/cdc-wdm0) and data port (net/wwan0)
    Wed Jul 29 14:44:06 2020 daemon.debug [1567]: <debug> Defaulting to use static IP method
    Wed Jul 29 14:44:06 2020 daemon.debug [1567]: <debug> Running IPv4 connection setup
    ...

The 'Start Network' for IPv4 succeeds and we get a proper packet data
handle:

    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: [/dev/cdc-wdm0] sent generic request (translated)... <<<<<< QMUX: <<<<<<   length  = 23 <<<<<<   flags   = 0x00 <<<<<<   service = "wds" <<<<<<   client  = 20 <<<<<< QMI: <<<<<<   flags       = "none" <<<<<<   transaction = 3075 <<<<<<   tlv_length  = 11 <<<<<<   message     = "Start Network" (0x0020) <<<<<< TLV: <<<<<<   type       = "APN" (0x14) <<<<<<   length     = 8 <<<<<<   value      = 69:6E:74:65:72:6E:65:74 <<<<<<   translated = internet
    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: [/dev/cdc-wdm0] received generic response (translated)... <<<<<< QMUX: <<<<<<   length  = 26 <<<<<<   flags   = 0x80 <<<<<<   service = "wds" <<<<<<   client  = 20 <<<<<< QMI: <<<<<<   flags       = "response" <<<<<<   transaction = 3075 <<<<<<   tlv_length  = 14 <<<<<<   message     = "Start Network" (0x0020) <<<<<< TLV: <<<<<<   type       = "Result" (0x02) <<<<<<   length     = 4 <<<<<<   value      = 00:00:00:00 <<<<<<   translated = SUCCESS <<<<<< TLV: <<<<<<   type       = "Packet Data Handle" (0x01) <<<<<<   length     = 4 <<<<<<   value      = 80:CD:AD:81 <<<<<<   translated = 2175651200

Then, we start the IPv6 connection path:
    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: <debug> Running IPv6 connection setup
    ...

But, because we suddenly are not registered in the network, the
connection is aborted, and we don't cleanup the IPv4 path at this
point, as this patch wasn't available.

    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: <debug> Bearer not allowed to connect, not registered in 3GPP network
    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: <debug> Forcing disconnection of bearer '/org/freedesktop/ModemManager1/Bearer/56'
    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: transaction 0xe1 aborted, but message is not abortable
    Wed Jul 29 14:44:07 2020 daemon.info [1567]: <info>  Modem /org/freedesktop/ModemManager1/Modem/0: state changed (connecting -> enabled)
    Wed Jul 29 14:44:07 2020 daemon.debug [1567]: <debug> Couldn't connect bearer '/org/freedesktop/ModemManager1/Bearer/56': 'operation cancelled'

We then attempt a new connection request with the same settings:

    Wed Jul 29 14:44:22 2020 daemon.info [1567]: <info>  Modem /org/freedesktop/ModemManager1/Modem/0: state changed (registered -> connecting)
    Wed Jul 29 14:44:22 2020 daemon.debug [1567]: <debug> Launching connection with QMI port (usb/cdc-wdm0) and data port (net/wwan0)
    Wed Jul 29 14:44:22 2020 daemon.debug [1567]: <debug> Defaulting to use static IP method
    Wed Jul 29 14:44:22 2020 daemon.debug [1567]: <debug> Running IPv4 connection setup

And we see how the 'Start Network' command fails with a 'No Effect'
error, as the IPv4 was left connected earlier. Due to this, the modem
is assumed connected, but we won't have a valid packet data handle to
stop the connection cleanly:

    Wed Jul 29 14:44:22 2020 daemon.debug [1567]: [/dev/cdc-wdm0] sent generic request (translated)... <<<<<< QMUX: <<<<<<   length  = 23 <<<<<<   flags   = 0x00 <<<<<<   service = "wds" <<<<<<   client  = 20 <<<<<< QMI: <<<<<<   flags       = "none" <<<<<<   transaction = 3080 <<<<<<   tlv_length  = 11 <<<<<<   message     = "Start Network" (0x0020) <<<<<< TLV: <<<<<<   type       = "APN" (0x14) <<<<<<   length     = 8 <<<<<<   value      = 69:6E:74:65:72:6E:65:74 <<<<<<   translated = internet
    Wed Jul 29 14:44:23 2020 daemon.debug [1567]: [/dev/cdc-wdm0] received generic response (translated)... <<<<<< QMUX: <<<<<<   length  = 26 <<<<<<   flags   = 0x80 <<<<<<   service = "wds" <<<<<<   client  = 20 <<<<<< QMI: <<<<<<   flags       = "response" <<<<<<   transaction = 3080 <<<<<<   tlv_length  = 14 <<<<<<   message     = "Start Network" (0x0020) <<<<<< TLV: <<<<<<   type       = "Result" (0x02) <<<<<<   length     = 4 <<<<<<   value      = 01:00:1A:00 <<<<<<   translated = FAILURE: NoEffect <<<<<< TLV: <<<<<<   type       = "Packet Data Handle" (0x01) <<<<<<   length     = 4 <<<<<<   value      = 00:00:00:00 <<<<<<   translated = 0
This commit is contained in:
Aleksander Morgado
2020-08-12 11:36:21 +00:00
parent 16e3bb892d
commit 7cd373589c
+43 -22
View File
@@ -463,27 +463,48 @@ connect_context_free (ConnectContext *ctx)
g_free (ctx->user);
g_free (ctx->password);
if (ctx->packet_service_status_ipv4_indication_id) {
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
ctx->client_ipv4,
FALSE,
&ctx->packet_service_status_ipv4_indication_id);
if (ctx->client_ipv4) {
if (ctx->packet_service_status_ipv4_indication_id) {
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
ctx->client_ipv4,
FALSE,
&ctx->packet_service_status_ipv4_indication_id);
}
if (ctx->event_report_ipv4_indication_id) {
cleanup_event_report_unsolicited_events (ctx->self,
ctx->client_ipv4,
&ctx->event_report_ipv4_indication_id);
}
if (ctx->packet_data_handle_ipv4) {
g_autoptr(QmiMessageWdsStopNetworkInput) input = NULL;
input = qmi_message_wds_stop_network_input_new ();
qmi_message_wds_stop_network_input_set_packet_data_handle (input, ctx->packet_data_handle_ipv4, NULL);
qmi_client_wds_stop_network (ctx->client_ipv4, input, 30, NULL, NULL, NULL);
}
g_clear_object (&ctx->client_ipv4);
}
if (ctx->event_report_ipv4_indication_id) {
cleanup_event_report_unsolicited_events (ctx->self,
ctx->client_ipv4,
&ctx->event_report_ipv4_indication_id);
}
if (ctx->packet_service_status_ipv6_indication_id) {
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
ctx->client_ipv6,
FALSE,
&ctx->packet_service_status_ipv6_indication_id);
}
if (ctx->event_report_ipv6_indication_id) {
cleanup_event_report_unsolicited_events (ctx->self,
ctx->client_ipv6,
&ctx->event_report_ipv6_indication_id);
if (ctx->client_ipv6) {
if (ctx->packet_service_status_ipv6_indication_id) {
common_setup_cleanup_packet_service_status_unsolicited_events (ctx->self,
ctx->client_ipv6,
FALSE,
&ctx->packet_service_status_ipv6_indication_id);
}
if (ctx->event_report_ipv6_indication_id) {
cleanup_event_report_unsolicited_events (ctx->self,
ctx->client_ipv6,
&ctx->event_report_ipv6_indication_id);
}
if (ctx->packet_data_handle_ipv6) {
g_autoptr(QmiMessageWdsStopNetworkInput) input = NULL;
input = qmi_message_wds_stop_network_input_new ();
qmi_message_wds_stop_network_input_set_packet_data_handle (input, ctx->packet_data_handle_ipv6, NULL);
qmi_client_wds_stop_network (ctx->client_ipv6, input, 30, NULL, NULL, NULL);
}
g_clear_object (&ctx->client_ipv6);
}
if (ctx->explicit_qmi_open)
@@ -491,8 +512,6 @@ connect_context_free (ConnectContext *ctx)
g_clear_error (&ctx->error_ipv4);
g_clear_error (&ctx->error_ipv6);
g_clear_object (&ctx->client_ipv4);
g_clear_object (&ctx->client_ipv6);
g_clear_object (&ctx->ipv4_config);
g_clear_object (&ctx->ipv6_config);
g_object_unref (ctx->data);
@@ -1558,6 +1577,7 @@ connect_context_step (GTask *task)
g_assert (ctx->self->priv->client_ipv4 == NULL);
if (ctx->packet_data_handle_ipv4) {
ctx->self->priv->packet_data_handle_ipv4 = ctx->packet_data_handle_ipv4;
ctx->packet_data_handle_ipv4 = 0;
ctx->self->priv->packet_service_status_ipv4_indication_id = ctx->packet_service_status_ipv4_indication_id;
ctx->packet_service_status_ipv4_indication_id = 0;
ctx->self->priv->event_report_ipv4_indication_id = ctx->event_report_ipv4_indication_id;
@@ -1569,6 +1589,7 @@ connect_context_step (GTask *task)
g_assert (ctx->self->priv->client_ipv6 == NULL);
if (ctx->packet_data_handle_ipv6) {
ctx->self->priv->packet_data_handle_ipv6 = ctx->packet_data_handle_ipv6;
ctx->packet_data_handle_ipv6 = 0;
ctx->self->priv->packet_service_status_ipv6_indication_id = ctx->packet_service_status_ipv6_indication_id;
ctx->packet_service_status_ipv6_indication_id = 0;
ctx->self->priv->event_report_ipv6_indication_id = ctx->event_report_ipv6_indication_id;