aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-08-04 16:33:11 +0200
committerAleksander Morgado <aleksander@aleksander.es>2020-08-12 11:36:21 +0000
commit7cd373589cb7d81633a5df279e0b63c405cc2bb6 (patch)
tree3ba31369b5658f950ac2f4c0b483d2e78606d9d5
parent16e3bb892d25e3cb7796889082943b073924a695 (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.c65
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;