diff options
author | Dan Williams <dcbw@redhat.com> | 2012-12-17 14:23:00 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-12-17 14:23:00 -0600 |
commit | c08b03f6fde138bad5d4d3232af073314fdce640 (patch) | |
tree | a6ac7745802fef1f6470799a3dcfc72042f5c8e9 | |
parent | dc9bbefbc083a328fad0b770d1e716e704c72c65 (diff) |
sierra: fix APP1 PPP functionality
Unfortunately, Sierra secondary APP ports reply to +GCAP with
only "OK", and not their APP port number or model number. So instead
of using +GCAP, we have to use ATI to get secondary port information.
This allows us to detect which port is the APP1 port that we can
potentially use for PPP, leaving the primary port available for
control and status.
Also, some modems have up to 3 or 4 APP secondary ports, which we
need to ensure aren't used as primary. The previous check for +GCAP
handled that, but let's make it more explicit.
AT+GCAP reply:
OK
ATI reply:
Sierra Wireless, Inc.
C885
APP1
OK
See also: 3f3987e09ee762e48c1d53cb42a1288ce9f332cb (MM_06)
-rw-r--r-- | plugins/sierra/mm-plugin-sierra.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/plugins/sierra/mm-plugin-sierra.c b/plugins/sierra/mm-plugin-sierra.c index f51bca6d..356768e7 100644 --- a/plugins/sierra/mm-plugin-sierra.c +++ b/plugins/sierra/mm-plugin-sierra.c @@ -39,9 +39,8 @@ int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; /*****************************************************************************/ /* Custom init */ -#define TAG_SIERRA_APP1_PORT "sierra-app1-port" -#define TAG_SIERRA_APP_PPP_OK "sierra-app-ppp-ok" -#define TAG_SIERRA_SECONDARY_PORT "sierra-secondary-port" +#define TAG_SIERRA_APP_PORT "sierra-app-port" +#define TAG_SIERRA_APP1_PPP_OK "sierra-app1-ppp-ok" typedef struct { MMPortProbe *probe; @@ -86,28 +85,36 @@ gcap_ready (MMAtSerialPort *port, return; } - /* A valid reply to +GCAP tells us this is an AT port already */ + /* A valid reply to ATI tells us this is an AT port already */ mm_port_probe_set_result_at (ctx->probe, TRUE); - /* Some secondary ports in sierra modems like to reply just 'OK' to any - * command passed, like +GCAP. Detect that as soon as possible */ - if (!g_str_has_prefix (response->str, "+GCAP")) { - g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_SECONDARY_PORT, GUINT_TO_POINTER (TRUE)); - } else if (strstr (response->str, "APP1")) { - g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PORT, GUINT_TO_POINTER (TRUE)); + /* Sierra APPx ports have limited AT command parsers that just reply with + * "OK" to most commands. These can sometimes be used for PPP while the + * main port is used for status and control, but older modems tend to crash + * or fail PPP. So we whitelist modems that are known to allow PPP on the + * secondary APP ports. + */ + if (strstr (response->str, "APP1")) { + g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE)); - /* 885 can handle PPP on the APP ports, leaving the primary port open - * for command and status while connected. Older modems (ie 8775) say - * they can but fail during PPP. - */ + /* PPP-on-APP1-port whitelist */ if (strstr (response->str, "C885") || strstr (response->str, "USB 306")) - g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PPP_OK, GUINT_TO_POINTER (TRUE)); + g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE)); - /* For debugging: let users figure out if their device supports it or not */ + /* For debugging: let users figure out if their device supports PPP + * on the APP1 port or not. + */ if (getenv ("MM_SIERRA_APP1_PPP_OK")) { mm_dbg ("Sierra: APP1 PPP OK '%s'", response->str); - g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PPP_OK, GUINT_TO_POINTER (TRUE)); + g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE)); } + } else if (strstr (response->str, "APP2") || + strstr (response->str, "APP3") || + strstr (response->str, "APP4")) { + /* Additional APP ports don't support most AT commands, so they cannot + * be used as the primary port. + */ + g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE)); } g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); @@ -139,7 +146,7 @@ sierra_custom_init_step (SierraCustomInitContext *ctx) ctx->retries--; mm_at_serial_port_queue_command ( ctx->port, - "AT+GCAP", + "ATI", 3, FALSE, /* raw */ ctx->cancellable, @@ -181,8 +188,7 @@ sierra_port_probe_list_is_icera (GList *probes) * secondary. This will skip the stupid ports which reply OK to every * AT command, even the one we use to check for Icera support */ if (mm_port_probe_is_icera (MM_PORT_PROBE (l->data)) && - !g_object_get_data (G_OBJECT (l->data), TAG_SIERRA_SECONDARY_PORT) && - !g_object_get_data (G_OBJECT (l->data), TAG_SIERRA_APP1_PORT)) + !g_object_get_data (G_OBJECT (l->data), TAG_SIERRA_APP_PORT)) return TRUE; } @@ -235,13 +241,11 @@ grab_port (MMPlugin *self, ptype = mm_port_probe_get_port_type (probe); /* Is it a GSM secondary port? */ - if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP1_PORT)) { - if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP_PPP_OK)) + if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP_PORT)) { + if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP1_PPP_OK)) pflags = MM_AT_PORT_FLAG_PPP; else pflags = MM_AT_PORT_FLAG_SECONDARY; - } else if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_SECONDARY_PORT)) { - pflags = MM_AT_PORT_FLAG_SECONDARY; } else if (ptype == MM_PORT_TYPE_AT) pflags = MM_AT_PORT_FLAG_PRIMARY; |