转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38515343
这将是本项目的最后一篇,实现监控报警功能,可能还有改进的地方,我先放出第一个版本,后续更新请留意本博客。
一.软件框架
二.源代码
/*************************************************************** *版权:GPLv2,希望用到或更改代码的小伙伴自觉遵守 *文件名称:监控报警测试 *内容摘要: *其它说明:实现远程监控报警功能 *当前版本:V1.0 *作 者:若云流风 *完成日期:2014.8.8 ***************************************************************/ #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #include <termios.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <signal.h> #include <sys/types.h> #include <sys/select.h> #include <unistd.h> #include <fcntl.h> #include <pthread.h> //for gsm #define FUNC_RUN 0 #define FUNC_NOT_RUN 1 #define DEVICE_TTYS "/dev/ttySAC1" //modem分配的UART口,0为与PC调试串口,2为红外串口,故选择1 #define MAX_LEN_OF_SHORT_MESSAGE 14 #define RECEIVE_BUF_WAIT_1S 1 #define RECEIVE_BUF_WAIT_2S 2 #define RECEIVE_BUF_WAIT_3S 3 #define RECEIVE_BUF_WAIT_4S 4 #define RECEIVE_BUF_WAIT_5S 5 void GSM_call(int fd_g); void GSM_Send_Message(int fd_g); /* wvm_buttonstest */ int fd_b,fd_l,fd_p,fd_g,pos,alert; /*初始化设备*/ void init_ttyS(int fd_g) { struct termios options; bzero(&options, sizeof(options)); // clear options cfsetispeed(&options,B115200); // setup baud rate,输入、输出都为115200 cfsetospeed(&options,B115200); options.c_cflag |= (CS8 | CREAD); //Enable the receiver and Select 8 data bits options.c_iflag = IGNPAR; //Ignore parity errors tcflush(fd_g, TCIFLUSH); //*TCIFLUSH 刷清输入队列. 在打开串口后,串口其实已经可以开始读取 数据了 ,这段时间用户如果没有读取,将保存在缓冲区里,如果用户不想要开始的一段数据,或者发现缓冲区数据有误,可以使用这个函数清空缓冲 tcsetattr(fd_g, TCSANOW, &options); //Set the new options for the port } /*基本功能函数*/ void GSM_GPRS_send_cmd_read_result(int fd_g, char *send_buf, int rcv_wait) { char rcv_buf[2048]; if((send_buf==NULL) || (send_GSM_GPRS_cmd(fd_g,send_buf))){ // send success , then read bzero(rcv_buf,sizeof(rcv_buf)); //将rcv_buf清零,为接收做准备 if (read_GSM_GPRS_datas(fd_g,rcv_buf,rcv_wait)){ printf ("%s\n",rcv_buf); } else{ printf ("read error\n"); } } else{ printf("write error\n"); } } /*为GSM短信控制关闭警报*/ void GSM_GPRS_send_cmd_read_result_alert(int fd_g, char *send_buf, int rcv_wait) { char rcv_buf[2048]; if((send_buf==NULL) || (send_GSM_GPRS_cmd(fd_g,send_buf)))// send success , then read { bzero(rcv_buf,sizeof(rcv_buf)); //将rcv_buf清零,为接收做准备 if (read_GSM_GPRS_datas(fd_g,rcv_buf,rcv_wait)) { /*关闭警报密码:82E5 4E91 6D41 98CE 若云流风(更改密码请更改此处)*/ if (rcv_buf[pos-24] == '8' && rcv_buf[pos-23] == '2'&& rcv_buf[pos-22] == 'E' && rcv_buf[pos-21] == '5'&& rcv_buf[pos-20] == '4' && rcv_buf[pos-19] == 'E'&& rcv_buf[pos-18] == '9' && rcv_buf[pos-17] == '1'&&rcv_buf[pos-16] == '6' && rcv_buf[pos-15] == 'D'&& rcv_buf[pos-14] == '4' && rcv_buf[pos-13] == '1'&& rcv_buf[pos-12] == '9' && rcv_buf[pos-11] == '8'&& rcv_buf[pos-10] == 'C' && rcv_buf[pos-9] == 'E') alert=0; /*开启警报密码:6D41 98CE 82E5 4E91 流风若云(更改密码请更改此处)*/ if (rcv_buf[pos-24] == '6' && rcv_buf[pos-23] == 'D'&& rcv_buf[pos-22] == '4' && rcv_buf[pos-21] == '1'&& rcv_buf[pos-20] == '9' && rcv_buf[pos-19] == '8'&& rcv_buf[pos-18] == 'C' && rcv_buf[pos-17] == 'E'&&rcv_buf[pos-16] == '8' && rcv_buf[pos-15] == '2'&& rcv_buf[pos-14] == 'E' && rcv_buf[pos-13] == '5'&& rcv_buf[pos-12] == '4' && rcv_buf[pos-11] == 'E'&& rcv_buf[pos-10] == '9' && rcv_buf[pos-9] == '1') alert=1; } /* else { printf ("read error\n"); } */ } else { printf("write error\n"); } } /*发命令:主机->GSM*/ int send_GSM_GPRS_cmd(int fd_g, char *send_buf) { ssize_t ret; ret = write(fd_g,send_buf,strlen(send_buf)); if (ret == -1) { printf ("write device %s error\n", DEVICE_TTYS); return -1; } return 1; } /*读数据:GSM->主机 *此处我在测试的时候发现发送和接收的字符串长度不一致,最后经过试验发现 *发送的时候例如:AT+CSCS="UCS2"\r发送15个字节 * 接收的时候是21字节,后来发现接收除了发送的AT+CSCS="UCS2"\r以外还接收了\r\nOK\r\n这样就说明了多出的6个字节了。 *最后一个有效字节是pos-9 pos-24,四个汉字加密 */ int read_GSM_GPRS_datas(int fd_g, char *rcv_buf,int rcv_wait) { int retval; fd_set rfds; struct timeval tv; //int ret,pos; int ret; tv.tv_sec = 2.5; // 秒wait 2.5s tv.tv_usec = 0; //毫秒 pos = 0; // point to rceeive buf while (1) { FD_ZERO(&rfds); //清除套接字集合 FD_SET(fd_g, &rfds); //用于在文件描述符集合中增加一个新的文件描述符(读数据) retval = select(fd_g+1 , &rfds, NULL, NULL, &tv); if (retval == -1) //(-1)出错 { //超时 perror("select()"); break; } else if (retval) //(正数)已经准备好的描述符数 { //判断是否还有数据 ret = read(fd_g, rcv_buf+pos, 2048); pos += ret; //读出的数据长度 if (rcv_buf[pos-2] == '\r' && rcv_buf[pos-1] == '\n') //如果读到字符串末尾 { FD_ZERO(&rfds); FD_SET(fd_g, &rfds); retval = select(fd_g+1 , &rfds, NULL, NULL, &tv); if (!retval) break; // no datas, break } } else //(0)没有准备好描述符 { printf("No data\n"); break; } } return 1; } /*GSM初始化*/ void GSM_init_test(int fd_g) { char *send_buf="AT+CSCS=\"UCS2\"\r"; //选择TE字符集 GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); send_buf="AT+CNMI=2,1,0,0,0\r"; //设置新消息提示 GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); send_buf="AT+CMGF=0\r"; //PDU格式 GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); } /*发送信息*/ void GSM_Send_Message(int fd_g) { char *send_buf="AT+CMGS=29\r"; //发送PDU格式短信 GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); char *send_buf_pud="0891683108406105F011000D91685141128978F00008000E003153F7573070B962A58B66002E"; //1号地点报警 (8870发送的内容) GSM_GPRS_send_cmd_read_result(fd_g,send_buf_pud,RECEIVE_BUF_WAIT_1S); send_buf="\x01a"; //ctrl+z GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); sleep(3); //加3S延时,给手机接收短信的时间,否则和拨号造成冲突,无法拨号 } /*打电话*/ void GSM_call(int fd_g) { int i; char *send_buf="ATD114;\r\0"; //发送缓冲区 GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); //拨号 } /*做一些GSM初始化的工作*/ int gsm_init(fd_g) { init_ttyS(fd_g); // init device GSM_init_test(fd_g); return 0; } /*按键后触发的函数*/ void my_signal_fun(int signum) { printf("open my_signal_fun\n"); unsigned char key_val; unsigned int led_val; unsigned int cmd; //unsigned int alert=1; read(fd_b, &key_val, 1); printf("key_val: 0x%x\n", key_val); if(key_val==0x4) { char *send_buf="AT+CMGR=1\r"; //读取短消息1 GSM_GPRS_send_cmd_read_result_alert(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); send_buf="AT+CMGD=1\r"; //删除短消息1(所有的用1,4) GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); //alert=1; if(alert==1) { GSM_Send_Message(fd_g); GSM_call(fd_g); while(alert) { cmd=1; led_val=1; write(fd_l, &led_val, 4); ioctl(fd_p,cmd,700); //printf("on\n"); send_buf="AT+CMGR=1\r"; //读取短消息1 GSM_GPRS_send_cmd_read_result_alert(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); led_val=0; write(fd_l, &led_val, 4); ioctl(fd_p,cmd,2000); sleep(1); } //做一些清理工作,警报关闭,灯光关闭,删除短信 led_val=0; cmd=0; write(fd_l, &led_val, 4); ioctl(fd_p,cmd,0); send_buf="ATH\r"; //删除短消息1(所有的用1,4) GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); send_buf="AT+CMGD=1\r"; //删除短消息1(所有的用1,4) GSM_GPRS_send_cmd_read_result(fd_g,send_buf,RECEIVE_BUF_WAIT_1S); } } } /*主函数*/ int main(int argc, char **argv) { unsigned char key_val; int ret; int Oflags; alert=1; //初始化警报开启 signal(SIGIO, my_signal_fun); fd_b = open("/dev/buttons", O_RDWR); if (fd_b < 0) { printf("can't open/dev/buttons\n"); } printf("open /dev/buttons\n"); fd_l = open("/dev/led", O_RDWR); if (fd_l < 0) { printf("can't open/dev/led\n"); } printf("open /dev/led\n"); fd_p = open("/dev/wvm_pwm", O_RDWR); if (fd_b < 0) { printf("can't /dev/wvm_pwm\n"); } printf("open /dev/wvm_pwm\n"); fd_g = open("/dev/ttySAC1", O_RDWR); //打开TTY设备 if (fd_b < 0) { printf("can't /dev/ttySAC1\n"); } printf("open /dev/ttySAC1\n"); gsm_init(fd_g); fcntl(fd_b, F_SETOWN, getpid()); Oflags = fcntl(fd_b, F_GETFL); fcntl(fd_b, F_SETFL, Oflags | FASYNC); while (1) { sleep(1000); } return 0; }