int read_Packet(unsigned char* PacketBuf,const unsigned char* MeterID, const unsigned char* DataID)
{
int return_stat=0; // Function return status.
enum state_table
{
SEARCH_START, //search 0x68 of frame head
SEARCH_METERID, //search meterID {
PACKET_HEAD, //search 0x68 of data head
CTRL_CODE, //search control code
DATA_LEN, //receive data length
DATA_ID, //receive dataID
DATA_CONTENT, //receive datacontent
CHECK_SUM, //receive checksum
MACHINE_END, //end receiving
RECV_ERR, //error received from meter.
MACHINE_EXIT //done.
};
state_table state;
int Data_Len=0;
state = SEARCH_START;
// Loop until machine exit.
do
{
switch (state)
{
case SEARCH_START:
return_stat = Read_N_Byte(g_nSfd,PacketBuf,1);
if (return_stat <= 0)
{
return_stat=DLT_READ_ERR;
state=RECV_ERR;
}
else
{
if (PacketBuf[0] == STX)
state = SEARCH_METERID;
else
state = SEARCH_START;
}
break;
case SEARCH_METERID:
return_stat = Read_N_Byte(g_nSfd,PacketBuf+1,6);
if (return_stat <= 0)
{
return_stat=DLT_READ_ERR;
state=RECV_ERR;
}
else
{
if(strncmp((const char*)(PacketBuf+1),(const char *)MeterID,6)==0)
state=PACKET_HEAD;
else
{
return_stat=BAD_METERID;
state=RECV_ERR;
}
}
break;
case PACKET_HEAD:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+7,1);
if (return_stat <=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(*(PacketBuf+7)==STX)
state=CTRL_CODE;
else
{
return_stat=BAD_PACKETHEAD;
state=RECV_ERR;
}
}
break;
case CTRL_CODE :
return_stat =Read_N_Byte(g_nSfd,PacketBuf+8,1);
if (return_stat <=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(*(PacketBuf+8)==Normal)
state=DATA_LEN;
else
{
return_stat=BAD_CTRLCODE;
state=RECV_ERR;
}
}
break;
case DATA_LEN:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+9,1);
if(return_stat<=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(*(PacketBuf+9)>=2)
{
state=DATA_ID;
Data_Len=*(PacketBuf+9)-2;
}
else
{
return_stat=BAD_DATALEN;
state=RECV_ERR;
}
}
break;
case DATA_ID:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+10,2);
if(return_stat<=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(strncmp((const char*)(PacketBuf+10),(const char*)DataID,2)==0)
state=DATA_CONTENT;
else
{
return_stat=BAD_DATAID;
state=RECV_ERR;
}
}
break;
case DATA_CONTENT:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+12,Data_Len);
if(return_stat<=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else state=CHECK_SUM;
break;
case CHECK_SUM:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+12+Data_Len,1);
if(return_stat<=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(*(PacketBuf+12+Data_Len)==Cal_BCCSum(PacketBuf,12+Data_Len))
state = MACHINE_END;
else
{
return_stat=BAD_CHECKSUM;
state = RECV_ERR;
}
}
break;
case MACHINE_END:
return_stat =Read_N_Byte(g_nSfd,PacketBuf+13+Data_Len,1);
if(return_stat<=0)
{
return_stat=DLT_READ_ERR;
state = RECV_ERR;
}
else
{
if(*(PacketBuf+13+Data_Len)==ETX)
{
return_stat=READ_SUCC;
state=MACHINE_EXIT;
}
else
{
return_stat=BAD_ENDCODE;
state = RECV_ERR;
}
}
break;
case RECV_ERR :
// added at Apr 25,2002;
memset(PacketBuf,0x00,FRAME_REC_LEN_MAX);
// add end ;
state = MACHINE_EXIT;
break;
case MACHINE_EXIT:
default:break;
} // End of switch (state)
} while (state != MACHINE_EXIT);
return (return_stat);
}
int set_baud(int fd,speed_t baud)
{
struct termios oldtio;
tcgetattr(fd,&oldtio);
cfsetispeed(&oldtio,baud);
cfsetospeed(&oldtio,baud);
//added by johnny at Feb 24,2004;
//frame delay 500ms,unit 100 ms;
oldtio.c_cc[VTIME] = 5;
//add end
return(tcsetattr(fd,TCSANOW,&oldtio));
}