[PATCH 8/8] broadband-bearer: once connected, set flow control settings
Dan Williams
dcbw at redhat.com
Sat Apr 1 03:57:43 UTC 2017
On Sat, 2017-03-25 at 19:32 +0100, Aleksander Morgado wrote:
> During modem initialization we detected the flow control settings
> supported by the modem, and selected the best one to use from them,
> notifying it to the device via AT+IFC. The device was therefore
> instructed to use that flow control setting for data transmission in
> the TTY (i.e. not during AT control commands).
>
> The missing thing was to also configure ourselves our end of the
> serial port with the same flow control settings when getting into
> data
> mode. By doing it ourselves, we avoid requiring any explicit setting
> in pppd for flow control; pppd can assume the flow control settings
> are already the expected ones.
>
> Worth noting that all this setup is completely ignored for TTYs
> exposed directly via USB.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=100394
> ---
> src/mm-broadband-bearer.c | 32 ++++++++++++++++++++++++++++++++
> src/mm-broadband-modem.c | 36 +++++++++++++++++++++++++-----------
> src/mm-broadband-modem.h | 4 ++++
> 3 files changed, 61 insertions(+), 11 deletions(-)
>
> diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
> index 9491f5a8..bccee72b 100644
> --- a/src/mm-broadband-bearer.c
> +++ b/src/mm-broadband-bearer.c
> @@ -259,6 +259,14 @@ dial_cdma_ready (MMBaseModem *modem,
> * connect_succeeded(), we do it right away so that we stop our
> polling. */
> mm_port_set_connected (ctx->data, TRUE);
>
> + /* Configure flow control to use while connected */
> + if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx-
> >data),
> + mm_broadband_modem_get_con
> nected_flow_control (MM_BROADBAND_MODEM (modem)),
> + &error)) {
> + mm_warn ("Couldn't set flow control settings: %s", error-
> >message);
> + g_clear_error (&error);
> + }
> +
> /* Keep port open during connection */
> ctx->close_data_on_exit = FALSE;
>
> @@ -557,6 +565,8 @@ atd_ready (MMBaseModem *modem,
> GAsyncResult *res,
> Dial3gppContext *ctx)
> {
> + GError *error = NULL;
> +
> /* DO NOT check for cancellable here. If we got here without
> errors, the
> * bearer is really connected and therefore we need to reflect
> that in
> * the state machine. */
> @@ -576,6 +586,14 @@ atd_ready (MMBaseModem *modem,
> return;
> }
>
> + /* Configure flow control to use while connected */
> + if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx-
> >dial_port),
> + mm_broadband_modem_get_con
> nected_flow_control (MM_BROADBAND_MODEM (modem)),
> + &error)) {
> + mm_warn ("Couldn't set flow control settings: %s", error-
> >message);
> + g_clear_error (&error);
> + }
> +
> /* The ATD command has succeeded, and therefore the TTY is in
> data mode now.
> * Instead of waiting for setting the port as connected later in
> * connect_succeeded(), we do it right away so that we stop our
> polling. */
> @@ -1452,9 +1470,16 @@ data_flash_cdma_ready (MMPortSerial *data,
> DetailedDisconnectContext *ctx)
> {
> GError *error = NULL;
> + GError *flow_control_error = NULL;
>
> mm_port_serial_flash_finish (data, res, &error);
>
> + /* Cleanup flow control */
> + if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (data),
> MM_FLOW_CONTROL_NONE, &flow_control_error)) {
> + mm_dbg ("Couldn't reset flow control settings: %s",
> flow_control_error->message);
> + g_clear_error (&flow_control_error);
> + }
> +
> /* We kept the serial port open during connection, now we close
> that open
> * count */
> mm_port_serial_close (data);
> @@ -1569,9 +1594,16 @@ data_flash_3gpp_ready (MMPortSerial *data,
> DetailedDisconnectContext *ctx)
> {
> GError *error = NULL;
> + GError *flow_control_error = NULL;
>
> mm_port_serial_flash_finish (data, res, &error);
>
> + /* Cleanup flow control */
> + if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (data),
> MM_FLOW_CONTROL_NONE, &flow_control_error)) {
> + mm_dbg ("Couldn't reset flow control settings: %s",
> flow_control_error->message);
> + g_clear_error (&flow_control_error);
> + }
> +
> /* We kept the serial port open during connection, now we close
> that open
> * count */
> mm_port_serial_close (data);
> diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
> index e7376310..83302f63 100644
> --- a/src/mm-broadband-modem.c
> +++ b/src/mm-broadband-modem.c
> @@ -146,6 +146,7 @@ struct _MMBroadbandModemPrivate {
> guint modem_cind_max_signal_quality;
> guint modem_cind_indicator_roaming;
> guint modem_cind_indicator_service;
> + MMFlowControl modem_flow_control;
>
> /*<--- Modem 3GPP interface --->*/
> /* Properties */
> @@ -3101,17 +3102,20 @@ modem_setup_flow_control_finish
> (MMIfaceModem *self,
> }
>
> static void
> -ifc_test_ready (MMBaseModem *self,
> +ifc_test_ready (MMBaseModem *_self,
> GAsyncResult *res,
> GTask *task)
> {
> - GError *error = NULL;
> - const gchar *response;
> - MMFlowControl mask;
> - const gchar *cmd;
> + MMBroadbandModem *self;
> + GError *error = NULL;
> + const gchar *response;
> + MMFlowControl mask;
> + const gchar *cmd;
> +
> + self = MM_BROADBAND_MODEM (_self);
>
> /* Completely ignore errors in AT+IFC=? */
> - response = mm_base_modem_at_command_finish (self, res, &error);
> + response = mm_base_modem_at_command_finish (_self, res, &error);
> if (!response)
> goto out;
>
> @@ -3125,17 +3129,20 @@ ifc_test_ready (MMBaseModem *self,
> * XON/XOFF
> * None.
> */
> - if (mask & MM_FLOW_CONTROL_RTS_CTS)
> + if (mask & MM_FLOW_CONTROL_RTS_CTS) {
> + self->priv->modem_flow_control = MM_FLOW_CONTROL_RTS_CTS;
> cmd = "+IFC=2,2";
> - else if (mask & MM_FLOW_CONTROL_XON_XOFF)
> + } else if (mask & MM_FLOW_CONTROL_XON_XOFF) {
> + self->priv->modem_flow_control = MM_FLOW_CONTROL_XON_XOFF;
> cmd = "+IFC=1,1";
> - else if (mask & MM_FLOW_CONTROL_NONE)
> + } else if (mask & MM_FLOW_CONTROL_NONE) {
> + self->priv->modem_flow_control = MM_FLOW_CONTROL_NONE;
> cmd = "+IFC=0,0";
> - else
> + } else
> g_assert_not_reached ();
>
> /* Set flow control settings and ignore result */
> - mm_base_modem_at_command (self, cmd, 3, FALSE, NULL, NULL);
> + mm_base_modem_at_command (_self, cmd, 3, FALSE, NULL, NULL);
>
> out:
> /* Ignore errors */
> @@ -10315,6 +10322,12 @@ mm_broadband_modem_get_current_charset
> (MMBroadbandModem *self)
> return self->priv->modem_current_charset;
> }
>
> +MMFlowControl
> +mm_broadband_modem_get_connected_flow_control (MMBroadbandModem
> *self)
> +{
> + return self->priv->modem_flow_control;
> +}
This part is kinda icky; and mm-broadband-bearer has no other case of
calling a mm_broadband_modem...() function. Could we perhaps pass it
as a property or something into the bearer on creation? It's not like
it's going to change over the bearer lifetime.
Dan
> gchar *
> mm_broadband_modem_create_device_identifier (MMBroadbandModem *self,
> const gchar *ati,
> @@ -10635,6 +10648,7 @@ mm_broadband_modem_init (MMBroadbandModem
> *self)
> self->priv->current_sms_mem1_storage = MM_SMS_STORAGE_UNKNOWN;
> self->priv->current_sms_mem2_storage = MM_SMS_STORAGE_UNKNOWN;
> self->priv->sim_hot_swap_supported = FALSE;
> + self->priv->modem_flow_control = MM_FLOW_CONTROL_NONE;
> }
>
> static void
> diff --git a/src/mm-broadband-modem.h b/src/mm-broadband-modem.h
> index d6b55d9d..9ac4eabd 100644
> --- a/src/mm-broadband-modem.h
> +++ b/src/mm-broadband-modem.h
> @@ -24,6 +24,7 @@
>
> #include <ModemManager.h>
>
> +#include "mm-modem-helpers.h"
> #include "mm-charsets.h"
> #include "mm-base-modem.h"
>
> @@ -109,6 +110,9 @@ gchar
> *mm_broadband_modem_take_and_convert_to_current_charset
> (MMBroadbandModem
>
> MMModemCharset mm_broadband_modem_get_current_charset
> (MMBroadbandModem *self);
>
> +/* Get the flow control setting to apply when connected, if any */
> +MMFlowControl mm_broadband_modem_get_connected_flow_control
> (MMBroadbandModem *self);
> +
> /* Create a unique device identifier string using the ATI and ATI1
> replies and some
> * additional internal info */
> gchar *mm_broadband_modem_create_device_identifier (MMBroadbandModem
> *self,
More information about the ModemManager-devel
mailing list