diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2017-03-25 01:11:45 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-04-18 18:08:57 +0200 |
commit | 91391eb460645cc9407b16e1b516cb4c2cf723f7 (patch) | |
tree | 2217d24b65f89b8140c56a85d1684773defb43f4 /src | |
parent | 973c7d0970d5151f1b5d40b01ce0f2334c226b7c (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.c | 79 |
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); } /*****************************************************************************/ |