Files
HBshuiwuConcentrator/APP/protocol.c
2025-12-15 16:07:49 +08:00

2210 lines
57 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "protocol.h"
#include "Mem.h"
#include "General.h"
#include "addr.h"
#include "uart.h"
u8 DI901F[2] = {0x90, 0x1F};
u8 DI1F90[2] = {0x1F, 0x90};
u8 DIA017[2] = {0xA0, 0x17};
u8 cmd_read_woterMter[4] = {0x00, 0xFF, 0x01, 0x00};
u8 cmd_read_frozen[4] = {0x01, 0x01, 0x06, 0x05};
u8 cmd_E5E50000[4] = {0x00, 0x00, 0xE5, 0xE5};
u8 cmd_E5E50001[4] = {0x01, 0x00, 0xE5, 0xE5};
u8 cmd_FJWGData[4] = {0xFF, 0x00, 0x00, 0x70};
u8 cmd_OnOff_Key[4] = {0x03, 0x0E, 0x00, 0x04};
/*****************************************************************************
* Function : DLT645_07_addr_ack
* Description : none
* Input : u8 *buf
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170223
* Author : barry
* Modification: Created function
*****************************************************************************/
void DLT645_07_addr_ack(u8 *buf)
{
ST_645_read_ADDR *read_addr_ack = (ST_645_read_ADDR*)buf;
read_addr_ack->start68 = 0x68;
read_addr(read_addr_ack->addr);
read_addr_ack->end68 = 0x68;
read_addr_ack->ctrl = 0x93;
read_addr_ack->len = 0x06;
read_addr(read_addr_ack->id);
for (u8 i = 0; i < read_addr_ack->len; i++)
{
read_addr_ack->id[i] += 0x33;
}
read_addr_ack->cs = GetSum((u8*)read_addr_ack, sizeof(ST_645_read_ADDR) - 2);
read_addr_ack->end = 0x16;
}
void DLT645_07_watermetertype_ack(u8 *buf)
{
ST_645_head *read_mtype_ack = (ST_645_head*)buf;
read_mtype_ack->start68 = 0x68;
MemSet(read_mtype_ack->addr,0xBB,0x06);
read_mtype_ack->end68 = 0x68;
read_mtype_ack->ctrl = 0xF1;
read_mtype_ack->len = 0x03;
//read_maintain_time(&read_mtype_ack->DI[0],&read_mtype_ack->DI[1],&read_mtype_ack->DI[2]);
read_mtype_ack->DI[0] += 0x33;
read_mtype_ack->DI[1] += 0x33;
read_mtype_ack->DI[2] += 0x33;
read_mtype_ack->DI[3] = GetSum((u8*)read_mtype_ack, 13);
// read_mtype_ack->DI[4] = 0x16;
}
/*****************************************************************************
* Function : DLT645_97_1F_addr_ack
* Description : none
* Input : u8 *buf
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170223
* Author : barry
* Modification: Created function
*****************************************************************************/
void DLT645_97_1F_addr_ack(u8 *buf)
{
ST_645_read_ADDR99 *read_addr_ack99 = (ST_645_read_ADDR99*)buf;;
read_addr_ack99->start68 = 0x68;
read_addr_ack99->addr[0] = 0xA0;
read_addr_ack99->addr[1] = 0xA1;
read_addr_ack99->addr[2] = 0xA2;
read_addr_ack99->addr[3] = 0xA3;
read_addr_ack99->addr[4] = 0xA4;
read_addr_ack99->addr[5] = 0xA5;
read_addr_ack99->end68 = 0x68;
read_addr_ack99->ctrl = 0x9F;
read_addr_ack99->len = 0x08;
read_addr_ack99->defaultAF = 0xAF;
read_addr_ack99->defoult02 = 0x02;
MemSet(read_addr_ack99->id, 0xFF, 6);
for (u8 i = 0; i < read_addr_ack99->len; i++)
{
*(&read_addr_ack99->defaultAF + i) += 0x33;
}
read_addr_ack99->cs = GetSum((u8*)read_addr_ack99, sizeof(ST_645_read_ADDR99) - 2);
read_addr_ack99->end = 0x16;
}
/***************************************
HHCQ packet protocl
***************************************/
/*****************************************************************************
Prototype : calcrc_1byte
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 calcrc_1byte(u8 abyte)
{
int i;
u8 crc_1byte = 0;
for ( i = 0; i <8; i++)
{
if ((crc_1byte ^ abyte) & 0x01)
{
crc_1byte^= 0x18;
crc_1byte >>= 1;
crc_1byte |= 0x80;
}
else
{
crc_1byte >>= 1;
}
abyte >>=1;
}
return crc_1byte;
}
/*****************************************************************************
Prototype : calcrc_bytes CRC8
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 calcrc_bytes(u8 *p, u16 len)
{
u8 crc = 0;
while(len--)
{
crc = calcrc_1byte(crc^*p++);
}
return crc;
}
/*****************************************************************************
Prototype : code_HHCQ_buf
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void code_HHCQ_buf(u8 *buf, u8 len)
{
for (u8 i = 6; i < len - 2; i++)
{
buf[i] = buf[i - 1] ^ buf[i];
}
}
/*****************************************************************************
Prototype : decode_HHCQ_buf
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void decode_HHCQ_buf(u8* buf)
{
int i;
u8 tempbuf[50];
u8 len = buf[7]*256 + buf[8] + 11;
for ( i = 6; i < len - 2; i++)
{
tempbuf[i-6] = (buf[i - 1] ^ buf[i]);
}
for (i = 6; i < len - 2; i++)
{
buf[i] = tempbuf[i-6];
}
}
/*****************************************************************************
Prototype : check_645_packet
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 get_HHCQ_length(u8* buf)
{
u8 len = 0;
for (u8 i = 0; i < 50; i++)
{
if (buf[i] == 0x16)
{
len = i + 1;
break;
}
}
return len;
}
/*****************************************************************************
Prototype : transparent_tx
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 transparent_tx(u8 *buf, u8 inlen)
{
u8 buf2[50];
u8 index = 0;
//透明传输发送
buf2[index++] = 0x68;
for (u8 i = 1; i < inlen - 1; i++)
{
if ( (buf[i] == 0x68) || (buf[i] == 0x16) || (buf[i] == 0x7d))
{
buf2[index++] = 0x7D;
buf2[index++] = 0x20 ^ buf[i];
}
else
{
buf2[index++] = buf[i];
}
}
buf2[index++] = 0x16;
MemCpy(buf, buf2, index);
return index;
}
/*****************************************************************************
Prototype : check_HHQQ_protocol
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 check_HHQQ_protocol(u8 *buf, u8 length)
{
//1、找到最后一个 0x16,算最长长度
//2、将透明传输去掉
//3、从头找起 0x16,判断是否符合校验,然后再进行解密
#if 0
u8 tempBuf[100];
u8 index = 0;
u8 len;
for (u8 i = length - 1; i > sizeof(ST_HHCQ_head); i--)
{
if (buf[i] == 0x16)
{
len = i + 1;
break;
}
}
if (len < (sizeof(ST_HHCQ_head) + 1))
{
return 0;
}
tempBuf[index++] = buf[0];
for (u8 i = 1; i < len - 1; i ++)
{
if (buf[i] == 0x7d)
{
tempBuf[index++] = buf[i+1] ^ 0x20;
i++;
}
else
{
tempBuf[index++] = buf[i];
}
}
tempBuf[index++] = buf[len - 1];
for (u8 i = index - 1; i > sizeof(ST_HHCQ_head); i--)
{
if ( tempBuf[i - 1] == calcrc_bytes(tempBuf + 1, i - 2) )
{
for (u8 j = 0; j < i; j++)
{
if ( (j >= 6) && (j < i - 1) )
{
buf[j] = (tempBuf[j - 1] ^ tempBuf[j]);
}
else
{
buf[j] = tempBuf[j];
}
}
return i + 1;
}
}
return 0;
#endif
u8 temp_data;
u8 temp_start;
u8 len;
for (u8 i = length - 1; i > sizeof(ST_HHCQ_head); i--)
{
if (buf[i] == 0x16)
{
len = i + 1;
break;
}
}
if (len < (sizeof(ST_HHCQ_head) + 1))
{
return 0;
}
for (u8 i = 0; i < len; i ++)
{
if (buf[i] == 0x7d)
{
buf[i] = buf[i+1] ^ 0x20;
MemCpy(&buf[i+1], &buf[i+2], len - (i + 2));
len--;
}
}
for (u8 i = len - 1; i > sizeof(ST_HHCQ_head); i--)
{
if ( buf[i - 1] == calcrc_bytes(buf + 1, i - 2))
{
temp_start = buf[5];
for (u8 j = 6; j < i - 1; j++)
{
temp_data = buf[j];
buf[j] = (temp_start ^ buf[j]);
temp_start = temp_data;
}
return i+ 1;
}
}
return 0;
}
/*****************************************************************************
* Function : search_HHCQ_packet
* Description : none
* Input : u8* buf
u8 length
* Output : None
* Return : u8
* Others :
* Record
* 1.Date : 20170221
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 * search_HHCQ_packet(u8* buf, u8 length)
{
for (u16 i = 0; i < length; i++)
{
if (buf[i] == 0x68)
{
if ( check_HHQQ_protocol(&buf[i], length - i))
{
return &buf[i];
}
}
}
return NULL;
}
/***************************************
CTJ/188 packet protocl
***************************************/
/*****************************************************************************
Prototype : get_j188_length
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 get_j188_length(u8 *buf)
{
return buf[10] + 13;
}
/*****************************************************************************
Prototype : check_j188_protocol
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
bool check_j188_protocol(u8 *buf, u8 length)
{
u8 len = buf[10] + 13;
if (len > length)
{
return FALSE;
}
if ((buf[0] == 0x68) && (buf[len - 1] == 0x16))
{
if (GetSum(buf, len - 2) == buf[len - 2])
{
return TRUE;
}
}
return FALSE;
}
/*****************************************************************************
* Function : search_j188_packet
* Description : none
* Input : u8 *buf
u16 length
* Output : None
* Return : u8
* Others :
* Record
* 1.Date : 20170221
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 * search_j188_packet(u8 *buf, u16 length)
{
for (u16 i = 0; i < length; i++)
{
if (buf[i] == 0x68)
{
if (check_j188_protocol(&buf[i], length - i))
{
return &buf[i];
}
}
}
return NULL;
}
/*****************************************************************************
* Function : check_188_read_meter_packet
* Description : none
* Input : u8 *buf
u16 length
u8 *type
u8 *id
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170426
* Author : barry
* Modification: Created function
*****************************************************************************/
bool check_188_read_meter_packet(u8 *buf, u16 length, u8 *type, u8 *id, u8 *j188DI, u8 *j188SER)
{
ST_J188_read *ptr = (ST_J188_read *)buf;
if (check_j188_protocol(buf, length))
{
if ( cmp_datas(ptr->head.DI, DI901F, 2) || cmp_datas(ptr->head.DI, DI1F90, 2))
{
*type = ptr->head.type;
*j188SER = ptr->SER;
MemCpy(id, ptr->head.id, 7);
MemCpy(j188DI, ptr->head.DI, 2);
return TRUE;
}
}
return FALSE;
}
/***************************************
645 packet protocl
***************************************/
/*****************************************************************************
* Function : get_645_packet_length
* Description : none
* Input : u8* buf
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170221
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 get_645_packet_length(u8* buf)
{
return buf[9] + 12;
}
bool check_645_protocol(u8 *buf, u8 length)
{
u8 len = buf[9] + 12;
if (len > length)
{
return FALSE;
}
if ( (buf[0] == 0x68) && (buf[7] == 0x68) && (buf[buf[9] + 11] == 0x16))
{
if (GetSum(buf, len - 2) == buf[len - 2])
{
return TRUE;
}
}
return FALSE;
}
u8 * search_645_packet(u8 *buf, u16 length)
{
for (u16 i = 0; i < length; i++)
{
if ( (buf[i] == 0x68) && check_645_protocol(&buf[i], length - i) )
{
return &buf[i];
}
}
return NULL;
}
/*****************************************************************************
Prototype : check_yzsj_ack_protocol
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
bool check_yzsj_ack_protocol(u8 *buf, u16 len)
{
if (len < 5)
{
return FALSE;
}
if ( (buf[0] == 0x68) && (buf[4] == GetSum(&buf[1], 3)) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
* Function : search_yzsj_packet
* Description : none
* Input : u8 *buf
u16 length
* Output : None
* Return : u8
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 * search_yzsj_packet(u8 *buf, u16 length)
{
for (u16 i = 0; i < length; i++)
{
if ( (buf[i] == 0x68) && check_yzsj_ack_protocol(&buf[i], length - i) )
{
return &buf[i];
}
}
return NULL;
}
/*****************************************************************************
* Function : create_read_J188_Meter
* Description : none
* Input : u8 *id
bool j901f
u8 *outBuf
u16 *outLen
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170223
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_J188_Meter(u8 type, u8 *id, bool j901f, u8 *outBuf, u16 *outLen)
{
ST_J188_read * j188_read_ptr = (ST_J188_read*)outBuf;
j188_read_ptr->head.start68 = 0x68;
if (type == 0)
{
j188_read_ptr->head.type = 0x10;
}
else if (type == 0x70)
{
j188_read_ptr->head.type = 0x30;
}
else
{
j188_read_ptr->head.type = type;
}
MemCpy(j188_read_ptr->head.id, id, 7);
j188_read_ptr->head.ctrl = 0x01;
j188_read_ptr->head.len = 0x03;
j188_read_ptr->head.DI[0] = (j901f) ? 0x90:0x1F;
j188_read_ptr->head.DI[1] = (j901f) ? 0x1F:0x90;
j188_read_ptr->SER = 0x00;
j188_read_ptr->cs = GetSum((u8*)j188_read_ptr, *((u8*)j188_read_ptr + 10) + 11);
j188_read_ptr->end = 0x16;
*outLen = j188_read_ptr->head.len + 13;
}
/*****************************************************************************
* Function : create_read_HHCQ_Meter
* Description : none
* Input : u8 *id
u8 *outBuf
u16 *outLen
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_HHCQ_Meter(u8 *id, u8 *outBuf, u16 *outLen)
{
u8 tempAddrBuf[7];
ST_HHCQ_read * hhcq_read_ptr = (ST_HHCQ_read * )outBuf;
u32 seed = GetCRC16(id, 7);
for (u8 i = 0; i < 7; i++)
{
tempAddrBuf[i] = id[6-i];
}
srand(seed);
hhcq_read_ptr->start68 = 0x68;
hhcq_read_ptr->MSA = 0x00;
hhcq_read_ptr->SSA = 0xfa;
hhcq_read_ptr->WMA = 0xfa;
hhcq_read_ptr->type = 0x10;
hhcq_read_ptr->key = rand()%255 + 1;
hhcq_read_ptr->ctrl = 0x2e;
hhcq_read_ptr->lenH = 0x00;
hhcq_read_ptr->lenL = 0x04;
MemCpy(hhcq_read_ptr->data, tempAddrBuf + 3, 4);
hhcq_read_ptr->crc8 = 0x00;
hhcq_read_ptr->end16 = 0x16;
code_HHCQ_buf((u8*)hhcq_read_ptr, sizeof(ST_HHCQ_read));
hhcq_read_ptr->crc8 = calcrc_bytes((u8*)hhcq_read_ptr + 1, sizeof(ST_HHCQ_read) - 3);
*outLen = transparent_tx((u8*)hhcq_read_ptr, sizeof(ST_HHCQ_read));
}
/*****************************************************************************
* Function : create_read_CS485_Meter
* Description : none
* Input : u8* id
u8 *outBuf
u16 *outLen
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_CS485_Meter(u8* id, u8 *outBuf, u16 *outLen)
{
u16 crc;
st_CS485_read * read_mter_485_ptr = (st_CS485_read *)outBuf;
read_mter_485_ptr->head.start68 = 0x68;
read_mter_485_ptr->head.default80 = 0x80;
MemSet(read_mter_485_ptr->head.center_addr, 0xFF, 6);
read_mter_485_ptr->head.ctrl = 0x0c;
read_mter_485_ptr->head.dataLen[0] = 0x0c;
read_mter_485_ptr->head.dataLen[1] = 0x00;
read_mter_485_ptr->head.default70 = 0x70;
read_mter_485_ptr->head.DI[0] = 0x20;
read_mter_485_ptr->head.DI[1] = 0x0c;
read_mter_485_ptr->meterCount = 0X01;
MemCpy(read_mter_485_ptr->meterID, id, 5);
read_mter_485_ptr->day = 0xFF;
read_mter_485_ptr->month = 0xFF;
read_mter_485_ptr->year = 0xFF;
crc = MODBUS_CRC16((u8*)read_mter_485_ptr, sizeof(st_CS485_read) -3);
read_mter_485_ptr->crc16[0] = (u8)(crc & 0xFF);
read_mter_485_ptr->crc16[1] = (u8)((crc >> 8) & 0xFF);
read_mter_485_ptr->end16 = 0x16;
*outLen = sizeof(st_CS485_read);
}
/*****************************************************************************
* Function : create_read_NJSM485_Meter
* Description : none
* Input : u8 *id
u8 *outBuf
u16 *outLen
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_NJSM485_Meter( u8 *id, u8 *outBuf, u16 *outLen)
{
u8 tempAddrBuf[7];
st_NJSM485_read * read_mter_485_ptr = (st_NJSM485_read *)outBuf;
for (u8 i = 0; i < 7; i++)
{
tempAddrBuf[i] = id[6-i] ;
}
read_mter_485_ptr->startEB = 0xEB;
read_mter_485_ptr->cmd80 = 0x80;
MemCpy(read_mter_485_ptr->id, &tempAddrBuf[3], 4);
read_mter_485_ptr->len = 0x00;
read_mter_485_ptr->cs = GetSum((u8*)read_mter_485_ptr, sizeof(st_NJSM485_read) -1);
*outLen = sizeof(st_NJSM485_read);
}
/*****************************************************************************
* Function : create_read_YZSJ_Meter
* Description : none
* Input : u8 *id
u8 *outBuf
u16 *outLen
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_YZSJ_Meter( u8 *id, u8 *outBuf, u16 *outLen)
{
ST_yzsj_read * yzsj_read_ptr = (ST_yzsj_read*)outBuf;
yzsj_read_ptr->start68 = 0x68;
MemCpy(yzsj_read_ptr->id, id, 6);
yzsj_read_ptr->id[5] = 0x00;
yzsj_read_ptr->end68 = 0x68;
yzsj_read_ptr->ctrl = 0x01;
yzsj_read_ptr->len = 0x02;
yzsj_read_ptr->DI0 = 0x10 + 0x33;
yzsj_read_ptr->DI1 = 0x90 + 0x33;
yzsj_read_ptr->cs = GetSum((u8*)yzsj_read_ptr, yzsj_read_ptr->len + 10);
yzsj_read_ptr->end = 0x16;
*outLen = yzsj_read_ptr->len + 12;
}
/*****************************************************************************
* Function : create_read_HZJD_Meter
* Description : none
* Input : u8 *id
u8 *outBuf
u16 *outLen
* Output : None
* Return : void
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_HZJD_Meter(u8 *id, u8 *outBuf, u16 *outLen)
{
st_HZJD_read * read_ptr = (st_HZJD_read *)outBuf;
read_ptr->start68 = 0x68;
MemCpy(read_ptr->id, id, 6);
read_ptr->end68 = 0x68;
read_ptr->ctrl = 0x01;
read_ptr->len = 0x02;
read_ptr->DI[0] = 0x43;
read_ptr->DI[1] = 0xC3;
read_ptr->cs = GetSum((u8*)read_ptr, sizeof(st_HZJD_read) -2);
read_ptr->end16 = 0x16;
*outLen = sizeof(st_HZJD_read);
}
/*****************************************************************************
* Function : create_read_HYgas_Meter
* Description : none
* Input : u8 *id
u8 *outBuf
u16 *outLen
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_read_HYgas_Meter(u8 *id, u8 *outBuf, u16 *outLen)
{
/*
u8 tempAddrBuf[7];
for (u8 i = 0; i < 7; i++)
{
tempAddrBuf[i] = id[6-i];
}
get_ctrl_meter_buf(CMD_READ_GAS_METER, tempAddrBuf, outBuf);
*outLen = sizeof(st_ctrl_meter_packet);
return NEED_J188;
*/
}
/*****************************************************************************
* Function : J188_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *inID
u8 *out_datas
u8 *out_status
* Output : None
* Return : bool
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool J188_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
ST_J188_read_woter_ack *ptr = (ST_J188_read_woter_ack*)search_j188_packet(inbuf, len);
if (ptr == NULL)
{
return FALSE;
}
else
{
if (cmp_datas(inID, ptr->head.id, 7) == FALSE)
{
return FALSE;
}
if ((ptr->head.ctrl & 0xC0) == 0xC0) //下行帧,或者回复的异常帧
{
return FALSE;
}
if ((cmp_datas(ptr->head.DI, DI901F, 2) == FALSE) && (cmp_datas(ptr->head.DI, DI1F90, 2) == FALSE))
{
return FALSE;
}
out_datas[0] = ptr->data_block.current_sum[4];
//modify by jerry
#ifdef COMMON_VER
MemCpy(out_datas + 1, ptr->data_block.current_sum, 4);
#endif
#ifdef AMT_VER
MemCpy(out_datas + 1, &(ptr->data_block.current_sum[1]), 4);
#endif
MemCpy(out_status, ptr->data_block.status, 2);
return TRUE;
}
}
/*****************************************************************************
* Function : HHCQ_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *inID
u8 *out_datas
u8 *out_status
* Output : None
* Return : bool
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool HHCQ_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
ST_HHCQ_read_woter_ack * ack_ptr = (ST_HHCQ_read_woter_ack*)search_HHCQ_packet(inbuf, len);
if (ack_ptr == NULL)
{
return FALSE;
}
if (ack_ptr->ctrl != 0xAE)
{
return FALSE;
}
for (u8 i = 0; i < 4; i++)
{
if (ack_ptr->id[i] != inID[3-i])
{
return FALSE;
}
}
out_datas[0] = 0x2C;
out_datas[1] = 0x00;
out_datas[2] = ack_ptr->data[3];
out_datas[3] = ack_ptr->data[2];
out_datas[4] = ack_ptr->data[1];
out_status[0] = ((ack_ptr->status & 0x1f) != 0)?0x03:((ack_ptr->status >> 5) &0x01);
out_status[1] = 0x01;
return TRUE;
}
/*****************************************************************************
* Function : CS485_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *inID
u8 *out_datas
u8 *out_status
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool CS485_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
st_CS485_ack_ok * ack_ok_ptr = (st_CS485_ack_ok *)inbuf;
u8 errData[4] = {0xEE,0xEE,0xEE,0xEE};
if (ack_ok_ptr->head.ctrl != 0x8c)
{
return FALSE;
}
if (!cmp_datas(ack_ok_ptr->meterID, inID, 5))
{
return FALSE;
}
if (cmp_datas(ack_ok_ptr->meter_data, errData, 4))
{
return FALSE;
}
out_datas[0] = 0x2c;
MemCpy(out_datas + 1, ack_ok_ptr->meter_data, 4);
MemCpy(out_status, ack_ok_ptr->status, 2);
return TRUE;
}
/*****************************************************************************
* Function : NJSM485_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *inID
u8 *out_datas
u8 *out_status
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool NJSM485_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
st_NJSM485_ack * ack_ok_ptr = (st_NJSM485_ack *)inbuf;
if (ack_ok_ptr->len0F != 0x0F)
{
return FALSE;
}
if (ack_ok_ptr->cmd90 != 0x90)
{
return FALSE;
}
if (ack_ok_ptr->cs != GetSum((u8*)ack_ok_ptr, sizeof(st_NJSM485_ack) - 1))
{
return FALSE;
}
for (u8 i = 0; i < 4; i++)
{
if (ack_ok_ptr->id[i] != inID[3-i])
{
return FALSE;
}
}
out_datas[0] = 0x2c;
out_datas[1] = ack_ok_ptr->data[1];
out_datas[2] = ack_ok_ptr->data[2];
out_datas[3] = ack_ok_ptr->data[3];
out_datas[4] = 0x00;
out_status[0] = 0x00;
out_status[1] = 0x00;
return TRUE;
}
/*****************************************************************************
* Function : YZSJ_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *out_datas
u8 *out_status
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool YZSJ_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
u8 * ptr = search_yzsj_packet(inbuf, len);
if (ptr != NULL)
{
out_datas[0] = 0x2C;
out_datas[1] = 0x00;
out_datas[2] = ptr[1];
out_datas[3] = ptr[2];
out_datas[4] = ptr[3] & 0x0F;
out_status[0] = ((ptr[3] & 0x04)==0) ? 0:1;
out_status[1] = 0x01;
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
* Function : HZJD_ackPacket_analyse
* Description : none
* Input : u8 *inbuf
u16 len
u8 *inID
u8 *out_datas
u8 *out_status
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170224
* Author : barry
* Modification: Created function
*****************************************************************************/
bool HZJD_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status)
{
st_HZJD_ack * ack_ok_ptr = (st_HZJD_ack *)inbuf;
u8 JDDI[] = {0x10, 0x90};
if (ack_ok_ptr->ctrl != 0x81)
{
return FALSE;
}
if (ack_ok_ptr->len != 0x06)
{
return FALSE;
}
if (!cmp_datas(ack_ok_ptr->id, inID, 6))
{
return FALSE;
}
for (u8 i = 0; i < ack_ok_ptr->len; i++)
{
*(ack_ok_ptr->DI + i) -= 0x33;
}
if (!cmp_datas(ack_ok_ptr->DI, JDDI,2))
{
return FALSE;
}
out_datas[0] = 0x2c;
MemCpy(&out_datas[1], ack_ok_ptr->data, 4);
out_status[0] = 0x00;
out_status[1] = 0x00;
return TRUE;
}
/*****************************************************************************
* Function : COM_uplinkPacket_create
* Description : none
* Input : st_params * ptr
u8* outBuf
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170228
* Author : barry
* Modification: Created function
*****************************************************************************/
void COM_uplinkPacket_create(st_params * ptr, u8* outBuf)
{
ST_645_read_worter_ack * woter_ack_ptr = (ST_645_read_worter_ack *)outBuf;
woter_ack_ptr->start68 = 0x68;
read_addr(woter_ack_ptr->id);
woter_ack_ptr->end68 = 0x68;
woter_ack_ptr->ctrl = 0x91;
woter_ack_ptr->len = sizeof(ST_645_read_worter_ack) - 12;
MemCpy(woter_ack_ptr->DI, ptr->plc_DI, 4);
MemSet(woter_ack_ptr->data_block.saved5, 0xEE, 5);
woter_ack_ptr->data_block.type_data = (ptr->meter_type == 0)?0x10:ptr->meter_type;
MemCpy(woter_ack_ptr->data_block.current_sum , ptr->data, 5);
//woter_ack_ptr->data_block.current_sum[0] = 0x2c;
MemCpy(woter_ack_ptr->data_block.day_sum , ptr->data, 5);
// woter_ack_ptr->data_block.day_sum[0] = 0x2c;
// MemSet(woter_ack_ptr->data_block.day_sum + 1, 0, 4);
MemSet(woter_ack_ptr->data_block.kpa, 0xEE, 2);
MemSet(woter_ack_ptr->data_block.current, 0xEE, 3);
MemSet(woter_ack_ptr->data_block.saved16, 0xEE, 16);
MemSet(woter_ack_ptr->data_block.time_sum, 0xEE,3);
MemSet(woter_ack_ptr->data_block.current_time, 0, 7);
MemCpy(woter_ack_ptr->data_block.status, ptr->status, 2);
woter_ack_ptr->type = ptr->meter_type;
MemCpy(woter_ack_ptr->meter_id, ptr->meter_addr, 7);
for (u8 i = 0; i < woter_ack_ptr->len; i++)
{
*(woter_ack_ptr->DI + i) += 0x33;
}
woter_ack_ptr->cs = GetSum((u8*)woter_ack_ptr, sizeof(ST_645_read_worter_ack) - 2); //CS
woter_ack_ptr->end = 0x16;
}
/*****************************************************************************
* Function : COM_frozen_uplinkPacket_create
* Description : none
* Input : st_params * ptr
u8* outBuf
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170228
* Author : barry
* Modification: Created function
*****************************************************************************/
void COM_frozen_uplinkPacket_create(st_params * ptr, u8* outBuf)
{
ST_645_read_frozen_woter_ack * ack_ptr = (ST_645_read_frozen_woter_ack *)outBuf;
ack_ptr->start68 = 0x68;
read_addr(ack_ptr->id);
ack_ptr->end68 = 0x68;
ack_ptr->ctrl = 0x91;
ack_ptr->len = sizeof(ST_645_read_frozen_woter_ack) -12;
MemCpy(ack_ptr->DI, ptr->plc_DI, 4);
MemSet(ack_ptr->data_block.frozen_time_flag , 0xEE, 3);
MemSet(ack_ptr->data_block.teminal_read_time, 0xEE, 5);
ack_ptr->data_block.meter_type = (ptr->meter_type == 0)?0x10:ptr->meter_type;
MemCpy(ack_ptr->data_block.current_sum , ptr->data, 5);
// ack_ptr->data_block.check_day_sum[0] = 0x2c;
// MemSet(ack_ptr->data_block.check_day_sum + 1, 0, 4);
MemCpy(ack_ptr->data_block.check_day_sum , ptr->data, 5);
MemSet(ack_ptr->data_block.saved , 0xEE, 21);
MemSet(ack_ptr->data_block.time_sum , 0xEE, 3);
MemSet(ack_ptr->data_block.current_time, 0x00,7);
MemCpy(ack_ptr->data_block.status, ptr->status, 2);
ack_ptr->type = ptr->meter_type;
MemCpy(ack_ptr->meter_id, ptr->meter_addr, 7);
for (u8 i = 0; i < ack_ptr->len; i++)
{
*(ack_ptr->DI + i) += 0x33;
}
ack_ptr->cs = GetSum((u8*)ack_ptr, sizeof(ST_645_read_frozen_woter_ack) - 2);
ack_ptr->end = 0x16;
}
/*****************************************************************************
* Function : WHSF_uplinkPacket_create
* Description : none
* Input : st_params * ptr
u8* outBuf
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170228
* Author : barry
* Modification: Created function
*****************************************************************************/
void WHSF_uplinkPacket_create(st_params * ptr, u8* outBuf)
{
ST_645_SFDX_read_ack * stand645_ack_ptr = (ST_645_SFDX_read_ack *)outBuf;
stand645_ack_ptr->start68 = 0x68;
MemCpy(stand645_ack_ptr->addr, ptr->meter_addr, 6);
stand645_ack_ptr->end68 = 0x68;
stand645_ack_ptr->ctrl = 0x91;
stand645_ack_ptr->len = 0x17;
MemCpy(stand645_ack_ptr->DI, ptr->plc_DI, 2);
stand645_ack_ptr->MSB = 0x00;
stand645_ack_ptr->type = 0x10;
MemCpy(stand645_ack_ptr->current_sum, ptr->data, 5);
MemSet(stand645_ack_ptr->day_sum, 0, 4);
stand645_ack_ptr->day_sum[4] = 0x2c;
MemSet(stand645_ack_ptr->current_time, 0, 7);
MemCpy(stand645_ack_ptr->status, ptr->status, 2);
for (u8 i = 0; i < stand645_ack_ptr->len; i++)
{
*(stand645_ack_ptr->DI + i) += 0x33;
}
stand645_ack_ptr->cs = GetSum((u8*)stand645_ack_ptr, sizeof(ST_645_SFDX_read_ack) -2);
stand645_ack_ptr->end = 0x16;
}
/*****************************************************************************
* Function : E5E5_uplinkPacket_create
* Description : none
* Input : st_params * ptr
u8* outBuf
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170228
* Author : barry
* Modification: Created function
*****************************************************************************/
void E5E50001_uplinkPacket_create(st_params * ptr, u8* outBuf)
{
ST_E5E50001_ack *ack_ptr = (ST_E5E50001_ack*)outBuf;
ack_ptr->start68 = 0x68;
read_addr(ack_ptr->id);
ack_ptr->end68 = 0x68;
ack_ptr->ctrl = 0x91;
ack_ptr->len = sizeof(ST_E5E50001_ack) -12;
MemCpy(ack_ptr->DI, cmd_E5E50001, 4);
ack_ptr->DI[0] += 0x33;
ack_ptr->DI[1] += 0x33;
ack_ptr->DI[2] += 0x33;
ack_ptr->DI[3] += 0x33;
ack_ptr->packet188.head.start68 = 0x68;
ack_ptr->packet188.head.type = ptr->meter_type;
MemCpy(ack_ptr->packet188.head.id, ptr->meter_addr, 7);
ack_ptr->packet188.head.ctrl = 0x81;
ack_ptr->packet188.head.len = sizeof(ST_woter_data_block) + 3;
MemCpy(ack_ptr->packet188.head.DI, ptr->j188DI, 2);
ack_ptr->packet188.SER = ptr->j188SER;
MemCpy(ack_ptr->packet188.data_block.current_sum, ptr->data + 1, 4);
ack_ptr->packet188.data_block.current_sum[4] = 0x2c;
MemSet(ack_ptr->packet188.data_block.day_sum, 0, 5);
ack_ptr->packet188.data_block.day_sum[4] = 0x2c;
MemSet(ack_ptr->packet188.data_block.current_time, 0, 7);
MemCpy(ack_ptr->packet188.data_block.status, ptr->status, 2);
ack_ptr->packet188.cs = GetSum(&(ack_ptr->packet188.head.start68), sizeof(ST_J188_read_woter_ack) -2);
ack_ptr->packet188.end = 0x16;
ack_ptr->cs = GetSum(outBuf, sizeof(ST_E5E50001_ack) - 2);
ack_ptr->end16 = 0x16;
}
void E5E50000_uplinkPacket_create(st_params * ptr, u8 *inbuf, u8 inLen, u8* outBuf)
{
ST_E5E50000_ack *ack_ptr = (ST_E5E50000_ack *)outBuf;
u8 * pos_ptr = NULL;
ack_ptr->start68 = 0x68;
read_addr(ack_ptr->id);
ack_ptr->end68 = 0x68;
ack_ptr->ctrl = 0x91;
ack_ptr->len = inLen + 4;
ack_ptr->DI[0] = 0x33;
ack_ptr->DI[1] = 0x33;
ack_ptr->DI[2] = 0x18;
ack_ptr->DI[3] = 0x18;
pos_ptr = outBuf + sizeof(ST_E5E50000_ack);
MemCpy(pos_ptr, inbuf, inLen);
pos_ptr += inLen;
*pos_ptr++ = GetSum(outBuf, ack_ptr->len + 10);
*pos_ptr = 0x16;
}
//以下协议函数适应福建多表合一规约协议
//创建福建规约的读取水汽表常用数据块数据帧,该帧主要针对操作水表采集器
//u8* Pstr,数据帧输出指针
//u8* len, 创建的数据帧长度
//u8* Addr 水表地址
void CreatFuJian_Protocol_ReadWaterGasMeterDataBlockFrame( u8* str,u8* len,u8* Addr)
{
LPST_FUJIAN_SDPROTOCOL_READWGDATA Pstr = (LPST_FUJIAN_SDPROTOCOL_READWGDATA)str;
Pstr->FIXED_FE1 = 0xFE;
Pstr->FIXED_FE2 = 0xFE;
Pstr->FIXED_FE3 = 0xFE;
Pstr->StartSymbol = 0x68;
Pstr->MeterType = 0xF0;//F0H 无线 GPRS F1H 物联网大表 F2H:抄表站 F3H:物联网小表
MemSet(Pstr->GPRSAddr,0xAA,0x07);
Pstr->ControlWord = 0x04;
Pstr->FrameSum = 0x01;
Pstr->FrameSn = 0x01;
Pstr->FrameLength = 0x0A;
//Data Area
Pstr->DataFlag[0] = 0x37;
Pstr->DataFlag[1] = 0x10;
Pstr->DataFlag[2] = 0x01;
MemCpy(Pstr->MAddr,Addr,0x06);
Pstr->MAddr[4] = 0x01;//厂商代码
Pstr->MAddr[5] = 0x07;
Pstr->MAddr[6] = 0x00;
Pstr->CS = GetSum(&Pstr->StartSymbol,23);
Pstr->ENDSymbol = 0x16;
*len = sizeof(ST_FUJIAN_SDPROTOCOL_READWGDATA);
//
}
//检查福建规约的读取水汽表常用数据块数据帧失败返回NULL成功返回帧首地址
//u8* Pstr,数据帧传入指针
//u8* len, 数据帧长度
//u8* Addr :当前抄读的水表地址
//返回数据指针
u8* CheckFuJian_Protocol_ReadWaterGasMeterDataBlockAckFrame( u8* str,u8 len,u8* Addr)
{
LPST_FUJIAN_SDPROTOCOL_READWGACKDATA Pstr = NULL;
for(u8 index = 0x00; index < len; index ++)
{
if(str[index] == 0x68)
{
Pstr = (LPST_FUJIAN_SDPROTOCOL_READWGACKDATA)&str[index] ;
if( (Pstr->MeterType == 0xF0) && (Pstr->ControlWord == 0x84) && ( Pstr->DataFlag[0] == 0x37) && (Pstr->DataFlag[1] == 0x10) && (MemCmp(Addr,Pstr->MAddr,0x04) == 0x00) && (Pstr->CS == GetSum(&Pstr->StartSymbol,sizeof(ST_FUJIAN_SDPROTOCOL_READWGACKDATA) - 0x02)) )
{
return Pstr->DataBuff;
}
}
}
return NULL;
//
}
//创建福建规约的读取水汽表常用数据块数据帧,该帧主要针对操作水表采集器,该协议主要针对福建协议版本的J188标准协议
//u8* Pstr,数据帧输出指针
//u8* len, 创建的数据帧长度
//u8* Addr 水表地址
void CreatFuJian_Protocol_ReadXYWaterMeterDataBlockFrame( u8* str,u8* len,u8* Addr)
{
str[0] = 0xFE;
str[1] = 0xFE;
PLST_J188_read Pstr = (PLST_J188_read)(str+2);
Pstr->head.start68 = 0x68;
Pstr->head.type = 0x10;
MemCpy(Pstr->head.id,Addr,0x06);
Pstr->head.id[4] = 0x00;
Pstr->head.id[5] = 0x00;
Pstr->head.id[6] = 0x00;
Pstr->head.ctrl = 0x01;
Pstr->head.len = 0x03;
Pstr->head.DI[0] = 0x90;
Pstr->head.DI[1] = 0x1F;
Pstr->SER = 0x00;
Pstr->cs = GetSum(&Pstr->head.start68,sizeof(ST_J188_read) - 0x02);
Pstr->end = 0x16;
*len = sizeof(ST_J188_read) + 0x02;
//
}
//检查福建规约的读取水汽表常用数据块数据帧失败返回NULL成功返回帧首地址,针对福建版本增补协议以及地址规则J188协议
//u8* Pstr,数据帧传入指针
//u8* len, 数据帧长度
//u8* Addr :当前抄读的水表地址
//返回数据指针
u8* CheckFuJian_Protocol_ReadXYWaterMeterDataBlockAckFrame( u8* str,u8 len,u8* Addr)
{
PLST_XYJ188_read_woter_ack Pstr = NULL;
for(u8 index = 0x00; index < len; index ++)
{
if(str[index] == 0x68)
{
Pstr = (PLST_XYJ188_read_woter_ack)&str[index] ;
if( (MemCmp(Addr,Pstr->head.id,0x04) == 0x00) && (Pstr->head.DI[0] == 0x90) && (Pstr->head.DI[1] == 0x1F) && (Pstr->head.ctrl == 0x81) && ( Pstr->cs == GetSum(&Pstr->head.start68,sizeof(ST_XYJ188_read_woter_ack) - 0x02)) )
{
return &Pstr->Data[0];
}
}
}
return NULL;
//
}
u8 HexConvertBCD( u8 hex)
{
return ( ((hex/10)*16) + (hex%10) ) ;
}
//FE FE FE FE 68 11 90 78 56 34 12 68 91 1B FF 00 00 70 40 78 56 34 12 00 00 01 04 16 40 78 56 34 12 01 00 09 02 04 16 00 00 CS 16
//u8* Data水汽表数据BCD码格式123456.78 m3
//u8* Ftime:当前时间55 55 09 15 06 17 week
void CreatFuJian_Protocol_WaterGasMeter645DataACKFrame( u8* Pstr,u8* len,u8* Addr,u8* Data,u8* Ftime)
{
#define CURRENT_SAIDA_WATERMWTER_FACTOR (100)
u8 index = 0x00;
// u32 TempData = Data[0];
// TempData <<= 0x08;
//
// TempData |= Data[1];
// TempData <<= 0x08;
//
// TempData |= Data[2];
// TempData <<= 0x08;
//
// TempData |= Data[3];
//
// u32 TempLoop = 0x00;
//
//
// u8 BCD_Decimal = 0x00,BCD_Integer_L = 0x00,BCD_Integer_M = 0x00,BCD_Integer_H = 0x00;
//
// BCD_Decimal = HexConvertBCD(TempData%CURRENT_SAIDA_WATERMWTER_FACTOR); //对100取余数得到水表读数小数部分
//
// TempLoop = TempData/CURRENT_SAIDA_WATERMWTER_FACTOR;
// BCD_Integer_L = HexConvertBCD(TempLoop%CURRENT_SAIDA_WATERMWTER_FACTOR); //继续对对100取余数得到水表个位十分位
//
// TempLoop = TempLoop/CURRENT_SAIDA_WATERMWTER_FACTOR;
// BCD_Integer_M = HexConvertBCD(TempLoop%CURRENT_SAIDA_WATERMWTER_FACTOR); //继续对对100取余数得到水表百分位千分位
//
// TempLoop = TempLoop/CURRENT_SAIDA_WATERMWTER_FACTOR;
// BCD_Integer_H = HexConvertBCD(TempLoop%CURRENT_SAIDA_WATERMWTER_FACTOR); //继续对对100取余数得到水表万分位十万分位
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0x68;
MemCpy(Pstr + index, Addr , 0x06);
index += 0x06;
Pstr[index ++] = 0x68;
Pstr[index ++] = 0x91;
Pstr[index ++] = 0x1B;
//DI0 - DI3
Pstr[index ++] = 0xFF;
Pstr[index ++] = 0x00;
Pstr[index ++] = 0x00;
Pstr[index ++] = 0x70;
Pstr[index ++] = 0x40;
Pstr[index ++] = Data[0];
Pstr[index ++] = Data[1];
Pstr[index ++] = Data[2];
Pstr[index ++] = Data[3];
if(Ftime == NULL)
{
MemSet(Pstr + index, 0x99 , 16);
index += 16;
}
else
{
MemSet(Pstr + index, 0x99 , 10);
index += 10;
MemCpy(Pstr + index, Ftime , 0x06);
index += 0x06;
// Pstr[index ++] = Ftime[5];
// Pstr[index ++] = Ftime[4];
// Pstr[index ++] = Ftime[3];
// Pstr[index ++] = Ftime[2];
// Pstr[index ++] = Ftime[1];
// Pstr[index ++] = Ftime[0];
}
//ST
Pstr[index ++] = 00;
Pstr[index ++] = 00;
for(u8 loop = 0x00; loop < 0x1B; loop ++)
{
Pstr[loop+13] += 0x33;
}
Pstr[index] = GetSum(Pstr + 3,index - 3);
index += 1;
Pstr[index ++] = 0x16;
* len = index;
}
//FE FE FE FE 68 11 90 78 56 34 12 68 91 1B FF 00 00 70 40 78 56 34 12 00 00 01 04 16 40 78 56 34 12 01 00 09 02 04 16 00 00 CS 16
//u8* Data水汽表数据BCD码格式123456.78 m3
//u8* Ftime:当前时间17 06 15 09 55 55
void CreatFuJian_Protocol_WaterGasMeter645DataERRORACKFrame( u8* Pstr,u8* len,u8* Addr)
{
u8 index = 0x00;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0x68;
MemCpy(Pstr + index, Addr , 0x06);
index += 0x06;
Pstr[index ++] = 0x68;
Pstr[index ++] = 0xD1;
Pstr[index ++] = 0x01;
//ERROR Word
Pstr[index ++] = 0x01 + 0x33;
Pstr[index] = GetSum(Pstr + 3,index - 3);
index += 1;
Pstr[index ++] = 0x16;
* len = index;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************
//这里以CRC-CCITT标准生成多项式。CRC-CCITT是一个17位生成多项式
//G[1 0001 0000 0010 0001]用多项式形式表示为G(x)x16x12
//x51由它产生的检验码R的二进制位数是16位2字节
const unsigned char ha00[256] ={
0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x81,0x91,0xA1,0xB1,0xC1,0xD1,0xE1,0xF1,
0x12,0x02,0x32,0x22,0x52,0x42,0x72,0x62,0x93,0x83,0xB3,0xA3,0xD3,0xC3,0xF3,0xE3,
0x24,0x34,0x04,0x14,0x64,0x74,0x44,0x54,0xA5,0xB5,0x85,0x95,0xE5,0xF5,0xC5,0xD5,
0x36,0x26,0x16,0x06,0x76,0x66,0x56,0x46,0xB7,0xA7,0x97,0x87,0xF7,0xE7,0xD7,0xC7,
0x48,0x58,0x68,0x78,0x08,0x18,0x28,0x38,0xC9,0xD9,0xE9,0xF9,0x89,0x99,0xA9,0xB9,
0x5A,0x4A,0x7A,0x6A,0x1A,0x0A,0x3A,0x2A,0xDB,0xCB,0xFB,0xEB,0x9B,0x8B,0xBB,0xAB,
0x6C,0x7C,0x4C,0x5C,0x2C,0x3C,0x0C,0x1C,0xED,0xFD,0xCD,0xDD,0xAD,0xBD,0x8D,0x9D,
0x7E,0x6E,0x5E,0x4E,0x3E,0x2E,0x1E,0x0E,0xFF,0xEF,0xDF,0xCF,0xBF,0xAF,0x9F,0x8F,
0x91,0x81,0xB1,0xA1,0xD1,0xC1,0xF1,0xE1,0x10,0x00,0x30,0x20,0x50,0x40,0x70,0x60,
0x83,0x93,0xA3,0xB3,0xC3,0xD3,0xE3,0xF3,0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
0xB5,0xA5,0x95,0x85,0xF5,0xE5,0xD5,0xC5,0x34,0x24,0x14,0x04,0x74,0x64,0x54,0x44,
0xA7,0xB7,0x87,0x97,0xE7,0xF7,0xC7,0xD7,0x26,0x36,0x06,0x16,0x66,0x76,0x46,0x56,
0xD9,0xC9,0xF9,0xE9,0x99,0x89,0xB9,0xA9,0x58,0x48,0x78,0x68,0x18,0x08,0x38,0x28,
0xCB,0xDB,0xEB,0xFB,0x8B,0x9B,0xAB,0xBB,0x4A,0x5A,0x6A,0x7A,0x0A,0x1A,0x2A,0x3A,
0xFD,0xED,0xDD,0xCD,0xBD,0xAD,0x9D,0x8D,0x7C,0x6C,0x5C,0x4C,0x3C,0x2C,0x1C,0x0C,
0xEF,0xFF,0xCF,0xDF,0xAF,0xBF,0x8F,0x9F,0x6E,0x7E,0x4E,0x5E,0x2E,0x3E,0x0E,0x1E
};
const unsigned char la00[256] ={
0x00,0x21,0x42,0x63,0x84,0xA5,0xC6,0xE7,0x08,0x29,0x4A,0x6B,0x8C,0xAD,0xCE,0xEF,
0x31,0x10,0x73,0x52,0xB5,0x94,0xF7,0xD6,0x39,0x18,0x7B,0x5A,0xBD,0x9C,0xFF,0xDE,
0x62,0x43,0x20,0x01,0xE6,0xC7,0xA4,0x85,0x6A,0x4B,0x28,0x09,0xEE,0xCF,0xAC,0x8D,
0x53,0x72,0x11,0x30,0xD7,0xF6,0x95,0xB4,0x5B,0x7A,0x19,0x38,0xDF,0xFE,0x9D,0xBC,
0xC4,0xE5,0x86,0xA7,0x40,0x61,0x02,0x23,0xCC,0xED,0x8E,0xAF,0x48,0x69,0x0A,0x2B,
0xF5,0xD4,0xB7,0x96,0x71,0x50,0x33,0x12,0xFD,0xDC,0xBF,0x9E,0x79,0x58,0x3B,0x1A,
0xA6,0x87,0xE4,0xC5,0x22,0x03,0x60,0x41,0xAE,0x8F,0xEC,0xCD,0x2A,0x0B,0x68,0x49,
0x97,0xB6,0xD5,0xF4,0x13,0x32,0x51,0x70,0x9F,0xBE,0xDD,0xFC,0x1B,0x3A,0x59,0x78,
0x88,0xA9,0xCA,0xEB,0x0C,0x2D,0x4E,0x6F,0x80,0xA1,0xC2,0xE3,0x04,0x25,0x46,0x67,
0xB9,0x98,0xFB,0xDA,0x3D,0x1C,0x7F,0x5E,0xB1,0x90,0xF3,0xD2,0x35,0x14,0x77,0x56,
0xEA,0xCB,0xA8,0x89,0x6E,0x4F,0x2C,0x0D,0xE2,0xC3,0xA0,0x81,0x66,0x47,0x24,0x05,
0xDB,0xFA,0x99,0xB8,0x5F,0x7E,0x1D,0x3C,0xD3,0xF2,0x91,0xB0,0x57,0x76,0x15,0x34,
0x4C,0x6D,0x0E,0x2F,0xC8,0xE9,0x8A,0xAB,0x44,0x65,0x06,0x27,0xC0,0xE1,0x82,0xA3,
0x7D,0x5C,0x3F,0x1E,0xF9,0xD8,0xBB,0x9A,0x75,0x54,0x37,0x16,0xF1,0xD0,0xB3,0x92,
0x2E,0x0F,0x6C,0x4D,0xAA,0x8B,0xE8,0xC9,0x26,0x07,0x64,0x45,0xA2,0x83,0xE0,0xC1,
0x1F,0x3E,0x5D,0x7C,0x9B,0xBA,0xD9,0xF8,0x17,0x36,0x55,0x74,0x93,0xB2,0xD1,0xF0
};
void CRCCALFunction(u8 *a,u8 *b,u8 *c)
{
*c = la00[*a] ^ *c;
*a = ha00[*a] ^ *b;
*b = *c;
}
//--说明--
//j=5 --有效数据(0x78563412+0x52) 字节长度
//s[0]-s[j-1] --有效数据(0x78563412+0x52)
//s[j]-s[j+1] --CRC校验码(0xB135)
//iCrcACrcBCrcC --临时变量
//--程序--
u16 GetXYDXCrcValue(u8* sin,u8 len)
{
u16 TempCRC = 0x00;
u8 CrcA = sin[0];
u8 CrcB = sin[1];
u8 CrcC = sin[2];
for (u8 i=2;i<len;i++)
{
CRCCALFunction(&CrcA,&CrcB,&CrcC);
CrcC = sin[i+1];
}
TempCRC = CrcB;
TempCRC <<= 0x08;
TempCRC |= CrcA;
return TempCRC;
}
void CreatHubei_Protocol_ReadXYWaterMeterDataFrame( u8* str,u16* len,u8* Addr)
{ //5 10
u8 TempBuff[] = {0x42 ,0x42 ,0x42 ,0x42 ,0x53 ,0x78 ,0x56 ,0x34 ,0x12 ,0x52 ,0xB1 ,0x35 ,0x45};
//u8 Tempbuff2[] = {0x53 ,0x53 ,0x53 ,0x53 ,0x42 ,0x78 ,0x56 ,0x34 ,0x12 ,0x52 ,0x02 ,0x02 ,0x78 ,0x56 ,0x34 ,0x12 ,0x78 ,0x56 ,0x34 ,0x12 ,0x9E ,0xC2 ,0x45};
u16 TempCRC = 0x00;
MemCpy(&TempBuff[5],Addr,0x04);
TempCRC = GetXYDXCrcValue(&TempBuff[5],5);
//TempCRC = GetXYDXCrcValue(&Tempbuff2[5],15);
TempBuff[10] = TempCRC & 0x00FF;
TempBuff[11] = TempCRC >> 0x08;
*len = sizeof(TempBuff);
MemCpy(str,TempBuff,sizeof(TempBuff));
}
u8* CheckHubei_Protocol_ReadXYWaterMeterAckDataFrame( u8* str,u8 len,u8* Addr,u8* outaddr)
{ //5 10
//u8 Tempbuff2[] = {0x53 ,0x53 ,0x53 ,0x53 ,0x42 ,0x78 ,0x56 ,0x34 ,0x12 ,0x52 ,0x02 ,0x02 ,0x78 ,0x56 ,0x34 ,0x12 ,0x78 ,0x56 ,0x34 ,0x12 ,0x9E ,0xC2 ,0x45};
u16 TempCRC = 0x00;
u8 index = 0x00;
u8 StCrcIndex = 0x00;
while( (str[index ++] != 0x42) && (index < len) );
StCrcIndex = index;
if(Addr != NULL)
{
if( MemCmp(&str[index],Addr,0x04) != 0x00 ) return NULL;
}
if(outaddr != NULL)
{
MemCpy(outaddr,&str[index],0x04) ;
}
index += 0x04;
if(str[index] != 0x52) return NULL;
index += 0x01;
TempCRC = str[StCrcIndex+15+1];
TempCRC <<= 0x08;
TempCRC |= str[StCrcIndex+15];
if( TempCRC == GetXYDXCrcValue(&str[StCrcIndex],15) )
{
return &str[index];
}
else
{
return NULL;
}
}
void AnalyzeXYDXAckDataFrameProcess(u8* pData,st_params * pstr)
{
//0x02 ,0x02 ,0x78 ,0x56 ,0x34 ,0x12 ,0x78 ,0x56 ,0x34 ,0x12 ,
u32 Factor = 0x01;
u8 Tdata[6] = {0x00};
pstr->status[0] = pData[0]; //表类型,表数据倍率
pstr->status[1] = pData[1]; //表状态
Factor = pData[0]&0x0F;
Tdata[0] = pData[2];
Tdata[0] <<= 0x04;
Tdata[1] = pData[2];
Tdata[1] >>= 0x04;
Tdata[1] |= (pData[3] << 0x04);
Tdata[2] = pData[3];
Tdata[2] >>= 0x04;
Tdata[2] |= (pData[4] << 0x04);
Tdata[3] = pData[4];
Tdata[3] >>= 0x04;
Tdata[3] |= (pData[5] << 0x04);
Tdata[4] = pData[5];
Tdata[4] >>= 0x04;
if(Factor == 0x00)
{//0.001 01 23 45.67 80
MemCpy(&pstr->data[1], & Tdata[1], 4);
}
else if(Factor == 0x01)
{//0.01
MemCpy(&pstr->data[1], & pData[2], 4);
}
else if(Factor == 0x02)
{//0.1
MemCpy(&pstr->data[1], & Tdata[0], 4);
}
else if(Factor == 0x03)
{//1
pstr->data[1] = 0x00;
MemCpy(&pstr->data[2], & pData[2], 3);
}
else if(Factor == 0x04)
{//10
pstr->data[1] = 0x00;
MemCpy(&pstr->data[2], & Tdata[0], 3);
}
else if(Factor == 0x05)
{//100
pstr->data[1] = 0x00;
pstr->data[2] = 0x00;
MemCpy(&pstr->data[3], & pData[2], 2);
}
else if(Factor == 0x06)
{//1000
pstr->data[1] = 0x00;
pstr->data[2] = 0x00;
MemCpy(&pstr->data[3], & Tdata[0], 2);
}
else
{
//0.1
MemCpy(&pstr->data[1], & Tdata[0], 4);
}
}
//模块串口控制水表开关阀控
//68 10 00 00 17 03 17 03 86 04 04 A0 17 00 55 46 16
//
//68 10 00 00 17 03 17 03 86 04 04 A0 17 00 AA 9B 16
void CreatXinTian_Protocol_ControlONOFFKey(u8* Pstr,u8* Len,u8* Addr,u8 key)
{
u8 index = 0x00;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0xFE;
Pstr[index ++] = 0x68;
Pstr[index ++] = 0x10;//meter type
//MemCpy(&Pstr[index],Addr,0x07);
//index += 0x07;
Pstr[index ++] = Addr[0];
Pstr[index ++] = Addr[1];
Pstr[index ++] = Addr[2];
Pstr[index ++] = Addr[3];
Pstr[index ++] = Addr[4];
Pstr[index ++] = Addr[5];
Pstr[index ++] = Addr[6];
Pstr[index ++] = 0x04;
Pstr[index ++] = 0x04;
Pstr[index ++] = 0xA0;
Pstr[index ++] = 0x17;
Pstr[index ++] = 0x00;
Pstr[index ++] = key;
Pstr[index] = GetSum(&Pstr[4], index-4);
index ++;
Pstr[index ++] = 0x16;
*Len = index;
}
//开关阀控上行PLC返回帧
void CreatChenDianGuoJi_Protocol_ControlWaterGasMeterKeyAckFrame( u8* Pstr,u8* len,st_params * pstr,u16 key)
{
u8 index = 0x00;
Pstr[index ++] = 0x68;
read_addr(&Pstr[index]);
index += 0x06;
Pstr[index ++] = 0x68;
Pstr[index ++] = 0x99;
Pstr[index ++] = 0x0E;
MemCpy(&Pstr[index], pstr->plc_DI, 4);
index += 0x04;
Pstr[index ++] = key;
Pstr[index ++] = key;
Pstr[index ++] = pstr->meter_type;
MemCpy(&Pstr[index], pstr->meter_addr, 7);
index += 0x07;
for (u8 i = 10; i < index; i++)
{
Pstr[i] += 0x33;
}
Pstr[index] = GetSum(Pstr ,index );
index += 1;
Pstr[index ++] = 0x16;
* len = index;
}
//FE FE FE FE 68 11 90 78 56 34 12 68 91 1B FF 00 00 70 40 78 56 34 12 00 00 01 04 16 40 78 56 34 12 01 00 09 02 04 16 00 00 CS 16
//u8* Data水汽表数据BCD码格式123456.78 m3
//u8* Ftime:当前时间17 06 15 09 55 55
void CreatChenDianGuoJI_Protocol_WaterGasMeter645DataERRORACKFrame( u8* Pstr,u8* len,st_params * pstr)
{
u8 index = 0x00;
Pstr[index ++] = 0x68;
read_addr(&Pstr[index]);
index += 0x06;
Pstr[index ++] = 0x68;
Pstr[index ++] = 0xD1;
Pstr[index ++] = 0x09;
//ERROR Word
Pstr[index ++] = 0x01;
Pstr[index ++] = pstr->meter_type;
MemCpy(&Pstr[index], pstr->meter_addr, 7);
index += 0x07;
for (u8 i = 10; i < index; i++)
{
Pstr[i] += 0x33;
}
Pstr[index] = GetSum(Pstr ,index );
index += 1;
Pstr[index ++] = 0x16;
* len = index;
}
void CreatReadChangDeConcentratorDate(u8* outBuf, u16* outLen)
{
u8 Tempbuff[] = {0xAA ,0x00 ,0x00 ,0x03 ,0x00 ,0x2F ,0x0A ,0x07 ,0x43 ,0xFF};
MemCpy(outBuf,Tempbuff,sizeof(Tempbuff));
*outLen = sizeof(Tempbuff);
}
#if 0
15:36:28.625 AA000008000F010202BB000000D7FF
15:36:34.406 AA00002B0002050202C9349B10F3DD2E045A0000000000000000000000120518005D0100000000000000000020E8370006FF
15:36:34.408 AA000008000F020202EEBB0000C6FF
15:36:45.096 读取集中器时间 AA000003002F0A0743FF
15:36:45.098 Send---AA000003002F0A0743FF
15:36:45.164 AA00000A000F022F0A1205180F1914BFFF
15:37:06.288 读单表月历史数据 AA00000F000601PR10PR0000000000000029FF
15:37:06.290 读单表月历史数据 表1=10171593,C9349B
15:37:06.291 读单表月历史数据 数据日期=2018-05-23,1205
15:37:06.296 Send---AA00000F000601C9349B10120500000000000000D5FF
15:37:06.362 AA000008000F0106010001EEBBC9FF
15:37:06.419 AA00003200020506011205170F19000F91109B34C95A00000000005D010000001205180F19000F91109B34C95A00000000005D01000000EDFF
15:37:06.440 AA000008000F020601EEBB0000C9FF
15:40:54.600 读取集中器时间 AA000003002F0A0743FF
15:40:54.602 Send---AA000003002F0A0743FF
15:40:54.669 AA00000A000F022F0A1205190F1924D0FF
15:41:23.299 读单表月历史数据 AA 0000 0F00 0601 PR10PR0000000000000029FF
15:41:23.300 读单表月历史数据 表1=10171593,C9349B
15:41:23.302 读单表月历史数据 数据日期=2018-05-23,1205
15:41:23.305 Send---AA 0000 0F00 0601 C9349B10120500000000000000D5FF
15:41:23.360 AA000008000F0106010001EEBBC9FF
15:41:23.422 AA00004900020506011205170F19000F91109B34C95A00000000005D010000001205180F19000F91109B34C95A00000000005D010000001205190F19000F91109B34C95A00000000005D010000005CFF
15:41:23.441 AA000008000F020601EEBB0000C9FF
[15:46:39 --- Tx] AA 00 00 0F 00 06 01 C9 34 9B 10 12 05 00 00 00 00 00 00 00 D5 FF
[15:46:39 52 Rx] AA 00 00 08 00 0F 01 06 01 00 01 EE BB C9 FF
[15:46:39 61 Rx] AA 00 00 49 00 02 05 06 01 12 05 17 0F 19 00 0F 91 10 9B 34 C9 5A 00 00 00 00 00 5D 01 00 00 00 12 05 18 0F 19 00 0F 91 10 9B 34 C9 5A 00 00 00 00 00 5D 01 00 00 00 12 05 19 0F 19 00 0F 91 10 9B 34 C9 5A 00 00 00 00 00 5D 01 00 00 00 5C FF
AA 00 00 08 00 0F 02 06 01 EE BB 00 00 C9 FF
#endif
void CreatReadChangDeConcentratorData(u8* meter_id,u8* outBuf, u16* outLen)
{
static bool readdateflag = false;
static u8 year = 0,month = 0;
// u8 tempaddr[4] ;
if(readdateflag == false)
{
if(ReadRS232ConcentratorDate(&year,&month) == true)
{
readdateflag = true;
//day = 0x00;
}
}
}