Linux系統下通過PPP撥號上網

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。除了這兩個可執行程序外,還需要一些腳本,具體的腳本如下所示:

[root@Neolix /]# ls /etc/ppp/  -R
/etc/ppp/:
chap-secrets       ioptions           options            resolv.conf
connect-errors     ip-down            pap-secrets
gprs-connect-chat  ip-up              peers

/etc/ppp/peers:
gprsdial  

       

        ip-up:ppp撥號成功後,會調用這個腳本進行一些設置;

        ip-down:連接斷開後,會調用這個腳本;

        執行pppd call gpradial即可實現撥號,gprs-connect-chat裏是chatgprs模塊之間聊天所需的AT命令及應答。

  問題一:同樣的腳本可以使3G模塊正常撥號,但是2G模塊撥號失敗,撥號過程的信息如下:

pppd call gprsdial
timeout set to 15 seconds
abort on (DELAYED)
abort on (BUSY)
abort on (NO DIALTONE)
abort on (NO CARRIER)
timeout set to 40 seconds
send (AT^M)
expect (OK)
^M
OK
 -- got it

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

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

send (AT+CGEQREQ=1,2,128,384,,,0,,,,,,^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATDT*98*1#^M)
expect (CONNECT)
^M
^M
CONNECT
 -- got it

send (^M)
Script /sbin/chat -s -v -f /etc/ppp/gprs-connect-chat finished (pid 131), status
 = 0x0
Serial connection established.
using channel 2
Using interface ppp0
Connect: ppp0 <--> /dev/ttyS3
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
Warning - secret file /etc/ppp/pap-secrets has world and/or group access
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x7ae02b5a> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0xa0000> <auth pap> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x1 <auth pap>]
LCP: timeout sending Config-Requests
Connection terminated.
Modem hangup

  解決方案是在pppd的腳本gprsdial中加上local選項,local的意思是不使用調制解調器的控制線路,pppd將會忽略載波檢測。修改後的腳本內容如下:

# Usage:   root>pppd call gprs
/dev/ttyS3
115200
#crtscts
modem
noauth
debug
nodetach
local
#hide-password
usepeerdns
noipdefault
defaultroute
user "cmnet"
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的命令,如下所示:  

/system/bin/ndc resolver setifdns "$NAME" "$DNS1" "$DNS2"
/system/bin/ndc resolver setdefaultif "$NAME"

       

        調試過程中幾個常用的AT命令:

AT+CSMINS?    //查詢是否插入SIM卡
AT+CSQ        //查詢信號質量
ATDxxxxxx;    //撥打電話,命令尾一定要要分號
<pre class="plain" name="code">AT+CIMI      //查詢國際移動用戶標識
AT+COPS?     //查詢運營商
這兩條命令均可以用於查詢SIM卡是移動的還是聯通的。

        Android系統下增加自啓動服務

   首先,在init.rc腳本中增加pppd服務,實現開機自動撥號上網(但通常這一動作是由Android的RIL層觸發的,函數爲requestSetupDataCall())。Android中有專門的腳本init.gprs-pppd用於啓動pppd,當然也可以自己寫一個類似的腳本用於啓動pppd服務。

service pppd /system/etc/ppp/init.gprs-pppd call gprsdial
    class main
    user root
    group radio cache inet misc
service ril-daemon /system/bin/rild
    class main
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
    user root
    group radio cache inet misc audio log
service ril-daemon3 /system/bin/rild3
    class main
    socket rild3 stream 660 root radio
    socket rild-debug stream 660 radio system
    user root
    group radio cache inet misc audio log

        此步驟需要注意的是,pppd服務的class需要和rild服務的class保持一致。init.gprs-pppd腳本的內容如下:

#!/system/bin/sh
# An unforunate wrapper script 
# so that the exit code of pppd may be retrieved
# this is a workaround for issue #651747
#trap "/system/bin/sleep 1;exit 0" TERM

PPPD_PID=
/system/bin/setprop "net.gprs.ppp-exit" ""
/system/bin/log -t pppd "Starting pppd"
/system/bin/pppd $*

PPPD_EXIT=$?
PPPD_PID=$!

/system/bin/log -t pppd "pppd exited with $PPPD_EXIT"
/system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT"










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章