aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--src/Makefile.am28
-rw-r--r--src/mm-broadband-bearer.c125
-rw-r--r--src/mm-broadband-bearer.h3
-rw-r--r--src/mm-broadband-modem.c49
-rw-r--r--src/mm-broadband-modem.h3
-rw-r--r--src/mm-modem-helpers.h2
7 files changed, 196 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index 03c7d52e..9e79d258 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,8 @@ Makefile.in
/src/mm-daemon-enums-types.h
/src/mm-port-enums-types.c
/src/mm-port-enums-types.h
+/src/mm-helper-enums-types.c
+/src/mm-helper-enums-types.h
/src/mm-marshal.[ch]
/src/tests/test-modem-helpers
/src/tests/test-modem-helpers-qmi
diff --git a/src/Makefile.am b/src/Makefile.am
index 91b4e17a..13481e96 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,6 +67,28 @@ EXTRA_DIST += $(udevrules_DATA)
noinst_LTLIBRARIES += libhelpers.la
+HELPER_ENUMS_INPUTS = \
+ $(srcdir)/mm-modem-helpers.h \
+ $(NULL)
+
+HELPER_ENUMS_GENERATED = \
+ mm-helper-enums-types.h \
+ mm-helper-enums-types.c \
+ $(NULL)
+
+mm-helper-enums-types.h: Makefile.am $(HELPER_ENUMS_INPUTS) $(top_srcdir)/build-aux/mm-enums-template.h
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#include \"mm-modem-helpers.h\"\n#ifndef __MM_HELPER_ENUMS_TYPES_H__\n#define __MM_HELPER_ENUMS_TYPES_H__\n" \
+ --template $(top_srcdir)/build-aux/mm-enums-template.h \
+ --ftail "#endif /* __MM_HELPER_ENUMS_TYPES_H__ */\n" \
+ $(HELPER_ENUMS_INPUTS) > $@
+
+mm-helper-enums-types.c: Makefile.am $(top_srcdir)/build-aux/mm-enums-template.c mm-helper-enums-types.h
+ $(AM_V_GEN) $(GLIB_MKENUMS) \
+ --fhead "#include \"mm-helper-enums-types.h\"" \
+ --template $(top_srcdir)/build-aux/mm-enums-template.c \
+ $(HELPER_ENUMS_INPUTS) > $@
+
libhelpers_la_SOURCES = \
mm-error-helpers.c \
mm-error-helpers.h \
@@ -82,6 +104,8 @@ libhelpers_la_SOURCES = \
mm-sms-part-cdma.c \
$(NULL)
+nodist_libhelpers_la_SOURCES = $(HELPER_ENUMS_GENERATED)
+
if WITH_QMI
libhelpers_la_SOURCES += \
mm-modem-helpers-qmi.c \
@@ -96,6 +120,10 @@ libhelpers_la_SOURCES += \
$(NULL)
endif
+# Request to build enum types before anything else
+BUILT_SOURCES += $(HELPER_ENUMS_GENERATED)
+CLEANFILES += $(HELPER_ENUMS_GENERATED)
+
################################################################################
# kerneldevice library
################################################################################
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index 0565eee3..ac701733 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -35,6 +35,7 @@
#include "mm-log.h"
#include "mm-modem-helpers.h"
#include "mm-port-enums-types.h"
+#include "mm-helper-enums-types.h"
static void async_initable_iface_init (GAsyncInitableIface *iface);
@@ -48,6 +49,14 @@ typedef enum {
CONNECTION_TYPE_CDMA,
} ConnectionType;
+enum {
+ PROP_0,
+ PROP_FLOW_CONTROL,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
struct _MMBroadbandBearerPrivate {
/*-- Common stuff --*/
/* Data port used when modem is connected */
@@ -55,6 +64,9 @@ struct _MMBroadbandBearerPrivate {
/* Current connection type */
ConnectionType connection_type;
+ /* PPP specific */
+ MMFlowControl flow_control;
+
/*-- 3GPP specific --*/
/* CID of the PDP context */
guint cid;
@@ -254,6 +266,20 @@ dial_cdma_ready (MMBaseModem *modem,
return;
}
+ /* Configure flow control to use while connected */
+ if (ctx->self->priv->flow_control != MM_FLOW_CONTROL_NONE) {
+ gchar *flow_control_str;
+
+ flow_control_str = mm_flow_control_build_string_from_mask (ctx->self->priv->flow_control);
+ mm_dbg ("[%s] Setting flow control: %s", mm_port_get_device (ctx->data), flow_control_str);
+ g_free (flow_control_str);
+
+ if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx->data), ctx->self->priv->flow_control, &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. */
@@ -557,6 +583,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 +604,20 @@ atd_ready (MMBaseModem *modem,
return;
}
+ /* Configure flow control to use while connected */
+ if (ctx->self->priv->flow_control != MM_FLOW_CONTROL_NONE) {
+ gchar *flow_control_str;
+
+ flow_control_str = mm_flow_control_build_string_from_mask (ctx->self->priv->flow_control);
+ mm_dbg ("[%s] Setting flow control: %s", mm_port_get_device (MM_PORT (ctx->dial_port)), flow_control_str);
+ g_free (flow_control_str);
+
+ if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx->dial_port), ctx->self->priv->flow_control, &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. */
@@ -1455,6 +1497,16 @@ data_flash_cdma_ready (MMPortSerial *data,
mm_port_serial_flash_finish (data, res, &error);
+ /* Cleanup flow control */
+ if (ctx->self->priv->flow_control != MM_FLOW_CONTROL_NONE) {
+ GError *flow_control_error = NULL;
+
+ 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);
@@ -1572,6 +1624,16 @@ data_flash_3gpp_ready (MMPortSerial *data,
mm_port_serial_flash_finish (data, res, &error);
+ /* Cleanup flow control */
+ if (ctx->self->priv->flow_control != MM_FLOW_CONTROL_NONE) {
+ GError *flow_control_error = NULL;
+
+ 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);
@@ -2252,18 +2314,62 @@ mm_broadband_bearer_new (MMBroadbandModem *modem,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ MMFlowControl flow_control;
+
+ /* Inherit flow control from modem object directly */
+ g_object_get (modem,
+ MM_BROADBAND_MODEM_FLOW_CONTROL, &flow_control,
+ NULL);
+
g_async_initable_new_async (
MM_TYPE_BROADBAND_BEARER,
G_PRIORITY_DEFAULT,
cancellable,
callback,
user_data,
- MM_BASE_BEARER_MODEM, modem,
- MM_BASE_BEARER_CONFIG, properties,
+ MM_BASE_BEARER_MODEM, modem,
+ MM_BASE_BEARER_CONFIG, properties,
+ MM_BROADBAND_BEARER_FLOW_CONTROL, flow_control,
NULL);
}
static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MMBroadbandBearer *self = MM_BROADBAND_BEARER (object);
+
+ switch (prop_id) {
+ case PROP_FLOW_CONTROL:
+ self->priv->flow_control = g_value_get_flags (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MMBroadbandBearer *self = MM_BROADBAND_BEARER (object);
+
+ switch (prop_id) {
+ case PROP_FLOW_CONTROL:
+ g_value_set_flags (value, self->priv->flow_control);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
mm_broadband_bearer_init (MMBroadbandBearer *self)
{
/* Initialize private data */
@@ -2273,6 +2379,7 @@ mm_broadband_bearer_init (MMBroadbandBearer *self)
/* Set defaults */
self->priv->connection_type = CONNECTION_TYPE_NONE;
+ self->priv->flow_control = MM_FLOW_CONTROL_NONE;
}
static void
@@ -2300,8 +2407,9 @@ mm_broadband_bearer_class_init (MMBroadbandBearerClass *klass)
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerPrivate));
- /* Virtual methods */
- object_class->dispose = dispose;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+ object_class->dispose = dispose;
base_bearer_class->connect = connect;
base_bearer_class->connect_finish = connect_finish;
@@ -2325,4 +2433,13 @@ mm_broadband_bearer_class_init (MMBroadbandBearerClass *klass)
klass->disconnect_3gpp_finish = detailed_disconnect_finish;
klass->disconnect_cdma = disconnect_cdma;
klass->disconnect_cdma_finish = detailed_disconnect_finish;
+
+ properties[PROP_FLOW_CONTROL] =
+ g_param_spec_flags (MM_BROADBAND_BEARER_FLOW_CONTROL,
+ "Flow control",
+ "Flow control settings to use during connection",
+ MM_TYPE_FLOW_CONTROL,
+ MM_FLOW_CONTROL_NONE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_FLOW_CONTROL, properties[PROP_FLOW_CONTROL]);
}
diff --git a/src/mm-broadband-bearer.h b/src/mm-broadband-bearer.h
index bee2c521..c317bb5f 100644
--- a/src/mm-broadband-bearer.h
+++ b/src/mm-broadband-bearer.h
@@ -25,6 +25,7 @@
#define _LIBMM_INSIDE_MM
#include <libmm-glib.h>
+#include "mm-modem-helpers.h"
#include "mm-base-bearer.h"
#include "mm-broadband-modem.h"
@@ -39,6 +40,8 @@ typedef struct _MMBroadbandBearer MMBroadbandBearer;
typedef struct _MMBroadbandBearerClass MMBroadbandBearerClass;
typedef struct _MMBroadbandBearerPrivate MMBroadbandBearerPrivate;
+#define MM_BROADBAND_BEARER_FLOW_CONTROL "broadband-bearer-flow-control"
+
struct _MMBroadbandBearer {
MMBaseBearer parent;
MMBroadbandBearerPrivate *priv;
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index bb5c6d1a..4a14d33d 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -55,6 +55,7 @@
#include "libqcdm/src/commands.h"
#include "libqcdm/src/logs.h"
#include "libqcdm/src/log-items.h"
+#include "mm-helper-enums-types.h"
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
@@ -115,9 +116,12 @@ enum {
PROP_MODEM_VOICE_CALL_LIST,
PROP_MODEM_SIMPLE_STATUS,
PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
+ PROP_FLOW_CONTROL,
PROP_LAST
};
+static GParamSpec *properties[PROP_LAST];
+
/* When CIND is supported, invalid indicators are marked with this value */
#define CIND_INDICATOR_INVALID 255
#define CIND_INDICATOR_IS_VALID(u) (u != CIND_INDICATOR_INVALID)
@@ -146,6 +150,7 @@ struct _MMBroadbandModemPrivate {
guint modem_cind_max_signal_quality;
guint modem_cind_indicator_roaming;
guint modem_cind_indicator_service;
+ MMFlowControl flow_control;
/*<--- Modem 3GPP interface --->*/
/* Properties */
@@ -3124,17 +3129,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;
@@ -3148,17 +3156,23 @@ ifc_test_ready (MMBaseModem *self,
* XON/XOFF
* None.
*/
- if (mask & 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 if (mask & MM_FLOW_CONTROL_XON_XOFF)
+ } 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)
+ } else if (mask & MM_FLOW_CONTROL_NONE) {
+ self->priv->flow_control = MM_FLOW_CONTROL_NONE;
cmd = "+IFC=0,0";
- else
+ } else
g_assert_not_reached ();
+ /* Notify the flow control property update */
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FLOW_CONTROL]);
+
/* 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 */
@@ -10647,6 +10661,9 @@ get_property (GObject *object,
case PROP_MODEM_SIM_HOT_SWAP_SUPPORTED:
g_value_set_boolean (value, self->priv->sim_hot_swap_supported);
break;
+ case PROP_FLOW_CONTROL:
+ g_value_set_flags (value, self->priv->flow_control);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -10676,6 +10693,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->flow_control = MM_FLOW_CONTROL_NONE;
}
static void
@@ -11138,4 +11156,13 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
g_object_class_override_property (object_class,
PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED);
+
+ properties[PROP_FLOW_CONTROL] =
+ g_param_spec_flags (MM_BROADBAND_MODEM_FLOW_CONTROL,
+ "Flow control",
+ "Flow control settings to use in the connected TTY",
+ MM_TYPE_FLOW_CONTROL,
+ MM_FLOW_CONTROL_NONE,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_FLOW_CONTROL, properties[PROP_FLOW_CONTROL]);
}
diff --git a/src/mm-broadband-modem.h b/src/mm-broadband-modem.h
index d6b55d9d..4625b22a 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"
@@ -38,6 +39,8 @@ typedef struct _MMBroadbandModem MMBroadbandModem;
typedef struct _MMBroadbandModemClass MMBroadbandModemClass;
typedef struct _MMBroadbandModemPrivate MMBroadbandModemPrivate;
+#define MM_BROADBAND_MODEM_FLOW_CONTROL "broadband-modem-flow-control"
+
struct _MMBroadbandModem {
MMBaseModem parent;
MMBroadbandModemPrivate *priv;
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index bd10b940..297e15df 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -101,7 +101,7 @@ GRegex *mm_voice_clip_regex_get (void);
* For simplicity, we'll only consider flow control methods available in both
* TE and TA. */
-typedef enum {
+typedef enum { /*< underscore_name=mm_flow_control >*/
MM_FLOW_CONTROL_UNKNOWN = 0,
MM_FLOW_CONTROL_NONE = 1 << 0, /* IFC=0,0 */
MM_FLOW_CONTROL_XON_XOFF = 1 << 1, /* IFC=1,1 */