Commit 2d13a6aa authored by captainwong's avatar captainwong

add ADM-CID support: use ADM-CID id, use UTC timestamp

parent eb36d3cc
......@@ -675,6 +675,14 @@ static void getNowTimestamp(char* buff) {
tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
}
static void getGmtTimestamp(char* buff) {
time_t now = time(NULL);
struct tm* tm = gmtime(&now);
snprintf(buff, ADEMCO_PACKET_TIMESTAMP_LEN + 1, "_%02d:%02d:%02d,%02d-%02d-%04d",
tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
}
size_t ademcoMakeEmptyDataPacket(ademco_char_t* dst_buff, size_t len,
const char* id, uint16_t seq, const char* acct, AdemcoId ademcoId) {
char buff[ADEMCO_PACKET_MAX_LEN];
......@@ -724,10 +732,64 @@ size_t ademcoMakeEmptyDataPacket(ademco_char_t* dst_buff, size_t len,
return 0;
}
size_t ademcoMakeAdmEmptyDataPacket(ademco_char_t* dst_buff, size_t len,
const char* id, uint16_t seq, const char* acct, AdemcoId ademcoId) {
char buff[ADEMCO_PACKET_MAX_LEN];
char* p = buff;
char* pcrc = buff + 1;
char* plen = buff + 5;
char* pid = buff + 9;
buff[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, id, strlen(id));
p = pid + strlen(id);
snprintf((char*)p, 5, "%04d", seq);
p += 4;
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL && strlen(acct) > 0) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
} else {
snprintf((char*)p, 7, "%06X", ademcoId);
p += 6;
}
*p++ = '[';
*p++ = ']';
getGmtTimestamp((char*)p);
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
char temp[5];
size_t packet_len = p - buff;
// \n crc len \r
size_t ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
uint16_t crc = ademcoCRC16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buff, packet_len);
dst_buff[packet_len] = '\0'; // for debug convenience
return packet_len;
} else
return 0;
}
size_t ademcoMakeNullPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId) {
return ademcoMakeEmptyDataPacket(buff, len, ADEMCO_PACKET_ID_NULL, seq, acct, ademcoId);
}
size_t ademcoMakeAdmNullPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId) {
return ademcoMakeAdmEmptyDataPacket(buff, len, ADEMCO_PACKET_ID_NULL, seq, acct, ademcoId);
}
size_t ademcoMakeAckPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId) {
return ademcoMakeEmptyDataPacket(buff, len, ADEMCO_PACKET_ID_ACK, seq, acct, ademcoId);
}
......@@ -788,6 +850,59 @@ size_t ademcoMakeHbPacket(ademco_char_t* dst_buff, size_t len, uint16_t seq, con
return 0;
}
size_t ademcoMakeAdmPacket(ademco_char_t* dst_buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata) {
char buff[ADEMCO_PACKET_MAX_LEN];
char* p = buff;
char* pcrc = buff + 1;
char* plen = buff + 5;
char* pid = buff + 9;
buff[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, ADEMCO_PACKET_ID_ADM_CID, strlen(ADEMCO_PACKET_ID_ADM_CID));
p = pid + strlen(ADEMCO_PACKET_ID_ADM_CID);
snprintf((char*)p, 5, "%04d", seq);
p += 4;
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
} else {
snprintf(p, 7, "%06X", ademcoId);
p += 6;
}
p += ademcoAppendDataSegment(p, acct, ademcoId, ademcoEvent, gg, zone);
if (xdata && xdata->raw_len > 0) {
memcpy(p, xdata->raw, xdata->raw_len);
p += xdata->raw_len;
}
getGmtTimestamp(p);
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
char temp[5];
size_t packet_len = p - buff;
// \n crc len \r
size_t ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
uint16_t crc = ademcoCRC16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buff, packet_len);
dst_buff[packet_len] = '\0'; // for debug convenience
return packet_len;
}
return 0;
}
static void copyAcct2AdemcoPacket(AdemcoPacket* pkt, const char* acct) {
if (acct) {
size_t len = strlen(acct);
......@@ -806,6 +921,13 @@ size_t ademcoMakeNullPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct,
return pkt->raw_len = ademcoMakeNullPacket(pkt->raw, sizeof(pkt->raw), seq, acct, ademcoId);
}
size_t ademcoMakeAdmNullPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId) {
pkt->seq = seq;
copyAcct2AdemcoPacket(pkt, acct);
pkt->data.ademcoId = ademcoId;
return pkt->raw_len = ademcoMakeAdmNullPacket(pkt->raw, sizeof(pkt->raw), seq, acct, ademcoId);
}
size_t ademcoMakeAckPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId) {
pkt->seq = seq;
copyAcct2AdemcoPacket(pkt, acct);
......@@ -835,6 +957,21 @@ size_t ademcoMakeHbPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Ad
seq, acct, ademcoId, ademcoEvent, gg, zone, xdata);
}
size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata) {
pkt->seq = seq;
copyAcct2AdemcoPacket(pkt, acct);
ademcoAppendDataSegment2(&pkt->data, acct, ademcoId, ademcoEvent, gg, zone);
if (xdata && xdata->raw_len > 0) {
pkt->xdata.lenghFormat = xdata->lenghFormat;
memcpy(pkt->xdata.raw, xdata->raw, xdata->raw_len);
pkt->xdata.raw_len = xdata->raw_len;
} else
memset(&pkt->xdata, 0, sizeof(*xdata));
return pkt->raw_len = ademcoMakeAdmPacket(pkt->raw, sizeof(pkt->raw),
seq, acct, ademcoId, ademcoEvent, gg, zone, xdata);
}
AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, AdemcoPacket* pkt, size_t* cb_commited) {
if (len < 9) { return RESULT_NOT_ENOUGH; }
do {
......
......@@ -425,18 +425,25 @@ ADEMCO_EXPORT_SYMBOL const char* admecoPacketIdToString(AdemcoPacketId id);
*/
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeEmptyDataPacket(ademco_char_t* dst_buff, size_t len, const char* id, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmEmptyDataPacket(ademco_char_t* dst_buff, size_t len, const char* id, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNullPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmNullPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAckPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNakPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket(ademco_char_t* buff, size_t len, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata);
// like upper funcs, store buff and len to pkt->raw, pkt->raw_len
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNullPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmNullPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAckPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNakPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoGG gg, AdemcoZone zone, const AdemcoXDataSegment* xdata);
//! parse a ademco packet, if everything is OK, cb_commited is the packet length
ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, AdemcoPacket* pkt, size_t* cb_commited);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment