Huawei E3531 configuration Raspbian Jessie – pppd

In the previous post huawei-e3531-configuration-raspbian-jessie I got usb_modeswitch running to change the mode of the usb dongle into modem mode on insertion or reboot. This post is a continuation on the previous post to configure pppd to use the usb dongle as a modem and set up a point to point connection to the internet, or at least the mobile provider. When using a tutorial found online it didn’t work first time. A problem setting up the connection is described with logfiles and attempts to diagnose the problem, then the solution is provided. This solution is most likely specific to o2(uk). The final section describes the configuration file used just to get pppd working with o2. Networking is not covered since once the connection is established there are many ways you can configure routing, firewalls and VPN to name a few. An example use for this is you can configure hostapd and dnsmasq to provide a mobile broadband hotspot.

Following the advice on [Insert Link here, unknown source], when trying to the connect the connection would fail to come up. On checking /var/log/syslog I was getting the following PAP authentication succeeded but then the modem would hang up immediately afterwards:

Dec 24 12:54:28 raspberrypi pppd[9435]: Serial connection established.
Dec 24 12:54:28 raspberrypi pppd[9435]: Using interface ppp0
Dec 24 12:54:28 raspberrypi pppd[9435]: Connect: ppp0 <--> /dev/ttyUSB0
Dec 24 12:54:29 raspberrypi pppd[9435]: Remote message: Greetings!!
Dec 24 12:54:29 raspberrypi pppd[9435]: PAP authentication succeeded
Dec 24 12:54:29 raspberrypi pppd[9435]: LCP terminated by peer
<strong>Dec 24 12:54:29 raspberrypi pppd[9435]: Hangup (SIGHUP)</strong>
Dec 24 12:54:29 raspberrypi pppd[9435]: Modem hangup
Dec 24 12:54:29 raspberrypi pppd[9435]: Connection terminated.

This logfile isn’t very descriptive, luckily you can enable debugging by adding the “debug” option to the end of the pppd configuration file. The one I was using was located in: /etc/ppp/peers/gprs. I also changed the authentication to CHAP but this had no success. Below is the logfile with debugging enabled.

Dec 26 18:56:21 raspberrypi pppd[10226]: Using interface ppp0
Dec 26 18:56:21 raspberrypi pppd[10226]: Connect: ppp0 &lt;--&gt; /dev/ttyUSB0
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [LCP ConfReq id=0x2 &lt;asyncmap 0x0&gt; &lt;magic 0x55b552f8&gt; &lt;pcomp&gt; &lt;accomp&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [LCP ConfReq id=0x1 &lt;accomp&gt; &lt;pcomp&gt; &lt;asyncmap 0x0&gt; &lt;mru 1500&gt; &lt;magic 0x54d&gt; &lt;auth chap MD5&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [LCP ConfAck id=0x1 &lt;accomp&gt; &lt;pcomp&gt; &lt;asyncmap 0x0&gt; &lt;mru 1500&gt; &lt;magic 0x54d&gt; &lt;auth chap MD5&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [LCP ConfAck id=0x2 &lt;asyncmap 0x0&gt; &lt;magic 0x55b552f8&gt; &lt;pcomp&gt; &lt;accomp&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [LCP EchoReq id=0x0 magic=0x55b552f8]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [CHAP Challenge id=0x1 &lt;6a72fdb6d5e382736072d083cdd069ea&gt;, name = "HUAWEI_CHAP_SRVR"]
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [CHAP Response id=0x1 &lt;b30763faefba7325481226d08eeb2fb8&gt;, name = "o2web"]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [LCP EchoRep id=0x0 magic=0x54d]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [CHAP Success id=0x1 "Welcome!!"]
Dec 26 18:56:22 raspberrypi pppd[10226]: CHAP authentication succeeded: Welcome!!
Dec 26 18:56:22 raspberrypi pppd[10226]: CHAP authentication succeeded
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [CCP ConfReq id=0x2 &lt;deflate 15&gt; &lt;deflate(old#) 15&gt; &lt;bsd v1 15&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [IPCP ConfReq id=0x2 &lt;compress VJ 0f 01&gt; &lt;addr 0.0.0.0&gt; &lt;ms-dns1 0.0.0.0&gt; &lt;ms-dns2 0.0.0.0&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [IPCP ConfReq id=0x1]
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [IPCP ConfNak id=0x1 &lt;addr 0.0.0.0&gt;]
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [LCP ProtRej id=0x2 80 fd 01 02 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
Dec 26 18:56:22 raspberrypi pppd[10226]: Protocol-Reject for 'Compression Control Protocol' (0x80fd) received
<strong>Dec 26 18:56:22 raspberrypi pppd[10226]: Hangup (SIGHUP)</strong>
Dec 26 18:56:22 raspberrypi pppd[10226]: rcvd [LCP TermReq id=0x2]
Dec 26 18:56:22 raspberrypi pppd[10226]: LCP terminated by peer
Dec 26 18:56:22 raspberrypi pppd[10226]: sent [LCP TermAck id=0x2]
Dec 26 18:56:22 raspberrypi pppd[10226]: Modem hangup
Dec 26 18:56:22 raspberrypi pppd[10226]: Connection terminated.

It looks like “Protocol-Reject for ‘Compression Control Protocol’ (0x80fd) received” is causing the hangup. After trying additional options in /etc/ppp/peers/ to disable compression it seemed like this made things worse by not trying to negotiate over LCP and ending the connection sooner. The additional options used are listed below, these all resulted in no success but sometimes the modem would connect and provide a link! On reboot or reconnecting it would not reliably connect.

novj
lock
crtscts
modem
passive
holdoff 10
maxfail 0
novjccomp
nopcomp
nodeflate

The solution

In the default chatscript /etc/chatscript/gprs there is a line to dial in data mode:

OK ATD*99#

It turns out for o2 this should be:

OK ATD*99***2#

After changing that line connection attempts succeeded consistently.

Configuration files

This section describes all the configuration used to get a connection working with the E3531 and o2 uk pay as you go.

The first configuration is to install pppd the usual way (apt-get ppp). Once this has completed a ppp configuration need to be established. The default file located in /etc/ppp/peers/gprs does a good job. Each configuration file in the peers directory represents a different connection. There can be multiple peers to connect to that you can configure in this directory. My gprs configuration for o2 is listed below.

# example configuration for a dialup connection authenticated with PAP or CHAP
#
# This is the default configuration used by pon(1) and poff(1).
# See the manual page pppd(8) for information on all the options.

# MUST CHANGE: replace myusername@realm with the PPP login name given to
# your by your provider.
# There should be a matching entry with the password in /etc/ppp/pap-secrets
# and/or /etc/ppp/chap-secrets.
user "payandgo"
password "wap"

# MUST CHANGE: replace ******** with the phone number of your provider.
# The /etc/chatscripts/pap chat script may be modified to change the
# modem initialization string.
connect "/usr/sbin/chat -v -f /etc/chatscripts/gprs -T payandgo.o2.co.uk"

# Serial device to which the modem is connected.
/dev/ttyUSB0

# Speed of the serial line.
921600

# Assumes that your IP address is allocated dynamically by the ISP.
noipdefault
# Try to get the name server addresses from the ISP.
usepeerdns
# Use this connection as the default route.
defaultroute

# Makes pppd "dial again" when the connection is lost.
persist

# Do not ask the remote to authenticate.
noauth

The user and password at the top of the configuration seems to bypass the secrets file despite the comment “There should be a matching entry with the password in /etc/ppp/pap-secrets and/or /etc/ppp/chap-secrets.” In my configuration this is ignored.

The connect line gets /usr/sbin/chat to send AT commands to the modem pointed to at /dev/ttyUSB0.  The -v option enables verbose logging in syslog (you can probably omit this). The -f option provides the chatfile described below. The -T option provides additional arguments to the chatscript. In the comments this is described as the phone number but in 3G this is the APN that o2 uses for pay as you go connections, payandgo.o2.co.uk.

noipdefault obtains an ip address from o2 although during the connection negotiation it seems to default to 10.164.164.164.

defaultroute adds o2 as the default route and noauth is ok to leave.

As mentioned before the chatscript sets up the modem and “dials”, this is where the number needed to change from the default script /etc/chatscripts/gprs

# You can use this script unmodified to connect to cellular networks.
# The APN is specified in the peers file as the argument of the -T command
# line option of chat(8).

# For details about the AT commands involved please consult the relevant
# standard: 3GPP TS 27.007 - AT command set for User Equipment (UE).
# (http://www.3gpp.org/ftp/Specs/html-info/27007.htm)

ABORT BUSY
ABORT VOICE
ABORT "NO CARRIER"
ABORT "NO DIALTONE"
ABORT "NO DIAL TONE"
ABORT "NO ANSWER"
ABORT "DELAYED"
ABORT "ERROR"

# cease if the modem is not attached to the network yet
ABORT "+CGATT: 0"

"" AT
TIMEOUT 12
OK ATH
OK ATE1

# +CPIN provides the SIM card PIN
#OK "AT+CPIN=1234"

# +CFUN may allow to configure the handset to limit operations to
# GPRS/EDGE/UMTS/etc to save power, but the arguments are not standard
# except for 1 which means "full functionality".
OK AT+CFUN=1,1

OK AT+CGDCONT=1,"IP","\T","",0,0
OK ATD*99***2#
TIMEOUT 22
CONNECT ""

The final configuration is required in /etc/network/interfaces.

auto gprs
iface gprs inet ppp
&nbsp; &nbsp; provider gprs

The ppp tells networking to use pppd with the configuration given by the provider option. I could be wrong but this seems equivalent to networking calling pppd call gprs where gprs is the options file given in /etc/ppp/peers/gprs describing the individual connection. If you had multiple connections you could use provider conn1 …etc.

All the configuration required is complete. Run ifup gprs to start connecting to the mobile broadband modem.

On reboot this doesn’t seem to automatically connect on boot and nothing in syslog seems to shed light on why. Ifup is required to get the connection going again but a script could be added in a udev rule for when the ttyUSB0 comes online, that’s for another day.

Conclusion

That concludes this two part post on using the E3531 Huawei dongle as a modem with o2 pay as you go. I’m sure this can be applied to other networks with different APN, user and password setting along with the ATD number.

Note: This usb modem and ppp was configured with raspbian jessie lite, at the time of writing raspbian stretch was available and it had not been verified that the usb_modeswitch fix in the first post was still necessary. If you try this with raspbian stretch you may find that usb_modeswitch works correctly when the modem is inserted the first time.

Huawei E3531 configuration Raspbian Jessie

This post describes the configuration I used on raspbian Jessie lite to get a Huawei E3531 working with the o2(uk) carrier. After searching a lot over the forums and google it was difficult to determine the correct way to do this using raspbian with this particular model of modem and the problems I was experiencing. The first hurdle was getting usb_modeswitch working correctly to switch the usb modem from mass storage mode into modem mode. The second hurdle was configuring pppd to set up the modem correctly and make a ppp connection to o2.

The first problem was usb_modeswitch not being run or failing to switch the dongle into modem mode.

The second problem was pppd connecting and successfully getting past authentication but then receiving modem hangups after LCP compression negotiation (if that’s the right term?).

In the end the solution to get this working was from a mixture of posts and manpages and a little bit of hacking. There are two sections to this, usb_modeswitch which describes how to get usb_modeswitch working with udev (the kernel event handler). The second section pppd is the actual configuration of pppd to set up the modem and dial to create the ppp connection.

usb_modeswitch

Usually when a 3G USB dongle is inserted it starts up in mass storage mode that gives you access to pre-loaded windows drivers stored on the device. When installed these drivers then send a specific packet to the modem to switch the mode into the modem mode. In the case of the Huawei E3531 under windows for simplicity there is a third mode which runs the HiLink firmware on the dongle. What HiLink does is present a LAN interface on windows much like a USB to Ethernet adapter. This interface then acts as if you’ve connected the Ethernet port to a modem/router where you can navigate to 192.168.6.254 on your favorite browser and view usage, signal strength messages etc. A dhcp server issues the dns and default route addresses to get out onto the mobile broadband network. For casual use HiLink is probably good enough but this additional layer of complexity is not required for small projects.

What usb_modeswitch does is send the special packet to the usb dongle which causes the mode to switch. Once the dongle has switched to change modes again it needs to be unplugged and plugged back in again so that it starts in mass storage mode.

For the Huawei you can tell which mode the device is in by using lsusb, if usb_modeswitch hasn’t already changed the mode (as in my case) there will be a line reported somewhere like:

pi@raspberrypi:~ $ lsusb
Bus 001 Device 004: ID 12d1:1f01 Huawei Technologies Co., Ltd.

ID 12d1:1f01 identifies mass storage mode, modem mode for this dongle is identified by ID 12d1:1001 and HiLink mode is ID 12d1:14dc.

usb_modeswitch is installed through the usual way by apt-get, in Raspbian jessie it was already available but as noted before nothing happend after the device was plugged in. There is a way to manually switch this device through the command line:

sudo usb_modeswitch -W -I -v 12d1 -p 1f01 -M 55534243123456780000000000000011062000000101000100000000000000

sudo usb_modeswitch -W -I -v 12d1 -p 1f01 -M 55534243123456780000000000000011062000000100000000000000000000

The first command switches it into HiLink mode and the second command switches the device into modem mode where /dev/ttyUSB0, /dev/ttyUSB1, /dev/ttyUSB2 is created to communicate through the modem with AT commands. AT commands configure the modem much like the common conexant dial up modems. There are a vast variety of commands to get RSSI info and much more. You can also send/receive text messages, a little on that in a later post.

Using the second command you should see the output, lsusb result and tty devices:

pi@raspberrypi:~ $ sudo usb_modeswitch -W -I -v 12d1 -p 1f01 -M 55534243123456780000000000000011062000000100000000000000000000
Take all parameters from the command line

* usb_modeswitch: handle USB devices with multiple modes
* Version 2.2.0 (C) Josua Dietze 2014
* Based on libusb1/libusbx

! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor= 0x12d1
DefaultProduct= 0x1f01
MessageContent="55534243123456780000000000000011062000000100000000000000000000"
NeedResponse=0

InquireDevice=1

Look for default devices ...
found USB ID 12d1:1f01
vendor ID matched
product ID matched
found USB ID 0424:ec00
found USB ID 0424:9514
found USB ID 1d6b:0002
Found devices in default mode (1)
Access device 007 on bus 001
Current configuration number is 1
Use interface number 0
Use endpoints 0x01 (out) and 0x81 (in)
Inquire device details; driver will be detached ...
Looking for active driver ...
OK, driver detached

SCSI inquiry data (for identification)
-------------------------
Vendor String: HUAWEI
Model String: Mass Storage
Revision String: 2.31
-------------------------

USB description data (for identification)
-------------------------
Manufacturer: HUAWEI
Product: HUAWEI Mobile
Serial No.: FFFFFFFFFFFFFFFF
-------------------------
Set up interface 0
Use endpoint 0x01 for message sending ...
Trying to send message 1 to endpoint 0x01 ...
OK, message successfully sent
Reset response endpoint 0x81
Reset message endpoint 0x01
-&gt; Run lsusb to note any changes. Bye!

pi@raspberrypi:~ $ lsusb
Bus 001 Device 008: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
pi@raspberrypi:~ $ ls /dev/ttyUSB*
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2

The serial devices show up in /dev which great, pppd can then be configured to use these devices. One question remains is why is this not auto matically switching?

On http://www.draisberghof.de/usb_modeswitch/ the developer’s site, it mentions:

/etc/usb_modeswitch.d – a folder for customized config files. You can put new or modified config files here; they will take precedence over the collection of configurations in /usr/share/usb_modeswitch.”

On insertion of the USB dongle Udev should run usb_modeswitch and looking through syslog usb_modeswitch is being run, more worringly repeatedly. It first looked like usb_modeswitch does not recognise this device so I created the config file in usb_modeswitch.d below.

"/etc/usb_modeswitch.d/12d1:1f01"

DefaultVendor=0x12d1
DefaultProduct=0x1f01
MessageContent="55534243123456780000000000000011062000000100000000000000000000"
NoDriverLoading=1

This config file worked by manually running usb_modeswitch but not when inserting the dongle.

pi@raspberrypi:~ $ usb_modeswitch -c /etc/usb_modeswitch.d/12d1:1f01

Without investigating further as to why usb_modeswitch wasn’t automatically running and changing modes, since I’m not familiar with the internals of udev and usb_modeswitch, I hacked a little script in the home directory to get udev to run 15s after inserting the device so that usb_modeswitch isn’t required to be run manually. This script will take the usb ID from udev and run the config file saved in /etc/usb_modeswitch.d/. 

#!/bin/bash

CONFIG=/etc/usb_modeswitch.d/$1\:$2

sleep 15

usb_modeswitch -D -c $CONFIG

A udev rule is required to run this script, as a start a template was taken from /lib/udev/rules.d/40-usb_modeswitch.rules

"/etc/udev/rules.d/41-usb_modeswitch.rules"

ATTRS{idVendor}=="12d1", ATTR{bInterfaceNumber}=="00", ATTR{bInterfaceClass}=="08", RUN+="/home/pi/USBDevConnect %s{idVendor} %s{idProduct}"

The above rule runs /home/pi/USBDevConnect once on insertion of the E3531 and passes the vendor and product id to the script which the script uses as the config file. %s is a neat way to pass attributes to custom scripts.

Notice the use of sleep in USBDevConnect, I put this in to mimic the delay of manually running usb_modeswitch and the length is plucked out of thin air. Udev does have a limit of how long this script can run for, it seems 30s is hardcoded and any longer the script will get killed by udev unfortunately.

Using the above hack will get the E3531 to switch on insertion and at reboot. The next section will describe connecting to the internet via pppd.

pppd

See part 2 – pppd

Conclusion

This has turned into a two part post as the workaround to get usb_modeswitch working was long. A workaround has been proposed but please note this usb modem was configured with raspbian jessie lite, at the time of writing raspbian stretch was available and it had not been verified that the usb_modeswitch fix in the first post was still necessary. If you try this with raspbian stretch you may find that usb_modeswitch works correctly when the modem is inserted the first time.

See part 2 – pppd to get to the configuration of dialing the modem and establishing a point to point connection.