#include <Winsock2.h>
#include <stdio.h>
#include <iostream.h>
#include <time.h>
#include <math.h>
#define RECVBUF_LEN 1500
#define UDPPORT 60000
#define FUNCODE_DIN 1
#define FUNCODE_AIN 3
#define FUNCODE_CLOCK 6
#define FUNCODE_DITAG 8
#define FUNCODE_AITAG 9
#define POSITION_OF_LEN 2//lenth in message header
#define POSITION_OF_NUM 5//num in body header
#define POSITION_OF_DATA 9//data in body
#define POSITION_OF_TYPE 4//data type in body
#define NUMBER_OF_HEADER 4 //header of a complete message
#define NUMBER_OF_MSGHEADER 5//header of body
#define MAX_MESSAGE_LEN 1035
#define NAMESIZE 20 //size of tag name
#define ERRORMSG_LEN 1000
#define MAXRRECNUM 1000
struct _RECVDATA{
unsigned char DINValue;
float AINValue;
int type;//8-di;9-ai
char TAG[NAMESIZE];
}gRecv_DIData[MAXRRECNUM],gRecv_AIData[MAXRRECNUM];
void InitSocket();
void CloseSocket();
void exit_udp();
void MsgRecv();
void MsgProcess();
void DINRead();
void AINRead();
void SGRead();
void ClockRead();
void TAGRead(_RECVDATA *recvdata);
bool CheckSum(unsigned char *ptr);
unsigned short GetSum(unsigned char *ptr, int nbytes);
void InitData();
void TAGTransfer(char *tag,unsigned char *recvtag);
void MyPrintf(char* des,BYTE * buf,int len);
BYTE gRecvBuf[RECVBUF_LEN];
SOCKADDR_IN gLocal_SockAddr,gRemote_SockAddr;
WSADATA gWsadata;
WORD gWord;
SOCKET gSocket;
unsigned char gStationAddr;
int gAINCount;
int gDINCount;
struct tm *gTM;//receive time
int gbodylen;//body lenth,total count = gbodylen + NUMBER_OF_HEADER + 2
char gErrorMsg[ERRORMSG_LEN];
int gRedFlag;//flag of main/backup
void main()
{
InitSocket();
InitData();
while(1)
{
if(gRedFlag == 1) MsgRecv();
else
{
sprintf(gErrorMsg,"I'M BACKUP,WAITING...");
printf("%s\n",gErrorMsg);
}
// _sleep(100);
}
CloseSocket();
}//endof main()
void InitData()
{
gbodylen = 0;
gStationAddr = 1;
gRedFlag = 0;
}
void InitSocket()
{
gWord=MAKEWORD(1,1);
int err;
err=WSAStartup(gWord,&gWsadata);
if(err!=0)
{
printf("link err!");
exit_udp();
}
if(LOBYTE(gWsadata.wVersion)!=1 || HIBYTE(gWsadata.wVersion!=1))
{
printf("ver err");
exit_udp();
}
//create socket
gSocket = socket (AF_INET,SOCK_DGRAM, 0);
if(gSocket<0){
printf("ERR--Crerat socket error\n");
exit_udp();
}
gLocal_SockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
gLocal_SockAddr.sin_family = AF_INET;
gLocal_SockAddr.sin_port = htons(UDPPORT);
if(bind(gSocket, (SOCKADDR *)&gLocal_SockAddr,sizeof(SOCKADDR))<0)
{
printf("ERR--bind error\n");
exit_udp();
}
}//end of init_sock
void CloseSocket()
{
closesocket(gSocket);
WSACleanup();
}
void MsgRecv()
{
fd_set readfds;
timeval timeout={5,0};//5s recv timeout
int len=sizeof(SOCKADDR);
int a = 0;
int out=0;
char tempbuf = '0';
unsigned long total_lenth=0;
while(1){
FD_ZERO(&readfds);
FD_SET(gSocket,&readfds);
out = select(0, &readfds, NULL, NULL, &timeout);//receive timeout judg
ioctlsocket(gSocket,FIONREAD,&total_lenth);//get receive buffer's actual lenth
if(out>0){//data coming
memset(gRecvBuf,NULL,RECVBUF_LEN);//clear receive buffer
a=recvfrom(gSocket,(char *)gRecvBuf,MAX_MESSAGE_LEN,0,(SOCKADDR*)&gRemote_SockAddr,&len);//receive header
if(a == SOCKET_ERROR && WSAGetLastError()!=10040)
{
sprintf(gErrorMsg,"ERR----HEADER ERROR CODE:%d",WSAGetLastError());
printf("%s\n",gErrorMsg);
return;
}
else if(gRecvBuf[0] != 0x68)
{
sprintf(gErrorMsg,"ERR----WRONG START BIT:%d",gRecvBuf[0]);
printf("%s\n",gErrorMsg);
return;
}
else if(gRecvBuf[1] != gStationAddr)
{
sprintf(gErrorMsg,"%s","ERR-----Wrong Station Address");
printf("%s\n",gErrorMsg);
return;
}
gbodylen = gRecvBuf[POSITION_OF_LEN] + gRecvBuf[POSITION_OF_LEN+1]*256;//body lenth in header
if(gbodylen>RECVBUF_LEN)
{
sprintf(gErrorMsg,"%s","ERR-----Not Enough Buffer");
printf("%s\n",gErrorMsg);
return;
}
if(CheckSum(gRecvBuf)) MsgProcess();
} //end of if(out>0)
else
{
printf("%ds recv timeout\n",timeout.tv_sec);
}
}//end_while
}
void MsgProcess()
{
switch(gRecvBuf[POSITION_OF_TYPE]){
case FUNCODE_DIN:
printf("recvDIN\n");
DINRead();
_sleep(20);
break;
case FUNCODE_AIN:
printf("recvAIN\n");
AINRead();
_sleep(20);
break;
case FUNCODE_CLOCK:
printf("recvClock\n");
ClockRead();
_sleep(5);
break;
case FUNCODE_DITAG:
printf("Recv DITag\n");
TAGRead(&gRecv_DIData[0]);
_sleep(50);
break;
case FUNCODE_AITAG:
printf("Recv AITag\n");
TAGRead(&gRecv_AIData[0]);
_sleep(50);
break;
default:
printf("ERR-----Recv unknown code of %d\n",gRecvBuf[POSITION_OF_TYPE]);
return;
break;
}
}
void DINRead()
{
unsigned char *p=NULL;
int num = gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
int i = 0;
unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256; /*start number of data in each message
for one kind of data was split into several messages*/
gDINCount = num + addr;
p = &gRecvBuf[POSITION_OF_DATA];
if(num+NUMBER_OF_MSGHEADER != gbodylen)//lenth conflict
{
sprintf(gErrorMsg,"%s","ERR-----Wrong DIN Message");
printf("%s\n",gErrorMsg);
return;
}
for(i=addr;i<num+addr;i++)
{
gRecv_DIData[i].DINValue = *p;
printf("DIN[%d] = %d tag = %s\n",i,gRecv_DIData[i].DINValue,gRecv_DIData[i].TAG);
p++;
}
}
void AINRead()
{
unsigned char *p=NULL;
int num = gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
int i = 0;
unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256;
gAINCount = num + addr * 4 ;//consider of multi-messages
p = &gRecvBuf[POSITION_OF_DATA];
if((unsigned short)(num*sizeof(float)+NUMBER_OF_MSGHEADER) != gbodylen)//lenth conflict
{
sprintf(gErrorMsg,"%s","ERR-----Wrong AIN Message");
printf("%s\n",gErrorMsg);
return;
}
for(i=addr;i<num+addr;i++)
{
memcpy(&gRecv_AIData[i].AINValue,p,sizeof(float));
printf("AIN[%d] = %f tag = %s\n",i,gRecv_AIData[i].AINValue,gRecv_AIData[i].TAG);
p+=sizeof(float);
}
}
void TAGRead(_RECVDATA *recvdata)
{
int i = 0;
unsigned char *p=NULL;
unsigned short num = 0;
unsigned char type = 0;
unsigned short addr = gRecvBuf[POSITION_OF_NUM+2]+gRecvBuf[POSITION_OF_NUM+3]*256;
type = gRecvBuf[POSITION_OF_TYPE];
num = gRecvBuf[POSITION_OF_NUM]+gRecvBuf[POSITION_OF_NUM+1]*256;
p = &gRecvBuf[POSITION_OF_DATA];
gAINCount = num + addr * 4 ;
printf("%d----num=%d---addr=%d---------\n",gAINCount,num,addr);
if((unsigned short)(num*4+NUMBER_OF_MSGHEADER) != gbodylen)//lenth conflict
{
printf("%d-----%d------\n",num*4+NUMBER_OF_MSGHEADER,gbodylen);
sprintf(gErrorMsg,"%s","ERR-----Wrong Tag Message");
printf("%s\n",gErrorMsg);
return;
}
memset(recvdata,NULL,sizeof(_RECVDATA)*MAXRRECNUM);//clear buffer before write
for(i=addr;i<num+addr;i++)
{
TAGTransfer(recvdata[i].TAG,p);
recvdata[i].type = type;
printf("TAG[%d] = %s\n",i,recvdata[i].TAG);
p+=4;
}
}
void ClockRead()
{
time_t tt=0;
unsigned char *p=NULL;
p = &gRecvBuf[5];
memcpy(&tt,p,sizeof(time_t));
gTM = localtime(&tt);
printf("RecvTime: %s",ctime(&tt));
// printf("RecvTime= %d",gTM->tm_year);
}
unsigned short GetSum(unsigned char *ptr, int nbytes)
{
int i;
unsigned short sum;
sum = 0;
for (i=0; i<nbytes; i++) sum += ptr[i];
return(sum);
}
bool CheckSum(unsigned char *ptr)
{
int msglenth=0;
unsigned short sum=0;
msglenth = gRecvBuf[POSITION_OF_LEN]+(gRecvBuf[POSITION_OF_LEN+1]*256)+NUMBER_OF_HEADER;
sum = GetSum(ptr,msglenth);
if((sum%256 == gRecvBuf[msglenth]) && (sum/256 == gRecvBuf[msglenth+1]))
return true;
else
{
printf("CheckSum==>%x %x\n",sum%256,sum/256);
return false;
}
}
/*----------tagname:4 BYTES(6b.6b.3b.4b.13b)-----------------
------------translate tagname to char---------------*/
void TAGTransfer(char *tag,unsigned char *recvtag)
{
unsigned char temp,temp2;
unsigned short temp3;
temp3=0;
temp=temp2=0;
memset(tag,NULL,NAMESIZE);
temp =(recvtag[0]>>2) & 0x3f;
sprintf(tag,"%d",temp);
temp = recvtag[0] & 0x03;
temp2 = recvtag[1] & 0xf0;
temp =( temp <<4 ) | (temp2 >>4) & 0x3f;
sprintf(tag,"%s.%d",tag,temp);
temp = (recvtag[1]>>1) & 0x07;
sprintf(tag,"%s.%d",tag,temp);
temp = recvtag[1] & 0x01;
temp2 = (recvtag[2]>>5) & 0x1f;
temp = (temp<<3) | temp2 & 0x0f;
sprintf(tag,"%s.%d",tag,temp);
temp3 = (recvtag[2] & 0x1f)<<8 | recvtag[3];
sprintf(tag,"%s.%d.",tag,temp3);
// printf("%x %x %x %x -- tag -- %s\n",recvtag[0],recvtag[1],recvtag[2],recvtag[3],tag);
}
void exit_udp()
{
CloseSocket();
exit(0);
}
void MyPrintf(char* des,BYTE * buf,int len)
{
printf("%s,len=%d------>",des,len);
for(int i=0;i<len;i++)
{
printf(" %x",buf[i]);
}
printf("\n");
}