Linux/Android系统通过PPP拨号上网

 嵌入式系统经常需要具备无线上网的功能,但在有的应用场景中无法使用wifi,这时可以通过GPRS模块上网。GPRS模块是基于AT命令进行控制的。对于单片机这类没有复杂操作系统的平台来说,往往要通过应用程序,直接发送AT命令给GPRS模块,以使GPRS模块连接到网络并建立TCP连接,进而完成通信。对于具有LinuxAndroid等系统的平台而言,则不需要自己编写程序发送AT命令,可以使用ppp服务进行拨号上网。

  在Linux系统下,执行man ppp,可以看到PPP的介绍。

  PPPPoint to Point Protocol,是一种用于建立通过拨号调制解调器的网络连接、DSL连接或者其它类型的点对点连接的协议。

    RIL:Radio Interface Layer。

  在网上可以下载ppp源码,并编译出ppp拨号上网所必需的可执行文件,pppdchat。除了这两个可执行程序外,还需要一些脚本,具体的脚本如下所示:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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里是chatgprs模块之间聊天所需的AT命令及应答。

  问题一:同样的脚本可以使3G模块正常拨号,但是2G模块拨号失败,拨号过程的信息如下:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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
  在CODE上查看代码片 派生到我的代码片
  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
  在CODE上查看代码片 派生到我的代码片
  1. /system/bin/ndc resolver setifdns "$NAME" "$DNS1" "$DNS2"  
  2. /system/bin/ndc resolver setdefaultif "$NAME"  

       

        调试过程中几个常用的AT命令:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. AT+CSMINS?    //查询是否插入SIM卡  
  2. AT+CSQ        //查询信号质量  
  3. ATDxxxxxx;    //拨打电话,命令尾一定要要分号  
[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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
  在CODE上查看代码片 派生到我的代码片
  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
  在CODE上查看代码片 派生到我的代码片
  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"  
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值