aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-03-25 01:11:45 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-04-18 18:08:57 +0200
commit91391eb460645cc9407b16e1b516cb4c2cf723f7 (patch)
tree2217d24b65f89b8140c56a85d1684773defb43f4 /src
parent973c7d0970d5151f1b5d40b01ce0f2334c226b7c (diff)
broadband-modem: query supported flow control modes before setting
Instead of assuming XON/XOFF is supported, we query the supported flow control modes, and then we set the best one based on that, preferring hardware flow control over software flow control.
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem.c79
1 files changed, 60 insertions, 19 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index b480255b..bb5c6d1a 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -3116,12 +3116,59 @@ modem_load_supported_charsets (MMIfaceModem *self,
/* configuring flow control (Modem interface) */
static gboolean
-modem_setup_flow_control_finish (MMIfaceModem *self,
- GAsyncResult *res,
- GError **error)
+modem_setup_flow_control_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
{
- /* Completely ignore errors */
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+ifc_test_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ const gchar *response;
+ MMFlowControl mask;
+ const gchar *cmd;
+
+ /* Completely ignore errors in AT+IFC=? */
+ response = mm_base_modem_at_command_finish (self, res, &error);
+ if (!response)
+ goto out;
+
+ /* Parse response */
+ mask = mm_parse_ifc_test_response (response, &error);
+ 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)
+ cmd = "+IFC=2,2";
+ else if (mask & MM_FLOW_CONTROL_XON_XOFF)
+ cmd = "+IFC=1,1";
+ else if (mask & MM_FLOW_CONTROL_NONE)
+ cmd = "+IFC=0,0";
+ else
+ g_assert_not_reached ();
+
+ /* Set flow control settings and ignore result */
+ mm_base_modem_at_command (self, cmd, 3, FALSE, NULL, NULL);
+
+out:
+ /* Ignore errors */
+ if (error) {
+ mm_dbg ("couldn't load supported flow control methods: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static void
@@ -3129,23 +3176,17 @@ modem_setup_flow_control (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
- /* By default, try to set XOFF/XON flow control */
+ /* Query supported flow control methods */
mm_base_modem_at_command (MM_BASE_MODEM (self),
- "+IFC=1,1",
+ "+IFC=?",
3,
- FALSE,
- NULL,
- NULL);
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_setup_flow_control);
- g_simple_async_result_set_op_res_gboolean (result, TRUE);
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
+ TRUE,
+ (GAsyncReadyCallback)ifc_test_ready,
+ task);
}
/*****************************************************************************/