summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>2018-09-03 09:03:56 +0200
committerDan Williams <dcbw@redhat.com>2018-09-12 17:15:46 +0000
commit4e69c10c2dd1409eb8e1b82051e758ff13164f35 (patch)
tree492b0732d25dad1813e87d1684ba6fa6f43f19b3
parenta1c27bf89d8f238509479f7223de7bb8677c005e (diff)
downloadModemManager-4e69c10c2dd1409eb8e1b82051e758ff13164f35.tar.gz
port-serial: add flow control property
Add flow control property to the MMPortSerial class, and use it when setting the port flow control.
-rw-r--r--src/mm-port-serial.c104
-rw-r--r--src/mm-port-serial.h2
2 files changed, 77 insertions, 29 deletions
diff --git a/src/mm-port-serial.c b/src/mm-port-serial.c
index 225a684e4..ff02213ec 100644
--- a/src/mm-port-serial.c
+++ b/src/mm-port-serial.c
@@ -35,6 +35,7 @@
#include "mm-port-serial.h"
#include "mm-log.h"
+#include "mm-helper-enums-types.h"
static gboolean port_serial_queue_process (gpointer data);
static void port_serial_schedule_queue_process (MMPortSerial *self,
@@ -53,6 +54,7 @@ enum {
PROP_BITS,
PROP_PARITY,
PROP_STOPBITS,
+ PROP_FLOW_CONTROL,
PROP_SEND_DELAY,
PROP_FD,
PROP_SPEW_CONTROL,
@@ -94,6 +96,7 @@ struct _MMPortSerialPrivate {
guint bits;
char parity;
guint stopbits;
+ MMFlowControl flow_control;
guint64 send_delay;
gboolean spew_control;
gboolean flash_ok;
@@ -404,6 +407,48 @@ internal_tcsetattr (MMPortSerial *self,
}
static gboolean
+set_flow_control_termios (MMPortSerial *self,
+ MMFlowControl flow_control,
+ struct termios *options)
+{
+ gboolean had_xon_xoff;
+ gboolean had_rts_cts;
+ tcflag_t iflag_orig, cflag_orig;
+
+ iflag_orig = options->c_iflag;
+ cflag_orig = options->c_cflag;
+
+ had_xon_xoff = !!(options->c_iflag & (IXON | IXOFF));
+ options->c_iflag &= ~(IXON | IXOFF | IXANY);
+
+ had_rts_cts = !!(options->c_cflag & (CRTSCTS));
+ options->c_cflag &= ~(CRTSCTS);
+
+ /* setup the requested flags */
+ switch (flow_control) {
+ case MM_FLOW_CONTROL_XON_XOFF:
+ mm_dbg ("(%s): enabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
+ options->c_iflag |= (IXON | IXOFF | IXANY);
+ break;
+ case MM_FLOW_CONTROL_RTS_CTS:
+ mm_dbg ("(%s): enabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
+ options->c_cflag |= (CRTSCTS);
+ break;
+ case MM_FLOW_CONTROL_NONE:
+ case MM_FLOW_CONTROL_UNKNOWN:
+ if (had_xon_xoff)
+ mm_dbg ("(%s): disabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
+ if (had_rts_cts)
+ mm_dbg ("(%s): disabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return iflag_orig != options->c_iflag || cflag_orig != options->c_cflag;
+}
+
+static gboolean
real_config_fd (MMPortSerial *self, int fd, GError **error)
{
struct termios stbuf;
@@ -471,6 +516,12 @@ real_config_fd (MMPortSerial *self, int fd, GError **error)
return FALSE;
}
+ mm_dbg ("(%s): flow control is: %d",
+ mm_port_get_device (MM_PORT (self)),
+ self->priv->flow_control);
+
+ set_flow_control_termios (self, self->priv->flow_control, &stbuf);
+
return internal_tcsetattr (self, fd, &stbuf, error);
}
@@ -1787,8 +1838,6 @@ mm_port_serial_set_flow_control (MMPortSerial *self,
GError **error)
{
struct termios options;
- gboolean had_xon_xoff;
- gboolean had_rts_cts;
/* retrieve current settings */
memset (&options, 0, sizeof (struct termios));
@@ -1798,37 +1847,18 @@ mm_port_serial_set_flow_control (MMPortSerial *self,
return FALSE;
}
- /* clear all flow control flags */
-
- had_xon_xoff = !!(options.c_iflag & (IXON | IXOFF));
- options.c_iflag &= ~(IXON | IXOFF | IXANY);
-
- had_rts_cts = !!(options.c_cflag & (CRTSCTS));
- options.c_cflag &= ~(CRTSCTS);
-
- /* setup the requested flags */
- switch (flow_control) {
- case MM_FLOW_CONTROL_XON_XOFF:
- mm_dbg ("(%s): enabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
- options.c_iflag |= (IXON | IXOFF | IXANY);
- break;
- case MM_FLOW_CONTROL_RTS_CTS:
- mm_dbg ("(%s): enabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
- options.c_cflag |= (CRTSCTS);
- break;
- case MM_FLOW_CONTROL_NONE:
- if (had_xon_xoff)
- mm_dbg ("(%s): disabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
- if (had_rts_cts)
- mm_dbg ("(%s): disabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
- break;
- default:
- g_assert_not_reached ();
- }
+ /* Return if current settings are already what we want */
+ if (!set_flow_control_termios (self, flow_control, &options))
+ return TRUE;
return internal_tcsetattr (self, self->priv->fd, &options, error);
}
+MMFlowControl mm_port_serial_get_flow_control (MMPortSerial *self)
+{
+ return self->priv->flow_control;
+}
+
/*****************************************************************************/
MMPortSerial *
@@ -1895,6 +1925,7 @@ mm_port_serial_init (MMPortSerial *self)
self->priv->bits = 8;
self->priv->parity = 'n';
self->priv->stopbits = 1;
+ self->priv->flow_control = MM_FLOW_CONTROL_UNKNOWN;
self->priv->send_delay = 1000;
self->priv->queue = g_queue_new ();
@@ -1925,6 +1956,9 @@ set_property (GObject *object,
case PROP_STOPBITS:
self->priv->stopbits = g_value_get_uint (value);
break;
+ case PROP_FLOW_CONTROL:
+ self->priv->flow_control = g_value_get_enum (value);
+ break;
case PROP_SEND_DELAY:
self->priv->send_delay = g_value_get_uint64 (value);
break;
@@ -1964,6 +1998,9 @@ get_property (GObject *object,
case PROP_STOPBITS:
g_value_set_uint (value, self->priv->stopbits);
break;
+ case PROP_FLOW_CONTROL:
+ g_value_set_enum (value, self->priv->flow_control);
+ break;
case PROP_SEND_DELAY:
g_value_set_uint64 (value, self->priv->send_delay);
break;
@@ -2062,6 +2099,15 @@ mm_port_serial_class_init (MMPortSerialClass *klass)
G_PARAM_READWRITE));
g_object_class_install_property
+ (object_class, PROP_FLOW_CONTROL,
+ g_param_spec_enum (MM_PORT_SERIAL_FLOW_CONTROL,
+ "flowcontrol",
+ "Select flow control (see MMFlowControl definition)",
+ MM_TYPE_FLOW_CONTROL,
+ MM_FLOW_CONTROL_UNKNOWN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
(object_class, PROP_SEND_DELAY,
g_param_spec_uint64 (MM_PORT_SERIAL_SEND_DELAY,
"SendDelay",
diff --git a/src/mm-port-serial.h b/src/mm-port-serial.h
index 0514e3607..bac79b442 100644
--- a/src/mm-port-serial.h
+++ b/src/mm-port-serial.h
@@ -35,6 +35,7 @@
#define MM_PORT_SERIAL_BITS "bits"
#define MM_PORT_SERIAL_PARITY "parity"
#define MM_PORT_SERIAL_STOPBITS "stopbits"
+#define MM_PORT_SERIAL_FLOW_CONTROL "flowcontrol"
#define MM_PORT_SERIAL_SEND_DELAY "send-delay"
#define MM_PORT_SERIAL_FD "fd" /* Construct-only */
#define MM_PORT_SERIAL_SPEW_CONTROL "spew-control" /* Construct-only */
@@ -154,4 +155,5 @@ gboolean mm_port_serial_set_flow_control (MMPortSerial *self,
MMFlowControl flow_control,
GError **error);
+MMFlowControl mm_port_serial_get_flow_control (MMPortSerial *self);
#endif /* MM_PORT_SERIAL_H */