summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>2018-09-03 09:09:17 +0200
committerDan Williams <dcbw@redhat.com>2018-09-12 17:15:46 +0000
commite3c2f0e9cccd26794e4fa54dcd8663d97e129414 (patch)
treecb7eb0f5e63858af1378c713392eca60d7d294b1
parent94879ce1ce7c04060d74e6dcca610e2f239b5820 (diff)
downloadModemManager-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.c81
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