📄 gprs_modem.c
字号:
/*
*Copyright (c) 2006 .南京e嵌嵌入式科技有限公司
*All rights reserved
*
*filename :gprs_modem_test.c
*
*version 1.0
*
*author:lichao
*completed:20070723
*
*description:The file is used to test whether the gprs modem works correctly
*
*email:lichao@njupt.edu.cn
*/
//int fd;
#include "gprs_modem.h"
int speed_arr[] = { B38400, B57600,B19200, B9600, B4800, B2400, B1200, B300 };
int name_arr[] = {38400, 57600, 19200, 9600, 4800, 2400, 1200, 300 };
//char *DEV="/dev/ttyS0";
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄*
*@param databits 类型 int 数据位 取值 为 7 或者8*
*@param stopbits 类型 int 停止位 取值为 1 或者2*
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;/*屏蔽字符大小位*/
switch (databits) /*设置数据位数*/
{
case 5:
options.c_cflag |= CS5;//选择5位数据位
break;
case 6:
options.c_cflag |= CS6;//选择6位数据位
break;
case 7:
options.c_cflag |= CS7;//选择7位数据位
break;
case 8:
options.c_cflag |= CS8;//选择8位数据位
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity,无校验位*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
/*如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,
那么使用原始模式(Raw Mode)方式来通讯,设置方式如下*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_cc[VTIME] = 10; // 1 seconds
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
/**
*设置流控
*/
void SetFlowControl(int com,int mode)
{
struct termios options;
if ( tcgetattr( com,&options) != 0)
{
perror("SetupSerial 1");
return;
}
switch(mode)
{
case 1:
options.c_cflag &= ~CRTSCTS;//无流控
break;
case 2:
options.c_cflag |= CRTSCTS;//硬件流控
break;
case 3:
options.c_cflag |= IXON|IXOFF|IXANY;//软件流控
}
tcsetattr(com,TCSANOW,&options);
}
/**
*@breif 打开串口,
*参数Dev为打开设备的设备名,如/dev/ttyS0
*返回值:-1:打开失败,否则返回打开设备的设备句柄
*/
int Open_Init_COM(char *Dev)
{
int com=open( Dev, O_RDWR | O_NOCTTY); //| O_NOCTTY | O_NDELAY
if (-1 == com)
{
/*设置数据位数*/
perror("Can't Open Serial Port");
return -1;
}
/*初始化串口*/
//设置串口属性
fcntl(com,F_SETFL,0);//没有数据就阻塞,直到数据到来或者到了规定时间。
//如果要使read()函数立即返回,请用fcntl(com,F_SETFL,FNDELAY)函数
set_speed(com,57600);//速度9600BPS
set_parity(com,8,1,'s');//数据位8位,1位停止位,没有奇偶校验位
SetFlowControl(com,1); //无流控
return com;
}
/**
*从串口读取数据
*/
int ReadCOM(int n,char *buf,int length)
{
return read(n,buf,length);
}
/**
*向串口写数据
*/
int WriteCOM(int n,char *buf,int length)
{
return write(n,buf,length);
}
/**
*关闭串口
*/
int CloseCOM(int n)
{
return close(n);
}
/*
*接收短消息前的准备
*/
int Gprs_MessageReady(int com)
{
int nRead,k=0,num=0;
char gprs_buf[100];
char *at_cmd;
char ReceiveMessageCmd[][30]={{"ATZ\r"},{"AT+CMGF=1\r"},{"AT+CSCA=\"+8613800250500\"\r"},{""}};
at_cmd=ReceiveMessageCmd[k++];
while(strcmp(at_cmd,"")) {
bzero(gprs_buf,100);
WriteCOM(com,at_cmd,strlen(at_cmd));
sleep(2);
at_cmd=ReceiveMessageCmd[k++];
if((nRead=ReadCOM(com,gprs_buf,100))<0) {
perror("ReadCOM error");
return -1;
}
printf("num=%d gprs_buf=%s",num,gprs_buf);
if(strstr(gprs_buf,"OK")!=NULL) {
num++;
continue;
}else
{
return num;
}
}
return 0;
}
/*
解析短信内容,这是移动的解析方式,联通可能不同
*/
int Gprs_AnalyzeMessage(char *as_gprs_info,struct shortmsg *pShortMsg) {
char *pGprs_sender,*pGprs_time,*pGprs_con,*pGprs_con_last;
char Gprs_recvcon[100];
int i=0,j=0;
memset(pShortMsg->sender,0,20);
memset(pShortMsg->msgcontent,0,100);
if((pGprs_sender=strstr(as_gprs_info,"+86"))==NULL) return 1;
strncpy(pShortMsg->sender,pGprs_sender,14);
printf("sender %s\n",pShortMsg->sender);
if((pGprs_time=strstr(pGprs_sender,"\",,\""))==NULL) return 2;
/* pShortMsg->sendtime=time(NULL);
printf("sendtime %s",pShortMsg->sendtime);*/
if((pGprs_con=strstr(pGprs_sender,"\n\n"))==NULL) return 3;
pGprs_con+=2;
while(isalnum(pGprs_con[i]))
{
Gprs_recvcon[j]=pGprs_con[i];
i++;j++;
}
strcpy(pShortMsg->msgcontent,Gprs_recvcon);
printf("msgcontent %s\n",pShortMsg->msgcontent);
return 0;
}
/*
*写入短信中的Index号码
*/
void Gprs_GetMessage(int com)
{
int nRead,nWrite;
char gprs_rev_Number[25];
char getNumber[10],*catNumber;
char get_message[25];
char message_info[][15]={{"AT+CMGR="},{"AT+CMGD="}};
int k=0,i=0;
catNumber=getNumber;
memset(gprs_rev_Number,0,25);
while(strlen(gprs_rev_Number)<7) {
nRead=ReadCOM(com,gprs_rev_Number,25);//读取+CMTI:“SM”,56
}
printf("gprs_rev_Number=%s\n",gprs_rev_Number);
memset(getNumber,0,10);
for(i=0;i<nRead;i++)
{
if(gprs_rev_Number[i]>='0'&&gprs_rev_Number[i]<='9')
{
getNumber[k]=gprs_rev_Number[i];
k++;
}//取得INDEX号码
}
memset(gprs_rev_Number,0,25);
nRead=ReadCOM(com,gprs_rev_Number,25);//再次读取因为有时候只能读取最后两位中的一位如56 有时只能读取5原因不明,所以只能再次读取一次
if(nRead>0)
{
for(i=0;i<nRead;i++) {
if(gprs_rev_Number[i]>='0'&&gprs_rev_Number[i]<='9')
{
getNumber[k]=gprs_rev_Number[i];
k++;
}
}//取得INDEX号码
}
memset(get_message,0,25);
getNumber[k++]='\r';
strncpy(get_message,message_info[0],strlen(message_info[0]));
strncat(get_message,catNumber,k);
WriteCOM(com,get_message,strlen(get_message));
sleep(2);
}
/*
*读取短信信息
*/
int Gprs_RecvRead(int com,struct shortmsg *pShortMsg) {
char gprs_rev_buf[100];
int nRead;
int i;
memset(gprs_rev_buf,0,100);
if((nRead=ReadCOM(com,gprs_rev_buf,100))>0)
{
for(i=0;i<nRead;i++)
{
printf("%c",gprs_rev_buf[i]);
}
printf("\n");
Gprs_AnalyzeMessage(gprs_rev_buf,pShortMsg);
}
}
/*
*收短信,并将短信内容解析出来
*/
int Gprs_ReceiveMessage(int com,struct shortmsg *pShortMsg)
{
pid_t pc,pr;
int ret;
Gprs_GetMessage(com);
Gprs_RecvRead(com,pShortMsg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -