Package: network-manager
Version: 0.7.1-1
Severity: normal

The Huawei E220 USB 3G (HSDPA) modem accepts to do very little until the SIM
PIN is entered. Meanwhile, it replies "+CME ERROR: SIM PIN ..." on any
command. This is not expected by Network Manager's modem init code; NM tries
various init strings, always falling in timeout, then eventually gives up
(making the modem unusable). Sometimes, for reasons I don't understand, one
of the init strings causes the modem to spit out another "OK", which lets NM
proceed and provide the PIN. Once this happened, the modem is happy forever
(or a power loss happens, whichever is first).

It is also possible that debian/patches/04-struct_termios.patch introduces some
subtle shift of semantics and that in fact the modem intended to send both
+CME ERROR and OK aftwerwards.

The patch attached here adds "+CME ERROR" as a valid handshake terminator on
most exchanges; this considerably speeds up and improves the robustness of
the E220's startup. I'm not positive it's the best strategy, but it Works
For Me(tm) and might help someone else.

        -- Cyrille


-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (800, 'testing'), (600, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.30-1-686 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages network-manager depends on:
ii  adduser      3.110                       add and remove users and groups
ii  dbus         1.2.12-1                    simple interprocess messaging syst
ii  dhcp3-client 3.1.1-6                     DHCP client
ii  hal          0.5.12~git20090406.46dc48-2 Hardware Abstraction Layer
ii  ifupdown     0.6.8+nmu1                  high level tools to configure netw
ii  libc6        2.9-13                      GNU C Library: Shared libraries
ii  libdbus-1-3  1.2.12-1                    simple interprocess messaging syst
ii  libdbus-glib 0.80-4                      simple interprocess messaging syst
ii  libgcrypt11  1.4.4-2                     LGPL Crypto library - runtime libr
ii  libglib2.0-0 2.20.0-2                    The GLib library of C routines
ii  libgnutls26  2.6.6-1                     the GNU TLS library - runtime libr
ii  libgpg-error 1.6-1                       library for common error values an
ii  libhal1      0.5.12~git20090406.46dc48-2 Hardware Abstraction Layer - share
ii  libnl1       1.1-5                       library for dealing with netlink s
ii  libnm-glib0  0.7.1-1                     network management framework (GLib
ii  libnm-util1  0.7.1-1                     network management framework (shar
ii  libpolkit-db 0.9-3                       library for accessing PolicyKit vi
ii  libpolkit2   0.9-3                       library for accessing PolicyKit
ii  libtasn1-3   1.8-1                       Manage ASN.1 structures (runtime)
ii  libudev0     0.141-1                     libudev shared library
ii  libuuid1     1.41.3-1                    universally unique id library
ii  lsb-base     3.2-22                      Linux Standard Base 3.2 init scrip
ii  wpasupplican 0.6.9-2                     client support for WPA and WPA2 (I
ii  zlib1g       1:1.2.3.3.dfsg-13           compression library - runtime

Versions of packages network-manager recommends:
ii  dnsmasq-base               2.47-3        A small caching DNS proxy and DHCP
ii  iptables                   1.4.3.2-2     administration tools for packet fi
ii  network-manager-gnome      0.7.1-1       network management framework (GNOM
ii  policykit                  0.9-3         framework for managing administrat
ii  ppp                        2.4.4rel-10.1 Point-to-Point Protocol (PPP) - da

Versions of packages network-manager suggests:
ii  avahi-autoipd                 0.6.25-1   Avahi IPv4LL network address confi

-- no debconf information
diff -ur network-manager-0.7.1.vanilla2/ChangeLog network-manager-0.7.1/ChangeLog
--- network-manager-0.7.1.vanilla2/ChangeLog	2009-06-23 19:31:16.000000000 +0200
+++ network-manager-0.7.1/ChangeLog	2009-06-23 19:41:05.000000000 +0200
@@ -1,3 +1,10 @@
+2009-06-23  Cyrille Chépélov <cyri...@chepelov.org>
+
+    * callouts/nm-modem-probe.c:
+        - the Huawei E220 3G USB modem tends to reply "+CME ERROR:" instead 
+        of simply "ERROR" before a valid PIN is entered. Adding this to 
+        most terminator lists.
+
 2009-06-10  Cyrille Chépélov <cyri...@chepelov.org>
     
     * callouts/nm-modem-probe.c:
diff -ur network-manager-0.7.1.vanilla2/src/nm-gsm-device.c network-manager-0.7.1/src/nm-gsm-device.c
--- network-manager-0.7.1.vanilla2/src/nm-gsm-device.c	2009-04-13 00:29:59.000000000 +0200
+++ network-manager-0.7.1/src/nm-gsm-device.c	2009-06-23 19:00:27.000000000 +0200
@@ -244,7 +244,7 @@
 	NMSettingGsm *setting;
 	char *command;
 	const char *apn;
-	const char *responses[] = { "OK", "ERROR", NULL };
+	const char *responses[] = { "OK", "ERROR", "+CME ERROR", NULL };
 	guint cid = 1;
 
 	priv->reg_tries = 0;
@@ -322,7 +322,7 @@
 {
 	NMSettingGsm *setting;
 	char *command;
-	const char *responses[] = { "OK", "ERROR", "ERR", NULL };
+	const char *responses[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
 
@@ -353,7 +353,7 @@
 automatic_registration_get_network (NMGsmDevice *device)
 {
 	const char *responses[] = { "+COPS: ", NULL };
-	const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
+	const char *terminators[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	modem_wait_for_reply (device, "AT+COPS?", 10, responses, terminators, get_network_response, NULL);
 }
@@ -451,7 +451,7 @@
 	NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
 	const char *creg_responses[] = { "+CREG: 0,0", "+CREG: 0,1", "+CREG: 0,2", "+CREG: 0,3", "+CREG: 0,4", "+CREG: 0,5", NULL };
 	const char *cgreg_responses[] = { "+CGREG: 0,0", "+CGREG: 0,1", "+CGREG: 0,2", "+CGREG: 0,3", "+CGREG: 0,4", "+CGREG: 0,5", NULL };
-	const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
+	const char *terminators[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	if (priv->needs_cgreg)
 		modem_wait_for_reply (device, "AT+CGREG?", 15, cgreg_responses, terminators, automatic_registration_response, NULL);
@@ -505,7 +505,7 @@
 	NMGsmDevice *self = NM_GSM_DEVICE (device);
 	NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self);
 	const char *responses[] = { "E160G", "F3507g", "D5530", "MD300", NULL };
-	const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
+	const char *terminators[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	/* Get the model the first time */
 	if (!priv->checked_cgmm)
@@ -517,7 +517,7 @@
 static void
 power_up (NMGsmDevice *device)
 {
-	const char *responses[] = { "OK", "ERROR", "ERR", NULL };
+	const char *responses[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	nm_info ("(%s): powering up...", nm_device_get_iface (NM_DEVICE (device)));		
 	modem_wait_for_reply (device, "AT+CFUN=1", 10, responses, responses, power_up_response, NULL);
@@ -575,7 +575,8 @@
 init_modem_full (NMGsmDevice *device)
 {
 	NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
-	const char *responses[] = { "OK", "ERROR", "ERR", NULL };
+	const char *responses[] = { "OK", "ERROR", "ERR", "+CME ERROR",
+						 NULL };
 
 	/* Make sure that E0 gets sent here again, because some devices turn echo
 	 * back on after CPIN which just breaks stuff since echo-ed commands are
@@ -657,7 +658,7 @@
 	g_object_get (setting, secret_name, &secret, NULL);
 	if (secret) {
 		char *command;
-		const char *responses[] = { "OK", "ERROR", "ERR", NULL };
+		const char *responses[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 		command = g_strdup_printf ("AT+CPIN=\"%s\"", secret);
 		modem_wait_for_reply (device, command, 3, responses, responses, enter_pin_done, GUINT_TO_POINTER (secret_type));
@@ -742,7 +743,7 @@
 check_pin (NMGsmDevice *self)
 {
 	const char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
-	const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
+	const char *terminators[] = { "OK", "ERROR", "ERR", "+CME ERROR", NULL };
 
 	modem_wait_for_reply (self, "AT+CPIN?", 3, responses, terminators, check_pin_done, NULL);
 }
@@ -808,7 +809,8 @@
 init_modem (NMSerialDevice *device)
 {
 	NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
-	const char *responses[] = { "OK", "NO CARRIER", "ERROR", "ERR", NULL };
+	const char *responses[] = { "OK", "NO CARRIER", "ERROR", "ERR", 
+				"+CME ERROR", NULL };
 	const char *init_string = modem_init_sequences[priv->init_tries];
 
 	modem_wait_for_reply (NM_GSM_DEVICE (device), init_string, 10, responses, responses, init_done, NULL);

Reply via email to