📄 main.c
字号:
/***********************************GSM接收短信实例步骤:1 打开串口;2 初始化串口参数;3 发送AT+CMGF命令,通知GSM模块采用PDU模式;4 利用AT+CNMI命令设置自动提醒功能;5 利用AT+CMGR命令读取短信,并处理读取的短信;6 发送结束,关闭串口。作者:蒙德鑫时间:2008/12/10************************************/#include <stdio.h> /*标准输入输出定义*/#include <stdlib.h> /*标准函数库定义*/#include <unistd.h> /*Unix标准函数定义*/#include <string.h>#include <sys/types.h> /**/#include <sys/stat.h> /**/#include <fcntl.h> /*文件控制定义*/#include <termios.h> /*PPSIX终端控制定义*/#include <errno.h> /*错误号定义*/#include "decode.h" /* 解码PDU字符串 *//* 串口设备宏定义 */#define ttyS0 "/dev/ttyS0"#define ttyS1 "/dev/ttyS1"#define ttyUSB0 "/dev/ttyUSB0"#define ttyUSB1 "/dev/ttyUSB1"/* 初始化串口参数 */void init_device(int portfd);int main(int argc,char *argv[]){ int portfd; char cmd[256],msg[256]; char *pdu,*pdu_end; int n,newSMSNum; /* 以读写方式打开串口 */ char portdevice[256]; memset(portdevice,0,sizeof(portdevice)); strncpy(portdevice,ttyUSB0,strlen(ttyUSB0)); portfd = open(portdevice,O_RDWR); if(portfd == -1){//打开失败,则退出 printf("Can't Open Serial Port:%s\n",portdevice); return EXIT_FAILURE; } /* 初始化串口参数 */ init_device(portfd); /* 发送AT+CMGF命令,通知GSM模块采用PDU模式 */ memset(cmd,0,sizeof(cmd)); sprintf(cmd,"AT+CMGF=0\r"); sleep(1);//等待GSM模块命令处理完成 write(portfd,cmd,strlen(cmd));//发送AT+CMGF命令 sleep(1); /* 利用AT+CNMI命令设置自动提醒功能 */ memset(cmd,0,sizeof(cmd)); sprintf(cmd,"AT+CNMI=2,1\r"); write(portfd,cmd,strlen(cmd));//发送AT+CNMI命令 sleep(1); int flag = 1; char buf[512]; char *my_ptr,*my_ptr_end; //获取新短信的序号,存入newSMSNum变量中 while(flag){ n = read(portfd,buf,sizeof(buf)-1); if(NULL != strstr(buf,"+CMTI:")){ printf("CMTI->%s<-\n",buf); my_ptr = strstr(buf,"+CMTI: \"SM\",") + strlen("+CMTI: \"SM\",");//开头 my_ptr_end = strstr(my_ptr,"\n");//结尾 my_ptr_end = 0; sscanf(my_ptr,"%d",&newSMSNum); printf("New SMS Num:%d\n",newSMSNum); flag = 0; }else{ memset(buf,0,sizeof(buf)); sleep(3); } } /* 利用AT+CMGR命令读取新到来的短信 */ tcflush(portfd,TCIOFLUSH);//清空串口读写缓存 memset(cmd,0,sizeof(cmd)); sprintf(cmd,"AT+CMGR=%d\r",newSMSNum); sleep(1); write(portfd,cmd,strlen(cmd)); sleep(1); //int left = sizeof(msg); //do{ memset(msg,0,sizeof(msg)); n = read(portfd,msg,sizeof(msg)-1); //left -= n; //}while(n > 0); printf("read Num:%d\n",n); printf("content:%s<-end\n",msg); //判断是否读取成功 //char *ptr; char time[13]; char phone[14]; char real_msg[256]; memset(real_msg,0,sizeof(msg)); memset(phone,0,sizeof(phone)); memset(time,0,sizeof(time)); if(NULL != strstr(msg,"+CMGR:")){ pdu = strstr(msg,"089168");//短信内容的开头 pdu_end = strstr(pdu,"\n");//短信内容的结尾 *pdu_end = 0; printf("pdu:%s<-end\n",pdu); if(-1 == decode_pdu(pdu,time,phone,real_msg)){ printf("convert failed.\n"); return EXIT_FAILURE; } printf("time:%s\n",time); printf("phone:%s\n",phone); printf("msg:%s\n",real_msg); } /* 接收结束,关闭串口 */ close(portfd); return EXIT_SUCCESS;}/* 初始化串口参数使用非规范方式(raw mode);设置波特率为B9600;采用软件流控制,不使用硬件流控制;传输数据时使用8位数据位和一位停止位(8N1);不使用奇偶校验;*/void init_device(int portfd){ struct termios tty; tcgetattr(portfd,&tty); /*串口参数:9600bps,使用非规范方式,采用软件流控制*/ //设置输入输出波特率为9600bps cfsetospeed(&tty,B9600); cfsetispeed(&tty,B9600); //使用非规范方式 tty.c_lflag &= ~(ICANON | ECHO | ECHOE); //采用软件流控制,不使用硬件流控制 tty.c_iflag |= (IXON | IXOFF | IXANY); tty.c_cflag &= ~CRTSCTS; /* 8N1,不使用奇偶校验 */ //传输数据时使用8位数据位 tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; //一位停止位,不使用奇偶校验 tty.c_cflag &= ~(PARENB | CSTOPB); //忽略DCD信号,启用接收装置 tty.c_cflag |= (CLOCAL | CREAD); /* Minimum number of characters to read */ tty.c_cc[VMIN] = 0; /* Time to wait for data (tenths of seconds)*/ tty.c_cc[VTIME] = 10; /* 使设置立即生效 */ tcsetattr(portfd,TCSANOW,&tty);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -