diff options
author | Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com> | 2018-09-03 09:09:17 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-09-12 17:15:46 +0000 |
commit | e3c2f0e9cccd26794e4fa54dcd8663d97e129414 (patch) | |
tree | cb7eb0f5e63858af1378c713392eca60d7d294b1 | |
parent | 94879ce1ce7c04060d74e6dcca610e2f239b5820 (diff) | |
download | ModemManager-e3c2f0e9cccd26794e4fa54dcd8663d97e129414.tar.gz |
broadband-modem: set flow control from port
Set the flow control used in the data connection from the one
set in the port.
-rw-r--r-- | src/mm-broadband-modem.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index fe8e01df9..1ca614971 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -3313,6 +3313,9 @@ ifc_test_ready (MMBaseModem *_self, const gchar *response; MMFlowControl mask; const gchar *cmd; + MMFlowControl flow_control = MM_FLOW_CONTROL_UNKNOWN; + MMPortSerialAt *port; + const gchar *err_str = NULL; self = MM_BROADBAND_MODEM (_self); @@ -3326,22 +3329,63 @@ ifc_test_ready (MMBaseModem *_self, if (mask == MM_FLOW_CONTROL_UNKNOWN) goto out; - /* We prefer the methods in this order: - * RTS/CTS - * XON/XOFF - * None. - */ - if (mask & MM_FLOW_CONTROL_RTS_CTS) { - self->priv->flow_control = MM_FLOW_CONTROL_RTS_CTS; - cmd = "+IFC=2,2"; - } else if (mask & MM_FLOW_CONTROL_XON_XOFF) { - self->priv->flow_control = MM_FLOW_CONTROL_XON_XOFF; - cmd = "+IFC=1,1"; - } else if (mask & MM_FLOW_CONTROL_NONE) { - self->priv->flow_control = MM_FLOW_CONTROL_NONE; - cmd = "+IFC=0,0"; - } else - g_assert_not_reached (); + port = mm_base_modem_peek_best_at_port (_self, &error); + if (!port) + goto out; + + flow_control = mm_port_serial_get_flow_control (MM_PORT_SERIAL (port)); + + switch (flow_control) { + case MM_FLOW_CONTROL_RTS_CTS: + if (mask & MM_FLOW_CONTROL_RTS_CTS) { + self->priv->flow_control = MM_FLOW_CONTROL_RTS_CTS; + cmd = "+IFC=2,2"; + } else + err_str = "RTS/CTS"; + break; + case MM_FLOW_CONTROL_XON_XOFF: + if (mask & MM_FLOW_CONTROL_XON_XOFF) { + self->priv->flow_control = MM_FLOW_CONTROL_XON_XOFF; + cmd = "+IFC=1,1"; + } else + err_str = "xon/xoff"; + break; + case MM_FLOW_CONTROL_NONE: + if (mask & MM_FLOW_CONTROL_NONE) { + self->priv->flow_control = MM_FLOW_CONTROL_NONE; + cmd = "+IFC=0,0"; + } else + err_str = "none"; + break; + case MM_FLOW_CONTROL_UNKNOWN: + /* If flow control is not set explicitly by udev tags, + * we prefer the methods in this order: + * RTS/CTS + * XON/XOFF + * None. + */ + if (mask & MM_FLOW_CONTROL_RTS_CTS) { + self->priv->flow_control = MM_FLOW_CONTROL_RTS_CTS; + cmd = "+IFC=2,2"; + } else if (mask & MM_FLOW_CONTROL_XON_XOFF) { + self->priv->flow_control = MM_FLOW_CONTROL_XON_XOFF; + cmd = "+IFC=1,1"; + } else if (mask & MM_FLOW_CONTROL_NONE) { + self->priv->flow_control = MM_FLOW_CONTROL_NONE; + cmd = "+IFC=0,0"; + } else + g_assert_not_reached (); + break; + } + + if (err_str) { + g_set_error (&error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "%s: failed to set serial flow control to %s", + __func__, err_str); + goto fatal; + } /* Notify the flow control property update */ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FLOW_CONTROL]); @@ -3358,6 +3402,11 @@ out: g_task_return_boolean (task, TRUE); g_object_unref (task); + return; + +fatal: + g_task_return_error (task, error); + g_object_unref (task); } static void |