pppd和autoconnect问题要请教。-------问题都解决了,谢谢xtang,:D------

关于chat的命令脚本:
文档中说,所期待的字符串后可以跟随备用命令,当超时的时候有备用命令的,就执行备用命令,否则退出。但没有给出写备用命令的格式。
例如,我发送"\03\r"后,有可能会有两种回复,如果当前GPRS处于连接状态,会得到回复"OK",如果当前GPRS没工作,得到的回复是只包含回车的字符串,无论是哪种回复我都想发送"AT",这段chat脚本该怎么写?

对于pppd和autoconnect:
设置环境变量AUTOCONNECT=1;
在/etc下增加可执行脚本autoconnect,该脚本经手工测试能正常拨号上网;
正常拨号上网,当我重置了GPRS模块后(拉低它的reset pin),pppd却不能发现GPRS模块其实已经断线了,该怎么让pppd能发现已经断线并自动重连呢?

另外,slay pppd后,让系统自动连接,例如用
ping www.google.com
虽然系统自动调用了autoconnect,而且也连上internet了,但这个ping却一直停在那,另开一个pterm输入同样的命令却能ping通。why?


请多多指教,谢谢。
在技术上碰了壁,希望能得到高人指点

如果不关心返回值的话,可以叫chat等回车。大概是:

chat “\03\r” “\r” “AT”

chat 程序是public domain的,在网上应该可以找上源码。

pppd只是写出到一个设备,比方 /dev/ser1。如果断线,设备的驱动程序会通知pppd。你的情况,要看你的设备驱动了。
还有一个办法,是让pppd每隔一定时间就发一个echo包,有点像“心跳”实现。这样,如果在一定时间内pppd没有收到回复,就超时。去网上查查pppd的资料,看看 lcp-echo-* 命令行参数。

关于ping,一下子想不到理由。我猜是同你的DNS设定有关。

:open_mouth:
把链路控制协议(lcp)的选项加上后

lcp-echo-interval 3
lcp-echo-failure 10

现象是这样的:
首先,GPRS正常连接到了Internet,pppd开始周期性地echo并得到rep;
但是,当我reset GPRS模块后,pppd的echo仍然能得到rep,而且由原来的每周期一对echo-rep变成了每个周期两对echo-rep,就象是这样:
正常时的情况:

sent [LCP EchoReq id=0x1 magic=0x0]
rcvd [LCP EchoRep id=0x1 magic=0x0]
sent [LCP EchoReq id=0x2 magic=0x0]
rcvd [LCP EchoRep id=0x2 magic=0x0]
......

重置后的样子:

sent [LCP EchoReq id=0x10 magic=0x0]
rcvd [LCP EchoReq id=0x10 magic=0x0]
sent [LCP EchoRep id=0x10 magic=0x0]
rcvd [LCP EchoRep id=0x10 magic=0x0]
sent [LCP EchoReq id=0x11 magic=0x0]
rcvd [LCP EchoReq id=0x11 magic=0x0]
sent [LCP EchoRep id=0x11 magic=0x0]
rcvd [LCP EchoRep id=0x11 magic=0x0]
......

看现象似乎是:
GPRS模块在重起后直接把pppd发送的内容反弹回去了;
GPRS模块把pppd的req反弹回去后,pppd自己发送了一个应答rep;
GPRS模块把rep再反弹回去,pppd认为收到了正常的应答;

另外,我用两种方法重起GPRS模块得到的结果都是一样的:
1.拉低reset pin
2.用at+wrst指令让模块周期地自动重起。

不好意思,上面的问题是由于我开了GPRS模块的echo,用ate0命令关闭后该问题解决。但下面的问题依然存在。

其实我的目的很简单,就是想在pppd与ISP之间的连接失效后,使pppd能检测到,从而能退出或重新连接。pppd与GPRS模块间的连接是串口,一般不会出问题,经常出问题的应该是GPRS模块与ISP之间的无线连接。

换句话说,就是我还没太理解lcp-echo交换的远端,指的是modem,还是ISP。如果是ISP那么上述问题就没意义了,如果是modem本身,那么该怎么检测与ISP之间的连接?本来这个问题应该由自己来试验得到答案,但是我没想出办法,使已经连接上internet的GPRS模块断线。

:smiley:

对于autoconnect之后gethostbyname()会block的问题,我在openqnx看到有许多人曾经问过。xtang也曾回答过,用getconf _CS_RESOLVE看当前的dns设置是否生效。别人的方法是用confstr()轮询,直到dns生效,再调用gethostbyname()就不会死了。

我的一位同事找到了一种更简单的解决方法,那就是给gethostbyname()加上超时,最重要的一点是每当要调用gethostbyname()之前先调用一次res_init()。

我怀疑这是qnx操作系统中的bug,或是neutrino文档的缺陷。qnx关于resolv.conf的文档是这么写的:

The socket library uses the following search order to locate the resolver data: 

confstr() configuration strings 
resolv.conf.hostname 
resolv.conf

我对这段的理解是这样的,需要解析域名时,先用confstr()来定位resolver。

而我遇到的现象是,当我尝试连接internet时(比如是ping www.google.com),系统自动调用/etc/autoconnect,pppd启动并接受了远端的dns设置,在其他pterm中可以
ping www.google.com
在别的pterm中执行getconf _CS_RESOLVE可以得到正确的nameserver的设置,但惟独造成autoconnect启动的这个ping指令(或者是应用程序中的gethostbyname()会block(或失败)。
这不得不让我怀疑,对于每个进程来说,只调用过一次res_init(),而之后_CS_RESOLVE的改变该进程却不知道,因此会一直失败。除非人为地在该进程中再次调用res_init()。

lcp-echo是ppp协议,是你的pppd跟你的ISP的pppd之间的对话。如果连接被切断,lcp-echo-reply不会进来。

其实,你的GPRS模块自己应该能知道无线连接无效吧。它可以向pppd发送一个SIGHUP来中断pppd。