在物联网领域网络互连是非常重要的一个环节。各种传感器采集必要的信息经过单片机的处理之后需要通过网络将数据上报给服务器。在物联网领域联网方式一般为无线网,而用得最多的又是各运营商提供的物网卡(物联网SIM卡)拨号上网。
这里基于3G拨号上网做一个学习总结。我使用的是联通的WCDMA拨号上网方式,其他的拨号上网方式大同小异。
在内核的make menuconfig中添加USB转串口支持
Device Drivers ---> [*] USB support ---> <*> USB Serial Converter support ---> <*> USB driver for GSM and CDMA modems添加内核对PPP拨号支持
Device Drivers ---> [*] Network device support ---> <*> PPP (point-to-point protocol) support [*]PPP multilink support (EXPERIMENTAL) [*]PPP filtering <*>PPP support for async serial ports <*>PPP support for sync tty ports <*>PPP Deflate compression <*>PPP BSD-Compress compression将内核按照上面添加完USB转串口驱动和PPP拨号支持之后,将其重新编译并下载到开发板,这个时候插上3G模块在屏幕将会打印如下信息:
>: usb 1-1.2: new full speed USB device number 3 using s3c2410-ohci option 1-1.2:1.0: GSM modem (1-port) converter detected usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB0 option 1-1.2:1.1: GSM modem (1-port) converter detected usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB1 option 1-1.2:1.2: GSM modem (1-port) converter detected usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB2 option 1-1.2:1.3: GSM modem (1-port) converter detected usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB3 option 1-1.2:1.4: GSM modem (1-port) converter detected usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB4用ls命令可以看到/dev目录下多了五个串口设备分别为ttyUSB0,ttyUSB1,ttyUSB2,ttyUSB3,ttyUSB4。查阅SIM5360E官方手册发现五个串口分别为五个不同功能模块工作,并且可以看到ttyUSB2作为AT命令的接口,所以接下来我们使用AT命令测试3G模块是否正常工作的时候只能监听ttyUSB2.
>: ls dev/ttyUSB* dev/ttyUSB0 dev/ttyUSB1 dev/ttyUSB2 dev/ttyUSB3 dev/ttyUSB4插上SIM5630E如果出现上述现象说明内核使能成功,下面开始拨号上网测试。
Linux下用ppp上网需要两个程序:pppd和chat 。这两个程序有开源代码,我们下载后根据自己情况稍加修改编译得到这两个程序。 下载解压
[lwn@localhost 3g]$ wget https://coding.net/u/sfantree/p/OSS2/git/raw/master/source/ppp-2.4.5.tar.gz [lwn@localhost 3g]$ tar zxvf ppp-2.4.5.tar.gz [lwn@localhost 3g]$ cd ppp-2.4.5 [lwn@localhost ppp-2.4.5]$ ./configure [lwn@localhost ppp-2.4.5]$ cd chat/修改配置文件 1. 在chat/目录下chat.c找到相应行,添加如下代码
[lwn@localhost chat]$ vim chat.c …… …… 1168 if (timeout_next) { 1169 timeout_next = 0; 1170 s = clean(s, 0); /* Add by liwanneng*/ 1171 timeout = atoi(s); 1172 free(s); /* Add by liwanneng*/ 1173 1174 if (timeout <= 0) 1175 timeout = DEFAULT_CHAT_TIMEOUT; …… …… 在Makefile中找到相应行,添加如下信息 [lwn@localhost chat]$ vim Makefile 16 INSTALL= install 17 CC=/opt/dl/buildroot-2012.08/ARM920t/usr/bin/arm-linux-gcc /*根据自己情况添加交叉编译器路径*/ 18 19 all: chat 20 21 chat: chat.o 22 $(CC) -static -o chat chat.o /*add by liwanneng*/ 23 $(CC) -o chat chat.o 在/pppd/目录下的auth.c文件中找到相应行,修改代码如下: [lwn@localhost chat]$ cd ../pppd [lwn@localhost pppd]$ vim auth.c 1323 int hadchap; 1324 1325 hadchap = -1; 1326 /* Modify by liwanneng*/ 1327 /* ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));*/ 1328 ao->neg_upap = !refuse_pap; 1329 ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2); 修改Makefile,找到相应行,修改代码如下: [lwn@localhost pppd]$ vim Makefile 33 CC = /opt/dl/buildroot-2012.08/ARM920t/usr/bin/arm-linux-gcc /*根据自己情况添加交叉编译器路径*/ 46 #MPPE=y /*modify by liwanneng*/ 51 #FILTER=y /*modify by liwanneng*/ 56 #HAVE_MULTILINK=y /*modify by liwanneng*/ 68 #PLUGIN=y /*modify by liwanneng*/编译下载 修改完成配置文件以后使用make命令编译,将生成的chat(chat目录下)和pppd(pppd目录下)拷贝到开发板的/user/sbin目录下
[lwn@localhost pppd]$ cd .. [lwn@localhost ppp-2.4.5]$ make [lwn@localhost ppp-2.4.5]$ cd chat/ [lwn@localhost chat]$ ls chat chat.8 chat.c chat.o Makefile Makefile.linux Makefile.sol2 [lwn@localhost chat]$ file chat chat: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped [lwn@localhost chat]$ cd ../pppd [lwn@localhost pppd]$ file pppd pppd: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped在开发板的/etc目录新建/ppp/peers目录并在peers目录下创建如下配置文件
pppd脚本:给pppd进程提供配置参数: >: pwd /etc/ppp/peers >: vi wcdma #Copyright (c) 2017 liwanneng #set debug ,send message to /var/log/messages debug #To keep pppd on the terminal nodetach lock #set seriral /dev/ttyUSB3 # set baudrate 115200 user "lwn" #如果需要chap或pap认证,则输入该用户名和密码 password "liwanneng" # set flowrate crtscts #接口带硬件流控 show-password usepeerdns noauth #不设置认证 noipdefault #禁用默认IP novj #禁用TCP压缩 novjccomp noccp # Accept the peer's idea of our local IP address ipcp-accept-local # ipcp-accept-remote ipcp-accept-remote connect '/usr/sbin/chat -s -v -f /etc/ppp/peers/wcdma-chat-connect' disconnect '/usr/sbin/chat -s -v -f /etc/ppp/peers/wcdma-chat-disconnect' chat脚本:AT指令的发送和接收脚本 >: vi wcdma-chat-connect ABORT 'NO CARRIER' ABORT 'ERROR' ABORT 'NO DIALTONE' ABORT 'BUSY' ABORT 'NO ANSWER' '' \rAT #发送AT命令 OK \rATZ #等待接收OK,接收到OK发送ATZ命令 OK \rAT+CGDCONT=1,"IP","3gnet",,0,0#接收到OK,发送AT+CGDCONT=1...命令 #下面一行是联通的拨号设置,不同的运营商拨号方式有所不同 OK-AT-OK ATDT*99# #拨号 CONNECT \d\cABORT指定了AT指令交互时,出了什么样的错误chat将退出。 “3gnet”表示联通3G接入点 ATDT为拨号命令,*99#为联通3G拨号方式。不同的运营商拨号方式不同。如中国移动 GPRS/EGDE(2G)拨号方式:*99***1#;中国移动TD-SCDMA(3G)拨号方式:*98*1#。
出错处理 >: vi wcdma-chat-disconnect ABORT "ERROR" ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" '' "\K" '' "+++ATH" SAY "\nGoodbay\n"现在该目录下应该有三个配置文件如下
>: pwd /etc/ppp/peers >: ls wcdma wcdma-chat-connect wcdma-chat-disconnect编写完成上述配置文件之后,在开发板上插上3G模块SIM5360E(将3G模块接上天线和插入SIM卡)就可以拨号上网了 拨号启动pppd程序:
>: pppd call wcdma&pppd程序的作用就是建立协议,生成网络接口ppp0。末尾的&符号表示让该进程在后台运行。 如果拨号成功,将会打印如下信息:
>: pppd call wcdma& abort on (NO CARRIER) abort on (ERROR) abort on (NO DIALTONE) abort on (BUSY) abort on (NO ANSWER) send (^MAT^M) expect (OK) AT^M^M OK -- got it send (^MATZ^M) expect (OK) ^M ATZ^M^M OK -- got it send (^MAT+CGDCONT=1,"IP","3gnet",,0,0^M) expect (OK) ^M AT+CGDCONT=1,"IP","3gnet",,0,0^M^M OK -- got it send (ATDT*99#^M) expect (CONNECT) ^M ATDT*99#^M^M CONNECT -- got it send (\d) Script /usr/sbin/chat -s -v -f /etc/ppp/peers/wcdma-chat-connect finished (pid 943), status = 0x0 Serial connection established. using channel 2 Using interface ppp0 Connect: ppp0 <--> /dev/ttyUSB3 sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xb5d6017b> <pcomp> <accomp>] rcvd [LCP ConfReq id=0x0 <asyncmap 0x0> <auth chap MD5> <magic 0x2e7d040> <pcomp> <accomp>] sent [LCP ConfAck id=0x0 <asyncmap 0x0> <auth chap MD5> <magic 0x2e7d040> <pcomp> <accomp>] rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xb5d6017b> <pcomp> <accomp>] rcvd [LCP DiscReq id=0x1 magic=0x2e7d040] rcvd [CHAP Challenge id=0x1 <d612450adea4d73c060a8971244af1db>, name = "UMTS_CHAP_SRVR"] sent [CHAP Response id=0x1 <405a09264551a88a19f474c7390462f4>, name = "liwanneng"] rcvd [CHAP Success id=0x1 ""] CHAP authentication succeeded CHAP authentication succeeded sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>] rcvd [proto=0x3] 01 00 04 Unsupported protocol 0x3 received sent [LCP ProtRej id=0x2 00 03 01 00 04] sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>] rcvd [IPCP ConfReq id=0x0] sent [IPCP ConfNak id=0x0 <addr 0.0.0.0>] rcvd [IPCP ConfNak id=0x1 <addr 10.213.104.41> <ms-dns1 218.106.127.114> <ms-dns2 218.104.111.122>] sent [IPCP ConfReq id=0x2 <addr 10.213.104.41> <ms-dns1 218.106.127.114> <ms-dns2 218.104.111.122>] rcvd [IPCP ConfReq id=0x1] sent [IPCP ConfAck id=0x1] rcvd [IPCP ConfAck id=0x2 <addr 10.213.104.41> <ms-dns1 218.106.127.114> <ms-dns2 218.104.111.122>] Could not determine remote IP address: defaulting to 10.64.64.64 local IP address 10.213.104.41 remote IP address 10.64.64.64 primary DNS address 218.106.127.114 secondary DNS address 218.104.111.122稍微注意一下不难看出,以上的打印信息正是chat脚本中的AT指令交互情况。 前面提到pppd程序的作用是生成网络接口ppp0,所以拨号成功之后使用ifconfig命令可以看到多了一个网口ppp0。
接下来配置好网关就可以连入因特网了
>route add default gw 10.64.64.64 #配置默认网关 >: ping 114.114.114.114 #ping外网DNS PING 114.114.114.114 (114.114.114.114): 56 data bytes 64 bytes from 114.114.114.114: seq=0 ttl=66 time=347.746 ms 64 bytes from 114.114.114.114: seq=1 ttl=87 time=318.662 ms --- 114.114.114.114 ping statistics --- 3 packets transmitted, 2 packets received, 33% packet loss round-trip min/avg/max = 318.662/333.204/347.746 ms现在已经通过pppd拨号将开发板接入因特网了,如果需要访问域名则还需要添加DNS配置,否则无法将域名解析成IP地址即不能访问网页。
>:vi /etc/resolv.conf nameserver 114.114.114.114 nameserver 8.8.8.8 >: mv /etc/resolv.conf /etc/resolv.conf.bak >: ln -s /etc/ppp/resolv.conf /etc/resolv.conf#建立一个软链接,链接到全局DNS >: ping baidu.com #现在可以成功解析出域名了 PING baidu.com (111.13.101.208): 56 data bytes 64 bytes from 111.13.101.208: seq=0 ttl=52 time=119.372 ms 64 bytes from 111.13.101.208: seq=1 ttl=52 time=122.650 ms --- baidu.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 119.372/121.011/122.650 ms