T.W. Chang's Blog

Raspberry Pi 與 SIM7000 PPP 連線設定

02 Aug 2022

SIM7000C Module

Devices & Software

Hardwares

Softwares

Hardware Connection

Connect the module to Raspberry Pi with USB cable.

+------------------+
|                  |   USB   +----------+
|   Raspberry Pi   | <-------+ SIM7000C |
|                  |         +----------+
+------------------+

Linux Setting

Package Installation

Some linux distro may already have ppp package installed. But in Raspberry Pi OS you have to download it using package manager (apt in the case).

$ sudo apt install ppp

If you want to manually configure the module, you probably need a serial console like minicom or screen. Both of these softwares are available on apt.

$ sudo apt install minicom # or screen

Connect to the module

When you plug-in the module. System will automatically appears 5 USB devices in the /dev folder.

$ ls -l /dev | grep USB
crw-rw---- 1 root dialout 188,   0 Aug  4 13:32 ttyUSB0
crw-rw---- 1 root dialout 188,   1 Aug  4  2022 ttyUSB1
crw-rw---- 1 root dialout 188,   2 Aug  4 13:32 ttyUSB2
crw-rw---- 1 root dialout 188,   3 Aug  4 13:32 ttyUSB3
crw-rw---- 1 root dialout 188,   4 Aug  4  2022 ttyUSB4

In this document (SIM7000 Series Linux User Guide_V2.00) from SIMCOM we can find a table about the SIM7000 USB Description. Each USB device provides different functions describe by following table.

USB Device Interface
/dev/ttyUSB0 Diagnostic
/dev/ttyUSB1 GPS NMEA
/dev/ttyUSB2 AT
/dev/ttyUSB3 Modem
/dev/ttyUSB4 USB Audio

PPP Configuration

When we want to establish a ppp connection. We need to create 2 config files, the chatscript and the peer provider’s config.

/etc/ppp directory’s structure can observed using tree command, it contants interfaces and provider’s configs.

$ tree /etc/ppp
/etc/ppp
├── chap-secrets
├── ip-down
├── ip-down.d
│   ├── 0000usepeerdns
│   └── 000resolvconf
├── ip-pre-up
├── ip-pre-up.d
├── ip-up
├── ip-up.d
│   ├── 0000usepeerdns
│   └── 000resolvconf
├── ipv6-down
├── ipv6-down.d
├── ipv6-up
├── ipv6-up.d
├── options
├── pap-secrets
└── peers
    └── provider

6 directories, 13 files

Chatscript

First, create a chatscript that execute the AT commands on SIM7000 module. We can copy the template from /etc/chatscripts/gprs to /etc/ppp/sim7000. Open copied file and change the APN to internet.iot (The CHT’s APN).

$ ls -l /etc/chatscripts/
total 12
-rw-r--r-- 1 root root 950 Jan  7  2021 gprs
-rw-r--r-- 1 root root 653 Jan  7  2021 pap
-rw-r----- 1 root dip  656 Aug  5 16:25 provider


$ sudo cp /etc/chatscripts/gprs /etc/ppp/sim7000
$ sudo vim /etc/ppp/sim7000
# At line 34 change \T into the APN that ISP provieds.
# OK        AT+CGDCONT=1,"IP","\T","",0,0
# OK        AT+CGDCONT=1,"IP","internet.iot","",0,0

Peer Provider Config

In /etc/ppp/peers/ have a provider file. Copy it and rename into anything you want (e.g. sim7000) in the same folder. Open the file and do the following three modifications.

$ sudo cp /etc/ppp/peers/provider /etc/ppp/peers/sim7000
$ sudo vim /etc/ppp/peers/sim7000

1. Replace the chatscript’s path

 12 # MUST CHANGE: replace ******** with the phone number of your provider.
 13 # The /etc/chatscripts/pap chat script may be modified to change the
 14 # modem initialization string.
 15 connect "/usr/sbin/chat -v -f /etc/ppp/sim7000"

2. Change the serial console port

In USB devices section. We can see that the modem’s port located in /dev/ttyUSB3.

 17 # Serial device to which the modem is connected.
 18 /dev/ttyUSB3

3. Add few options

 23 debug
 24 nocrtscts
 25 nodetach
 26 ipcp-accept-local
 27 ipcp-accept-remote

Establish The Connection

Use pppd to call the provider’s config (sim7000).

$ sudo pppd call sim7000
Script /usr/sbin/chat -v -f /etc/ppp/sim7000 finished (pid 8470), status = 0x0
Serial connection established.
using channel 1
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB3
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xc7630ae8> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x0 <asyncmap 0x0> <auth chap MD5> <magic 0xae79c4ba> <pcomp> <accomp>]
sent [LCP ConfNak id=0x0 <auth pap>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xc7630ae8> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0x0> <auth pap> <magic 0xae79c4ba> <pcomp> <accomp>]
sent [LCP ConfAck id=0x1 <asyncmap 0x0> <auth pap> <magic 0xae79c4ba> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0xc7630ae8]
sent [PAP AuthReq id=0x1 user="myusername@realm" password=<hidden>]
rcvd [LCP DiscReq id=0x2 magic=0xae79c4ba]
rcvd [LCP EchoRep id=0x0 magic=0xae79c4ba c7 63 0a e8]
rcvd [PAP AuthAck id=0x1 ""]
PAP authentication succeeded
sent [CCP ConfReq id=0x1 <deflate 15> <deflate(old#) 15> <bsd v1 15>]
sent [IPCP ConfReq id=0x1 <compress VJ 0f 01> <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
sent [IPV6CP ConfReq id=0x1 <addr fe80::ed80:bb63:1b64:4447>]
rcvd [LCP ProtRej id=0x3 80 fd 01 01 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
Protocol-Reject for 'Compression Control Protocol' (0x80fd) received
Modem hangup
Connection terminated.

If no error shows up. We can use ip a command to verify the connection and check the ip address.

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
# ...
12: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 3
    link/ppp
    inet 10.174.46.45 peer 10.64.64.64/32 scope global ppp0
       valid_lft forever preferred_lft forever

But how can we actually know whether the IP can communicate with the public network? By simply use ping command with -I argument with the interface name ppp0.

$ ping -I ppp0 8.8.8.8 -c 4
PING 8.8.8.8 (8.8.8.8) from 10.174.46.45 ppp0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=113 time=187 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=113 time=46.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=113 time=88.0 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=113 time=307 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 46.946/157.260/307.272/100.437 ms

Use ip command to set the default route to ppp0 interface.

$ sudo ip route add default dev ppp0

Verify the routing path using traceroute command.

$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  10.156.65.128 (10.156.65.128)  318.093 ms  531.195 ms  530.528 ms
 2  10.156.65.1 (10.156.65.1)  440.673 ms 10.156.65.5 (10.156.65.5)  415.479 ms 10.156.65.1 (10.156.65.1)  439.359 ms
 3  * * *
 4  10.156.67.66 (10.156.67.66)  447.782 ms 10.156.67.65 (10.156.67.65)  481.002 ms  480.337 ms
 5  tpdb-3311.hinet.net (210.65.126.94)  479.690 ms tpdb-3312.hinet.net (210.65.126.98)  479.039 ms  488.838 ms
 6  tpdt-3032.hinet.net (220.128.4.190)  497.950 ms  70.715 ms tpdt-3032.hinet.net (220.128.2.250)  69.541 ms
 7  tylc-3032.hinet.net (220.128.9.33)  78.521 ms * *
 8  pcpd-3212.hinet.net (220.128.13.189)  120.847 ms 220-128-13-129.hinet-ip.hinet.net (220.128.13.129)  87.522 ms pcpd-4102.hinet.net (220.128.13.109)  120.041 ms
 9  72.14.202.162 (72.14.202.162)  119.585 ms 72.14.221.186 (72.14.221.186)  119.698 ms 142.250.171.152 (142.250.171.152)  140.647 ms
10  * * *
11  dns.google (8.8.8.8)  129.792 ms  87.433 ms  97.758 ms

Systemd

Now we want the connection automatically start when system startup. We can create a system daemon (/etc/systemd/system/sim7000.service) that dialing-up and log the debug information into the log file.

[Unit]
Description=PPP SIM7000C dialing

[Service]
ExecStart=/usr/sbin/pppd call sim7000
KillMode=process
Restart=on-failure
Type=simple

[Install]
WantedBy=multi-user.target
Alias=sim7000.service

Reload the daemon and start it.

 $ sudo systemctl daemon-reload
 $ sudo systemctl enable --now sim7000
 $ sudo systemctl status sim7000
 ● sim7000.service - PPP SIM7000C dialing
      Loaded: loaded (/etc/systemd/system/sim7000.service; enabled; vendor preset: enabled)
      Active: active (running) since Mon 2022-08-08 10:58:10 CST; 1min 4s ago
    Main PID: 4174 (pppd)
       Tasks: 1 (limit: 415)
         CPU: 266ms
      CGroup: /system.slice/sim7000.service
              └─4174 /usr/sbin/pppd call sim7000
 
 Aug 08 10:58:13 raspberrypi pppd[4174]: local  IP address 10.172.102.128
 Aug 08 10:58:13 raspberrypi pppd[4174]: remote IP address 10.64.64.64
 Aug 08 10:58:13 raspberrypi pppd[4174]: primary   DNS address 168.95.1.1
 Aug 08 10:58:13 raspberrypi pppd[4174]: secondary DNS address 168.95.192.1
 Aug 08 10:58:13 raspberrypi pppd[4174]: local  IP address 10.172.102.128
 Aug 08 10:58:13 raspberrypi pppd[4174]: remote IP address 10.64.64.64
 Aug 08 10:58:13 raspberrypi pppd[4174]: primary   DNS address 168.95.1.1
 Aug 08 10:58:13 raspberrypi pppd[4174]: secondary DNS address 168.95.192.1
 Aug 08 10:58:43 raspberrypi pppd[4174]: IPV6CP: timeout sending Config-Requests
 Aug 08 10:58:43 raspberrypi pppd[4174]: IPV6CP: timeout sending Config-Requests

Deploy

Download the deploy script from https://blog.wilicw.dev/files/deploy_sim7000.sh and exectute it (Only works on debian-base distro).

$ curl https://blog.wilicw.dev/files/deploy_sim7000.sh | bash -

Appendix

This section have some scripts been mentioned earlier in this article.

PPP

chatscript (/etc/ppp/sim7000)

# 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

OK		AT+CGDCONT=1,"IP","internet.iot","",0,0
OK		ATD*99#
TIMEOUT		22
CONNECT		""

Provider’s config (/etc/ppp/peers/sim7000)

# 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 "myusername@realm"

# 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/ppp/sim7000"

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

# Speed of the serial line.
115200

debug
nocrtscts
nodetach
ipcp-accept-local
ipcp-accept-remote

# 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

Deploy Script

#!/bin/bash

chatscript="
ABORT		BUSY
ABORT		VOICE
ABORT		\"NO CARRIER\"
ABORT		\"NO DIALTONE\"
ABORT		\"NO DIAL TONE\"
ABORT		\"NO ANSWER\"
ABORT		\"DELAYED\"
ABORT		\"ERROR\"
ABORT		\"+CGATT: 0\"
\"\"		AT
TIMEOUT		12
OK		ATH
OK		ATE1
OK		AT+CGDCONT=1,\"IP\",\"internet.iot\",\"\",0,0
OK		ATD*99#
TIMEOUT		22
CONNECT		\"\"
"

peers="
user \"myusername@realm\"
connect \"/usr/sbin/chat -v -f /etc/ppp/sim7000\"
/dev/ttyUSB3
115200
debug
nocrtscts
nodetach
ipcp-accept-local
ipcp-accept-remote
noipdefault
usepeerdns
defaultroute
persist
noauth
"

daemonfile="
[Unit]
Description=PPP SIM7000C dialing

[Service]
ExecStart=/usr/sbin/pppd call sim7000
KillMode=process
Restart=on-failure
Type=simple

[Install]
WantedBy=multi-user.target
Alias=sim7000.service
"

echo "$peers" | sudo tee /etc/ppp/peers/sim7000
echo "$chatscript" | sudo tee /etc/ppp/sim7000
echo "$daemonfile" | sudo tee /etc/systemd/system/sim7000.service

if [ "$(whereis pppd)" == "pppd:" ]; then
        sudo apt clean
        sudo apt update -y
        sudo apt update ppp
fi

sudo systemctl daemon-reload
sudo systemctl enable --now sim7000
sudo systemctl status sim7000