嵌入式系统经常需要具备无线上网的功能,但在有的应用场景中无法使用wifi,这时可以通过GPRS模块上网。GPRS模块是基于AT命令进行控制的。对于单片机这类没有复杂操作系统的平台来说,往往要通过应用程序,直接发送AT命令给GPRS模块,以使GPRS模块连接到网络并建立TCP连接,进而完成通信。对于具有Linux、Android等系统的平台而言,则不需要自己编写程序发送AT命令,可以使用ppp服务进行拨号上网。
Linux系统下,执行man ppp,可以看到PPP的介绍。
即Point to Point Protocol,是一种用于建立通过拨号调制解调器的网络连接、DSL连接或者其它类型的点对点连接的协议。
RIL:Radio Interface Layer。
ppp源码,并编译出ppp拨号上网所必需的可执行文件,pppd和chat。除了这两个可执行程序外,还需要一些脚本,具体的脚本如下所示:
[plain] view plain copy
1. [root@Neolix /]# ls /etc/ppp/ -R
2. /etc/ppp/:
3. chap-secrets ioptions options resolv.conf
4. connect-errors ip-down pap-secrets
5. gprs-connect-chat ip-up peers
6.
7. /etc/ppp/peers:
8. gprsdial
ip-up:ppp拨号成功后,会调用这个脚本进行一些设置;
ip-down:连接断开后,会调用这个脚本;
pppd call gpradial即可实现拨号,gprs-connect-chat里是chat与gprs模块之间聊天所需的AT命令及应答。
问题一:同样的脚本可以使3G模块正常拨号,但是2G模块拨号失败,拨号过程的信息如下:
[plain] view plain copy
1. pppd call gprsdial
2. timeout set to 15 seconds
3. abort on (DELAYED)
4. abort on (BUSY)
5. abort on (NO DIALTONE)
6. abort on (NO CARRIER)
7. timeout set to 40 seconds
8. send (AT^M)
9. expect (OK)
10. ^M
11. OK
12. -- got it
13.
14. send (ATE0^M)
15. expect (OK)
16. ^M
17. ^M
18. OK
19. -- got it
20.
21. send (AT+CGDCONT=1,"IP","CMNET"^M)
22. expect (OK)
23. ^M
24. ^M
25. OK
26. -- got it
27.
28. send (AT+CGEQREQ=1,2,128,384,,,0,,,,,,^M)
29. expect (OK)
30. ^M
31. ^M
32. OK
33. -- got it
34.
35. send (ATDT*98*1#^M)
36. expect (CONNECT)
37. ^M
38. ^M
39. CONNECT
40. -- got it
41.
42. send (^M)
43. Script /sbin/chat -s -v -f /etc/ppp/gprs-connect-chat finished (pid 131), status
44. = 0x0
45. Serial connection established.
46. using channel 2
47. Using interface ppp0
48. Connect: ppp0 <--> /dev/ttyS3
49. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
50. Warning - secret file /etc/ppp/pap-secrets has world and/or group access
51. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
52. No auth is possible
53. sent [LCP ConfRej id=0x1 <auth pap>]
54. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
55. No auth is possible
56. sent [LCP ConfRej id=0x1 <auth pap>]
57. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
58. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
59. No auth is possible
60. sent [LCP ConfRej id=0x1 <auth pap>]
61. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
62. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
63. No auth is possible
64. sent [LCP ConfRej id=0x1 <auth pap>]
65. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
66. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
67. No auth is possible
68. sent [LCP ConfRej id=0x1 <auth pap>]
69. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
70. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
71. No auth is possible
72. sent [LCP ConfRej id=0x1 <auth pap>]
73. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
74. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
75. No auth is possible
76. sent [LCP ConfRej id=0x1 <auth pap>]
77. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
78. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
79. No auth is possible
80. sent [LCP ConfRej id=0x1 <auth pap>]
81. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
82. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
83. No auth is possible
84. sent [LCP ConfRej id=0x1 <auth pap>]
85. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
86. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
87. No auth is possible
88. sent [LCP ConfRej id=0x1 <auth pap>]
89. sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
90. rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
91. No auth is possible
92. sent [LCP ConfRej id=0x1 <auth pap>]
93. LCP: timeout sending Config-Requests
94. Connection terminated.
95. Modem hangup
pppd的脚本gprsdial中加上local选项,local的意思是不使用调制解调器的控制线路,pppd将会忽略载波检测。修改后的脚本内容如下:
[plain] view plain copy
1. # Usage: root>pppd call gprs
2. /dev/ttyS3
3. 115200
4. #crtscts
5. modem
6. noauth
7. debug
8. nodetach
9. local
10. #hide-password
11. usepeerdns
12. noipdefault
13. defaultroute
14. user "cmnet"
15. 0.0.0.0:0.0.0.0
问题二:通过AT命令“ATD10001;”拨打电话时,模块返回“NO DIALTONE”,通过AT命令“ATD*99#”拨号进行数据连接时,模块返回“NO CARRIER”
原因:此问题是由于没有插天线,信号不好导致的。
问题三:2G的模块(sim800),用3G的SIM卡,能正常通信和拨打电话吗?
答案:可以。
问题四:ip-up:ppp拨号成功会,会调用这个脚本;
联网后,DNS不起作用!
可以在ip-up文件中添加设置DNS的命令,如下所示:
[plain] view plain copy
1. /system/bin/ndc resolver setifdns "$NAME" "$DNS1" "$DNS2"
2. /system/bin/ndc resolver setdefaultif "$NAME"
调试过程中几个常用的AT命令:
[plain] view plain copy
1. AT+CSMINS? //查询是否插入SIM卡
2. AT+CSQ //查询信号质量
3. ATDxxxxxx; //拨打电话,命令尾一定要要分号
[plain] view plain copy
1. <pre class="plain" name="code">AT+CIMI //查询国际移动用户标识
2. AT+COPS? //查询运营商
这两条命令均可以用于查询SIM卡是移动的还是联通的。
Android系统下增加自启动服务
首先,在init.rc脚本中增加pppd服务,实现开机自动拨号上网(但通常这一动作是由Android的RIL层触发的,函数为requestSetupDataCall())。Android中有专门的脚本init.gprs-pppd用于启动pppd,当然也可以自己写一个类似的脚本用于启动pppd服务。
[plain] view plain copy
1. service pppd /system/etc/ppp/init.gprs-pppd call gprsdial
2. class main
3. user root
4. group radio cache inet misc
5. service ril-daemon /system/bin/rild
6. class main
7. socket rild stream 660 root radio
8. socket rild-debug stream 660 radio system
9. user root
10. group radio cache inet misc audio log
11. service ril-daemon3 /system/bin/rild3
12. class main
13. socket rild3 stream 660 root radio
14. socket rild-debug stream 660 radio system
15. user root
16. group radio cache inet misc audio log
此步骤需要注意的是,pppd服务的class需要和rild服务的class保持一致。init.gprs-pppd脚本的内容如下:
[plain] view plain copy
1. #!/system/bin/sh
2. # An unforunate wrapper script
3. # so that the exit code of pppd may be retrieved
4. # this is a workaround for issue #651747
5. #trap "/system/bin/sleep 1;exit 0" TERM
6.
7. PPPD_PID=
8. /system/bin/setprop "net.gprs.ppp-exit" ""
9. /system/bin/log -t pppd "Starting pppd"
10. /system/bin/pppd $*
11.
12. PPPD_EXIT=$?
13. PPPD_PID=$!
14.
15. /system/bin/log -t pppd "pppd exited with $PPPD_EXIT"
16. /system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT"
















