📄 new_communication.c
字号:
/********************************************************************
*以下为串口通讯进程 *
*功能:实现家庭网络中网关与各子节点通讯 *
*进程名:communication.c *
*此程序为测试版 版号:1.1 *
*完成日期:2004.7.18 *
*进程包含主要函数有: *
*1、 main函数 //主函数 *
*2、 Signal_Handler_IO //信号处理函数,响应主动上报的报警信息 *
*3、 Alarm_Inf //报警信息处理函数 *
*4、 Renew_Html_Inf //网页中小区信息处理函数 *
*5、 Renew_Html //动态网页刷新函数 *
*6、 Control_Order_Send //接收并向下转发控制命令函数 *
*7、 Receive_Packet //接收子节点脉冲量、模拟量函数 *
*8、 Send_Mail_packet //发送邮件数据包函数 *
*9、 Get_Mail_Address //获取邮件服务器IP地址 *
*10、Get_User_Inf //获取用户信息 *
*11、Get_Collect_Time //从IIC中读出数据采集设定时间参数 *
*12、Anniu_Inf_Send //紧急报警按钮信息发送邮件函数 *
*13、Judge_Node_Type //判断节点类型函数 *
*14、Select_Time_Interval //网关定时采集数据时间判断函数 *
*进程包含自定义头文件有: *
*maillip.h //邮件函数库头文件 *
*iic.h //I2C函数库头文件 *
*htmllib.h //动态网页函数库文件 *
*ds1302.h //ds1302实时时钟函数头文件 *
*communication.h //进程子定义函数库头文件 *
*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <signal.h>
#include "maillip.h"
#include "iic.h"
#include "htmllib.h"
#include "ds1302.h"
#include "new_communication.h"
/********************************************************************
*信号处理函数 *
*功能:有信号到来,则调用此函数。 *
*返回值: wait_flag = FALSE *
*********************************************************************/
void Signal_Handler_IO (int status)
{
printf("received SIGIO signal.\n");
wait_flag = FALSE;
}
/*********************************************************************
*报警信息处理函数 *
*功能:接收并处理来自子节点的报警或安防信息,并发送邮件 *
*返回值:0或1或2或-1 *
*返回1表示收到设防信息并设置设防标志; *
*返回0表示收到撤防信息并设置撤防标志; *
*返回2表示收到报警信息并设置报警标志; *
*返回-1表示此数据包有误; *
**********************************************************************/
int Alarm_Inf(BYTE pac_buffer[20])
{
BYTE alarm_buf[20];
BYTE fun_code; //定义数据包功能码
BYTE *alarm_inf,tmp_buf[20];
BYTE *SendMailStr;
BYTE tittle[30]; //定义邮件的标题
BYTE body[50]; //定义邮件的内容
BYTE TimeBuffer[8];
BYTE netwk,node; //定义网络号和节点号
int show_node;
alarm_inf = tmp_buf;
strcpy(alarm_buf,pac_buffer);
if(alarm_buf[0]==0x44)
{
/*网络中有两种节点号,Zigbee节点号和拨码设置节点号 *
*在网络初始后他们建立一一对应关系 */
netwk = (alarm_buf[1]&0xf0); //将高四位网络号赋给netwk
show_node = (int)(alarm_buf[1]&0x0f);//将低四位Zigbee节点号赋给show_node
fun_code=(alarm_buf[3]&0x0f);
node=(alarm_buf[3]>>4)&0x0f;//将低四位拨码设置节点号赋给node
if(fun_code==0x0f)
{
tmp_buf[0] = alarm_buf[5];
tmp_buf[1] = '\0';
if(alarm_buf[5] == alarm_set_mode)
{
/*发送设防邮件*/
sprintf(tittle,"she fang xin xi");
sprintf(body,"an fang xi tong qi dong");
SendMailStr = Send_Mail_Packet(netwk,node,alarm_inf);
mail(DstStr,SrcStr,tittle,body,SendMailStr);
NetNode[(int)netwk][show_node].state="设防";
Get_Time(&TimeBuffer[0]);
sprintf(NetNode[(int)netwk][show_node].show_node_time, \
"(%02i/%02i;%02i:%02i)",ds_1302_time.month,ds_1302_time.date, \
ds_1302_time.hour,ds_1302_time.min);
/*点亮安防信息指示灯*/
leddev = open("/dev/led",O_RDWR | O_NOCTTY );
if ( leddev == -1 )
{
printf("why not open file \n");
//exit(0);
}
alarm_flag=1; /*设防标志为置1*/
return(1);
}
else if(alarm_buf[5] == alarm_cancel_mode)
{
/*发送撤防邮件*/
sprintf(tittle,"che fang xing xi");
sprintf(body,"an fang xi tong guan bi");
SendMailStr = Send_Mail_Packet(netwk,node,alarm_inf);
mail(DstStr,SrcStr,tittle,body,SendMailStr);
NetNode[(int)netwk][show_node].state="撤防";
Get_Time(&TimeBuffer[0]);
sprintf(NetNode[(int)netwk][show_node].show_node_time, \
"(%02i/%02i;%02i:%02i)",ds_1302_time.month,ds_1302_time.date, \
ds_1302_time.hour,ds_1302_time.min);
if(alarm_flag==1)
{
close(leddev); /*熄灭安防信息指示灯*/
}
alarm_flag = 0; /*设防标志为置0*/
return(0);
}
else
{printf("alarm data error");return(-1);}
}
else if((fun_code==0x04)||(fun_code==0x05))/*传送一路报警信息*/
{
if(alarm_flag==0)/*未设防不进行报警处理*/
{
return(2);
}
else if(alarm_flag==1)
{
/*发送报警邮件*/
tmp_buf[0] = alarm_buf[5];
tmp_buf[1] = '\0';
sprintf(tittle,"jie dian bao jing");
sprintf(body,"you jie dian bao jing");
SendMailStr = Send_Mail_Packet(netwk,node,alarm_inf);
mail(DstStr,SrcStr,tittle,body,SendMailStr);
AlarmNodeNum = show_node;
AlarmNetNum = (int)netwk;
alarm_tran_flag = 1;
NetNode[AlarmNetNum][AlarmNodeNum].state="报警";
/*获取报警时间*/
Get_Time(&TimeBuffer[0]);
sprintf(NetNode[(int)netwk][show_node].show_node_time, \
"(%02i/%02i;%02i:%02i)",ds_1302_time.month,ds_1302_time.date, \
ds_1302_time.hour,ds_1302_time.min);
return(2);
}
else
{printf("alarm_flag error\n");return(-1);}
}
else
{printf("fun_code error\n");return(-1);}
}
else
{printf("information error\n");return(-1);}
}
/***************************************************************************
*小区信息处理函数 *
*功能:刷新网页中的小区信息。 *
***************************************************************************/
void Renew_Html_Inf(BYTE PipeBuffer1[PIPEBUFFER_SIZE],int num)
{
BYTE TimeBuffer[8];
BYTE buffer[30];
int i;
i = num; //i 表示是小区的第i条信息
/*获取小区信息发送时间*/
Get_Time(&TimeBuffer[0]);
memset(PipeInfBuffer[i],'\0',sizeof(PipeInfBuffer[i]));
sprintf(buffer,"T(%02i-%02i %02i:%02i)", \
ds_1302_time.month,ds_1302_time.date,ds_1302_time.hour,ds_1302_time.min);
strcat(PipeInfBuffer[i],buffer);
strcat(PipeInfBuffer[i],PipeBuffer1);
}
/***************************************************************************
*函数名:Renew_Html 动态网页刷新 *
* 功能:将数据实时添入网页中,动态刷新网页函数 *
***************************************************************************/
void Renew_Html(void)
{
int fd1,i,j,restr,size;
BYTE TimeBuffer[8];
BYTE tmp_buffer[PIPEBUFFER_SIZE+1];
fd1= open("/tmp/index.html", O_WRONLY | O_CREAT | O_TRUNC,0666 );
if (fd1<0) {printf("can't open index.html");}
htmlHeader(fd1);
htmlBody(fd1);
htmlFormStr(fd1);
/*获取网页显示时间*/
Get_Time(&TimeBuffer[0]);
size = sprintf(tmp_buffer,"时间: %s 20%02i-%02i-%02i %02i:%02i:%02i", \
&my_1302_days[TimeBuffer[5]-1][0],ds_1302_time.year,ds_1302_time.month, \
ds_1302_time.date,ds_1302_time.hour,ds_1302_time.min,ds_1302_time.sec);
htmlText(fd1,tmp_buffer,size);
htmlTextHead(fd1);
htmlText(fd1,"<P><font face=\"宋体\" size=\"4\" color=\"#FF00FF\"><b>个人信息:</b></font></P>",73);
htmlText(fd1,"<P><font face=\"楷体_GB2312\" size=\"3\" color=\"#008080\"></font></P>",64);
size = sprintf(tmp_buffer,"用户名: %s",NameStr);
htmlText(fd1,tmp_buffer,size);
size = sprintf(tmp_buffer,"家庭地址: %s",AddressStr);
htmlText(fd1,tmp_buffer,size);
htmlTextEnd(fd1);
htmlText(fd1,"<P><font face=\"宋体\" size=\"4\" color=\"#FF00FF\"><b>家庭网络信息:</b></font></P>",77);
htmlText(fd1,"<P><font face=\"楷体_GB2312\" size=\"3\" color=\"#008080\"></font></P>",64);
htmlText2(fd1);
for(i=0;i<NetNum;i++)
{
/*子网1中有节点0,而子网0中没有节点0,有一一对应表*/
/*子网0中节点0是主节点*/
if(i!=0)
{j=0;}
else
{j=1;}
for(;j<NodeNum;j++)
{
if(NetNode[i][j].flag==1)
{
restr = (int)(NetNode[i][j].real_node>>4)&0x0f;
htmlText3(fd1);
size = sprintf(tmp_buffer,"%d",i);
htmlText5(fd1,tmp_buffer,size);
size = sprintf(tmp_buffer,"%d",restr);//显示节点号
htmlText5(fd1,tmp_buffer,size);
size = sprintf(tmp_buffer,"%u",NetNode[i][j].node_data);
htmlText5(fd1,tmp_buffer,size);//显示节点采集数据
size = sprintf(tmp_buffer,"%s",NetNode[i][j].show_node_time);
htmlText5(fd1,tmp_buffer,size);//显示节点采集数据时间
size = sprintf(tmp_buffer,"%d",NetNode[i][j].cell);
htmlText5(fd1,tmp_buffer,size);//显示节点电池电量
size = sprintf(tmp_buffer,"%s",NetNode[i][j].funtion);
htmlText5(fd1,tmp_buffer,size);//显示节点功能
size = sprintf(tmp_buffer,"%s",NetNode[i][j].state);
htmlText5(fd1,tmp_buffer,size);//显示节点状态
htmlText6(fd1);
}
}
}
htmlText7(fd1);
htmlTextHead1(fd1);
for(i=0;i<SetInfNum+1;i++)
{
/*用是否显示T来区分信息是否读过*/
if(PipeInfBuffer[i][0]=='T')
{
size = sprintf(tmp_buffer,"小区信息:%s",PipeInfBuffer[i]);
htmlText1(fd1,tmp_buffer,size);}/*未读过的小区信息显示*/
else
{size = sprintf(tmp_buffer,"小区信息:%s",PipeInfBuffer[i]);
htmlText(fd1,tmp_buffer,size);}/*已读过的小区信息显示*/
}
htmlTextEnd1(fd1);
if(anniu_flag==1)
{htmlAnniuStr(fd1,AnniuTimeBuffer,TimeSize);}
else
{htmlAnniuQuit(fd1);}
htmlText(fd1,"<p><input type=\"submit\" value=\"信息确认\" name=\"B0\"></p>",55);
htmlFormEnd(fd1);
htmlText4(fd1,"<td width=\"100%\"><p align=center>Copyright© By智园慧家 2002--2003<BR>E-mail:<A href=\"sohu\">ercdc.bjut.edu.cn</A></p></td>",127);
htmlFooter(fd1);
close(fd1);
}
/***************************************************************************
*函数名:Control_Order_Send 接收并向下转发控制命令函数 *
*功能:接收控制网页通过管道(pipe)传送控制命令,并将按通信协议打包发送 *
***************************************************************************/
void Control_Order_Send(int fd,BYTE PipeBuffer[BUFFER_SIZE])
{
int i,res,con_len;
BYTE con_ch;
WORD con_netwk,con_node,re;
BYTE TimeBuffer[8];
int read_flag = 0;
int con_order_flag;
BYTE data_buf[20];
int alarm_return;
int client_fd,show_node;
int open_mode2=O_WRONLY|O_NONBLOCK;
BYTE SenConData[10];
BYTE ResDevData[7]={0x44,0x00,0x02,0x00,0x98,0x00,0x00};//发送帧格式
BYTE PipeBuf[BUFFER_SIZE];
BYTE some_data[BUFFER_SIZE];
strcpy(PipeBuf,PipeBuffer);
con_len=strlen(PipeBuf);
PipeBuf[con_len] = '\0';
if(strcmp(PipeBuf,"ok") == 0)
{
/*网页中确认按钮动作,用户已看到报警信息 *
*因而给报警节点发送命令关掉报警灯 */
con_order_flag = 0;/*无需给网页返回应答信息因而con_order_flag置0*/
memset(SenConData,'\0',sizeof(SenConData));
SenConData[0] = 0x44;
SenConData[1] = NetNode[AlarmNetNum][AlarmNodeNum].zigbee_node;
SenConData[2] = 0x03;
SenConData[3] = NetNode[AlarmNetNum][AlarmNodeNum].real_node;
SenConData[4] = set_relay_order;
SenConData[5] = 0x3f;
SenConData[6] = Bit_Xor(6,SenConData);
}
else
{
/*收到网页发送的控制命令,按不同类型组成命令帧,准备发送*/
con_order_flag = 1;/*需给网页返回应答信息因而con_order_flag置1*/
/*打开应答管道,命令控制成功则返回应答信息给网页*/
client_fd = open(CLIENT_NAME,open_mode2);/*打开返回应答管道*/
if(client_fd == -1){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -