Connecting a Linux Computer to the Internet using a USB GSM Modem

In the previous post we had looked at how to use a ZTE MF190 USB GSM modem to
send and receive SMS using a Perl script. For this post, we will setup this USB
modem as an internet access point and connect to the mobile network with the SIM
card we purchased for the previous post. The mobile network is LycaMobile which
is an MVNO of the T-Mobile cellular network.

This post has been tested using the Beaglebone Black (BBB) we had setup in an
earlier post, so is a perfect example of how to prototype an IoT device that can
connect to the internet by itself using an external GSM modem. The same
instructions will be valid for a Raspberry Pi or any other computer that has a
USB A port and runs a Debian/Ubuntu variant of Linux.


Pre-requisites

The first step is to install the required applications using apt-get.

$ sudo apt-get -y install wvdial usb-modeswitch ppp

Then we plug-in the USB modem into the BBB and make sure it has been detected by the kernel.

root@beaglebone:# lsusb                                                                                                                                                                              
Bus 001 Device 002: ID 19d2:0117 ZTE WCDMA Technologies MSM                                                                                                                                          
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Setting up WVDial

There is a program called wvdial that can be setup to connect to one or more GSM
networks using the commandline. To configure this program we have to edit the
default /etc/wvdial.conf file that was installed with the application.

The first step we did was to make a backup of the original file. Below you can
see that we have copied the original file to /etc/wvdial.conf.bak and run
cat on it to see its contents.

root@beaglebone:# cp /etc/wvdial.conf /etc/wvdial.conf.bak                                                                                                                                           
## original file                                                                                                                                                                                     
root@beaglebone3:/etc# cat wvdial.conf.bak                                                                                                                                                           

[Dialer Defaults]                                                                                                                                                                                    
Init1 = ATZ                                                                                                                                                                                          
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0                                                                                                                                                            
Modem Type = Analog Modem                                                                                                                                                                            
Baud = 9600                                                                                                                                                                                          
New PPPD = yes                                                                                                                                                                                       
Modem = /dev/ttyUSB1                                                                                                                                                                                 
ISDN = 0                                                                                                                                                                                             
; Phone = <Target Phone Number>                                                                                                                                                                      
; Password = <Your Password>                                                                                                                                                                         
; Username = <Your Login Name>                                                                                                                                                                       
`

We have to edit this file, update the Phone, Password and Username
fields and add a few more fields that can set the APN (Access Point Name) to the value that the network operator, LycaMobile, wants you to use. That value
is the domain data.lycamobile.com. This is done using the modem AT command
AT+CGDCONT as shown below. We also have to edit the Modem value to point to the device identifier which in our case is /dev/ttyUSB2. The Baud rate is set to be higher than 115200 so that we can achieve a good connection speed.

By default, the Username and Password fields are blank for LycaMobile and various other operators, but may not be empty for your specific operator.

## updated file                                                                                                                                                                                      
root@beaglebone:/etc# cat wvdial.conf                                                                                                                                                                

;; change the name of the Dialer to what you want                                                                                                                                                    
;; in our case we use the name of the data provider                                                                                                                                                  
[Dialer LycaMobile]                                                                                                                                                                                  
Init1 = ATZ                                                                                                                                                                                          
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0                                                                                                                                                            
;; change this to your service APN                                                                                                                                                                   
Init3 = AT+CGDCONT=1,"IP","data.lycamobile.com"                                                                                                                                                      
Stupid Mode = 1                                                                                                                                                                                      
Modem Type = Analog Modem                                                                                                                                                                            
Baud = 460800                                                                                                                                                                                        
New PPPD = yes                                                                                                                                                                                       
;; change the modem address to whatever your system supports                                                                                                                                         
Modem = /dev/ttyUSB2                                                                                                                                                                                 
ISDN = 0                                                                                                                                                                                             
Phone = *99#                                                                                                                                                                                         
Username = { }                                                                                                                                                                                       
Password = { }                                                                                                                                                                                       
```

Now we run the configuration which has been renamed from Defaults in the
original file to LycaMobile in the updated file. As soon as we run it, we
should be able to see that the internet connection has succeeded and that the
device has received an IP address from the network as shown below.

root@beaglebone3:/etc# wvdial LycaMobile                                                                                                                                                             
--> WvDial: Internet dialer version 1.61                                                                                                                                                             
--> Initializing modem.                                                                                                                                                                              
--> Sending: ATZ                                                                                                                                                                                     
ATZ                                                                                                                                                                                                  
OK                                                                                                                                                                                                   
--> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0                                                                                                                                                       
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0                                                                                                                                                                    
OK                                                                                                                                                                                                   
--> Sending: AT+CGDCONT=1,"IP","data.lycamobile.com"                                                                                                                                                 
AT+CGDCONT=1,"IP","data.lycamobile.com"                                                                                                                                                              
OK                                                                                                                                                                                                   
--> Modem initialized.                                                                                                                                                                               
--> Sending: ATDT*99#                                                                                                                                                                                
--> Waiting for carrier.                                                                                                                                                                             
ATDT*99#                                                                                                                                                                                             
CONNECT 7200000                                                                                                                                                                                      
--> Carrier detected.  Starting PPP immediately.                                                                                                                                                     
--> Starting pppd at Fri Aug 27 20:00:40 2021                                                                                                                                                        
--> Pid of pppd: 24168                                                                                                                                                                               
--> Using interface ppp0                                                                                                                                                                             
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> local  IP address 25.35.102.16                                                                                                                                                                   
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> remote IP address 10.64.67.64                                                                                                                                                                    
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> primary   DNS address 10.187.0.36                                                                                                                                                                
--> pppd: �[0f]%[01]�[0f]%[01]                                                                                                                                                                       
--> secondary DNS address 10.187.0.200                                                                                                                                                               
--> pppd: �[0f]%[01]�[0f]%[01]

Run ifconfig in a separate shell to verify that the connection has been truly
given an IP address and that it is exchanging packets.

debian@beaglebone3:~$ ifconfig                                                                                                                                                                       
ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500                                                                                                                                   
        inet 25.35.102.16  netmask 255.255.255.255  destination 10.64.67.64                                                                                                                          
        ppp  txqueuelen 3  (Point-to-Point Protocol)                                                                                                                                                 
        RX packets 5  bytes 62 (62.0 B)                                                                                                                                                              
        RX errors 0  dropped 0  overruns 0  frame 0                                                                                                                                                  
        TX packets 6  bytes 101 (101.0 B)                                                                                                                                                            
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

To exit wvdial, you have to hit Ctrl-C and kill the connection. This program
has to be manually started or can be started in an /etc/rc.local like script
once the full system has booted up.


In this simple way, you can now have a Linux computer connect to the internet
using the cellular network with a $10 modem and a SIM card.