From 939f8e8e83de8c5527a35feceb75f9b757f65f02 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Wed, 3 Dec 2014 19:25:26 +0100 Subject: [PATCH] port-probe: retry icera probing up to 3 times, with some time in between cmds Icera-based modems need to return a correct response to the AT%IPSYS? command, so that they are properly detected as being Icera-based. Now, some modems, like the Nokia 21M-02, don't seem to return a correct response to AT%IPSYS just after being plugged in. So, setup a retry mechanism (3 retries, with 2 seconds between retries) to try to cope with this issue. https://bugs.freedesktop.org/show_bug.cgi?id=85012 Logs from the error situation: [mm-port-serial-at.c:440] debug_log(): (ttyACM0): --> 'ATE1 E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM2): --> 'ATE1 E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): --> 'ATE1 E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM0): <-- 'E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM0): <-- 'ERROR' [mm-serial-parsers.c:364] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error [mm-port-probe-at.c:43] mm_port_probe_response_processor_is_at(): Parsing AT got: 'Unknown error' [mm-port-probe.c:155] mm_port_probe_set_result_at(): (tty/ttyACM0) port is AT-capable [mm-port-serial-at.c:440] debug_log(): (ttyACM2): <-- 'ATE1 E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- ' E0' [mm-port-serial-at.c:440] debug_log(): (ttyACM2): <-- '' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- 'ERROR' [mm-serial-parsers.c:364] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error [mm-port-probe-at.c:43] mm_port_probe_response_processor_is_at(): Parsing AT got: 'Unknown error' [mm-port-probe.c:155] mm_port_probe_set_result_at(): (tty/ttyACM1) port is AT-capable [mm-port-serial-at.c:440] debug_log(): (ttyACM2): <-- 'OK' [mm-port-probe.c:155] mm_port_probe_set_result_at(): (tty/ttyACM2) port is AT-capable [mm-port-serial-at.c:440] debug_log(): (ttyACM0): --> 'AT%IPSYS?' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): --> 'AT%IPSYS?' [mm-port-serial-at.c:440] debug_log(): (ttyACM2): --> 'AT%IPSYS?' [mm-port-serial-at.c:440] debug_log(): (ttyACM0): <-- 'AT%IPSYS?' [mm-port-serial-at.c:440] debug_log(): (ttyACM0): <-- '' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- 'AT%IPSYS?' [mm-port-serial-at.c:440] debug_log(): (ttyACM1): <-- 'ERROR' --- src/mm-port-probe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 94e7d3b..18adb38 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -103,6 +103,8 @@ typedef struct { const MMPortProbeAtCommand *at_custom_probe; /* Current group of AT commands to be sent */ const MMPortProbeAtCommand *at_commands; + /* Seconds between each AT command sent in the group */ + guint at_commands_wait_secs; /* Current AT Result processor */ void (* at_result_processor) (MMPortProbe *self, GVariant *result); @@ -916,7 +918,15 @@ serial_probe_at_parse_response (MMPortSerialAt *port, } /* Schedule the next command in the probing group */ - task->source_id = g_idle_add ((GSourceFunc)serial_probe_at, self); + if (task->at_commands_wait_secs == 0) + task->source_id = g_idle_add ((GSourceFunc)serial_probe_at, self); + else { + mm_dbg ("(%s/%s) re-scheduling next command in probing group in %u seconds...", + g_udev_device_get_subsystem (self->priv->port), + g_udev_device_get_name (self->priv->port), + task->at_commands_wait_secs); + task->source_id = g_timeout_add_seconds (task->at_commands_wait_secs, (GSourceFunc)serial_probe_at, self); + } goto out; } @@ -992,6 +1002,8 @@ static const MMPortProbeAtCommand product_probing[] = { static const MMPortProbeAtCommand icera_probing[] = { { "%IPSYS?", 3, mm_port_probe_response_processor_string }, + { "%IPSYS?", 3, mm_port_probe_response_processor_string }, + { "%IPSYS?", 3, mm_port_probe_response_processor_string }, { NULL } }; @@ -1040,6 +1052,7 @@ serial_probe_schedule (MMPortProbe *self) /* Cleanup */ task->at_result_processor = NULL; task->at_commands = NULL; + task->at_commands_wait_secs = 0; /* AT check requested and not already probed? */ if ((task->flags & MM_PORT_PROBE_AT) && @@ -1071,6 +1084,8 @@ serial_probe_schedule (MMPortProbe *self) /* Prepare AT product probing */ task->at_result_processor = serial_probe_at_icera_result_processor; task->at_commands = icera_probing; + /* By default, wait 2 seconds between ICERA probing retries */ + task->at_commands_wait_secs = 2; } /* If a next AT group detected, go for it */ -- 2.1.3