准备:移植好pppd软件工具(可见下面的参考文章)、ppp拨号脚本、能上网的SIM卡、使能复位好EC20模块、串口初始化、读写的接口(因为CPU的USB接口给占用了,因此这里使用串口与模块通信)
识别、适应运营商原理:每个运营商的SIM卡会有相应规则的IMSI号码。通过AT指令(AT+CIMI)和EC20模块通信,读取SIM卡的IMSI号,然后判断CIMI号是哪个运营商的SIM卡,最后根据运营商的拨号码传递给拨号脚本进行拨号。
判断运营商的接口:根据获取到的IMSI判断运营商
static int get_IMSI(char *IMSI)
{
char s2[128]="AT+CIMI\r\n";
char s1[1024]={
0};
tcflush(ec20_fd,TCIOFLUSH);
UART0_Send(ec20_fd, s2,strlen(s2));
usleep(500000);
int count=UART0_Recv(ec20_fd,5,0,s1,1024);
int i=0;
#if 0
printf("count=%d\n",count);
while(count-->0)
{
printf("%c",s1[i++]);
}
printf("\n");
#endif
char *p=s1;
while(*p++)
{
// printf("%c ",*p);
if(*p>='0'&&*p<='9')
{
memcpy(IMSI,p,15);
break;
}
}
//printf("IMSI:%s\n",IMSI);
if(IMSI[0]=='4'&&IMSI[1]=='6'&&IMSI[2]=='0')
{
if(IMSI[3]=='0' && IMSI[4]=='0' || IMSI[3]=='0' && IMSI[4]=='2' || IMSI[3]=='0' && IMSI[4]=='7'||IMSI[3]=='2'&&IMSI[4]=='0')
{
printf("中国移动\n");
return 0;
}
if(IMSI[3]=='0' && IMSI[4]=='1' || IMSI[3]=='0' && IMSI[4]=='6' || IMSI[3]=='0' && IMSI[4]=='9' )
{
printf("中国联通\n");
return 1;
}
if(IMSI[3]=='0' && IMSI[4]=='3' || IMSI[3]=='0' && IMSI[4]=='5' || IMSI[3]=='1' && IMSI[4]=='1' )
{
printf("中国电信\n");
return 2;
}
printf("code[%c] [%c]\n",IMSI[3],IMSI[3]);
return 3;
}
sleep(1);
return 0;
}
PPP拨号接口:根据获取到的运营商向PPP拨号脚本传递对应运营商的拨号号码进行拨号,并且执行pppd拨号程序
拨号号码:
移动:ATD991#或981#
联通:ATD*99#
电信:#777(ATD#777)
#define SHELL_PPPD_PATH "/etc/ppp/peers/pppd.sh"
#define USER "user"
#define PASSWORAD "password"
#define EC20 "/dev/ttyPS1"
static int ppp_ec20()
{
char IMSI[128]={
0};
char buf[1024]={
0};
int ret=get_IMSI(IMSI);
if(ret==0)
//ret=execlp("pppd","pppd","call","provider",NULL);
{
sprintf(buf,"%s %s %d cmnet %s %s ATD*99***1# &",SHELL_PPPD_PATH,EC20,921600,USER,PASSWORAD);
}
if(ret==1)
{
sprintf(buf,"%s %s %d 3gnet %s %s ATD*99# &",SHELL_PPPD_PATH,EC20,921600,USER,PASSWORAD);
}
if(ret==2)
{
sprintf(buf,"%s %s %d ctnet %s %s ATD#777 &",SHELL_PPPD_PATH,EC20,921600,USER,PASSWORAD);
}
change_baud(921600);//AT指令修改模块波特率。因为使用的是串口通信,所以默认的115200速率上网较慢,这里直接修改到最大波特率
sleep(1);
ret=system(buf);
}
手敲的拨号脚本pppd:可传递4个参数进来
#!/bin/sh
echo "devname baud apn user password"
#默认的参数设置
DEVNAME=/dev/ttyPS1
BAUD=115200
APN=ctnet
USER=user
PASSWORD=password
NUM=ATD#777
if [ $# -ge 1 ]; then
DEVNAME=$1
echo "devname $DEVNAME"
fi
if [ $# -ge 2 ]; then
BAUD=$2
echo "BAUD $BAUD"
fi
if [ $# -ge 3 ]; then
APN=$3
echo "apn $APN"
fi
if [ $# -ge 4 ]; then
USER=$4
echo "user $USER"
fi
if [ $# -ge 5 ]; then
PASSWORD=$5
echo "password $PASSWORD"
fi
if [ $# -ge 6 ]; then
NUM=$6
echo "NUM $NUM"
fi
CONNECT="'chat -s -v ABORT \"BUSY\" ABORT \"NO CARRIER\" ABORT \"NO DIALTONE\" ABORT \"ERROR\" ABORT \"NO ANSWER\" \"\" AT OK ATE0 OK ATI OK AT+CSUB OK AT+CSQ OK AT+CPIN? OK AT+COPS? OK AT+CGREG? OK AT+CGDCONT=1,\\\"IP\\\",\\\"$APN\\\",,0,0 OK $NUM CONNECT'"
DISCONNECT="'chat -s -v ABORT ERROR ABORT OK ABORT DELAYED ABORT \"NO CARRIER\" ABORT \"NO DIALTONE\" SAY \"\nSending break to the modem\n\" \"\" +++ \"\" +++ \"\" +++ SAY \"\nGood bay\n\"'"
pppd $DEVNAME $BAUD user "$USER" password "$PASSWORD" connect "'$CONNECT'" disconnect "'$DISCONNECT'" nodetach lock \
modem \
persist \
crtscts \
usepeerdns \
noauth \
noipdefault \
novj \
novjccomp \
noccp \
defaultroute \
ipcp-accept-local \
ipcp-accept-remote
编写、执行测试程序调试:
1.先查看SIM卡信号(AT+CSQ指令),良好
2.查看运营商,正确
3.拨号测试,正确识别运营商和成功拨号;输入ifconfig命令后可以看到已经生成ppp0网卡,添加ppp0默认路由后ping外网测试成功。
注意点:
1.不同运营商有不同的apn和拨号号码,要正确选择,否则拨号不成功
2.拨号前用AT指令检查能否接受到基站信号
3.用户名(user)和密码(password)可有可无,不重要。
4.ping测试识别不了域名的时候在/etc/resolv.conf上加上nameserver8.8.8.8/114.114.114.114
参考:
https://blog.csdn.net/zhaoxd200808501/article/details/72637695
https://blog.csdn.net/blog_xu/article/details/99676812
http://t.zoukankan.com/zhuangquan-p-12191214.html