嵌入式Linux利用ppp实现4G模块联网

欧大琛 2018-10-21 PM 4059℃ 0条

之前做项目时需要用到SIM7100模块,便快速了解下ppp拨号,实现了功能,但是功能虽然实现了,却依然有许多疑问,这段时间有点时间,打算更加详细的研究下。

编译ppp2.4.5

  • 下载:官方地址
  • 编译:

    #1.解压ppp程序包
    tar -xzvf ppp-2.4.5.tar.gz
    #2.进入并生成Makefile
    cd ./ppp-2.4.5
    ./config
    #3.指定交差编译工具make
    make CC=arm-linux-gcc

配置内核

Device Drivers --->Network device support---> <*>   PPP (point-to-point protocol) support 

menuconfig

ppp安装

以上编译过程将会生成pppd、pppdump、pppstats、chat四个运行程序,将他们复制到开发平台下的/usr/sbin/中。

chat:调制解调器的自动对话脚本,Chat程序定义了一个计算机和调制解调器之间对话交流,其主要目的是用来在本地PPPD和远端PPPD程序之间建立连接(简单说就是与4G模块进行AT命令交互的流程表,最终实现与ISP运营商的连接)。

pppd:点对点协议守护进程,其功能为实现ppp策略性的内容,包括所有鉴权、压缩/解压和加密/解密等扩展功能的控制协议。

pppdump:将使用pppd记录选项编写的文件转换为人类可读的格式。

pppstats:显示PPP连线状态。pppstats(point to point protocol status)。

拨号流程简图

menuconfig

脚本配置

在开发平台上建立两个文件夹,并拷贝ppp.2.4.5文件夹中的chap-secrets、pap-secrets脚本至/etc/ppp文件夹。

mkdir /etc/ppp
mkdir /etc/ppp/peers
cp ./chap-secrets ./pap-secrets /etc/ppp
# 顺便创建一下ip-up、ip-down脚本

  • pppd配置文件介绍

    pppd的参数略多啊,具体可以自己man一下或者点击这里查看。
    这里我介绍下我用的,配置文件名称暂定为“gprs”

    # /etc/ppp/peers/gprs
    # This is pppd script for China Mobile, used SIMCOM SIM7100C Module
    # Usage: root>pppd call gprs
    # Interface should be used is the interface which connects physics interface of SIM7100C Module
    
    # ttyname 串口端口,若非以”/“开头,则会自动补充”/dev/“
    /dev/ttyUSB3
    
    # speed 串口波特率
    115200
    
    #硬件流控
    crtscts
    
    # 调制解调器模式
    modem
    
    # 无需身份验证
    noauth
    
    # 不要求使用chap授权
    refuse-chap
    
    # 不要求使用mschap授权
    refuse-mschap
    
    # 不要求使用mschap-v2授权
    refuse-mschap-v2
    
    # 调试模式 pppd将以可读形式记录发送或接收的所有控制数据包的内容
    debug
    
    # 前台运行
    nodetach
    #hide-password
    
    # 向ISP请求2个dns服务器地址。这两个地址将以DNS1与DNS2两个环境变量传送到/etc/ppp/ip-up脚本中,并且将环境变USEPEERDNS量置为1
    usepeerdns
    
    # 禁用本地ip,由ISP提供
    noipdefault
    
    # 添加ISP网关至路由表,作为默认路由
    defaultroute
    
    # 用户名
    user "cmnet"
    
    0.0.0.0:0.0.0.0
    
    #ipcp-accept-local
    #ipcp-accept-remote
    
    # 使能一下两个选项可以实现ppp掉线自动重播
    # lcp连接失败尝试次数
    lcp-echo-failure 6
    
    # lcp echo发送间隔
    lcp-echo-interval 10
    
    # 禁用压缩控制协议ccp
    #noccp
    
    # 禁用Van  Jacobson格式的tcp/ip报头
    #novj
    
    
    #novjccomp
    
    # 连接终止后不要退出,而是重新尝试连接,连接次数收到maxfail限制
    persist
    
    # 连接最大尝试次数,0无限制
    #maxfail
    
    # 启动ppp协议前,进行硬件拨号
    connect '/usr/sbin/chat -s -v -f /etc/ppp/gprs-connect-chat'
  • chat脚本

    chat脚本主要用来通过AT命令完成4G模块的拨号过程,关于其选项含义可以man一下或者点击这里查看,下面先介绍下其语法:
    chat最主要语法就是“期望-发送”,直白点说就是,我期望收到[某某AT响应],若收到,则发送[某某AT命令]。

    chat还有个常用的关键词为ABORT,这个关键词用于判断何时终止脚本,在AT交互过程中,模块发生错误,并且输出一些错误信息时,ABORT可根据设定的词,停止当前脚本。

    以下脚本命名为“gprs-connect-chat”

    #Chat script for China Mobile, used SIMCOM sim7100 TD module.
    
    # 设置响应超时
    TIMEOUT 15
    
    # 若接收到“DELAYED”、“BUSY”、“ERROR”、“NO DIALTONE”、“NO CARRIER”,则退出脚本
    ABORT "DELAYED"
    ABORT "BUSY"
    ABORT "ERROR"
    ABORT "NO DIALTONE"
    ABORT "NO CARRIER"
    
    # 无期望,直接发送AT字符串
    '' AT
    
    # 以下内容可以根据自己模块提供的AT命令手册查询含义
    OK ATS0=0
    OK ATE0V1
    
    # 设置APN,移动、联通、电信各不相同,见文末表格
    OK AT+CGDCONT=1,"IP","CMNET" 
    # 拨号开启GPRS服务,号码移动、联通、电信各不相同,见文末表格
    OK ATD*99***1#
    
    #期望收到CONNECT
    CONNECT
  • ip-up脚本

    之前的脚本如果没有问题,正常的话运行 pppd call gprs 就可以拨号成功,并且ifconfig后可以查看到ppp0这个网卡。但是如果你在拨号之前已经启用了以太网eth0,此时指定使用ppp0网卡ping指定ip或域名ping -I ppp0 www.baidu.com 并不能成功,原因有两个,一个是路由表中的默认网关是之前eth0生成的,一个是默认的dns服务器地址有问题。

  • 解决默认网关问题

    在pppd脚本中使能了defaultroute后,pppd会在拨号成功后向路由表中添加一条默认网关信息,但是因为之前已经有一条默认网关了,于是添加失败,默认网关依然是之前eth设置的,因此在pppd call gprs之前我们应该先route del default来删除默认路由(最好写个脚本来实现删除默认路由--拨号等一系列操作)。

  • 解决dns问题

在pppd脚本中使能了usepeerdns后,pppd会在拨号成功后,在/etc/ppp下生成resolv.conf,这是ISP运营商提供的dns,我们应该将拷贝或者连接到/etc目录下,当然这件事就可以交给ip-up来做。

ip-up脚本:

#!/bin/bash
#ip-up
dns_file="/etc/resolv.conf"

rm "$dns_file"
ln /etc/ppp/resolv.conf "$dns_file"
  • ip-down脚本

    按照ppp拨号过程中打印信息可以发现,在退出pppd进程时,会调用/etc/ppp/ip-down。因此删除默认网关,恢复dns就交由ip-down脚本做了。
#!/bin/bash
#ip-down
#set -vx
dns_file="/etc/resolv.conf"

rm $dns_file

cat > "$dns_file" <<EOF
# auto create by ip-down
nameserver 114.114.114.114
nameserver 8.8.8.8
EOF

chmod 755 "$dns_file"

/etc/init.d/networking restart

echo "Set dns for eth0" 

调试信息

运行pppd call gprs后成功拨号的调试打印信息:

timeout set to 15 seconds
abort on (DELAYED)
abort on (BUSY)
abort on (ERROR)
abort on (NO DIALTONE)
abort on (NO CARRIER)
timeout set to 15 seconds
send (^MAT^M)
expect (OK)
^M
OK
 -- got it

send (ATS0=0^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATE0V1^M)
expect (OK)
^M
^M
OK
 -- got it

send (AT+CGDCONT=1,"IP","CMNET"^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATD*99***1#^M)
expect (CONNECT)
^M
^M
CONNECT
 -- got it

Script /usr/sbin/chat -s -v -f /etc/ppp/gprs-connect-chat finished (pid 21001), status = 0x0
Serial connection established.
using channel 19
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB3
Warning - secret file /etc/ppp/pap-secrets has world and/or group access
sent [LCP ConfReq id=0x4 <asyncmap 0x0> <magic 0xc2c88df0> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x60 <asyncmap 0x0> <auth chap MD5> <magic 0x5742a3f6> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x60 <auth chap MD5>]
rcvd [LCP ConfAck id=0x4 <asyncmap 0x0> <magic 0xc2c88df0> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x61 <asyncmap 0x0> <magic 0x5742a3f6> <pcomp> <accomp>]
sent [LCP ConfAck id=0x61 <asyncmap 0x0> <magic 0x5742a3f6> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0xc2c88df0]
sent [CCP ConfReq id=0x2 <deflate 15> <deflate(old#) 15> <bsd v1 15>]
sent [IPCP ConfReq id=0x4 <compress VJ 0f 01> <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [LCP DiscReq id=0x62 magic=0x5742a3f6]
rcvd [LCP EchoRep id=0x0 magic=0x5742a3f6 c2 c8 8d f0]
rcvd [LCP ProtRej id=0x63 80 fd 01 02 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
Protocol-Reject for 'Compression Control Protocol' (0x80fd) received
rcvd [IPCP ConfReq id=0x2e]
sent [IPCP ConfNak id=0x2e <addr 0.0.0.0>]
rcvd [IPCP ConfRej id=0x4 <compress VJ 0f 01>]
sent [IPCP ConfReq id=0x5 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [IPCP ConfReq id=0x2f]
sent [IPCP ConfAck id=0x2f]
rcvd [IPCP ConfNak id=0x5 <addr 10.149.99.154> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
sent [IPCP ConfReq id=0x6 <addr 10.149.99.154> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
rcvd [IPCP ConfAck id=0x6 <addr 10.149.99.154> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
Could not determine remote IP address: defaulting to 10.64.64.64
local  IP address 10.149.99.154
remote IP address 10.64.64.64
primary   DNS address 211.136.17.107
secondary DNS address 211.136.20.203
Script /etc/ppp/ip-up started (pid 21008)
Script /etc/ppp/ip-up finished (pid 21008), status = 0x0

以下为设置了断线重拨(lcp-echo-failure、lcp-echo-interval)后的打印信息:

No response to 6 echo-requests   # 6次echo未收到ISP回应,自动重拨。
Serial link appears to be disconnected.
Connect time 719.4 minutes.
Sent 0 bytes, received 0 bytes.
Script /etc/ppp/ip-down started (pid 29547)   # 调用了 /etc/ppp/ip-down 但是我脚本的未运行
sent [LCP TermReq id=0x5 "Peer not responding"]
Script /etc/ppp/ip-down finished (pid 29547), status = 0x0
sent [LCP TermReq id=0x6 "Peer not responding"]
Connection terminated.
Modem hangup
timeout set to 15 seconds
abort on (DELAYED)
abort on (BUSY)
abort on (ERROR)
abort on (NO DIALTONE)
abort on (NO CARRIER)
timeout set to 15 seconds
send (^MAT^M)
expect (OK)
^M
OK
 -- got it

send (ATS0=0^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATE0V1^M)
expect (OK)
^M
^M
OK
 -- got it

send (AT+CGDCONT=1,"IP","CMNET"^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATD*99***1#^M)
expect (CONNECT)
^M
^M
CONNECT
 -- got it

Script /usr/sbin/chat -s -v -f /etc/ppp/gprs-connect-chat finished (pid 29664), status = 0x0
Serial connection established.
using channel 20
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB3
Warning - secret file /etc/ppp/pap-secrets has world and/or group access
sent [LCP ConfReq id=0x7 <asyncmap 0x0> <magic 0xf8a6761> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x64 <asyncmap 0x0> <auth chap MD5> <magic 0x59d5de84> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x64 <auth chap MD5>]
rcvd [LCP ConfAck id=0x7 <asyncmap 0x0> <magic 0xf8a6761> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x65 <asyncmap 0x0> <magic 0x59d5de84> <pcomp> <accomp>]
sent [LCP ConfAck id=0x65 <asyncmap 0x0> <magic 0x59d5de84> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0xf8a6761]
sent [CCP ConfReq id=0x3 <deflate 15> <deflate(old#) 15> <bsd v1 15>]
sent [IPCP ConfReq id=0x7 <compress VJ 0f 01> <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [LCP DiscReq id=0x66 magic=0x59d5de84]
rcvd [LCP EchoRep id=0x0 magic=0x59d5de84 0f 8a 67 61]
rcvd [LCP ProtRej id=0x67 80 fd 01 03 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
Protocol-Reject for 'Compression Control Protocol' (0x80fd) received
rcvd [IPCP ConfReq id=0x30]
sent [IPCP ConfNak id=0x30 <addr 0.0.0.0>]
rcvd [IPCP ConfRej id=0x7 <compress VJ 0f 01>]
sent [IPCP ConfReq id=0x8 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [IPCP ConfReq id=0x31]
sent [IPCP ConfAck id=0x31]
rcvd [IPCP ConfNak id=0x8 <addr 10.42.72.220> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
sent [IPCP ConfReq id=0x9 <addr 10.42.72.220> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
rcvd [IPCP ConfAck id=0x9 <addr 10.42.72.220> <ms-dns1 211.136.17.107> <ms-dns2 211.136.20.203>]
Could not determine remote IP address: defaulting to 10.64.64.64
local  IP address 10.42.72.220
remote IP address 10.64.64.64
primary   DNS address 211.136.17.107
secondary DNS address 211.136.20.203
Script /etc/ppp/ip-up started (pid 29675)
Script /etc/ppp/ip-up finished (pid 29675), status = 0x0

三大运营商拨号设置

运营商(ISP)APN拨号号码账号密码
中国联通WCDMA3GNET*99#
中国电信CDMA#777ctnet@mycdma.cnvnet.mobi
中国移动TD-SCDMACMNET981#
中国移动GPRS/EGDECMNET99**1#
标签: Linux, 4G模块, PPP

「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」

欧大琛

(๑>ڡ<)☆谢谢老板~

使用微信扫描二维码完成赞赏

非特殊说明,本博所有文章均为博主原创。

评论啦~