Commit bd0995ff authored by captainwong's avatar captainwong

release 1.2.0

parent b1221fd5
# Ademco Change Log # Ademco Change Log
## 1.2.0
- add config
- add `offset` for parse error
- refactor parser
## 1.1.0 ## 1.1.0
- ADEMCO_PACKET_ACCT_MAX_LEN changed from 64 to 18 - ADEMCO_PACKET_ACCT_MAX_LEN changed from 64 to 18
......
...@@ -226,7 +226,7 @@ const char* ademcoEventToString(AdemcoEvent ademcoEvent) { ...@@ -226,7 +226,7 @@ const char* ademcoEventToString(AdemcoEvent ademcoEvent) {
} }
} }
#ifdef ADEMCO_ENABLE_CHINESE #if ADEMCO_ENABLE_CHINESE
const char* ademcoEventToStringChinese(AdemcoEvent ademcoEvent) { const char* ademcoEventToStringChinese(AdemcoEvent ademcoEvent) {
switch (ademcoEvent) { switch (ademcoEvent) {
#define XX(name, code, zh) \ #define XX(name, code, zh) \
...@@ -364,23 +364,25 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac ...@@ -364,23 +364,25 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
} else if (packet_len >= ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN && } else if (packet_len >= ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN &&
packet[0] == '[' && packet[0] == '[' &&
packet[packet_len - 1] == ']') { // [#000000|1400 00 000] packet[packet_len - 1] == ']') { // [#000000|1400 00 000]
do {
const char* p = packet + 2; const char* p = packet + 2;
size_t acct_len = packet_len - 15; size_t acct_len = packet_len - 15;
if (acct_len < 6) { if (acct_len < 6) {
ADEMCO_FILL_PARSE_ERROR(err, "acct_len < 6"); ADEMCO_FILL_PARSE_ERROR(err, p - packet, "acct_len < 6");
break; return RESULT_ERROR;
} else if (acct_len > ADEMCO_PACKET_ACCT_MAX_LEN) {
ADEMCO_FILL_PARSE_ERROR(err, p - packet, "acct_len > ADEMCO_PACKET_ACCT_MAX_LEN");
return RESULT_ERROR;
} }
char temp[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX] = {0}; char temp[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX] = { 0 };
strncpy(temp, (const char*)p, acct_len); strncpy(temp, (const char*)p, acct_len);
temp[acct_len] = '\0'; temp[acct_len] = '\0';
dataSegment->ademcoId = (AdemcoId)strtoul(temp, NULL, 16); dataSegment->ademcoId = (AdemcoId)strtoul(temp, NULL, 16);
p += acct_len; p += acct_len;
if (*p++ != '|') { if (*p++ != '|') {
ADEMCO_FILL_PARSE_ERROR(err, "*p++ != '|'"); ADEMCO_FILL_PARSE_ERROR(err, p - packet, "*p++ != '|'");
break; return RESULT_ERROR;
} }
strncpy(temp, (const char*)p, 4); strncpy(temp, (const char*)p, 4);
temp[4] = '\0'; temp[4] = '\0';
...@@ -388,8 +390,8 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac ...@@ -388,8 +390,8 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
p += 4; p += 4;
if (*p++ != ' ') { if (*p++ != ' ') {
ADEMCO_FILL_PARSE_ERROR(err, "*p++ != ' '"); ADEMCO_FILL_PARSE_ERROR(err, p - packet, "*p++ != ' '");
break; return RESULT_ERROR;
} }
if (*p == 'E' && *(p + 1) == 'E') { if (*p == 'E' && *(p + 1) == 'E') {
dataSegment->gg = 0xEE; dataSegment->gg = 0xEE;
...@@ -401,22 +403,21 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac ...@@ -401,22 +403,21 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
p += 2; p += 2;
if (*p++ != ' ') { if (*p++ != ' ') {
ADEMCO_FILL_PARSE_ERROR(err, "*p++ != ' '"); ADEMCO_FILL_PARSE_ERROR(err, p - packet, "*p++ != ' '");
break; return RESULT_ERROR;
} }
strncpy(temp, (const char*)p, 3); strncpy(temp, (const char*)p, 3);
temp[3] = '\0'; temp[3] = '\0';
dataSegment->zone = atoi(temp); dataSegment->zone = (AdemcoZone)atoi(temp);
if (dataSegment->raw != packet) { if (dataSegment->raw != packet) {
memcpy(dataSegment->raw, packet, packet_len); memcpy(dataSegment->raw, packet, packet_len);
} }
dataSegment->raw_len = packet_len; dataSegment->raw_len = packet_len;
return RESULT_OK; return RESULT_OK;
} while (0);
} }
ADEMCO_FILL_PARSE_ERROR(err, "dig in source code for more info"); ADEMCO_FILL_PARSE_ERROR(err, 0, "dig in source code for more info");
return RESULT_ERROR; return RESULT_ERROR;
} }
...@@ -984,89 +985,107 @@ size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, uint16_t seq, ...@@ -984,89 +985,107 @@ size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, uint16_t seq,
AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
AdemcoPacket* pkt, size_t* cb_commited, AdemcoPacket* pkt, size_t* cb_commited,
AdemcoParseError* err) { AdemcoParseError* err) {
const char *p, *q, *pid, *pend, *pacct, *pdata;
uint16_t crc;
size_t len_needed;
if (len < 9) { if (len < 9) {
return RESULT_NOT_ENOUGH; return RESULT_NOT_ENOUGH;
} }
do {
const char* p = buff; p = buff;
if (*p++ != ADEMCO_PACKET_PREFIX) { if (*p++ != ADEMCO_PACKET_PREFIX) {
ADEMCO_FILL_PARSE_ERROR(err, "*p++ != ADEMCO_PACKET_PREFIX"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "fixed prefix not found");
break; return RESULT_ERROR;
} }
char temp[5];
// crc // crc
memcpy(temp, p, 4); crc = 0;
temp[4] = '\0'; for (const char* q = p; p - q < 4; p++) {
uint16_t crc = strtoul(temp, NULL, 16) & 0xFFFF; uint8_t h = char2hex(*p);
p += 4; if (h == 0xFF) {
ADEMCO_FILL_PARSE_ERROR(err, p - buff, "crc contains non-hex characters");
return RESULT_ERROR;
}
crc = (crc << 4) | h;
}
// len // len
memcpy(temp, p, 4); pkt->len = 0;
temp[4] = '\0'; for (const char* q = p; p - q < 4; p++) {
pkt->len = strtoul(temp, NULL, 16); uint8_t h = char2hex(*p);
p += 4; if (h == 0xFF) {
size_t len_needed = 9 + pkt->len + 1; ADEMCO_FILL_PARSE_ERROR(err, p - buff, "len contains non-hex characters");
if (len < len_needed) return RESULT_ERROR;
}
pkt->len = (pkt->len << 4) | h;
}
len_needed = 9 + pkt->len + 1;
if (len < len_needed) {
return RESULT_NOT_ENOUGH; return RESULT_NOT_ENOUGH;
if (len_needed >= ADEMCO_PACKET_MAX_LEN) { } else if (len_needed >= ADEMCO_PACKET_MAX_LEN) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "len_needed >= ADEMCO_PACKET_MAX_LEN"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "len_needed >= ADEMCO_PACKET_MAX_LEN");
return RESULT_ERROR; return RESULT_ERROR;
} }
const char* pid = p; pid = p;
const char* pcr = pid + pkt->len; pend = pid + pkt->len;
if (pcr > buff + len || *pcr != ADEMCO_PACKET_SUFIX) { if (pend > buff + len) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "pcr > buff + len || *pcr != ADEMCO_PACKET_SUFIX"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "suffix out of range");
break; return RESULT_ERROR;
}
if (*pend != ADEMCO_PACKET_SUFIX) {
dline;
ADEMCO_FILL_PARSE_ERROR(err, p - buff, "suffix not found");
return RESULT_ERROR;
} }
pkt->crc = ademcoCRC16(pid, pkt->len); pkt->crc = ademcoCRC16(pid, pkt->len);
if (pkt->crc != crc) { if (pkt->crc != crc) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "pkt->crc != crc"); ADEMCO_FILL_PARSE_ERROR(err, 1, "crc error");
break; return RESULT_ERROR;
} }
// id // id
if (*pid != '\"') { if (*pid != '\"') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "*pid != '\"'"); ADEMCO_FILL_PARSE_ERROR(err, pid - buff, "left \" of id not found");
break; return RESULT_ERROR;
} }
p = pid + 1; p = pid + 1;
while (p < pcr && *p != '\"') { while (p < pend && *p != '\"') {
p++; p++;
} }
if (p >= pcr || *p != '\"') { if (p >= pend || *p != '\"') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "p >= pcr || *p != '\"'"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "right \" of id not found");
break; return RESULT_ERROR;
} }
pkt->id = getAdemcoPacketId((const char*)pid, ++p - pid); pkt->id = getAdemcoPacketId((const char*)pid, ++p - pid);
if (pkt->id == AID_INVALID) { if (pkt->id == AID_INVALID) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "pkt->id == AID_INVALID"); ADEMCO_FILL_PARSE_ERROR(err, pid - buff, "unknown ademco id");
break; return RESULT_ERROR;
} }
// seq // seq
const char* pseq = p; pkt->seq = 0;
while (p < pcr && *p != 'R' && *p != 'L') { for (q = p; p - q < 4; p++) {
p++; if ('0' <= *p && *p <= '9') {
} pkt->seq = (pkt->seq * 10) + (*p - '0');
if (p - pseq != 4 || (*p != 'R' && *p != 'L')) { } else {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "p - pseq != 4 || (*p != 'R' && *p != 'L')"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "seq contains non-digit characters");
break; // some apps use FFFF, wtf
// return RESULT_ERROR;
}
} }
memcpy(temp, pseq, 4);
temp[4] = '\0';
pkt->seq = strtoul(temp, NULL, 10) & 0xFFFF;
if (pkt->seq >= 10000) { if (pkt->seq >= 10000) {
pkt->seq = 0; pkt->seq = 0;
} }
...@@ -1074,100 +1093,102 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, ...@@ -1074,100 +1093,102 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
// *rrcvr // *rrcvr
if (*p == 'R') { // rrcvr exists if (*p == 'R') { // rrcvr exists
// const char* prcvr = p; // const char* prcvr = p;
while (p < pcr && *p != 'L' && *p != '#') { while (p < pend && *p != 'L' && *p != '#') {
p++; p++;
} }
if (p >= pcr || (*p != 'L' && *p != '#')) { if (p >= pend || (*p != 'L' && *p != '#')) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "p >= pcr || (*p != 'L' && *p != '#')"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "p >= pend || (*p != 'L' && *p != '#')");
break; return RESULT_ERROR;
} }
// only check if format is correct, ignore it's content // only check if format is correct, ignore it's content
} else if (*p == 'L') { // rrcvr not exits } else if (*p == 'L') { // rrcvr not exits
// pass // pass
} else { } else {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "both LPREF and RRCVR not found"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "both LPREF and RRCVR not found");
break; return RESULT_ERROR;
} }
// lpref // lpref
if (*p != 'L') { if (*p != 'L') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "LPREF not found"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "LPREF not found");
break; return RESULT_ERROR;
} }
while (p < pcr && *p != '#') { while (p < pend && *p != '#') {
p++; p++;
} }
// only check if format is correct, ignore it's content // only check if format is correct, ignore it's content
if (p >= pcr || *p != '#') { if (p >= pend || *p != '#') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "# not found"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "# not found");
break; return RESULT_ERROR;
} }
// lpref passed // lpref passed
// #acct // #acct
const char* pacct = ++p; pacct = ++p;
while (p < pcr && *p != '[') { while (p - pacct < ADEMCO_PACKET_ACCT_MAX_LEN && *p != '[') {
if (!isxdigit(*p)) { if (!isxdigit(*p)) {
p = NULL;
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "acct contains non-hex characters"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "acct contains non-hex characters");
break; return RESULT_ERROR;
} }
p++; p++;
} }
if (p == NULL || if (*p != '[') {
p >= pcr ||
*p != '[' ||
p - pacct >= ADEMCO_PACKET_ACCT_MAX_LEN) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "data's [ not found"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "acct too long");
break; return RESULT_ERROR;
} }
strncpy(pkt->acct, (const char*)pacct, p - pacct); strncpy(pkt->acct, (const char*)pacct, p - pacct);
pkt->acct[p - pacct] = '\0'; pkt->acct[p - pacct] = '\0';
// data // data
const char* pdata = p; pdata = p;
while (p < pcr && *p != ']') { if (*p != '[') {
dline;
ADEMCO_FILL_PARSE_ERROR(err, p - buff, "data's [ not found");
return RESULT_ERROR;
}
while (p < pend && *p != ']') {
p++; p++;
} }
if (p >= pcr || *p != ']') { if (p >= pend || *p != ']') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "data's ] not found"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "data's ] not found");
break; return RESULT_ERROR;
} }
if (ademcoParseDataSegment(pdata, ++p - pdata, &pkt->data, err) != RESULT_OK) { if (ademcoParseDataSegment(pdata, ++p - pdata, &pkt->data, err) != RESULT_OK) {
dline; dline;
break; return RESULT_ERROR;
} }
// *xdata // *xdata
if (*p == '[') { // xdata exists if (*p == '[') { // xdata exists
const char* pxdata = p++; const char* pxdata = p++;
AdemcoXDataLengthFormat xlf = FOUR_DECIMAL; AdemcoXDataLengthFormat xlf = FOUR_DECIMAL;
size_t valid_len; size_t valid_len = 0;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (!isxdigit(*(uint8_t*)(p + i))) if (!isxdigit(*(uint8_t*)(p + i)))
xlf = TWO_HEX; xlf = TWO_HEX;
if (xlf == FOUR_DECIMAL) { if (xlf == FOUR_DECIMAL) {
memcpy(temp, pxdata + 1, 4); valid_len = (char2hex(*(pxdata + 1)) << 12) |
temp[4] = '\0'; (char2hex(*(pxdata + 2)) << 8) |
valid_len = strtoul(temp, NULL, 16); (char2hex(*(pxdata + 3)) << 4) |
(char2hex(*(pxdata + 4)));
p += 4 + valid_len; p += 4 + valid_len;
} else { } else {
valid_len = (pxdata[1] << 8) | pxdata[2]; valid_len = (pxdata[1] << 8) | pxdata[2];
p += 2 + valid_len; p += 2 + valid_len;
} }
if (p >= pcr || *p != ']' || *(p + 1) != '_') { if (p >= pend || *p != ']' || *(p + 1) != '_') {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "xdata's ] not found or next char is not _"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "xdata's ] not found or next char is not _");
break; return RESULT_ERROR;
} }
pkt->xdata.lenghFormat = xlf; pkt->xdata.lenghFormat = xlf;
pkt->xdata.raw_len = ++p - pxdata; pkt->xdata.raw_len = ++p - pxdata;
...@@ -1176,43 +1197,72 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, ...@@ -1176,43 +1197,72 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
pkt->xdata.raw_len = 0; pkt->xdata.raw_len = 0;
} }
// timestamp // timestamp, _%02d:%02d:%02d,%02d-%02d-%04d
if (pcr - p != ADEMCO_PACKET_TIMESTAMP_LEN) { // only check lengh, if format is incorrect, use local time instead
dline; if (pend - p == ADEMCO_PACKET_TIMESTAMP_LEN) {
ADEMCO_FILL_PARSE_ERROR(err, "timestamp length not correct"); struct tm tm;
do {
if (*p++ != '_') {
break; break;
} }
{ tm.tm_hour = char2hex(*p++);
struct tm tm; tm.tm_hour = tm.tm_hour * 10 + char2hex(*p++);
int ret = sscanf((const char*)p, "_%02d:%02d:%02d,%02d-%02d-%04d", if (*p++ != ':') {
&tm.tm_hour, &tm.tm_min, &tm.tm_sec, break;
&tm.tm_mon, &tm.tm_mday, &tm.tm_year);
if (ret != 6) {
// wont break
} }
tm.tm_min = char2hex(*p++);
tm.tm_min = tm.tm_min * 10 + char2hex(*p++);
if (*p++ != ':') {
break;
}
tm.tm_sec = char2hex(*p++);
tm.tm_sec = tm.tm_sec * 10 + char2hex(*p++);
if (*p++ != ',') {
break;
}
tm.tm_mon = char2hex(*p++);
tm.tm_mon = tm.tm_mon * 10 + char2hex(*p++);
if (*p++ != '-') {
break;
}
tm.tm_mday = char2hex(*p++);
tm.tm_mday = tm.tm_mday * 10 + char2hex(*p++);
if (*p++ != '-') {
break;
}
tm.tm_year = char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + char2hex(*p++);
} while (0);
tm.tm_year -= 1900; tm.tm_year -= 1900;
tm.tm_mon--; tm.tm_mon--;
tm.tm_isdst = -1; tm.tm_isdst = -1;
pkt->timestamp = mktime(&tm); pkt->timestamp = mktime(&tm);
if (pkt->timestamp < 0) { // use local time instead if (pkt->timestamp <= 0) { // use local time instead
pkt->timestamp = time(NULL); pkt->timestamp = time(NULL);
} }
p += ADEMCO_PACKET_TIMESTAMP_LEN; } else {
dline;
ADEMCO_FILL_PARSE_ERROR(err, p - buff, "timestamp length not correct");
return RESULT_ERROR;
} }
if (p++ != pcr) { if (p++ != pend) {
dline; dline;
ADEMCO_FILL_PARSE_ERROR(err, "packet length not correct"); ADEMCO_FILL_PARSE_ERROR(err, p - buff, "packet length not correct");
break; return RESULT_ERROR;
} }
pkt->raw_len = *cb_commited = p - buff; pkt->raw_len = *cb_commited = p - buff;
if (pkt->raw != buff) if (pkt->raw != buff)
memcpy(pkt->raw, buff, pkt->raw_len); memcpy(pkt->raw, buff, pkt->raw_len);
return RESULT_OK; return RESULT_OK;
} while (0);
return RESULT_ERROR;
} }
size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, const uint8_t* arr, size_t len) { size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, const uint8_t* arr, size_t len) {
......
...@@ -3,37 +3,16 @@ ...@@ -3,37 +3,16 @@
#pragma once #pragma once
#ifdef ADEMCO_EXPORTS
#if defined __GNUC__
#define ADEMCO_EXPORT_SYMBOL __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#define ADEMCO_EXPORT_SYMBOL __declspec(dllexport)
#else
#define ADEMCO_EXPORT_SYMBOL
#endif
#else // ADEMCO_EXPORTS
#define ADEMCO_EXPORT_SYMBOL
#endif
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
#include "ademco_config.h"
#include "ademco_version.h" #include "ademco_version.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
#define ademco_char_t uint8_t
#else
#define ademco_char_t char
#endif
#define ADEMCO_OK 0 #define ADEMCO_OK 0
#define ADEMCO_ERR -1 #define ADEMCO_ERR -1
...@@ -52,7 +31,7 @@ typedef uint32_t AdemcoId; ...@@ -52,7 +31,7 @@ typedef uint32_t AdemcoId;
typedef uint32_t AdemcoGG; typedef uint32_t AdemcoGG;
typedef uint32_t AdemcoZone; typedef uint32_t AdemcoZone;
//! 安定宝ID范围 // 安定宝ID范围
#define ADEMCO_ID_INVALID 0 #define ADEMCO_ID_INVALID 0
#define ADEMCO_ID_MIN 1 #define ADEMCO_ID_MIN 1
#define ADEMCO_ID_MAX 999999 // 兼容性考虑,最大安定宝 ID 为 0x0F423F #define ADEMCO_ID_MAX 999999 // 兼容性考虑,最大安定宝 ID 为 0x0F423F
...@@ -61,20 +40,20 @@ static inline int ademcoIsValidAdemcoId(AdemcoId ademcoId) { ...@@ -61,20 +40,20 @@ static inline int ademcoIsValidAdemcoId(AdemcoId ademcoId) {
return ADEMCO_ID_MIN <= ademcoId && ademcoId <= ADEMCO_ID_MAX; return ADEMCO_ID_MIN <= ademcoId && ademcoId <= ADEMCO_ID_MAX;
} }
//! 防区号为0时表示主机自身 // 防区号为0时表示主机自身
#define ADEMCO_ZONE_FOR_MACHINE_SELF 0 #define ADEMCO_ZONE_FOR_MACHINE_SELF 0
//! 主机防区号范围 // 主机防区号范围
#define ADEMCO_ZONE_MIN 1 #define ADEMCO_ZONE_MIN 1
//! 对任何主机类型,最大的防区号 // 对任何主机类型,最大的防区号
#define ADEMCO_ZONE_MAX 999 #define ADEMCO_ZONE_MAX 999
#define ADEMCO_ZONE_SENTINEL (ADEMCO_ZONE_MAX + 1) #define ADEMCO_ZONE_SENTINEL (ADEMCO_ZONE_MAX + 1)
//! 对任何主机类型,防区号是否合法(可以包含0防区) // 对任何主机类型,防区号是否合法(可以包含0防区)
static inline int ademcoIsValidZone(AdemcoZone zone) { static inline int ademcoIsValidZone(AdemcoZone zone) {
return ADEMCO_ZONE_FOR_MACHINE_SELF <= zone && zone <= ADEMCO_ZONE_MAX; return ADEMCO_ZONE_FOR_MACHINE_SELF <= zone && zone <= ADEMCO_ZONE_MAX;
} }
//! 对任何主机类型,防区号是否合法(不可以包含0防区) // 对任何主机类型,防区号是否合法(不可以包含0防区)
static inline int ademcoIsValidZoneStrict(AdemcoZone zone) { static inline int ademcoIsValidZoneStrict(AdemcoZone zone) {
return ADEMCO_ZONE_MIN <= zone && zone <= ADEMCO_ZONE_MAX; return ADEMCO_ZONE_MIN <= zone && zone <= ADEMCO_ZONE_MAX;
} }
...@@ -83,7 +62,7 @@ static inline int ademcoIsValidZoneStrict(AdemcoZone zone) { ...@@ -83,7 +62,7 @@ static inline int ademcoIsValidZoneStrict(AdemcoZone zone) {
#define ADEMCO_GG_MAX 99 #define ADEMCO_GG_MAX 99
#define ADEMCO_GG_SENTINEL 100 #define ADEMCO_GG_SENTINEL 100
//! 信号强度范围 [0, 31] // 信号强度范围 [0, 31]
#define ADEMCO_SIGNAL_STRENGTH_MIN 0 #define ADEMCO_SIGNAL_STRENGTH_MIN 0
#define ADEMCO_SIGNAL_STRENGTH_MAX 31 #define ADEMCO_SIGNAL_STRENGTH_MAX 31
...@@ -165,11 +144,11 @@ static inline int ademcoIsValidZoneStrict(AdemcoZone zone) { ...@@ -165,11 +144,11 @@ static inline int ademcoIsValidZoneStrict(AdemcoZone zone) {
XX(EXIT_SETTING_MODE, 3712, "主机退出设置状态") \ XX(EXIT_SETTING_MODE, 3712, "主机退出设置状态") \
XX(RESTORE_FACTORY_SETTINGS_710, 1710, "主机恢复出厂设置") \ XX(RESTORE_FACTORY_SETTINGS_710, 1710, "主机恢复出厂设置") \
XX(RESTORE_FACTORY_SETTINGS, 1713, "主机恢复出厂设置") \ XX(RESTORE_FACTORY_SETTINGS, 1713, "主机恢复出厂设置") \
XX(SIM_IS_IOT_CARD, 1756, "主机SIM卡为物联卡,禁用主机侧电话设置") \ XX(SIM_IS_IOT_CARD, 1756, "物联卡") \
XX(SIM_IS_IOT_PLATFORM_CARD, 2756, "主机SIM卡为平台物联卡,禁用主机侧电话设置") \ XX(SIM_IS_IOT_PLATFORM_CARD, 2756, "平台物联卡") \
XX(SIM_IS_NOT_IOT_CARD, 3756, "主机SIM卡为非物联卡,启用主机侧电话设置") \ XX(SIM_IS_NOT_IOT_CARD, 3756, "非物联卡") \
XX(WHAT_IS_YOUR_TYPE, 1798, "索要主机类型") \ XX(WHAT_IS_YOUR_TYPE, 1798, "索要主机类型") \
XX(SIGNAL_STRENGTH_CHANGED, 1799, "主机信号强度变化,强度值编码后以 xdata 传输") \ XX(SIGNAL_STRENGTH_CHANGED, 1799, "信号强度") \
XX(OFFLINE, 1944, "主机断线") \ XX(OFFLINE, 1944, "主机断线") \
XX(ONLINE, 1946, "主机上线") XX(ONLINE, 1946, "主机上线")
...@@ -180,9 +159,13 @@ typedef enum AdemcoEvent { ...@@ -180,9 +159,13 @@ typedef enum AdemcoEvent {
#define XX(name, code, zh) EVENT_##name = code, #define XX(name, code, zh) EVENT_##name = code,
// ----标准安定宝协议事件---- // ----标准安定宝协议事件----
// 主机状态
ADEMCO_STATUS_EVENTS_MAP(XX) ADEMCO_STATUS_EVENTS_MAP(XX)
// 防区报警
ADEMCO_ALARM_EVENTS_MAP(XX) ADEMCO_ALARM_EVENTS_MAP(XX)
// 防区异常
ADEMCO_EXEPTION_EVENTS_MAP(XX) ADEMCO_EXEPTION_EVENTS_MAP(XX)
// 防区异常恢复
ADEMCO_RESUME_EVENTS_MAP(XX) ADEMCO_RESUME_EVENTS_MAP(XX)
// ---私有事件--------- // ---私有事件---------
...@@ -204,25 +187,18 @@ typedef enum AdemcoEventLevel { ...@@ -204,25 +187,18 @@ typedef enum AdemcoEventLevel {
// 安定宝协议解析结果 // 安定宝协议解析结果
typedef enum AdemcoParseResult { typedef enum AdemcoParseResult {
RESULT_OK, //! 解析到正确、完整的一包 RESULT_OK, // 解析到正确、完整的一包
RESULT_NOT_ENOUGH, //! 解析到正确、不完整的一包,需要缓存数据,下次继续处理 RESULT_NOT_ENOUGH, // 解析到正确、不完整的一包,需要缓存数据,下次继续处理
RESULT_ERROR, //! 解析到错误的数据,应当丢弃该数据包 RESULT_ERROR, // 解析到错误的数据,应当丢弃该数据包
} AdemcoParseResult; } AdemcoParseResult;
// 安定宝协议解析错误信息 // 安定宝协议解析错误信息
typedef struct AdemcoParseError { typedef struct AdemcoParseError {
int line; int line; // line number in ademco.c
size_t offset; // error offset
const char* msg; // user do not free const char* msg; // user do not free
} AdemcoParseError; } AdemcoParseError;
#define ADEMCO_FILL_PARSE_ERROR(err, msg_) \
do { \
if (err) { \
err->line = __LINE__; \
err->msg = (msg_); \
} \
} while (0);
// 安定宝协议data段 // 安定宝协议data段
typedef struct AdemcoDataSegment { typedef struct AdemcoDataSegment {
ademco_char_t raw[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX]; ademco_char_t raw[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX];
...@@ -282,6 +258,7 @@ typedef struct AdemcoPacket { ...@@ -282,6 +258,7 @@ typedef struct AdemcoPacket {
size_t len; size_t len;
AdemcoPacketId id; AdemcoPacketId id;
uint16_t seq; uint16_t seq;
// +1 for '\0'
char acct[ADEMCO_PACKET_ACCT_MAX_LEN + 1]; char acct[ADEMCO_PACKET_ACCT_MAX_LEN + 1];
AdemcoDataSegment data; AdemcoDataSegment data;
AdemcoXDataSegment xdata; AdemcoXDataSegment xdata;
...@@ -293,59 +270,76 @@ typedef struct AdemcoPacket { ...@@ -293,59 +270,76 @@ typedef struct AdemcoPacket {
//////////////////////// Functions //////////////////////// //////////////////////// Functions ////////////////////////
ADEMCO_EXPORT_SYMBOL unsigned int ademcoVersion(void); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL const char* ademcoVersionString(void); unsigned int ademcoVersion(void);
//! print as HEX
ADEMCO_EXPORT_SYMBOL void ademcoPrint(const ademco_char_t* buff, size_t len); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL uint8_t ademcoEncodeSignalStrength(uint8_t strength); const char* ademcoVersionString(void);
ADEMCO_EXPORT_SYMBOL uint8_t ademcoDecodeSignalStrength(uint8_t code);
ADEMCO_EXPORT_SYMBOL
void ademcoPrint(const ademco_char_t* buff, size_t len);
ADEMCO_EXPORT_SYMBOL
uint8_t ademcoEncodeSignalStrength(uint8_t strength);
ADEMCO_EXPORT_SYMBOL
uint8_t ademcoDecodeSignalStrength(uint8_t code);
//////////////////////// AdemcoEvent functions //////////////////////// //////////////////////// AdemcoEvent functions ////////////////////////
//! 是否合法主机账号 // 是否合法主机账号
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
int ademcoIsValidAccount(const char* acct); int ademcoIsValidAccount(const char* acct);
//! 是否主机状态事件
// 是否主机状态事件
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
int ademcoIsMachineStatusEvent(AdemcoEvent ademcoEvent); int ademcoIsMachineStatusEvent(AdemcoEvent ademcoEvent);
//! 是否主机类型事件
// 是否主机类型事件
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
int ademcoIsMachineTypeEvent(AdemcoEvent ademcoEvent); int ademcoIsMachineTypeEvent(AdemcoEvent ademcoEvent);
//! 事件是否需要控制源
// 事件是否需要控制源
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
int ademcoIsEventNeedControlSource(AdemcoEvent ademcoEvent); int ademcoIsEventNeedControlSource(AdemcoEvent ademcoEvent);
//! 获取安定宝事件级别
// 获取安定宝事件级别
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
AdemcoEventLevel ademcoGetEventLevel(AdemcoEvent ademcoEvent); AdemcoEventLevel ademcoGetEventLevel(AdemcoEvent ademcoEvent);
//! 获取异常恢复事件所对应的异常事件
// 获取异常恢复事件所对应的异常事件
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
AdemcoEvent ademcoGetExceptionEventByResumeEvent(AdemcoEvent resumeEvent); AdemcoEvent ademcoGetExceptionEventByResumeEvent(AdemcoEvent resumeEvent);
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
const char* ademcoEventToString(AdemcoEvent ademcoEvent); const char* ademcoEventToString(AdemcoEvent ademcoEvent);
#ifdef ADEMCO_ENABLE_CHINESE
#if ADEMCO_ENABLE_CHINESE
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
const char* ademcoEventToStringChinese(AdemcoEvent ademcoEvent); const char* ademcoEventToStringChinese(AdemcoEvent ademcoEvent);
#endif #endif
//////////////////////// AdemcoDataSegment functions //////////////////////// //////////////////////// AdemcoDataSegment functions ////////////////////////
//! make a `DATA` packet and store to `packet`, return length // make a `DATA` packet and store to `packet`, return length
ADEMCO_EXPORT_SYMBOL size_t ademcoAppendDataSegment(ademco_char_t* packet, ADEMCO_EXPORT_SYMBOL
size_t ademcoAppendDataSegment(ademco_char_t* packet,
const char* acct, const char* acct,
AdemcoId ademcoId, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoEvent ademcoEvent,
AdemcoGG gg, AdemcoGG gg,
AdemcoZone zone); AdemcoZone zone);
//! make a `DATA` packet and store to `dataSegment`, return length // make a `DATA` packet and store to `dataSegment`, return length
ADEMCO_EXPORT_SYMBOL size_t ademcoAppendDataSegment2(AdemcoDataSegment* dataSegment, ADEMCO_EXPORT_SYMBOL
size_t ademcoAppendDataSegment2(AdemcoDataSegment* dataSegment,
const char* acct, const char* acct,
AdemcoId ademcoId, AdemcoId ademcoId,
AdemcoEvent ademcoEvent, AdemcoEvent ademcoEvent,
AdemcoGG gg, AdemcoGG gg,
AdemcoZone zone); AdemcoZone zone);
//! parse `DATA` packet, if ok, `dataSegment`'s members will be useful // parse `DATA` packet, if ok, `dataSegment`'s members will be useful
//! err can be NULL; caller should only check err on got RESULT_ERROR // err can be NULL; caller should only check err on got RESULT_ERROR
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet,
size_t packet_len, size_t packet_len,
...@@ -361,11 +355,12 @@ size_t ademcoDataSegmentToCongwinFe100(ademco_char_t* fe100, ...@@ -361,11 +355,12 @@ size_t ademcoDataSegmentToCongwinFe100(ademco_char_t* fe100,
//////////////////////// AdemcoXDataSegment functions //////////////////////// //////////////////////// AdemcoXDataSegment functions ////////////////////////
// init a empty xdata // init a empty xdata
ADEMCO_EXPORT_SYMBOL void ademcoXDataInit(AdemcoXDataSegment* xdata); ADEMCO_EXPORT_SYMBOL
void ademcoXDataInit(AdemcoXDataSegment* xdata);
// return ADEMCO_OK for success, ADEMCO_ERR for failed // return ADEMCO_OK for success, ADEMCO_ERR for failed
ADEMCO_EXPORT_SYMBOL int ademcoXDataConvert(AdemcoXDataSegment* xdata, ADEMCO_EXPORT_SYMBOL
AdemcoXDataLengthFormat xlf); int ademcoXDataConvert(AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf);
#ifndef SWIG #ifndef SWIG
// get valid content address of xdata (except [len]) // get valid content address of xdata (except [len])
...@@ -378,16 +373,19 @@ ADEMCO_EXPORT_SYMBOL ...@@ -378,16 +373,19 @@ ADEMCO_EXPORT_SYMBOL
size_t ademcoXDataGetValidContentLen(const AdemcoXDataSegment* xdata); size_t ademcoXDataGetValidContentLen(const AdemcoXDataSegment* xdata);
// return 0 if xdata's valid content is exactly the same as [buf, buf+buf_len) // return 0 if xdata's valid content is exactly the same as [buf, buf+buf_len)
ADEMCO_EXPORT_SYMBOL int ademcoXDataMemcmp(const AdemcoXDataSegment* xdata, ADEMCO_EXPORT_SYMBOL
int ademcoXDataMemcmp(const AdemcoXDataSegment* xdata,
const void* buf, const void* buf,
size_t buf_len); size_t buf_len);
// copy xdata content from src to dst, return copied length = src.raw_len // copy xdata content from src to dst, return copied length = src.raw_len
ADEMCO_EXPORT_SYMBOL size_t ademcoXDataCopy(AdemcoXDataSegment* dst, ADEMCO_EXPORT_SYMBOL
size_t ademcoXDataCopy(AdemcoXDataSegment* dst,
const AdemcoXDataSegment* src); const AdemcoXDataSegment* src);
// return ADEMCO_OK for success, return ADEMCO_ERR for len is too long // return ADEMCO_OK for success, return ADEMCO_ERR for len is too long
ADEMCO_EXPORT_SYMBOL int ademcoMakeXData(AdemcoXDataSegment* xdata, ADEMCO_EXPORT_SYMBOL
int ademcoMakeXData(AdemcoXDataSegment* xdata,
AdemcoXDataLengthFormat xlf, AdemcoXDataLengthFormat xlf,
AdemcoXDataTransform xtr, AdemcoXDataTransform xtr,
const ademco_char_t* content, const ademco_char_t* content,
...@@ -395,14 +393,17 @@ ADEMCO_EXPORT_SYMBOL int ademcoMakeXData(AdemcoXDataSegment* xdata, ...@@ -395,14 +393,17 @@ ADEMCO_EXPORT_SYMBOL int ademcoMakeXData(AdemcoXDataSegment* xdata,
//////////////////////// AdemcoPacketId functions //////////////////////// //////////////////////// AdemcoPacketId functions ////////////////////////
ADEMCO_EXPORT_SYMBOL int isAdemcoPacketId(const char* standard, ADEMCO_EXPORT_SYMBOL
int isAdemcoPacketId(const char* standard,
const char* id, const char* id,
size_t len); size_t len);
ADEMCO_EXPORT_SYMBOL AdemcoPacketId getAdemcoPacketId(const char* id, ADEMCO_EXPORT_SYMBOL
AdemcoPacketId getAdemcoPacketId(const char* id,
size_t len); size_t len);
ADEMCO_EXPORT_SYMBOL const char* ademcoPacketIdToString(AdemcoPacketId id); ADEMCO_EXPORT_SYMBOL
const char* ademcoPacketIdToString(AdemcoPacketId id);
/* /*
* ademcoMake*Packet functions * ademcoMake*Packet functions
...@@ -410,45 +411,52 @@ ADEMCO_EXPORT_SYMBOL const char* ademcoPacketIdToString(AdemcoPacketId id); ...@@ -410,45 +411,52 @@ ADEMCO_EXPORT_SYMBOL const char* ademcoPacketIdToString(AdemcoPacketId id);
* otherwise return 0 * otherwise return 0
*/ */
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeEmptyDataPacket(ademco_char_t* dst_buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeEmptyDataPacket(ademco_char_t* dst_buff,
size_t len, size_t len,
const char* id, const char* id,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmEmptyDataPacket(ademco_char_t* dst_buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAdmEmptyDataPacket(ademco_char_t* dst_buff,
size_t len, size_t len,
const char* id, const char* id,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNullPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeNullPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmNullPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAdmNullPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAckPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAckPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNakPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeNakPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeHbPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
...@@ -458,7 +466,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket(ademco_char_t* buff, ...@@ -458,7 +466,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket(ademco_char_t* buff,
AdemcoZone zone, AdemcoZone zone,
const AdemcoXDataSegment* xdata); const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket(ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAdmPacket(ademco_char_t* buff,
size_t len, size_t len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
...@@ -469,22 +478,26 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket(ademco_char_t* buff, ...@@ -469,22 +478,26 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket(ademco_char_t* buff,
const AdemcoXDataSegment* xdata); const AdemcoXDataSegment* xdata);
// like upper funcs, store buff and len to pkt->raw, pkt->raw_len // like upper funcs, store buff and len to pkt->raw, pkt->raw_len
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNullPacket2(AdemcoPacket* pkt, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeNullPacket2(AdemcoPacket* pkt,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAckPacket2(AdemcoPacket* pkt, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAckPacket2(AdemcoPacket* pkt,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeNakPacket2(AdemcoPacket* pkt, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeNakPacket2(AdemcoPacket* pkt,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId); AdemcoId ademcoId);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket2(AdemcoPacket* pkt, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeHbPacket2(AdemcoPacket* pkt,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId, AdemcoId ademcoId,
...@@ -493,7 +506,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket2(AdemcoPacket* pkt, ...@@ -493,7 +506,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeHbPacket2(AdemcoPacket* pkt,
AdemcoZone zone, AdemcoZone zone,
const AdemcoXDataSegment* xdata); const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, ADEMCO_EXPORT_SYMBOL
size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
AdemcoId ademcoId, AdemcoId ademcoId,
...@@ -502,9 +516,10 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, ...@@ -502,9 +516,10 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt,
AdemcoZone zone, AdemcoZone zone,
const AdemcoXDataSegment* xdata); const AdemcoXDataSegment* xdata);
//! parse a ademco packet, if everything is OK, cb_commited is the packet length // parse a ademco packet, if everything is OK, cb_commited is the packet length
//! err can be NULL; caller should only check err on got RESULT_ERROR // err can be NULL; caller should only check err on got RESULT_ERROR
ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff,
size_t len, size_t len,
AdemcoPacket* pkt, AdemcoPacket* pkt,
size_t* cb_commited, size_t* cb_commited,
...@@ -521,8 +536,8 @@ ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const ademco_char_t* bu ...@@ -521,8 +536,8 @@ ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const ademco_char_t* bu
* Xor constant to output CRC : 0x0000 * Xor constant to output CRC : 0x0000
* Output for "123456789" : 0xBB3D * Output for "123456789" : 0xBB3D
*/ */
ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const ademco_char_t* buff, ADEMCO_EXPORT_SYMBOL
size_t len); uint16_t ademcoCRC16(const ademco_char_t* buff, size_t len);
// 将一串以高低字节表示的十六进制数组转换为10进制数字符串 // 将一串以高低字节表示的十六进制数组转换为10进制数字符串
// 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则停止 // 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则停止
...@@ -530,7 +545,8 @@ ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const ademco_char_t* buff, ...@@ -530,7 +545,8 @@ ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const ademco_char_t* buff,
// 注意:函数不会在str末尾补 null terminator // 注意:函数不会在str末尾补 null terminator
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃 // 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101" // 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, ADEMCO_EXPORT_SYMBOL
size_t ademcoHiLoArrayToDecStr(ademco_char_t* str,
const uint8_t* arr, const uint8_t* arr,
size_t len); size_t len);
...@@ -542,7 +558,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, ...@@ -542,7 +558,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr(ademco_char_t* str,
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃 // 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101" // 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
// 示例:输入数组:0x24 0x94 0x94 0x4c 0x48 0x15 0xff,输出字符串"2494944C4815" // 示例:输入数组:0x24 0x94 0x94 0x4c 0x48 0x15 0xff,输出字符串"2494944C4815"
ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr2(ademco_char_t* str, ADEMCO_EXPORT_SYMBOL
size_t ademcoHiLoArrayToDecStr2(ademco_char_t* str,
const uint8_t* arr, const uint8_t* arr,
size_t len); size_t len);
...@@ -558,7 +575,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr2(ademco_char_t* str, ...@@ -558,7 +575,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr2(ademco_char_t* str,
// 0x12 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78 // 0x12 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78
// return 9 // return 9
// 示例:输入NULL,返回 9个 0xFF // 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray(uint8_t* arr, ADEMCO_EXPORT_SYMBOL
size_t ademcoDecStrToHiLoArray(uint8_t* arr,
size_t len, size_t len,
const char* str); const char* str);
...@@ -574,7 +592,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray(uint8_t* arr, ...@@ -574,7 +592,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray(uint8_t* arr,
// 0x12 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78 // 0x12 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78
// return 9 // return 9
// 示例:输入NULL,返回 9个 0xFF // 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray2(uint8_t* arr, ADEMCO_EXPORT_SYMBOL
size_t ademcoDecStrToHiLoArray2(uint8_t* arr,
size_t len, size_t len,
const char* str); const char* str);
...@@ -584,7 +603,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray2(uint8_t* arr, ...@@ -584,7 +603,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoDecStrToHiLoArray2(uint8_t* arr,
// 注意:函数不会在str末尾补 null terminator // 注意:函数不会在str末尾补 null terminator
// 示例:输入 arr=[0xEB 0xBA 0x3F], len=3, 则str = "EBBA3F",返回6 // 示例:输入 arr=[0xEB 0xBA 0x3F], len=3, 则str = "EBBA3F",返回6
// 示例:输入 ary="123", len=3, 则str = "313233",返回6 // 示例:输入 ary="123", len=3, 则str = "313233",返回6
ADEMCO_EXPORT_SYMBOL size_t ademcoHexArrayToStr(char* str, ADEMCO_EXPORT_SYMBOL
size_t ademcoHexArrayToStr(char* str,
const uint8_t* arr, const uint8_t* arr,
size_t len); size_t len);
...@@ -595,14 +615,16 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHexArrayToStr(char* str, ...@@ -595,14 +615,16 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHexArrayToStr(char* str,
// 示例:输入字符串str="EBBA3F", 输出arr = [0xEB, 0xBA, 0x3F],返回 3 // 示例:输入字符串str="EBBA3F", 输出arr = [0xEB, 0xBA, 0x3F],返回 3
// 示例:输入字符串str="ABC", padding = 0, 输出arr=[0xAB, 0xC0],返回2 // 示例:输入字符串str="ABC", padding = 0, 输出arr=[0xAB, 0xC0],返回2
// 示例:输入字符串str="ABC", padding = 0x0F, 输出arr=[0xAB, 0xCF],返回2 // 示例:输入字符串str="ABC", padding = 0x0F, 输出arr=[0xAB, 0xCF],返回2
ADEMCO_EXPORT_SYMBOL size_t ademcoHexStrToArray(uint8_t* arr, ADEMCO_EXPORT_SYMBOL
size_t ademcoHexStrToArray(uint8_t* arr,
const char* str, const char* str,
uint8_t padding); uint8_t padding);
// 功能同ademcoHexStrToArray // 功能同ademcoHexStrToArray
// 若strlen(str) > len, str[len]及之后的内容将被舍弃以避免溢出 // 若strlen(str) > len, str[len]及之后的内容将被舍弃以避免溢出
// 示例:输入字符串str="ABCDE", len = 4 padding = 0x0F, 输出arr=[0xAB, 0xCD], return 2 // 示例:输入字符串str="ABCDE", len = 4 padding = 0x0F, 输出arr=[0xAB, 0xCD], return 2
ADEMCO_EXPORT_SYMBOL size_t ademcoHexStrToArrayN(uint8_t* arr, ADEMCO_EXPORT_SYMBOL
size_t ademcoHexStrToArrayN(uint8_t* arr,
const char* str, const char* str,
size_t len, uint8_t padding); size_t len, uint8_t padding);
...@@ -610,7 +632,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHexStrToArrayN(uint8_t* arr, ...@@ -610,7 +632,8 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHexStrToArrayN(uint8_t* arr,
// 即'0'~'9','a'~'f','A'~'F'之外的内容,以 padding 替换 // 即'0'~'9','a'~'f','A'~'F'之外的内容,以 padding 替换
// 示例:str="AB\xFFD", len=4, padding=0x0F, 则 arr=[ 0xAB, 0xFD ], return 2 // 示例:str="AB\xFFD", len=4, padding=0x0F, 则 arr=[ 0xAB, 0xFD ], return 2
// 网线主机 0d 00 命令,接警中心账号部分,有可能是这种 // 网线主机 0d 00 命令,接警中心账号部分,有可能是这种
ADEMCO_EXPORT_SYMBOL size_t ademcoHexStrToArrayN_allow_non_hex_str(uint8_t* arr, ADEMCO_EXPORT_SYMBOL
size_t ademcoHexStrToArrayN_allow_non_hex_str(uint8_t* arr,
const char* str, const char* str,
size_t len, size_t len,
uint8_t padding); uint8_t padding);
......
#ifndef __ADEMCO_CONFIG_H__
#define __ADEMCO_CONFIG_H__
#pragma once
#ifdef ADEMCO_EXPORTS
#if defined __GNUC__
#define ADEMCO_EXPORT_SYMBOL __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#define ADEMCO_EXPORT_SYMBOL __declspec(dllexport)
#else
#define ADEMCO_EXPORT_SYMBOL
#endif
#else // ADEMCO_EXPORTS
#define ADEMCO_EXPORT_SYMBOL
#endif // ADEMCO_EXPORTS
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
#define ademco_char_t uint8_t
#else
#define ademco_char_t char
#endif
#ifndef ADEMCO_ENABLE_CHINESE
#define ADEMCO_ENABLE_CHINESE 1
#endif
#ifndef ADEMCO_ENABLE_PARSE_ERROR
#define ADEMCO_ENABLE_PARSE_ERROR 1
#endif
#if ADEMCO_ENABLE_PARSE_ERROR
#define ADEMCO_FILL_PARSE_ERROR(err, offset_, msg_) \
do { \
if (err) { \
err->line = __LINE__; \
err->offset = (offset_); \
err->msg = (msg_); \
} \
} while (0);
#else
#define ADEMCO_FILL_PARSE_ERROR(err, offset_, msg_)
#endif // ADEMCO_ENABLE_PARSE_ERROR
#endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
*/ */
#define ADEMCO_VERSION_MAJOR 1 #define ADEMCO_VERSION_MAJOR 1
#define ADEMCO_VERSION_MINOR 1 #define ADEMCO_VERSION_MINOR 2
#define ADEMCO_VERSION_PATCH 0 #define ADEMCO_VERSION_PATCH 0
#define ADEMCO_VERSION_IS_RELEASE 1 #define ADEMCO_VERSION_IS_RELEASE 1
#define ADEMCO_VERSION_SUFFIX "" #define ADEMCO_VERSION_SUFFIX ""
......
...@@ -62,15 +62,14 @@ ...@@ -62,15 +62,14 @@
* `1/3` 前缀,`1` 表示打开,`3` 表示关闭。如 `3400` 表示布防,`1400` 表示撤防。 * `1/3` 前缀,`1` 表示打开,`3` 表示关闭。如 `3400` 表示布防,`1400` 表示撤防。
* `E/R` 前缀,`E` 表示打开,`R` 表示关闭。如 `R400` 表示布防,`E400` 表示撤防。 * `E/R` 前缀,`E` 表示打开,`R` 表示关闭。如 `R400` 表示布防,`E400` 表示撤防。
* 报警时 `1/E` 前缀表示警情触发,`3/R` 表示警情恢复,如 `1387` 表示探测器受到强光干扰,`3387` 表示防区从光扰状态恢复。 * 报警时 `1/E` 前缀表示警情触发,`3/R` 表示警情恢复,如 `1387` 表示探测器受到强光干扰,`3387` 表示防区从光扰状态恢复。
### 主机状态 ### 主机状态
|事件码|含义|en| |事件码|含义|en|
|-----|----|--| |-----|----|--|
|3400|布防|ARM| |3400|布防|ARM|
|1400|撤防|DISARM| |1400|撤防|DISARM|
|1456|半布防|HALFARM|
|3456|半布防|HALFARM| |3456|半布防|HALFARM|
|1456|半布防|HALFARM_1456|
|1120|紧急报警|EMERGENCY| |1120|紧急报警|EMERGENCY|
### 防区报警 ### 防区报警
...@@ -83,93 +82,93 @@ ...@@ -83,93 +82,93 @@
|1121|胁迫|DURESS| |1121|胁迫|DURESS|
|1151|煤气|GAS| |1151|煤气|GAS|
|1113|水警|WATER| |1113|水警|WATER|
|1137|防拆|TAMPER| |1137|主机防拆|TAMPER|
|1383|防区防拆|ZONE_TAMPER| |1383|防区防拆|ZONE_TAMPER|
|1570|旁路|BYPASS| |1570|旁路|BYPASS|
|3570|解除旁路|BYPASS_RESUME|
### 防区异常 ### 防区异常
|事件码|含义|en| |事件码|含义|en|
|-----|----|--| |-----|----|--|
|1301|主机AC掉电|AC BROKE| |1301|主机AC掉电|AC_BROKE|
|3301|主机AC恢复|AC RECOVER|
|1302|低电|LOWBATTERY| |1302|低电|LOWBATTERY|
|3302|复电|BATATTERY_RECOVER|
|1311|坏电|BADBATTERY| |1311|坏电|BADBATTERY|
|3311|坏电恢复|BADBATTERY_RECOVER|
|1387|光扰|SOLARDISTURB| |1387|光扰|SOLARDISTURB|
|3387|光扰恢复|SOLARDISTURB_RECOVER|
|1381|失效|DISCONNECT| |1381|失效|DISCONNECT|
|3381|恢复|RECONNECT|
|1384|防区电源故障|BATTERY_EXCEPTION|
|3384|防区电源故障恢复|BATTERY_EXCEPTION_RECOVER|
|1380|防区其他故障|OTHER_EXCEPTION|
|3380|防区其他故障恢复|OTHER_EXCEPTION_RECOVER|
|1393|失联|LOST| |1393|失联|LOST|
|3393|恢复|LOST_RECOVER| |1384|电源故障|BATTERY_EXCEPTION|
|3100|液晶主机清除异常指示|LCD CLEAR EXCEPTION| |1380|其他故障|OTHER_EXCEPTION|
|3570|解除旁路|BYPASS_RESUME|
|3301|主机AC复电|AC_RECOVER|
|3302|低电恢复|BATTERY_RECOVER|
|3311|坏电恢复|BADBATTERY_RECOVER|
|3387|光扰恢复|SOLARDISTURB_RECOVER|
|3381|失效恢复|RECONNECT|
|3393|失联恢复|LOST_RECOVER|
|3384|电源故障恢复|BATTERY_EXCEPTION_RECOVER|
|3380|其他故障恢复|OTHER_EXCEPTION_RECOVER|
|3100|清除异常指示|CLEAR_EXCPTION|
### *恒博私有事件码* ### *恒博私有事件码*
|事件码|含义|en| |事件码|含义|en|
|-----|----|--| |-----|----|--|
|1485|485断开|485DIS| |1485|485断开|SERIAL485DIS|
|3485|485恢复|485CONN| |3485|485连接|SERIAL485CONN|
|1700|链路挂起|CONN_HANGUP| |1700|链路挂起|CONN_HANGUP|
|3700|链路恢复|CONN_RESUME| |3700|链路恢复|CONN_RESUME|
|1701|撤防密码错误|DISARM_PWD_ERR| |1701|撤防密码错误|DISARM_PWD_ERR|
|1702|分防区异常|SUB_SENSOR_EXCEPTION| |1702|分机探头异常|SUB_MACHINE_SENSOR_EXCEPTION|
|3702|分防区恢复|SUB_SENSOR_RESUME| |3702|分机探头恢复|SUB_MACHINE_SENSOR_RESUME|
|1703|分防区电源异常|SUB_POWER_EXCEPTION| |1703|分机电源异常|SUB_MACHINE_POWER_EXCEPTION|
|3703|分防区电源恢复|SUB_POWER_RESUME| |3703|分机电源恢复|SUB_MACHINE_POWER_RESUME|
|1704|串口透传|COM_PASSTHROUGH| |1704|串口透传|COM_PASSTHROUGH|
|2704|进入设置状态|ENTER_SET_MODE| |2704|进入设置状态|ENTER_SET_MODE|
|3704|拒绝/停止设置|EXIT_SET_MODE| |3704|退出设置状态|EXIT_SET_MODE|
|1705|查询|QUERY| |1705|查询分机信息|QUERY_SUB_MACHINE|
|1706|写入主机信息|WRITE_TO_MACHINE| |1706|写入主机信息|WRITE_TO_MACHINE|
|1707|我是网络模块|I_AM_NET_MODULE| |1707|主机类型--网络模块|I_AM_NET_MODULE|
|1717|我是GPRS主机|I_AM_GPRS_MACHINE| |1717|主机类型--GPRS主机|I_AM_GPRS|
|1727|我是液晶主机|I_AM_LCD_MACHINE| |1727|主机类型--液晶主机|I_AM_LCD_MACHINE|
|1737|我是网线主机|I_AM_WIRE_MACHINE| |1737|主机类型--网线主机|I_AM_WIRE_MACHINE|
|1747|我是WiFi主机|I_AM_WIFI_MACHINE| |1747|主机类型--WiFi主机(停用)|I_AM_WIFI_MACHINE|
|1757|我是三区段主机|I_AM_3_SECTION_MACHINE| |1757|主机类型--三区段主机|I_AM_3_SECTION_MACHINE|
|1767|我是物联卡主机|I_AM_IOT_MACHINE| |1767|主机类型--物联卡主机|I_AM_IOT_MACHINE|
|1777|我是真彩主机|I_AM_TRUE_COLOR| |1777|主机类型--真彩主机|I_AM_TRUE_COLOR|
|1787|我是简化版物联卡主机|I_AM_GPRS_IOT| |1787|主机类型--物联卡主机|I_AM_GPRS_IOT|
|1797|我是GPRS主机能打电话|I_AM_GPRS_PHONE| |1797|主机类型--GRPS主机带电话功能|I_AM_GPRS_PHONE|
|1807|我是NB报警接收主机|I_AM_NB_MACHINE| |1807|主机类型--NB报警接收主机|I_AM_NB_MACHINE|
|1817|我是WiFi主机新版|I_AM_WIFI2_MACHINE| |1817|主机类型--WiFi主机(新版)|I_AM_WIFI2_MACHINE|
|1709|手机用户SOS|SOS| |1709|手机用户SOS|PHONE_USER_SOS|
|1711|手机用户消警|PHONE_USER_CANCLE_ALARM| |1711|手机用户消警|PHONE_USER_CANCLE_ALARM|
|1712|主机进入设置状态|ENTER_SETTING_MODE| |1712|主机进入设置状态|ENTER_SETTING_MODE|
|3712|主机退出设置状态|EXIT_SETTING_MODE| |3712|主机退出设置状态|EXIT_SETTING_MODE|
|1710|主机恢复出厂设置|RESTORE_FACTORY_SETTINGS| |1710|主机恢复出厂设置|RESTORE_FACTORY_SETTINGS_710|
|1713|主机恢复出厂设置|RESTORE_FACTORY_SETTINGS| |1713|主机恢复出厂设置|RESTORE_FACTORY_SETTINGS|
|1756|SIM卡为物联卡|SIM card is IOT| |1756|物联卡|SIM_IS_IOT_CARD|
|2756|SIM卡为平台物联卡|SIM card is Platform IOT| |2756|平台物联卡|SIM_IS_IOT_PLATFORM_CARD|
|3756|SIM卡为非物联卡|SIM card is not IOT| |3756|非物联卡|SIM_IS_NOT_IOT_CARD|
|1798|索要主机类型|WHAT_IS_YOUR_TYPE| |1798|索要主机类型|WHAT_IS_YOUR_TYPE|
|1799|信号强度变化|SIGNAL_STRENGTH_CHANGED| |1799|信号强度|SIGNAL_STRENGTH_CHANGED|
|1944|上线|EVENT_OFFLINE| |1944|主机断线|OFFLINE|
|1946|离线|EVENT_ONLINE| |1946|主机上线|ONLINE|
### *恒博主机类型对照表* ### *恒博主机类型对照表*
*SMS指主机自身是否可以拨打电话、发送短信,不是指通过阿里语音打电话* *SMS指主机自身是否可以拨打电话、发送短信,不是指通过阿里语音打电话*
|事件码类型|主机类型|布防|撤防|半布防|设置|信号强度|防区|有线防区|SMS|内核|网络|型号| |事件码类型|主机类型|布防|撤防|半布防|设置|信号强度|防区|有线防区|SMS|内核|网络|型号|
|---------|-------|----|----|-----|----|-------|----|-------|---|----|---|----| |---------|-------|----|----|-----|----|-------|----|-------|---|----|---|----|
|1707 我是网络模块|3 网络模块+工程主机|√|√|√|√| |1~999|1~8| |jjf|qfm|<ul><li>G250</li></ul>| |1707 主机类型--网络模块|网络模块主机|√|√|√|√| |1~999|1~8| |jjf|qfm|<ul><li>G250</li></ul>|
|1717 我是GPRS主机|4 GPRS主机|√|√| |√|√|1~99| |√|wzq|qfm|<ul><li>4040G</li><li>5050G</li><li>5050G-4G</li></ul>| |1717 主机类型--GPRS主机|GPRS主机|√|√| |√|√|1~99| |√|wzq|qfm|<ul><li>4040G</li><li>5050G</li><li>5050G-4G</li></ul>|
|1727 我是液晶主机|5 液晶主机|√|√|√|√|√|1~249| |√|jjf|qfm|<ul><li>BJQ560</li><li>BJQ560B</li></ul>| |1727 主机类型--液晶主机|液晶主机|√|√|√|√|√|1~249| |√|jjf|qfm|<ul><li>BJQ560</li><li>BJQ560B</li></ul>|
|1737 我是网线主机|6 网线主机|√|√| |√| |1~99| | |wzq|qfm|<ul><li>4040R</li><li>5050R</li></ul>| |1737 主机类型--网线主机|网线主机|√|√| |√| |1~99| | |wzq|qfm|<ul><li>4040R</li><li>5050R</li></ul>|
|1757 我是三区段主机|8 三区段主机|√|√| |√|√|1~191|61~68|√|jjf|qfm|<ul><li>G1000</li><li>G1000-4G</li></ul>| |1757 主机类型--三区段主机|三区段主机|√|√| |√|√|1~191|61~68|√|jjf|qfm|<ul><li>G1000</li><li>G1000-4G</li></ul>|
|1767 我是物联卡主机|9 物联卡主机|√|√| |√|√|1~60| | |jjf|qfm|<ul><li>2050-4GW</li></ul>| |1767 主机类型--物联卡主机|物联卡主机|√|√| |√|√|1~60| | |jjf|qfm|<ul><li>2050-4GW</li></ul>|
|1777 我是真彩主机|7 真彩主机|√|√| |√|√|1~68|1~8|√|jjf|qfm|<ul><li>G1000</li><li>G1000-4G</li></ul>| |1777 主机类型--真彩主机|真彩主机|√|√| |√|√|1~68|1~8|√|jjf|qfm|<ul><li>G1000</li><li>G1000-4G</li></ul>|
|1787 我是简化版物联卡主机|2 简化的物联卡主机|√|√| |√|√|1~99| | |wzq|qfm|<ul><li>5050G-4GW</li></ul>| |1787 主机类型--物联卡主机|简化物联卡主机|√|√| |√|√|1~99| | |wzq|qfm|<ul><li>5050G-4GW</li></ul>|
|1797 我是GPRS主机能打电话|10 GPRS主机能打电话|√|√| |√|√|1~60| |√|jjf|qfm|<ul><li>2050</li></ul>| |1797 主机类型--GRPS主机带电话功能|GPRS主机可电话|√|√| |√|√|1~60| |√|jjf|qfm|<ul><li>2050</li></ul>|
|1807 我是NB报警接收主机|11 NB报警接收主机| | | |√|√|1~999| | |||<ul></ul>| |1807 主机类型--NB报警接收主机|NB报警接收主机| | | |√|√|1~999| | |||<ul></ul>|
|1817 我是WiFi主机新版|12 WiFi主机新版|√|√| |√| |1~99| | |wzq|qfm|<ul></ul>| |1817 主机类型--WiFi主机(新版)|WiFi主机新版|√|√| |√|√|1~99| | |wzq|qfm|<ul></ul>|
### *恒博主机型号示例图片* ### *恒博主机型号示例图片*
......
...@@ -59,6 +59,12 @@ AdemcoEvent allEvents[] = { ...@@ -59,6 +59,12 @@ AdemcoEvent allEvents[] = {
#undef XX #undef XX
}; };
HbZoneProperty allZoneProperties[] = {
#define XX(name, value, str) HZP_##name,
HB_ZONE_PROPERTY_MAP(XX)
#undef XX
};
void printEvents(const AdemcoEvent* events, size_t len) void printEvents(const AdemcoEvent* events, size_t len)
{ {
printf("|事件码|含义|en|\n|-----|----|--|\n"); printf("|事件码|含义|en|\n|-----|----|--|\n");
...@@ -85,7 +91,7 @@ const char* get_core_author(HbMachineType t) ...@@ -85,7 +91,7 @@ const char* get_core_author(HbMachineType t)
case HMT_NETMOD: case HMT_NETMOD:
case HMT_LCD: case HMT_LCD:
case HMT_TRUE_COLOR: case HMT_TRUE_COLOR:
case HMT_3_SECTION: case HMT_THREE_SECTION:
case HMT_IOT: case HMT_IOT:
case HMT_GPRS_PHONE: case HMT_GPRS_PHONE:
return "jjf"; return "jjf";
...@@ -104,7 +110,7 @@ const char* get_net_author(HbMachineType t) ...@@ -104,7 +110,7 @@ const char* get_net_author(HbMachineType t)
case HMT_GPRS: case HMT_GPRS:
case HMT_LCD: case HMT_LCD:
case HMT_TRUE_COLOR: case HMT_TRUE_COLOR:
case HMT_3_SECTION: case HMT_THREE_SECTION:
case HMT_IOT: case HMT_IOT:
case HMT_GPRS_PHONE: case HMT_GPRS_PHONE:
case HMT_WIFI2: case HMT_WIFI2:
...@@ -125,7 +131,7 @@ std::vector<std::string> get_machine_brands(HbMachineType t) ...@@ -125,7 +131,7 @@ std::vector<std::string> get_machine_brands(HbMachineType t)
case HMT_LCD: return { "BJQ560", "BJQ560B" }; case HMT_LCD: return { "BJQ560", "BJQ560B" };
case HMT_WIRED: return { "4040R", "5050R" }; case HMT_WIRED: return { "4040R", "5050R" };
case HMT_TRUE_COLOR:return { "G1000", "G1000-4G" }; case HMT_TRUE_COLOR:return { "G1000", "G1000-4G" };
case HMT_3_SECTION:return { "G1000", "G1000-4G" }; case HMT_THREE_SECTION:return { "G1000", "G1000-4G" };
case HMT_IOT: return { "2050-4GW" }; case HMT_IOT: return { "2050-4GW" };
case HMT_GPRS_PHONE: return { "2050" }; case HMT_GPRS_PHONE: return { "2050" };
//case hb::common::Nb: return { "" }; //case hb::common::Nb: return { "" };
...@@ -247,19 +253,19 @@ void print_available_zone_props() ...@@ -247,19 +253,19 @@ void print_available_zone_props()
printf("* 防区属性是否支持失联报告\n\n"); printf("* 防区属性是否支持失联报告\n\n");
printf("|"); printf("|");
for (auto zp : hbZoneProperties) { for (auto zp : allZoneProperties) {
printf("|"); print_prop(zp); printf("|"); print_prop(zp);
} }
printf("|\n"); printf("|\n");
printf("|----"); printf("|----");
for (size_t i = 0; i < sizeof(hbZoneProperties) / sizeof(hbZoneProperties[0]); i++) { for (size_t i = 0; i < sizeof(allZoneProperties) / sizeof(allZoneProperties[0]); i++) {
printf("|----"); printf("|----");
} }
printf("|\n"); printf("|\n");
printf("|失联支持"); printf("|失联支持");
for (auto zp : hbZoneProperties) { for (auto zp : allZoneProperties) {
printf("|%s", print_bool(hbZonePropCanReportLost(zp))); printf("|%s", print_bool(hbZonePropCanReportLost(zp)));
} }
printf("|\n\n"); printf("|\n\n");
...@@ -267,14 +273,14 @@ void print_available_zone_props() ...@@ -267,14 +273,14 @@ void print_available_zone_props()
printf("* 主机类型与支持的防区属性对照表\n\n"); printf("* 主机类型与支持的防区属性对照表\n\n");
printf("|事件码|类型|型号"); printf("|事件码|类型|型号");
for (auto zp : hbZoneProperties) { for (auto zp : allZoneProperties) {
//printf("|"); print_prop(zp); //printf("|"); print_prop(zp);
printf("|%02X", (int)zp); printf("|%02X", (int)zp);
} }
printf("|\n"); printf("|\n");
printf("|----|----|----"); printf("|----|----|----");
for (size_t i = 0; i < sizeof(hbZoneProperties) / sizeof(hbZoneProperties[0]); i++) { for (size_t i = 0; i < sizeof(allZoneProperties) / sizeof(allZoneProperties[0]); i++) {
printf("|----"); printf("|----");
} }
printf("|\n"); printf("|\n");
...@@ -288,7 +294,7 @@ void print_available_zone_props() ...@@ -288,7 +294,7 @@ void print_available_zone_props()
print_machine_brands(t); print_machine_brands(t);
HbZoneProperty avail_props[12]; HbZoneProperty avail_props[12];
int count = hbGetAvailableZoneProperties(t, avail_props); int count = hbGetAvailableZoneProperties(t, avail_props);
for (auto zp : hbZoneProperties) { for (auto zp : allZoneProperties) {
printf("|%s", print_bool(zprop_is_contain(avail_props, count, zp))); printf("|%s", print_bool(zprop_is_contain(avail_props, count, zp)));
} }
printf("|\n"); printf("|\n");
......
#include "hb_com.h" #include "hb_com.h"
#include <string.h> #include <string.h>
int hbGetAvailableZoneProperties(HbMachineType type, int hbGetAvailableZoneProperties(HbMachineType type,
HbZoneProperty props[12]) { HbZoneProperty props[HZP_COUNT]) {
switch (type) { switch (type) {
case HMT_WIFI: case HMT_WIFI:
break; break;
...@@ -10,94 +11,110 @@ int hbGetAvailableZoneProperties(HbMachineType type, ...@@ -10,94 +11,110 @@ int hbGetAvailableZoneProperties(HbMachineType type,
break; break;
case HMT_GPRS_IOT: case HMT_GPRS_IOT:
case HMT_GPRS: case HMT_GPRS:
case HMT_WIFI2: case HMT_WIFI2: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_EMERGENCY,
HZP_FIRE,
HZP_DURESS,
HZP_GAS,
HZP_WATER,
HZP_REMOTE_CONTROL,
}; };
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_NETMOD: case HMT_NETMOD: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_SUB_MACHINE, HZP_EMERGENCY,
HZP_REMOTE_CONTROL, HZP_BUGLAR_HALF, HZP_SHIELD, HZP_DOOR_RING, HZP_FIRE,
HZP_DURESS,
HZP_GAS,
HZP_WATER,
HZP_SUB_MACHINE,
HZP_REMOTE_CONTROL,
HZP_BUGLAR_HALF,
HZP_SHIELD,
HZP_DOOR_RING,
}; };
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_LCD: case HMT_LCD: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_SUB_MACHINE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_SUB_MACHINE,
HZP_REMOTE_CONTROL, HZP_BUGLAR_HALF, HZP_SHIELD, HZP_REMOTE_CONTROL, HZP_BUGLAR_HALF, HZP_SHIELD,
HZP_DOOR_RING, HZP_BYPASS HZP_DOOR_RING, HZP_BYPASS};
};
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_WIRED: case HMT_WIRED: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_EMERGENCY,
HZP_FIRE,
HZP_DURESS,
HZP_GAS,
HZP_WATER,
HZP_REMOTE_CONTROL,
}; };
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_TRUE_COLOR: case HMT_TRUE_COLOR: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
};
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_3_SECTION: case HMT_THREE_SECTION: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
};
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_IOT: case HMT_IOT: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
};
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_GPRS_PHONE: case HMT_GPRS_PHONE: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_EMERGENCY,
HZP_FIRE,
HZP_DURESS,
HZP_GAS,
HZP_WATER,
HZP_REMOTE_CONTROL,
}; };
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
case HMT_NB: case HMT_NB: {
{
HbZoneProperty hzps[] = { HbZoneProperty hzps[] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_BUGLAR,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_DOOR_RING, HZP_EMERGENCY,
HZP_FIRE,
HZP_DURESS,
HZP_GAS,
HZP_WATER,
HZP_DOOR_RING,
}; };
memcpy(props, hzps, sizeof(hzps)); memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty); return sizeof(hzps) / sizeof(HbZoneProperty);
} }
default: return 0; default:
return 0;
} }
return 0; return 0;
} }
...@@ -120,7 +137,7 @@ uint16_t hbZoneMax(HbMachineType type) { ...@@ -120,7 +137,7 @@ uint16_t hbZoneMax(HbMachineType type) {
case HMT_TRUE_COLOR: case HMT_TRUE_COLOR:
return 68; return 68;
case HMT_3_SECTION: case HMT_THREE_SECTION:
return 191; return 191;
case HMT_IOT: case HMT_IOT:
...@@ -152,7 +169,7 @@ int hbMachineIsSelling(HbMachineType type) { ...@@ -152,7 +169,7 @@ int hbMachineIsSelling(HbMachineType type) {
type == HMT_LCD || type == HMT_LCD ||
type == HMT_WIRED || type == HMT_WIRED ||
type == HMT_TRUE_COLOR || type == HMT_TRUE_COLOR ||
type == HMT_3_SECTION || type == HMT_THREE_SECTION ||
type == HMT_GPRS_PHONE || type == HMT_GPRS_PHONE ||
type == HMT_NB || type == HMT_NB ||
type == HMT_WIFI2; type == HMT_WIFI2;
...@@ -180,7 +197,7 @@ int hbMachineCanReportSignalStrength(HbMachineType type) { ...@@ -180,7 +197,7 @@ int hbMachineCanReportSignalStrength(HbMachineType type) {
type == HMT_IOT || type == HMT_IOT ||
type == HMT_LCD || type == HMT_LCD ||
type == HMT_TRUE_COLOR || type == HMT_TRUE_COLOR ||
type == HMT_3_SECTION || type == HMT_THREE_SECTION ||
type == HMT_GPRS_PHONE || type == HMT_GPRS_PHONE ||
type == HMT_NB || type == HMT_NB ||
type == HMT_WIFI2; type == HMT_WIFI2;
...@@ -190,31 +207,39 @@ int hbMachineCanReportBySMS(HbMachineType type) { ...@@ -190,31 +207,39 @@ int hbMachineCanReportBySMS(HbMachineType type) {
return type == HMT_GPRS || return type == HMT_GPRS ||
type == HMT_LCD || type == HMT_LCD ||
type == HMT_TRUE_COLOR || type == HMT_TRUE_COLOR ||
type == HMT_3_SECTION || type == HMT_THREE_SECTION ||
type == HMT_GPRS_PHONE; type == HMT_GPRS_PHONE;
} }
int hbMachineHasWiredZone(HbMachineType type) { int hbMachineHasWiredZone(HbMachineType type) {
return type == HMT_NETMOD || return type == HMT_NETMOD ||
type == HMT_TRUE_COLOR || type == HMT_TRUE_COLOR ||
type == HMT_3_SECTION; type == HMT_THREE_SECTION;
} }
AdemcoZone hbWiredZoneMin(HbMachineType type) { AdemcoZone hbWiredZoneMin(HbMachineType type) {
switch (type) { switch (type) {
case HMT_NETMOD: return 1; case HMT_NETMOD:
case HMT_TRUE_COLOR: return 1; return 1;
case HMT_3_SECTION: return 61; case HMT_TRUE_COLOR:
default: return 0; return 1;
case HMT_THREE_SECTION:
return 61;
default:
return 0;
} }
} }
AdemcoZone hbWiredZoneMax(HbMachineType type) { AdemcoZone hbWiredZoneMax(HbMachineType type) {
switch (type) { switch (type) {
case HMT_NETMOD: return 8; case HMT_NETMOD:
case HMT_TRUE_COLOR: return 8; return 8;
case HMT_3_SECTION: return 68; case HMT_TRUE_COLOR:
default: return 0; return 8;
case HMT_THREE_SECTION:
return 68;
default:
return 0;
} }
} }
...@@ -288,24 +313,28 @@ void hbMachineTimerFromGreenwich(HbMachineTimer* timer) { ...@@ -288,24 +313,28 @@ void hbMachineTimerFromGreenwich(HbMachineTimer* timer) {
AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status) { AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status) {
switch (status) { switch (status) {
case HMS_ARM: return EVENT_ARM; #define XX(hms, ae) \
case HMS_DISARM: return EVENT_DISARM; case hms: \
case HMS_HALF_ARM: return EVENT_HALFARM; // EVENT_HALFARM_1456 return ae;
case HMS_SETTING: return EVENT_ENTER_SETTING_MODE; // EVENT_ENTER_SET_MODE
default: return EVENT_INVALID_EVENT; HMS_EVENT_MAP(XX)
#undef XX
default:
return EVENT_INVALID_EVENT;
} }
} }
HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent) { HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent) {
switch (ademcoEvent) { switch (ademcoEvent) {
case EVENT_ARM: #define XX(hms, ae) \
return HMS_ARM; case ae: \
case EVENT_DISARM: return hms;
return HMS_DISARM;
case EVENT_HALFARM: HMS_EVENT_MAP(XX)
#undef XX
case EVENT_HALFARM_1456: case EVENT_HALFARM_1456:
return HMS_HALF_ARM; return HMS_HALF_ARM;
case EVENT_ENTER_SETTING_MODE:
case EVENT_ENTER_SET_MODE: case EVENT_ENTER_SET_MODE:
return HMS_SETTING; return HMS_SETTING;
default: default:
...@@ -315,154 +344,121 @@ HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent) { ...@@ -315,154 +344,121 @@ HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent) {
AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type) { AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type) {
switch (type) { switch (type) {
case HMT_WIFI: return EVENT_I_AM_WIFI_MACHINE; #define XX(hmt, ae) \
case HMT_GPRS_IOT: return EVENT_I_AM_GPRS_IOT; case hmt: \
case HMT_NETMOD: return EVENT_I_AM_NET_MODULE; return ae;
case HMT_GPRS: return EVENT_I_AM_GPRS;
case HMT_LCD: return EVENT_I_AM_LCD_MACHINE; HMT_EVENT_MAP(XX)
case HMT_WIRED: return EVENT_I_AM_WIRE_MACHINE; #undef XX
case HMT_TRUE_COLOR: return EVENT_I_AM_TRUE_COLOR;
case HMT_3_SECTION: return EVENT_I_AM_3_SECTION_MACHINE; default:
case HMT_IOT: return EVENT_I_AM_IOT_MACHINE; return EVENT_INVALID_EVENT;
case HMT_GPRS_PHONE: return EVENT_I_AM_GPRS_PHONE;
case HMT_NB: return EVENT_I_AM_NB_MACHINE;
case HMT_WIFI2: return EVENT_I_AM_WIFI2_MACHINE;
default: return EVENT_INVALID_EVENT;
} }
} }
HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent) { HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent) {
switch (ademcoEvent) { switch (ademcoEvent) {
case EVENT_I_AM_NET_MODULE: return HMT_NETMOD; #define XX(hmt, ae) \
case EVENT_I_AM_GPRS: return HMT_GPRS; case ae: \
case EVENT_I_AM_LCD_MACHINE: return HMT_LCD; return hmt;
case EVENT_I_AM_WIRE_MACHINE: return HMT_WIRED;
case EVENT_I_AM_WIFI_MACHINE: return HMT_WIFI; HMT_EVENT_MAP(XX)
case EVENT_I_AM_3_SECTION_MACHINE: return HMT_3_SECTION; #undef XX
case EVENT_I_AM_IOT_MACHINE: return HMT_IOT;
case EVENT_I_AM_TRUE_COLOR: return HMT_TRUE_COLOR; default:
case EVENT_I_AM_GPRS_IOT: return HMT_GPRS_IOT; return HMT_INVALID;
case EVENT_I_AM_GPRS_PHONE: return HMT_GPRS_PHONE;
case EVENT_I_AM_NB_MACHINE: return HMT_NB;
case EVENT_I_AM_WIFI2_MACHINE: return HMT_WIFI2;
default: return HMT_INVALID;
} }
} }
AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp) { AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp) {
switch (zp) { switch (zp) {
case HZP_BUGLAR: #define XX(hzp, ae) \
case HZP_BUGLAR_HALF: return EVENT_BURGLAR; case hzp: \
case HZP_EMERGENCY: return EVENT_EMERGENCY; return ae;
case HZP_FIRE: return EVENT_FIRE;
case HZP_DURESS: return EVENT_DURESS; HZP_EVENT_MAP(XX)
case HZP_GAS: return EVENT_GAS; #undef XX
case HZP_WATER: return EVENT_WATER;
case HZP_DOOR_RING: return EVENT_DOORRINGING; default:
default: return EVENT_INVALID_EVENT; return EVENT_INVALID_EVENT;
} }
} }
const char* hbMachineStatusToString(HbMachineStatus status) { const char* hbMachineStatusToString(HbMachineStatus status) {
switch (status) { switch (status) {
case HMS_ARM: return "Arm"; #define XX(name, value, str) \
case HMS_HALF_ARM: return "Half-Arm"; case HMS_##name: \
case HMS_DISARM: return "Disarm"; return #name;
case HMS_SETTING: return "Setting"; HB_MACHINE_STATUS_MAP(XX)
default: return "InvalidMachineStatus"; #undef XX
default:
return "InvalidMachineStatus";
} }
} }
const char* hbMachineTypeToString(HbMachineType type) { const char* hbMachineTypeToString(HbMachineType type) {
switch (type) { switch (type) {
case HMT_WIFI: return "0 WiFi"; #define XX(name, value, str) \
case HMT_CAMERA: return "1 Camera"; case HMT_##name: \
case HMT_GPRS_IOT: return "2 Gprs_IoT"; return #name;
case HMT_NETMOD: return "3 NetMod"; HB_MACHINE_TYPE_MAP(XX)
case HMT_GPRS: return "4 GPRS"; #undef XX
case HMT_LCD: return "5 LCD";
case HMT_WIRED: return "6 Wired"; default:
case HMT_TRUE_COLOR: return "7 TrueColor"; return "Unknown HbMachineType";
case HMT_3_SECTION: return "8 ThreeSection";
case HMT_IOT: return "9 IoT";
case HMT_GPRS_PHONE: return "10 Gprs_Phone";
case HMT_NB: return "11 Nb";
case HMT_WIFI2: return "12 WiFi2";
default: return "Unknown HbMachineType";
} }
} }
const char* hbZonePropertyToString(HbZoneProperty zp) { const char* hbZonePropertyToString(HbZoneProperty zp) {
switch (zp) { switch (zp) {
case HZP_BUGLAR: return "HZP_BUGLAR"; #define XX(name, value, str) \
case HZP_EMERGENCY: return "HZP_EMERGENCY"; case HZP_##name: \
case HZP_FIRE: return "HZP_FIRE"; return #name;
case HZP_DURESS: return "HZP_DURESS"; HB_ZONE_PROPERTY_MAP(XX)
case HZP_GAS: return "HZP_GAS"; #undef XX
case HZP_WATER: return "HZP_WATER";
case HZP_SUB_MACHINE: return "HZP_SUB_MACHINE"; default:
case HZP_REMOTE_CONTROL: return "HZP_REMOTE_CONTROL"; return "InvalidZoneProperty";
case HZP_BUGLAR_HALF: return "HZP_BUGLAR_HALF"; }
case HZP_SHIELD: return "HZP_SHIELD"; }
case HZP_DOOR_RING: return "HZP_DOOR_RING";
case HZP_RESERVED_0B: return "Reserved0B"; #if ADEMCO_ENABLE_CHINESE
case HZP_RESERVED_0C: return "Reserved0C";
case HZP_RESERVED_0D: return "Reserved0D";
case HZP_RESERVED_0E: return "Reserved0E";
case HZP_BYPASS: return "HZP_BYPASS";
default: return "InvalidZoneProperty";
}
}
#ifdef ADEMCO_ENABLE_CHINESE
const char* hbMachineStatusToStringChinese(HbMachineStatus status) { const char* hbMachineStatusToStringChinese(HbMachineStatus status) {
switch (status) { switch (status) {
case HMS_ARM: return "布防"; #define XX(name, value, str) \
case HMS_HALF_ARM: return "半布防"; case HMS_##name: \
case HMS_DISARM: return "撤防"; return str;
case HMS_SETTING: return "设置"; HB_MACHINE_STATUS_MAP(XX)
default: return "InvalidMachineStatus"; #undef XX
default:
return "无效状态";
} }
} }
const char* hbMachineTypeToStringChinese(HbMachineType type) { const char* hbMachineTypeToStringChinese(HbMachineType type) {
switch (type) { switch (type) {
case HMT_WIFI: return "0 WiFi主机"; #define XX(name, value, str) \
case HMT_CAMERA: return "1 摄像头主机"; case HMT_##name: \
case HMT_GPRS_IOT: return "2 简化的物联卡主机"; return str;
case HMT_NETMOD: return "3 网络模块+工程主机"; HB_MACHINE_TYPE_MAP(XX)
case HMT_GPRS: return "4 GPRS主机"; #undef XX
case HMT_LCD: return "5 液晶主机";
case HMT_WIRED: return "6 网线主机"; default:
case HMT_TRUE_COLOR: return "7 真彩主机"; return "未知机型";
case HMT_3_SECTION: return "8 三区段主机";
case HMT_IOT: return "9 物联卡主机";
case HMT_GPRS_PHONE: return "10 GPRS主机能打电话";
case HMT_NB: return "11 NB报警接收主机";
case HMT_WIFI2: return "12 WiFi主机新版";
default: return "未知主机";
} }
} }
const char* hbZonePropertyToStringChinese(HbZoneProperty zp) { const char* hbZonePropertyToStringChinese(HbZoneProperty zp) {
switch (zp) { switch (zp) {
case HZP_BUGLAR: return "匪警全局"; #define XX(name, value, str) \
case HZP_EMERGENCY: return "匪警紧急"; case HZP_##name: \
case HZP_FIRE: return "火警防区"; return str;
case HZP_DURESS: return "胁迫防区"; HB_ZONE_PROPERTY_MAP(XX)
case HZP_GAS: return "燃气防区"; #undef XX
case HZP_WATER: return "淹水防区";
case HZP_SUB_MACHINE: return "分机"; default:
case HZP_REMOTE_CONTROL: return "遥控器"; return "无效属性";
case HZP_BUGLAR_HALF: return "匪警半局";
case HZP_SHIELD: return "屏蔽防区";
case HZP_DOOR_RING: return "门铃防区";
case HZP_RESERVED_0B: return "保留";
case HZP_RESERVED_0C: return "保留";
case HZP_RESERVED_0D: return "保留";
case HZP_RESERVED_0E: return "保留";
case HZP_BYPASS: return "旁路防区";
default: return "无效属性";
} }
} }
#endif #endif
...@@ -503,52 +499,81 @@ HbComRequestType hbComParseRequest(const uint8_t* data, ...@@ -503,52 +499,81 @@ HbComRequestType hbComParseRequest(const uint8_t* data,
size_t len, size_t len,
HbComData* cd) { HbComData* cd) {
do { do {
if (len < 5) { break; } if (len < 5) {
if (data[0] != 0xEB) { break; } break;
}
if (data[0] != 0xEB) {
break;
}
switch (data[1]) { switch (data[1]) {
case 0xAB: case 0xAB: {
{ if (data[2] != 0x3F) {
if (data[2] != 0x3F) { break; } break;
}
switch (data[3]) { switch (data[3]) {
case 0xA0: // EB AB 3F A0 75 case 0xA0: // EB AB 3F A0 75
{ {
if (len != HbComReq_A0_len) { break; } if (len != HbComReq_A0_len) {
if (memcmp(HbComReq_A0_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_A0_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_A0; return HbComReq_A0;
} }
case 0xA1: // EB AB 3F A1 76 case 0xA1: // EB AB 3F A1 76
{ {
if (len != HbComReq_A1_len) { break; } if (len != HbComReq_A1_len) {
if (memcmp(HbComReq_A1_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_A1_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_A1; return HbComReq_A1;
} }
case 0xA2: // EB AB 3F A2 77 case 0xA2: // EB AB 3F A2 77
{ {
if (len != HbComReq_A2_len) { break; } if (len != HbComReq_A2_len) {
if (memcmp(HbComReq_A2_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_A2_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_A2; return HbComReq_A2;
} }
case 0xA5: // EB AB 3F A5 7A case 0xA5: // EB AB 3F A5 7A
{ {
if (len != HbComReq_A5_len) { break; } if (len != HbComReq_A5_len) {
if (memcmp(HbComReq_A5_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_A5_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_A5; return HbComReq_A5;
} }
case 0xAC: // EB AB 3F AC 81 case 0xAC: // EB AB 3F AC 81
{ {
if (len != HbComReq_AC_len) { break; } if (len != HbComReq_AC_len) {
if (memcmp(HbComReq_AC_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_AC_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_AC; return HbComReq_AC;
} }
case 0xAD: // EB AB 3F AD 82 case 0xAD: // EB AB 3F AD 82
{ {
if (len != HbComReq_AD_len) { break; } if (len != HbComReq_AD_len) {
if (memcmp(HbComReq_AD_data, data, len) != 0) { break; } break;
}
if (memcmp(HbComReq_AD_data, data, len) != 0) {
break;
}
copy_data_to_com; copy_data_to_com;
return HbComReq_AD; return HbComReq_AD;
} }
...@@ -557,9 +582,10 @@ HbComRequestType hbComParseRequest(const uint8_t* data, ...@@ -557,9 +582,10 @@ HbComRequestType hbComParseRequest(const uint8_t* data,
} }
break; break;
} }
case 0xBA: case 0xBA: {
{ if (data[2] != 0x3F) {
if (data[2] != 0x3F) { break; } break;
}
if (len == HbComReq_READ_acct_len && if (len == HbComReq_READ_acct_len &&
memcmp(data, HbComReq_READ_acct_data, len) == 0) { memcmp(data, HbComReq_READ_acct_data, len) == 0) {
copy_data_to_com; copy_data_to_com;
...@@ -567,9 +593,10 @@ HbComRequestType hbComParseRequest(const uint8_t* data, ...@@ -567,9 +593,10 @@ HbComRequestType hbComParseRequest(const uint8_t* data,
} }
break; break;
} }
case 0xCB: case 0xCB: {
{ if (data[2] != 0x3F) {
if (data[2] != 0x3F) { break; } break;
}
if (data[3] == 0x09 && if (data[3] == 0x09 &&
data[4] == 0xA3 && data[4] == 0xA3 &&
...@@ -631,24 +658,31 @@ HbComRequestType hbComParseRequest(const uint8_t* data, ...@@ -631,24 +658,31 @@ HbComRequestType hbComParseRequest(const uint8_t* data,
HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata, HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata,
HbComData* cd) { HbComData* cd) {
if (!xdata) { return HbComReq_Invalid; } if (!xdata) {
return HbComReq_Invalid;
}
return hbComParseRequest( return hbComParseRequest(
(const uint8_t*)ademcoXDataGetValidContentAddr(xdata), (const uint8_t*)ademcoXDataGetValidContentAddr(xdata),
ademcoXDataGetValidContentLen(xdata), ademcoXDataGetValidContentLen(xdata),
cd cd);
);
} }
HbComResponseType hbComParseResponse(const uint8_t* data, HbComResponseType hbComParseResponse(const uint8_t* data,
size_t len, size_t len,
HbComData* cd) { HbComData* cd) {
do { do {
if (len < 7) { break; } // 所有的 response ,长度最小为 7 if (len < 7) {
if (data[0] != 0xEB || data[1] != 0xBA || data[2] != 0x3F) { break; } break;
} // 所有的 response ,长度最小为 7
if (data[0] != 0xEB || data[1] != 0xBA || data[2] != 0x3F) {
break;
}
switch (data[5]) { switch (data[5]) {
case 0xA0: // EB BA 3F 07 P0 A0 P1 P2 P3 SUM case 0xA0: // EB BA 3F 07 P0 A0 P1 P2 P3 SUM
{ {
if (len != HbComResp_A0_len) { break; } if (len != HbComResp_A0_len) {
break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A0; return HbComResp_A0;
...@@ -658,7 +692,9 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -658,7 +692,9 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
case 0xA2: // EB BA 3F PN P0 A2 [Z, P]xN P1 SUM case 0xA2: // EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
{ {
if (len != data[3]) { break; } if (len != data[3]) {
break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A2; return HbComResp_A2;
...@@ -666,9 +702,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -666,9 +702,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA3: case 0xA3: {
{ if (len != HbComResp_A3_len) {
if (len != HbComResp_A3_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A3; return HbComResp_A3;
...@@ -676,9 +713,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -676,9 +713,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA4: case 0xA4: {
{ if (len != HbComResp_A4_len) {
if (len != HbComResp_A4_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A4; return HbComResp_A4;
...@@ -686,9 +724,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -686,9 +724,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA6: case 0xA6: {
{ if (len != HbComResp_A6_len) {
if (len != HbComResp_A6_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A6; return HbComResp_A6;
...@@ -696,9 +735,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -696,9 +735,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA7: case 0xA7: {
{ if (len != HbComResp_A7_len) {
if (len != HbComResp_A7_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A7; return HbComResp_A7;
...@@ -706,9 +746,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -706,9 +746,10 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA8: case 0xA8: {
{ if (len != HbComResp_A8_len) {
if (len != HbComResp_A8_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_A8; return HbComResp_A8;
...@@ -716,15 +757,15 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -716,15 +757,15 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
break; break;
} }
case 0xA9: case 0xA9: {
{
// TODO // TODO
break; break;
} }
case 0xAB: case 0xAB: {
{ if (len != HbComResp_AB_len) {
if (len != HbComResp_AB_len) { break; } break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_AB; return HbComResp_AB;
...@@ -734,7 +775,9 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -734,7 +775,9 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
case 0xAD: // EB BA 3F PN P0 AD P1 DATA P2 SUM case 0xAD: // EB BA 3F PN P0 AD P1 DATA P2 SUM
{ {
if (len != data[3]) { break; } if (len != data[3]) {
break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_AD; return HbComResp_AD;
...@@ -744,20 +787,20 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -744,20 +787,20 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
case 0xAF: // TODO case 0xAF: // TODO
{ {
break; break;
} }
case 0xB1: // EB BA 3F 08 P0 B1 P1 SUM case 0xB1: // EB BA 3F 08 P0 B1 P1 SUM
{ {
if (len != HbComResp_B1_len) { break; } if (len != HbComResp_B1_len) {
break;
}
if (hbCheckSum(data, len)) { if (hbCheckSum(data, len)) {
copy_data_to_com; copy_data_to_com;
return HbComResp_B1; return HbComResp_B1;
} }
break; break;
} }
} }
} while (0); } while (0);
...@@ -780,12 +823,13 @@ HbComResponseType hbComParseResponse(const uint8_t* data, ...@@ -780,12 +823,13 @@ HbComResponseType hbComParseResponse(const uint8_t* data,
HbComResponseType hbComParseXDataResponse(const AdemcoXDataSegment* xdata, HbComResponseType hbComParseXDataResponse(const AdemcoXDataSegment* xdata,
HbComData* cd) { HbComData* cd) {
if (!xdata) { return HbComResp_Invalid; } if (!xdata) {
return HbComResp_Invalid;
}
return hbComParseResponse( return hbComParseResponse(
(const uint8_t*)ademcoXDataGetValidContentAddr(xdata), (const uint8_t*)ademcoXDataGetValidContentAddr(xdata),
ademcoXDataGetValidContentLen(xdata), ademcoXDataGetValidContentLen(xdata),
cd cd);
);
} }
void hbComMakeReqA0_getMachineStatus(HbComData* data) { void hbComMakeReqA0_getMachineStatus(HbComData* data) {
...@@ -877,14 +921,14 @@ void hbComMakeReqWrite_acct(HbComData* data, const char* acct) { ...@@ -877,14 +921,14 @@ void hbComMakeReqWrite_acct(HbComData* data, const char* acct) {
void hbComResp_A2_Iter_init(HbComResp_A2_Iter* iter, void hbComResp_A2_Iter_init(HbComResp_A2_Iter* iter,
const HbComData* com) { const HbComData* com) {
if (!iter || !com)return; if (!iter || !com) return;
memcpy(&iter->com, com, sizeof(HbComData)); memcpy(&iter->com, com, sizeof(HbComData));
iter->i = 0; iter->i = 0;
if (com->len > HbComResp_A2_len_min) { if (com->len > HbComResp_A2_len_min) {
iter->total = (com->len - HbComResp_A2_len_min) / 2; iter->total = (com->len - HbComResp_A2_len_min) / 2;
iter->p1 = (com->data[com->len - 2] == 0xFF) ? iter->p1 = (com->data[com->len - 2] == 0xFF)
HbComResp_A2_p1_nomore : ? HbComResp_A2_p1_nomore
HbComResp_A2_p1_more; : HbComResp_A2_p1_more;
} else { } else {
iter->total = 0; iter->total = 0;
iter->p1 = HbComResp_A2_p1_nomore; iter->p1 = HbComResp_A2_p1_nomore;
...@@ -916,7 +960,9 @@ void hbComMakeRespA2_getMachineZones(HbComData* data, ...@@ -916,7 +960,9 @@ void hbComMakeRespA2_getMachineZones(HbComData* data,
AdemcoZone* zones, AdemcoZone* zones,
HbZoneProperty* props, HbZoneProperty* props,
HbComResp_A2_p1 p1) { HbComResp_A2_p1 p1) {
if (count > HbComResp_A2_max_zone) { return; } if (count > HbComResp_A2_max_zone) {
return;
}
memcpy(data->data, HbComResp_A2_head, 6); memcpy(data->data, HbComResp_A2_head, 6);
data->data[3] = (HbComResp_A2_len_min + count * 2) & 0xFF; data->data[3] = (HbComResp_A2_len_min + count * 2) & 0xFF;
uint8_t* p = data->data + 6; uint8_t* p = data->data + 6;
...@@ -979,12 +1025,13 @@ void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, ...@@ -979,12 +1025,13 @@ void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data,
size_t count, size_t count,
AdemcoZone* zones, AdemcoZone* zones,
HbComResp_AD_p2 p2) { HbComResp_AD_p2 p2) {
if (count > HbComResp_AD_max_zone) { return; } if (count > HbComResp_AD_max_zone) {
return;
}
memcpy(data->data, HbComResp_AD_head, 6); memcpy(data->data, HbComResp_AD_head, 6);
data->data[3] = ( data->data[3] = (HbComResp_AD_len_min +
HbComResp_AD_len_min + (p1 == HbComResp_AD_p1_single ? count : count * 2)) &
(p1 == HbComResp_AD_p1_single ? count : count * 2) 0xFF;
) & 0xFF;
data->data[6] = p1; data->data[6] = p1;
uint8_t* p = data->data + 7; uint8_t* p = data->data + 7;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
......
...@@ -9,94 +9,118 @@ ...@@ -9,94 +9,118 @@
extern "C" { extern "C" {
#endif #endif
//! 三防区主机状态GG范围 1~3 // 三防区主机状态GG范围 1~3
#define HB_3SECTION_MACHINE_GG_MIN 1 #define HB_3SECTION_MACHINE_GG_MIN 1
#define HB_3SECTION_MACHINE_GG_MAX 3 #define HB_3SECTION_MACHINE_GG_MAX 3
//! 是否合法的三防区主机状态GG // 是否合法的三防区主机状态GG
static inline int hbIsValid3SectionMachineGG(AdemcoGG gg) { static inline int hbIsValid3SectionMachineGG(AdemcoGG gg) {
return HB_3SECTION_MACHINE_GG_MIN <= gg && return HB_3SECTION_MACHINE_GG_MIN <= gg &&
gg <= HB_3SECTION_MACHINE_GG_MAX; gg <= HB_3SECTION_MACHINE_GG_MAX;
} }
//! 主机状态 // 主机状态表
#define HB_MACHINE_STATUS_MAP(XX) \
XX(ARM, 0, "布防") \
XX(HALF_ARM, 1, "半布防") \
XX(DISARM, 2, "撤防") \
XX(SETTING, 3, "设置")
// 主机状态与安定宝事件码对照表
#define HMS_EVENT_MAP(XX) \
XX(HMS_ARM, EVENT_ARM) \
XX(HMS_HALF_ARM, EVENT_HALFARM) \
XX(HMS_DISARM, EVENT_DISARM) \
XX(HMS_SETTING, EVENT_ENTER_SETTING_MODE)
// 主机状态
typedef enum HbMachineStatus { typedef enum HbMachineStatus {
HMS_ARM, // 布防 #define XX(name, value, str) HMS_##name = value,
HMS_HALF_ARM, // 半布防 HB_MACHINE_STATUS_MAP(XX)
HMS_DISARM, // 撤防 #undef XX
HMS_SETTING, // 设置 // valid count
HMS_COUNT, HMS_COUNT = 4,
// invalid
HMS_INVALID = -1, HMS_INVALID = -1,
} HbMachineStatus; } HbMachineStatus;
// 主机类型表
#define HB_MACHINE_TYPE_MAP(XX) \
XX(WIFI, 0, "WiFi主机") \
XX(CAMERA, 1, "网络摄像机") \
XX(GPRS_IOT, 2, "简化物联卡主机") \
XX(NETMOD, 3, "网络模块主机") \
XX(GPRS, 4, "GPRS主机") \
XX(LCD, 5, "液晶主机") \
XX(WIRED, 6, "网线主机") \
XX(TRUE_COLOR, 7, "真彩主机") \
XX(THREE_SECTION, 8, "三区段主机") \
XX(IOT, 9, "物联卡主机") \
XX(GPRS_PHONE, 10, "GPRS主机可电话") \
XX(NB, 11, "NB报警接收主机") \
XX(WIFI2, 12, "WiFi主机新版")
// 主机类型与安定宝事件码对照表
#define HMT_EVENT_MAP(XX) \
XX(HMT_WIFI, EVENT_I_AM_WIFI_MACHINE) \
XX(HMT_GPRS_IOT, EVENT_I_AM_GPRS_IOT) \
XX(HMT_NETMOD, EVENT_I_AM_NET_MODULE) \
XX(HMT_GPRS, EVENT_I_AM_GPRS) \
XX(HMT_LCD, EVENT_I_AM_LCD_MACHINE) \
XX(HMT_WIRED, EVENT_I_AM_WIRE_MACHINE) \
XX(HMT_TRUE_COLOR, EVENT_I_AM_TRUE_COLOR) \
XX(HMT_THREE_SECTION, EVENT_I_AM_3_SECTION_MACHINE) \
XX(HMT_IOT, EVENT_I_AM_IOT_MACHINE) \
XX(HMT_GPRS_PHONE, EVENT_I_AM_GPRS_PHONE) \
XX(HMT_NB, EVENT_I_AM_NB_MACHINE) \
XX(HMT_WIFI2, EVENT_I_AM_WIFI2_MACHINE)
// 主机类型
typedef enum HbMachineType { typedef enum HbMachineType {
//! 0 WiFi主机 (已停用) #define XX(name, value, str) HMT_##name = value,
HMT_WIFI, HB_MACHINE_TYPE_MAP(XX)
//! 1 网络摄像机 (未启用) #undef XX
HMT_CAMERA, // valid count
//! 2 简化的物联卡主机 [ HB-5050G-4GW ] HMT_COUNT = 13,
HMT_GPRS_IOT, // invalid
//! 3 网络模块主机 [ HB-G250 ]
HMT_NETMOD,
//! 4 改进型卧式主机 [ HB-4040G HB-5050G HB-5050-4G ]
HMT_GPRS,
//! 5 液晶主机 [ HB-BJQ560 HB-BJQ-560B ]
HMT_LCD,
//! 6 网线主机 [ HB-4040R HB-5050R ]
HMT_WIRED,
//! 7 真彩主机 [ HTZ-G1000 HTZ-G1000-4G ]
HMT_TRUE_COLOR,
//! 8 三区段主机 [ HTZ-G1000 HTZ-G1000-4G ]
HMT_3_SECTION,
//! 9 物联卡主机 [ HB-2050-4GW ]
HMT_IOT,
//! 10 GPRS主机可以打电话 [ HB-2050 ]
HMT_GPRS_PHONE,
//! 11 NB报警接收主机
HMT_NB,
//! 12 WiFi主机新版
HMT_WIFI2,
HMT_COUNT,
HMT_INVALID = -1, HMT_INVALID = -1,
} HbMachineType; } HbMachineType;
// 防区属性表
#define HB_ZONE_PROPERTY_MAP(XX) \
XX(BUGLAR, 0, "匪警全局") \
XX(EMERGENCY, 1, "匪警紧急") \
XX(FIRE, 2, "火警防区") \
XX(DURESS, 3, "胁迫防区") \
XX(GAS, 4, "燃气防区") \
XX(WATER, 5, "淹水防区") \
XX(SUB_MACHINE, 6, "分机") \
XX(REMOTE_CONTROL, 7, "遥控器") \
XX(BUGLAR_HALF, 8, "匪警半局") \
XX(SHIELD, 9, "屏蔽防区") \
XX(DOOR_RING, 0x0A, "门铃防区") \
XX(BYPASS, 0x0F, "旁路防区")
// 防区属性与安定宝事件码对照表
#define HZP_EVENT_MAP(XX) \
XX(HZP_BUGLAR, EVENT_BURGLAR) \
XX(HZP_BUGLAR_HALF, EVENT_BURGLAR) \
XX(HZP_EMERGENCY, EVENT_EMERGENCY) \
XX(HZP_FIRE, EVENT_FIRE) \
XX(HZP_DURESS, EVENT_DURESS) \
XX(HZP_GAS, EVENT_GAS) \
XX(HZP_WATER, EVENT_WATER) \
XX(HZP_DOOR_RING, EVENT_DOORRINGING)
// 防区属性
typedef enum HbZoneProperty { typedef enum HbZoneProperty {
//! 匪警全局 #define XX(name, value, str) HZP_##name = value,
HZP_BUGLAR, HB_ZONE_PROPERTY_MAP(XX)
//! 匪警紧急 #undef XX
HZP_EMERGENCY,
//! 火警防区 // valid count
HZP_FIRE, #define HZP_COUNT 12
//! 胁迫防区 // invalid
HZP_DURESS,
//! 燃气防区
HZP_GAS,
//! 淹水防区
HZP_WATER,
//! 分机
HZP_SUB_MACHINE,
//! 遥控器
HZP_REMOTE_CONTROL,
//! 匪警半局
HZP_BUGLAR_HALF,
//! 屏蔽防区
HZP_SHIELD,
//! 门铃防区
HZP_DOOR_RING,
//! 保留
HZP_RESERVED_0B,
//! 保留
HZP_RESERVED_0C,
//! 保留
HZP_RESERVED_0D,
//! 保留
HZP_RESERVED_0E,
//! 旁路防区
//! 2019年9月2日16:01:58 适配金建峰真彩主机
HZP_BYPASS,
HZP_COUNT,
HZP_INVALID = -1, HZP_INVALID = -1,
} HbZoneProperty; } HbZoneProperty;
...@@ -167,19 +191,19 @@ typedef enum HbComResponseType { ...@@ -167,19 +191,19 @@ typedef enum HbComResponseType {
HbComResp_Invalid = -1, HbComResp_Invalid = -1,
} HbComResponseType; } HbComResponseType;
//! 索要主机状态 EB AB 3F A0 75 // 索要主机状态 EB AB 3F A0 75
#define HbComReq_A0_len 5 #define HbComReq_A0_len 5
#define HbComReq_A0_data "\xEB\xAB\x3F\xA0\x75" #define HbComReq_A0_data "\xEB\xAB\x3F\xA0\x75"
//! 回应主机状态 EB BA 3F 07 P0 A0 P1 P2 P3 SUM // 回应主机状态 EB BA 3F 07 P0 A0 P1 P2 P3 SUM
#define HbComResp_A0_len 9 #define HbComResp_A0_len 9
#define HbComResp_A0_head "\xEB\xBA\x3F\x07\xCC\xA0" #define HbComResp_A0_head "\xEB\xBA\x3F\x07\xCC\xA0"
//! 索要主机防区 EB AB 3F A1 76 // 索要主机防区 EB AB 3F A1 76
#define HbComReq_A1_len 5 #define HbComReq_A1_len 5
#define HbComReq_A1_data "\xEB\xAB\x3F\xA1\x76" #define HbComReq_A1_data "\xEB\xAB\x3F\xA1\x76"
//! 回应主机防区 EB BA 3F PN P0 A2 [Z, P]xN P1 SUM // 回应主机防区 EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
// 无防区数据时长度最小为8 // 无防区数据时长度最小为8
#define HbComResp_A2_len_min 8 #define HbComResp_A2_len_min 8
// 最多可以包含 20 个防区 // 最多可以包含 20 个防区
...@@ -197,73 +221,73 @@ typedef struct HbComResp_A2_Iter { ...@@ -197,73 +221,73 @@ typedef struct HbComResp_A2_Iter {
HbComResp_A2_p1 p1; HbComResp_A2_p1 p1;
} HbComResp_A2_Iter; } HbComResp_A2_Iter;
//! 索要更多主机防区 EB AB 3F A2 77 // 索要更多主机防区 EB AB 3F A2 77
//! 仅应在收到ZoneResponse的param非0xFF时发送,以索要全部防区 // 仅应在收到ZoneResponse的param非0xFF时发送,以索要全部防区
#define HbComReq_A2_len 5 #define HbComReq_A2_len 5
#define HbComReq_A2_data "\xEB\xAB\x3F\xA2\x77" #define HbComReq_A2_data "\xEB\xAB\x3F\xA2\x77"
//! 修改主机防区 EB CB 3F 09 A3 P1 P2 P3 SUM // 修改主机防区 EB CB 3F 09 A3 P1 P2 P3 SUM
#define HbComReq_A3_len 9 #define HbComReq_A3_len 9
#define HbComReq_A3_head "\xEB\xCB\x3F\x09\xA3" #define HbComReq_A3_head "\xEB\xCB\x3F\x09\xA3"
typedef enum HbComReq_A3_p3 { typedef enum HbComReq_A3_p3 {
HbComReq_A3_p3_del = 0x00, //! 删除防区 HbComReq_A3_p3_del = 0x00, // 删除防区
HbComReq_A3_p3_learn = 0x01, //! 学码 HbComReq_A3_p3_learn = 0x01, // 学码
HbComReq_A3_p3_stop = 0x02, //! 停止学码 HbComReq_A3_p3_stop = 0x02, // 停止学码
HbComReq_A3_p3_modify = 0x03, //! 修改防区属性 HbComReq_A3_p3_modify = 0x03, // 修改防区属性
} HbComReq_A3_op; } HbComReq_A3_op;
//! 学码开始回应 EB BA 3F 07 P0 A3 5A // 学码开始回应 EB BA 3F 07 P0 A3 5A
//! 因为学码时主机要等待外部无线信号(用户触发探测器), // 因为学码时主机要等待外部无线信号(用户触发探测器),
//! 因此先回应A3表示已经开始学码,学码成功时回 ZoneOpResponse A4 // 因此先回应A3表示已经开始学码,学码成功时回 ZoneOpResponse A4
#define HbComResp_A3_len 7 #define HbComResp_A3_len 7
#define HbComResp_A3_data "\xEB\xBA\x3F\x07\xCC\xA3\x5A" #define HbComResp_A3_data "\xEB\xBA\x3F\x07\xCC\xA3\x5A"
//! 修改防区回应 EB BA 3F 0A P0 A4 P1 P2 P3 SUM // 修改防区回应 EB BA 3F 0A P0 A4 P1 P2 P3 SUM
#define HbComResp_A4_len 10 #define HbComResp_A4_len 10
#define HbComResp_A4_head "\xEB\xBA\x3F\x0A\xCC\xA4" #define HbComResp_A4_head "\xEB\xBA\x3F\x0A\xCC\xA4"
typedef enum HbComResp_A4_p3 { typedef enum HbComResp_A4_p3 {
HbComResp_A4_p3_fail = 0x00, //! 失败 HbComResp_A4_p3_fail = 0x00, // 失败
HbComResp_A4_p3_ok = 0x01, //! 成功 HbComResp_A4_p3_ok = 0x01, // 成功
HbComResp_A4_p3_dup = 0x02, //! 失败--重码 HbComResp_A4_p3_dup = 0x02, // 失败--重码
HbComResp_A4_p3_ne = 0x03, //! 失败--防区未对码 not exists HbComResp_A4_p3_ne = 0x03, // 失败--防区未对码 not exists
} HbComResp_A4_p3; } HbComResp_A4_p3;
//! 获取主机定时器 // 获取主机定时器
//! EB AB 3F A5 7A // EB AB 3F A5 7A
#define HbComReq_A5_len 5 #define HbComReq_A5_len 5
#define HbComReq_A5_data "\xEB\xAB\x3F\xA5\x7A" #define HbComReq_A5_data "\xEB\xAB\x3F\xA5\x7A"
//! 获取主机定时器回应 // 获取主机定时器回应
//! EB BA 3F 0F P0 A6 H1 M1 H2 M2 H3 M3 H4 M4 SUM // EB BA 3F 0F P0 A6 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComResp_A6_len 15 #define HbComResp_A6_len 15
#define HbComResp_A6_head "\xEB\xBA\x3F\x0F\xCC\xA6" #define HbComResp_A6_head "\xEB\xBA\x3F\x0F\xCC\xA6"
//! 设置主机定时器 // 设置主机定时器
//! EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM // EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComReq_A7_len 14 #define HbComReq_A7_len 14
#define HbComReq_A7_head "\xEB\xCB\x3F\x0E\xA7" #define HbComReq_A7_head "\xEB\xCB\x3F\x0E\xA7"
#define hbComResq_A7_to_timer(a7, timer) \ #define hbComResq_A7_to_timer(a7, timer) \
memcpy((timer)->data, (a7) + 5, 8); memcpy((timer)->data, (a7) + 5, 8);
//! 设置主机定时器回应 // 设置主机定时器回应
//! EB BA 3F 07 P0 A7 SUM // EB BA 3F 07 P0 A7 SUM
#define HbComResp_A7_len 7 #define HbComResp_A7_len 7
#define HbComResp_A7_data "\xEB\xBA\x3F\x07\xCC\xA7\x5E" #define HbComResp_A7_data "\xEB\xBA\x3F\x07\xCC\xA7\x5E"
//! 拒绝设置回应 // 拒绝设置回应
//! EB BA 3F 07 P0 A8 SUM // EB BA 3F 07 P0 A8 SUM
//! 任何操作,主机如果认为非法,都可以用A8直接回复 // 任何操作,主机如果认为非法,都可以用A8直接回复
#define HbComResp_A8_len 7 #define HbComResp_A8_len 7
#define HbComResp_A8_data "\xEB\xBA\x3F\x07\xCC\xA8\x5F" #define HbComResp_A8_data "\xEB\xBA\x3F\x07\xCC\xA8\x5F"
//! 修改防区探头遗失/失联 // 修改防区探头遗失/失联
//! EB CB 3F 08 AA P1 P2 SUM // EB CB 3F 08 AA P1 P2 SUM
#define HbComReq_AA_len 8 #define HbComReq_AA_len 8
#define HbComReq_AA_head "\xEB\xAB\x3F\x08\xAA" #define HbComReq_AA_head "\xEB\xAB\x3F\x08\xAA"
//! 修改防区探头遗失/失联回应 // 修改防区探头遗失/失联回应
//! EB BA 3F 09 P0 AB P1 P2 SUM // EB BA 3F 09 P0 AB P1 P2 SUM
#define HbComResp_AB_len 9 #define HbComResp_AB_len 9
#define HbComResp_AB_head "\xEB\xBA\x3F\x09\xCC\xAB" #define HbComResp_AB_head "\xEB\xBA\x3F\x09\xCC\xAB"
typedef enum HbComResp_AB_p2 { typedef enum HbComResp_AB_p2 {
...@@ -272,18 +296,18 @@ typedef enum HbComResp_AB_p2 { ...@@ -272,18 +296,18 @@ typedef enum HbComResp_AB_p2 {
HbComResp_AB_p2_reject = 2, // 拒绝操作 HbComResp_AB_p2_reject = 2, // 拒绝操作
} HbComResp_AB_p2; } HbComResp_AB_p2;
//! 索要防区探头遗失/失联,第一次索要 // 索要防区探头遗失/失联,第一次索要
//! EB AB 3F AC 81 // EB AB 3F AC 81
#define HbComReq_AC_len 5 #define HbComReq_AC_len 5
#define HbComReq_AC_data "\xEB\xAB\x3F\xAC\x81" #define HbComReq_AC_data "\xEB\xAB\x3F\xAC\x81"
//! 索要防区探头遗失/失联,索要更多 // 索要防区探头遗失/失联,索要更多
//! EB AB 3F AD 82 // EB AB 3F AD 82
#define HbComReq_AD_len 5 #define HbComReq_AD_len 5
#define HbComReq_AD_data "\xEB\xAB\x3F\xAD\x82" #define HbComReq_AD_data "\xEB\xAB\x3F\xAD\x82"
//! 索要防区探头遗失/失联回应 // 索要防区探头遗失/失联回应
//! EB BA 3F PN P0 AD P1 DATA P2 SUM // EB BA 3F PN P0 AD P1 DATA P2 SUM
// 无防区失联数据时一包长度最小为9 // 无防区失联数据时一包长度最小为9
#define HbComResp_AD_len_min 9 #define HbComResp_AD_len_min 9
// 一包最多包含20个防区 // 一包最多包含20个防区
...@@ -314,19 +338,19 @@ typedef enum HbCom_3sec_which { ...@@ -314,19 +338,19 @@ typedef enum HbCom_3sec_which {
HbCom_3sec_section3, // 区段3 HbCom_3sec_section3, // 区段3
} HbCom_3sec_which; } HbCom_3sec_which;
//! 三区段主机布撤防命令 EB CB 3F 08 AE P1 P2 SUM // 三区段主机布撤防命令 EB CB 3F 08 AE P1 P2 SUM
#define HbComReq_AE_len 8 #define HbComReq_AE_len 8
#define HbComReq_AE_head "\xEB\xCB\x3F\x08\xAE" #define HbComReq_AE_head "\xEB\xCB\x3F\x08\xAE"
//! 三区段主机布撤防命令回应 EB BA 3F 08 P0 AF P1 P2 SUM // 三区段主机布撤防命令回应 EB BA 3F 08 P0 AF P1 P2 SUM
#define HbComResp_AF_len 9 #define HbComResp_AF_len 9
#define HbComResp_AF_head "\xEB\xBA\x3F\x08\xCC\xAF" #define HbComResp_AF_head "\xEB\xBA\x3F\x08\xCC\xAF"
//! 三区段主机索要主机状态 EB CB 3F 06 B0 AB // 三区段主机索要主机状态 EB CB 3F 06 B0 AB
#define HbComReq_B0_len 6 #define HbComReq_B0_len 6
#define HbComReq_B0_data "\xEB\xCB\x3F\x06\xB0\xAB" #define HbComReq_B0_data "\xEB\xCB\x3F\x06\xB0\xAB"
//! 三区段主机状态回应 EB BA 3F 08 P0 B1 P1 SUM // 三区段主机状态回应 EB BA 3F 08 P0 B1 P1 SUM
#define HbComResp_B1_len 8 #define HbComResp_B1_len 8
#define HbComResp_B1_head "\xEB\xBA\x3F\x08\xCC\xB1" #define HbComResp_B1_head "\xEB\xBA\x3F\x08\xCC\xB1"
#define hbComResp_B1_status(d) \ #define hbComResp_B1_status(d) \
...@@ -341,191 +365,293 @@ typedef enum HbCom_3sec_which { ...@@ -341,191 +365,293 @@ typedef enum HbCom_3sec_which {
#define hbComResp_B1_status3(d) \ #define hbComResp_B1_status3(d) \
((((d)[6]) & 0x03) == HbCom_3sec_arm ? HMS_ARM : HMS_DISARM) ((((d)[6]) & 0x03) == HbCom_3sec_arm ? HMS_ARM : HMS_DISARM)
//! 读取主机账号 // 读取主机账号
#define HbComReq_READ_acct_len 7 #define HbComReq_READ_acct_len 7
#define HbComReq_READ_acct_data "\xEB\xBA\x3F\x07\x00\x4C\x37" #define HbComReq_READ_acct_data "\xEB\xBA\x3F\x07\x00\x4C\x37"
//! 读取主机账号回应 // 读取主机账号回应
#define HbComResp_READ_acct_len 15 #define HbComResp_READ_acct_len 15
#define HbComResp_READ_acct_head "\xEB\xCB\x3F\x0F\x4C" #define HbComResp_READ_acct_head "\xEB\xCB\x3F\x0F\x4C"
//! 写入主机账号 // 写入主机账号
#define HbComReq_WRITE_acct_len 15 #define HbComReq_WRITE_acct_len 15
#define HbComReq_WRITE_acct_head "\xEB\xCB\x3F\x0F\x4D" #define HbComReq_WRITE_acct_head "\xEB\xCB\x3F\x0F\x4D"
//! 写入主机账号回应(与读取命令相同) // 写入主机账号回应(与读取命令相同)
#define HbComResp_WRITE_acct_len HbComReq_READ_acct_len #define HbComResp_WRITE_acct_len HbComReq_READ_acct_len
#define HbComResp_WRITE_acct_data HbComReq_READ_acct_data #define HbComResp_WRITE_acct_data HbComReq_READ_acct_data
static const HbZoneProperty hbZoneProperties[12] = {
HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS,
HZP_GAS, HZP_WATER, HZP_SUB_MACHINE, HZP_REMOTE_CONTROL,
HZP_BUGLAR_HALF, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS,
};
// return available count // return available count
ADEMCO_EXPORT_SYMBOL int hbGetAvailableZoneProperties(HbMachineType type, ADEMCO_EXPORT_SYMBOL
HbZoneProperty props[12]); int hbGetAvailableZoneProperties(HbMachineType type, HbZoneProperty props[HZP_COUNT]);
//! 最大防区号根据型号不同而不同 // 最大防区号根据型号不同而不同
ADEMCO_EXPORT_SYMBOL uint16_t hbZoneMax(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 防区号是否合法(可以包含0防区) uint16_t hbZoneMax(HbMachineType type);
ADEMCO_EXPORT_SYMBOL int hbIsValidZone(HbMachineType type, uint16_t zone);
//! 防区号是否合法(不可以可以包含0防区) // 防区号是否合法(可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbIsValidZoneStrict(HbMachineType type, uint16_t zone); ADEMCO_EXPORT_SYMBOL
//! 主机是否已投产使用 int hbIsValidZone(HbMachineType type, uint16_t zone);
ADEMCO_EXPORT_SYMBOL int hbMachineIsSelling(HbMachineType type);
//! 主机是否具有布防功能 // 防区号是否合法(不可以可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbMachineCanArm(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 主机是否具有撤防功能 int hbIsValidZoneStrict(HbMachineType type, uint16_t zone);
ADEMCO_EXPORT_SYMBOL int hbMachineCanDisarm(HbMachineType type);
//! 主机是否可以进入设置状态 // 主机是否已投产使用
ADEMCO_EXPORT_SYMBOL int hbMachineCanEnterSettings(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 主机是否具有半布防功能 int hbMachineIsSelling(HbMachineType type);
ADEMCO_EXPORT_SYMBOL int hbMachineCanHalfArm(HbMachineType type);
//! 主机是否可以报告信号强度 // 主机是否具有布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportSignalStrength(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 主机本身是否可以短信报警(不算通过服务如阿里语音等) int hbMachineCanArm(HbMachineType type);
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportBySMS(HbMachineType type);
//! 主机是否支持有线防区 // 主机是否具有撤防功能
ADEMCO_EXPORT_SYMBOL int hbMachineHasWiredZone(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 主机最小有线防区号 int hbMachineCanDisarm(HbMachineType type);
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMin(HbMachineType type);
//! 主机最大有线防区号 // 主机是否可以进入设置状态
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMax(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 主机是否可以直接写入防区数据(无需对码) int hbMachineCanEnterSettings(HbMachineType type);
ADEMCO_EXPORT_SYMBOL int hbMachineCanDirectlyWriteZone(HbMachineType type);
//! 主机是否可以挂载分机 // 主机是否具有半布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanLinkSubMachine(HbMachineType type); ADEMCO_EXPORT_SYMBOL
//! 根据防区属性判断是否支持失联报告 int hbMachineCanHalfArm(HbMachineType type);
//! 失联报告是主机侧实现的跟防区属性没关系,但是人为限制了只有以下属性的才可以设置
ADEMCO_EXPORT_SYMBOL int hbZonePropCanReportLost(HbZoneProperty zp); // 主机是否可以报告信号强度
ADEMCO_EXPORT_SYMBOL void hbInitMachineTimer(HbMachineTimer* timer); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL int hbIsValidTimePoint(HbMachineTimePoint* tp); int hbMachineCanReportSignalStrength(HbMachineType type);
ADEMCO_EXPORT_SYMBOL void hbTimePointToGreenwich(HbMachineTimePoint* tp);
ADEMCO_EXPORT_SYMBOL void hbTimePointFromGreenwich(HbMachineTimePoint* tp); // 主机本身是否可以短信报警(不算通过服务如阿里语音等)
ADEMCO_EXPORT_SYMBOL int hbIsValidTimer(HbTimer* timer); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL int hbIsValidMachineTimer(HbMachineTimer* timer); int hbMachineCanReportBySMS(HbMachineType type);
//! 传输的是格林威治时间
ADEMCO_EXPORT_SYMBOL void hbMachineTimerToGreenwich(HbMachineTimer* timer); // 主机是否支持有线防区
ADEMCO_EXPORT_SYMBOL void hbMachineTimerFromGreenwich(HbMachineTimer* timer); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status); int hbMachineHasWiredZone(HbMachineType type);
ADEMCO_EXPORT_SYMBOL HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent);
ADEMCO_EXPORT_SYMBOL AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type); // 主机最小有线防区号
ADEMCO_EXPORT_SYMBOL HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp); AdemcoZone hbWiredZoneMin(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbMachineStatusToString(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToString(HbMachineType type); // 主机最大有线防区号
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToString(HbZoneProperty zp); ADEMCO_EXPORT_SYMBOL
#ifdef ADEMCO_ENABLE_CHINESE AdemcoZone hbWiredZoneMax(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbMachineStatusToStringChinese(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToStringChinese(HbMachineType type); // 主机是否可以直接写入防区数据(无需对码)
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToStringChinese(HbZoneProperty zp); ADEMCO_EXPORT_SYMBOL
#endif int hbMachineCanDirectlyWriteZone(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbGetZoneFormatString(HbMachineType type); // 主机是否可以挂载分机
ADEMCO_EXPORT_SYMBOL
int hbMachineCanLinkSubMachine(HbMachineType type);
// 根据防区属性判断是否支持失联报告
// 失联报告是主机侧实现的跟防区属性没关系,但是人为限制了只有以下属性的才可以设置
ADEMCO_EXPORT_SYMBOL
int hbZonePropCanReportLost(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL
void hbInitMachineTimer(HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL
int hbIsValidTimePoint(HbMachineTimePoint* tp);
ADEMCO_EXPORT_SYMBOL
void hbTimePointToGreenwich(HbMachineTimePoint* tp);
ADEMCO_EXPORT_SYMBOL
void hbTimePointFromGreenwich(HbMachineTimePoint* tp);
ADEMCO_EXPORT_SYMBOL
int hbIsValidTimer(HbTimer* timer);
ADEMCO_EXPORT_SYMBOL
int hbIsValidMachineTimer(HbMachineTimer* timer);
// 传输的是格林威治时间
ADEMCO_EXPORT_SYMBOL
void hbMachineTimerToGreenwich(HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL
void hbMachineTimerFromGreenwich(HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL
AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL
HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent);
ADEMCO_EXPORT_SYMBOL
AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type);
ADEMCO_EXPORT_SYMBOL
HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent);
ADEMCO_EXPORT_SYMBOL
AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL
const char* hbMachineStatusToString(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL
const char* hbMachineTypeToString(HbMachineType type);
ADEMCO_EXPORT_SYMBOL
const char* hbZonePropertyToString(HbZoneProperty zp);
#if ADEMCO_ENABLE_CHINESE
ADEMCO_EXPORT_SYMBOL
const char* hbMachineStatusToStringChinese(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL
const char* hbMachineTypeToStringChinese(HbMachineType type);
ADEMCO_EXPORT_SYMBOL
const char* hbZonePropertyToStringChinese(HbZoneProperty zp);
#endif // ADEMCO_ENABLE_CHINESE
ADEMCO_EXPORT_SYMBOL
const char* hbGetZoneFormatString(HbMachineType type);
// 累加校验,计算data[0] ~ data[len-2],校验和放在data[len-1] // 累加校验,计算data[0] ~ data[len-2],校验和放在data[len-1]
ADEMCO_EXPORT_SYMBOL void hbSum(uint8_t* data, size_t len); ADEMCO_EXPORT_SYMBOL
void hbSum(uint8_t* data, size_t len);
// 校验和是否正确, return 0 for incorrect, otherwise correct // 校验和是否正确, return 0 for incorrect, otherwise correct
ADEMCO_EXPORT_SYMBOL int hbCheckSum(const uint8_t* data, size_t len); ADEMCO_EXPORT_SYMBOL
int hbCheckSum(const uint8_t* data, size_t len);
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
HbComRequestType hbComParseRequest(const uint8_t* buff, size_t len, HbComData* cd); HbComRequestType hbComParseRequest(const uint8_t* buff, size_t len, HbComData* cd);
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata, HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata, HbComData* cd);
HbComData* cd);
// parse COM response and return response type. // parse COM response and return response type.
// If cd is non-NULL, valid data will be copied to cd // If cd is non-NULL, valid data will be copied to cd
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
HbComResponseType hbComParseResponse(const uint8_t* buff, size_t len, HbComResponseType hbComParseResponse(const uint8_t* buff, size_t len, HbComData* cd);
HbComData* cd);
// parse COM response and return response type. // parse COM response and return response type.
// If cd is non-NULL, valid data will be copied to cd // If cd is non-NULL, valid data will be copied to cd
ADEMCO_EXPORT_SYMBOL ADEMCO_EXPORT_SYMBOL
HbComResponseType hbComParseXDataResponse(const AdemcoXDataSegment* xdata, HbComData* cd); HbComResponseType hbComParseXDataResponse(const AdemcoXDataSegment* xdata, HbComData* cd);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA0_getMachineStatus(HbComData* data); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA1_getMachineZones(HbComData* data); void hbComMakeReqA0_getMachineStatus(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA2_getMoreMachineZones(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA3_modifyMachineZone(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeReqA1_getMachineZones(HbComData* data);
ADEMCO_EXPORT_SYMBOL
void hbComMakeReqA2_getMoreMachineZones(HbComData* data);
ADEMCO_EXPORT_SYMBOL
void hbComMakeReqA3_modifyMachineZone(HbComData* data,
uint8_t zone, uint8_t zone,
HbZoneProperty prop, HbZoneProperty prop,
HbComReq_A3_op op); HbComReq_A3_op op);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA5_getMachineTimer(HbComData* data); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA7_setMachineTimer(HbComData* data, void hbComMakeReqA5_getMachineTimer(HbComData* data);
HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL
void hbComMakeReqA7_setMachineTimer(HbComData* data, HbMachineTimer* timer);
// TODO // TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeReqA9(HbComData* data, HbMachineStatus status, HbMachineType type); // ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAA_modifyMachineZoneLostConfig(HbComData* data, // void hbComMakeReqA9(HbComData* data, HbMachineStatus status, HbMachineType type);
uint8_t zone,
int on); ADEMCO_EXPORT_SYMBOL
void hbComMakeReqAA_modifyMachineZoneLostConfig(HbComData* data, uint8_t zone, int on);
ADEMCO_EXPORT_SYMBOL
void hbComMakeReqAC_getMachineZoneLostConfig(HbComData* data);
ADEMCO_EXPORT_SYMBOL
void hbComMakeReqAD_getMoreMachineZoneLostConfig(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAC_getMachineZoneLostConfig(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAD_getMoreMachineZoneLostConfig(HbComData* data);
// p2 must be HbCom_3sec_arm or HbCom_3sec_disarm // p2 must be HbCom_3sec_arm or HbCom_3sec_disarm
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data,
HbCom_3sec_which p1, HbCom_3sec_which p1,
HbCom_3sec_status status); HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL void hbComMakeReqRead_acct(HbComData* data); void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqWrite_acct(HbComData* data, const char* acct);
ADEMCO_EXPORT_SYMBOL void hbComResp_A2_Iter_init(HbComResp_A2_Iter* iter, ADEMCO_EXPORT_SYMBOL
const HbComData* com); void hbComMakeReqRead_acct(HbComData* data);
ADEMCO_EXPORT_SYMBOL HbComResp_A2_p1 hbComResp_A2_Iter_next(HbComResp_A2_Iter* iter, ADEMCO_EXPORT_SYMBOL
void hbComMakeReqWrite_acct(HbComData* data, const char* acct);
ADEMCO_EXPORT_SYMBOL
void hbComResp_A2_Iter_init(HbComResp_A2_Iter* iter, const HbComData* com);
ADEMCO_EXPORT_SYMBOL
HbComResp_A2_p1 hbComResp_A2_Iter_next(HbComResp_A2_Iter* iter,
HbZoneAndProperty* zp); HbZoneAndProperty* zp);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA0_getMachineStatus(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespA0_getMachineStatus(HbComData* data,
HbMachineStatus status, HbMachineStatus status,
HbMachineType type); HbMachineType type);
// zones and props length is count // zones and props length is count
// if count is 0, p1 wil be set to HbComResp_A2_p1_nomore // if count is 0, p1 wil be set to HbComResp_A2_p1_nomore
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA2_getMachineZones(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespA2_getMachineZones(HbComData* data,
size_t count, size_t count,
AdemcoZone* zones, AdemcoZone* zones,
HbZoneProperty* props, HbZoneProperty* props,
HbComResp_A2_p1 p1); HbComResp_A2_p1 p1);
// 学码开始,等待探测器无线信号中 // 学码开始,等待探测器无线信号中
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA3_waitingSignal(HbComData* data); ADEMCO_EXPORT_SYMBOL
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA4_modifyMachineZone(HbComData* data, void hbComMakeRespA3_waitingSignal(HbComData* data);
ADEMCO_EXPORT_SYMBOL
void hbComMakeRespA4_modifyMachineZone(HbComData* data,
AdemcoZone zone, AdemcoZone zone,
HbZoneProperty prop, HbZoneProperty prop,
HbComResp_A4_p3 p3); HbComResp_A4_p3 p3);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA6_getMachineTimer(HbComData* data, ADEMCO_EXPORT_SYMBOL
HbMachineTimer* timer); void hbComMakeRespA6_getMachineTimer(HbComData* data, HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL
void hbComMakeRespA7_setMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL
void hbComMakeRespA8_reject(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA7_setMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA8_reject(HbComData* data);
// TODO // TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeRespA9_(HbComData* data); // ADEMCO_EXPORT_SYMBOL void hbComMakeRespA9_(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data,
AdemcoZone zone, AdemcoZone zone,
HbComResp_AB_p2 p2); HbComResp_AB_p2 p2);
// 返回所有失联开的防区 // 返回所有失联开的防区
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data,
HbComResp_AD_p1 p1, HbComResp_AD_p1 p1,
size_t count, size_t count,
AdemcoZone* zones, AdemcoZone* zones,
HbComResp_AD_p2 p2); HbComResp_AD_p2 p2);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data,
HbCom_3sec_which p1, HbCom_3sec_which p1,
HbCom_3sec_status status); HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data, ADEMCO_EXPORT_SYMBOL
void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data,
HbMachineStatus statusMachine, HbMachineStatus statusMachine,
HbMachineStatus statusSec1, HbMachineStatus statusSec1,
HbMachineStatus statusSec2, HbMachineStatus statusSec2,
HbMachineStatus statusSec3); HbMachineStatus statusSec3);
ADEMCO_EXPORT_SYMBOL void hbComDataToAdemcoXData(const HbComData* const data, ADEMCO_EXPORT_SYMBOL
void hbComDataToAdemcoXData(const HbComData* const data,
AdemcoXDataSegment* xdata, AdemcoXDataSegment* xdata,
AdemcoXDataLengthFormat xlf, AdemcoXDataLengthFormat xlf,
AdemcoXDataTransform xtr); AdemcoXDataTransform xtr);
......
...@@ -3,4 +3,5 @@ xcopy /i /s /y G:\dev_libs\ademco\hb\ademco.c ..\ ...@@ -3,4 +3,5 @@ xcopy /i /s /y G:\dev_libs\ademco\hb\ademco.c ..\
xcopy /i /s /y G:\dev_libs\ademco\hb\hb_com.h ..\ xcopy /i /s /y G:\dev_libs\ademco\hb\hb_com.h ..\
xcopy /i /s /y G:\dev_libs\ademco\hb\hb_com.c ..\ xcopy /i /s /y G:\dev_libs\ademco\hb\hb_com.c ..\
xcopy /i /s /y G:\dev_libs\ademco\hb\ademco_version.h ..\ xcopy /i /s /y G:\dev_libs\ademco\hb\ademco_version.h ..\
xcopy /i /s /y G:\dev_libs\ademco\hb\ademco_config.h ..\
xcopy /i /s /y G:\dev_libs\ademco\hb\CHANGELOG.md ..\ xcopy /i /s /y G:\dev_libs\ademco\hb\CHANGELOG.md ..\
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