summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>2018-09-03 09:09:17 +0200
committerAleksander Morgado <aleksander@aleksander.es>2018-09-10 13:58:29 +0200
commit2ba7d6a054431fc1b8fa8560115952c0b6b3bb11 (patch)
tree033e9a70f39ae32a05caa9538650aecb164382b9
parentbfceaae6e32017f7023c1b982282a842cae2988f (diff)
downloadModemManager-2ba7d6a054431fc1b8fa8560115952c0b6b3bb11.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