diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-08-04 16:33:11 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-08-12 11:36:21 +0000 |
commit | 7cd373589cb7d81633a5df279e0b63c405cc2bb6 (patch) | |
tree | 3ba31369b5658f950ac2f4c0b483d2e78606d9d5 | |
parent | 16e3bb892d25e3cb7796889082943b073924a695 (diff) |
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
-rw-r--r-- | src/mm-bearer-qmi.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c index 91cb71d9..45185c6a 100644 --- a/src/mm-bearer-qmi.c +++ b/src/mm-bearer-qmi.c @@ -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->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->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_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; |