Commit 38c60906 authored by captainwong's avatar captainwong

releasing

parent 2eb71ce1
# Ademco Change Log
## 3.2.2 2024-8-7 15:10:37
- 解析形为 [#861234567890|3400 00 000] 之类的以账号为安定宝ID的data段,解析结果为安定宝ID为0
## 3.2.1 2024-8-7 14:29:35
- 修复安定宝协议data段 #acct 生成错误的bug
## 3.2.0 2024-8-4 22:16:32
- 全面支持 C51/gcc-avr/msvc/gcc 等编译器
## 3.1.0 2024-7-11 02:24:14
## 3.0.0 2024-7-1 06:19:01
- 可在 windows/linux/c51/avr 环境下编译
## 2.7.3 2024-6-28 19:32:18
- change `XX` sequence
## 2.7.2 2024-6-25 10:18:16
## 2.7.1 2024-6-4 16:34:48
## 2.7.0 2024-6-4 15:24:15
- shrink `ademco_packet_t` size
......
......@@ -13,22 +13,7 @@
#include <string.h>
#if ADEMCO_USE_UNIQUE_BUF
static char buf[ADEMCO_PACKET_MAX_LEN];
#endif
#ifdef __C51__
#include <stdarg.h>
#ifndef UNUSED
#define UNUSED(x) ((x) = (x))
#endif
int snprintf(char* str, size_t size, const char* format, ...) {
va_list args;
UNUSED(size);
va_start(args, format);
vsprintf(str, format, args);
va_end(args);
return strlen(str);
}
static char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
#define ADEMCO_STRINGIFY(v) ADEMCO_STRINGIFY_HELPER(v)
......@@ -52,7 +37,7 @@ const char* ademco_version_string(void) {
}
#endif
static uint8_t hex2char(uint8_t h) {
uint8_t ademco_hex2char(uint8_t h) {
h &= 0x0F;
if (h > 9)
return 'A' + h - 10;
......@@ -60,7 +45,7 @@ static uint8_t hex2char(uint8_t h) {
return '0' + h;
}
static uint8_t char2hex(uint8_t c) {
uint8_t ademco_char2hex(uint8_t c) {
if ('0' <= c && c <= '9')
return c - '0';
else if ('A' <= c && c <= 'F')
......@@ -95,9 +80,9 @@ uint8_t ademco_decode_signal_strength(uint8_t bcd_strength) {
return strength;
}
int ademco_is_valid_account(const char* acct) {
size_t len = 0;
int ishex = 0;
bool ademco_is_valid_account(const char* acct) {
size_t ADEMCO_BUF_MEMORY_MODIFIER len = 0;
int ADEMCO_BUF_MEMORY_MODIFIER ishex = 0;
while (*acct && len < ADEMCO_PACKET_ACCT_MAX_LEN) {
if (isdigit(*acct)) {
len++;
......@@ -113,27 +98,27 @@ int ademco_is_valid_account(const char* acct) {
(ishex ? len == ADEMCO_PACKET_ACCT_MAC_LEN : (len >= ADEMCO_PACKET_ACCT_MIN_LEN));
}
int ademco_is_valid_password(const char* pwd) {
size_t len = 0;
bool ademco_is_valid_password(const char* pwd) {
size_t ADEMCO_BUF_MEMORY_MODIFIER len = 0;
while (*pwd && len < ADEMCO_PACKET_PWD_MAX_LEN) {
if (isdigit(*pwd)) {
len++;
} else {
return 0;
return false;
}
pwd++;
}
return *pwd == '\0' && len >= ADEMCO_PACKET_PWD_MIN_LEN;
}
int ademco_is_machine_status_event(ademco_event_t ademco_event) {
bool ademco_is_machine_status_event(ademco_event_t ademco_event) {
return ademco_event == EVENT_ARM_AWAY ||
ademco_event == EVENT_ARM_STAY ||
ademco_event == EVENT_ARM_STAY_1456 ||
ademco_event == EVENT_DISARM;
}
int ademco_is_machine_type_event(ademco_event_t ademco_event) {
bool ademco_is_machine_type_event(ademco_event_t ademco_event) {
return ademco_event == EVENT_I_AM_NET_MODULE ||
ademco_event == EVENT_I_AM_GPRS ||
ademco_event == EVENT_I_AM_LCD ||
......@@ -148,7 +133,7 @@ int ademco_is_machine_type_event(ademco_event_t ademco_event) {
ademco_event == EVENT_I_AM_WIFI2;
}
int ademco_is_event_need_control_source(ademco_event_t ademco_event) {
bool ademco_is_event_need_control_source(ademco_event_t ademco_event) {
return ademco_event == EVENT_ARM_AWAY ||
ademco_event == EVENT_ARM_STAY ||
ademco_event == EVENT_ARM_STAY_1456 ||
......@@ -177,7 +162,7 @@ ademco_event_t ademco_get_exception_event_by_recover_event(ademco_event_t recove
case EVENT_OTHER_EXCEPTION_RECOVER:
return EVENT_OTHER_EXCEPTION;
case EVENT_AC_RECOVER:
return EVENT_AC_BROKE;
return EVENT_AC_BROKEN;
case EVENT_SOLAR_DISTURB_RECOVER:
return EVENT_SOLAR_DISTURB;
case EVENT_BAD_BATTERY_RECOVER:
......@@ -208,7 +193,7 @@ ademco_event_level_t ademco_get_event_level(ademco_event_t ademco_event) {
case EVENT_SOLAR_DISTURB_RECOVER:
return EVENT_LEVEL_EXCEPTION_RECOVER;
case EVENT_AC_BROKE:
case EVENT_AC_BROKEN:
case EVENT_LOW_BATTERY:
case EVENT_BAD_BATTERY:
case EVENT_SOLAR_DISTURB:
......@@ -239,7 +224,7 @@ ademco_event_level_t ademco_get_event_level(ademco_event_t ademco_event) {
#if ADEMCO_ENABLE_TO_STRING
const char* ademco_event_to_string(ademco_event_t ademco_event) {
switch (ademco_event) {
#define XX(name, code, zh) \
#define XX(code, name, zh) \
case EVENT_##name: \
return #name;
......@@ -262,7 +247,7 @@ const char* ademco_event_to_string(ademco_event_t ademco_event) {
#if ADEMCO_ENABLE_CHINESE
const char* ademco_event_to_string_chinese(ademco_event_t ademco_event) {
switch (ademco_event) {
#define XX(name, code, zh) \
#define XX(code, name, zh) \
case EVENT_##name: \
return zh;
......@@ -282,7 +267,8 @@ const char* ademco_event_to_string_chinese(ademco_event_t ademco_event) {
}
#endif
static const uint16_t crc16Table[256] = {
#ifndef ADEMCO_USE_EXTERNAL_CRC16
static const uint16_t ADEMCO_CONST_MODIFIER crc16Table[256] = {
/* DEFINE THE FIRST ORDER POLYINOMIAL TABLE */
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, // 0x00
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, // 0x08
......@@ -318,16 +304,18 @@ static const uint16_t crc16Table[256] = {
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, // 0xF8
};
uint16_t ademco_crc16(const ademco_char_t* buf, size_t len) {
uint16_t crc = 0;
uint16_t ademco_crc16(const ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* buf, size_t len) {
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc = 0;
while (len--)
crc = (crc >> 8) ^ crc16Table[(crc ^ *buf++) & 0xFF];
return crc;
}
#endif // ADEMCO_USE_EXTERNAL_CRC16
size_t ademco_append_data(ademco_char_t* buf, const char* acct, ademco_id_t ademco_id,
ademco_event_t ademco_event, ademco_gg_t gg, ademco_zone_t zone) {
char* p = (char*)buf;
uint8_t i;
if (ademco_event == EVENT_INVALID_EVENT) {
*p++ = '[';
*p++ = ']';
......@@ -336,17 +324,21 @@ size_t ademco_append_data(ademco_char_t* buf, const char* acct, ademco_id_t adem
*p++ = '[';
*p++ = '#';
if (acct && ademco_id == 0) {
p += snprintf(p, 20, "%s", acct);
ademco_id %= ADEMCO_ID_SENTINEL;
if (acct && acct[0] && ademco_id == 0) {
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *acct; i++) {
*p++ = *acct++;
}
} else {
snprintf(p, 6 + 1, "%06X", ademco_id % ADEMCO_ID_SENTINEL);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_id, 6);
}
*p++ = '|';
snprintf(p, 4 + 1, "%04d", ademco_event % ADEMCO_EVENT_SENTINEL);
p += 4;
*p++ = (uint8_t)(ademco_event / 1000) + '0';
*p++ = (uint8_t)((ademco_event % 1000) / 100) + '0';
*p++ = (uint8_t)((ademco_event % 100) / 10) + '0';
*p++ = (uint8_t)(ademco_event % 10) + '0';
*p++ = ' ';
......@@ -363,8 +355,10 @@ size_t ademco_append_data(ademco_char_t* buf, const char* acct, ademco_id_t adem
*p++ = ' ';
snprintf(p, 3 + 1, "%03d", zone % ADEMCO_ZONE_SENTINEL);
p += 3;
zone %= ADEMCO_ZONE_SENTINEL;
*p++ = (uint8_t)(zone / 100) + '0';
*p++ = (uint8_t)((zone % 100) / 10) + '0';
*p++ = (uint8_t)(zone % 10) + '0';
*p++ = ']';
......@@ -390,6 +384,7 @@ size_t ademco_append_data2(ademco_data_t* ademco_data, const char* acct,
size_t ademco_append_data3(ademco_data_t* ademco_data, const char* acct) {
char* p = (char*)ademco_data->raw;
uint8_t i;
if (ademco_data->ademco_event == EVENT_INVALID_EVENT) {
*p++ = '[';
*p++ = ']';
......@@ -398,17 +393,21 @@ size_t ademco_append_data3(ademco_data_t* ademco_data, const char* acct) {
*p++ = '[';
*p++ = '#';
if (acct && ademco_data->ademco_id == 0) {
p += snprintf(p, 20, "%s", acct);
ademco_data->ademco_id %= ADEMCO_ID_SENTINEL;
if (acct && acct[0] && ademco_data->ademco_id == 0) {
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *acct; i++) {
*p++ = *acct++;
}
} else {
snprintf(p, 6 + 1, "%06X", ademco_data->ademco_id % ADEMCO_ID_SENTINEL);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_data->ademco_id, 6);
}
*p++ = '|';
snprintf(p, 4 + 1, "%04d", ademco_data->ademco_event % ADEMCO_EVENT_SENTINEL);
p += 4;
*p++ = (uint8_t)(ademco_data->ademco_event / 1000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_event % 1000) / 100) + '0';
*p++ = (uint8_t)((ademco_data->ademco_event % 100) / 10) + '0';
*p++ = (uint8_t)(ademco_data->ademco_event % 10) + '0';
*p++ = ' ';
......@@ -425,8 +424,10 @@ size_t ademco_append_data3(ademco_data_t* ademco_data, const char* acct) {
*p++ = ' ';
snprintf(p, 3 + 1, "%03d", ademco_data->zone % ADEMCO_ZONE_SENTINEL);
p += 3;
ademco_data->zone %= ADEMCO_ZONE_SENTINEL;
*p++ = (uint8_t)(ademco_data->zone / 100) + '0';
*p++ = (uint8_t)((ademco_data->zone % 100) / 10) + '0';
*p++ = (uint8_t)(ademco_data->zone % 10) + '0';
*p++ = ']';
......@@ -445,18 +446,22 @@ ademco_parse_result_t ademco_parse_data(const ademco_char_t* packet, size_t pack
packet[0] == '[' && packet[1] == ']') {
memset(ademco_data, 0, sizeof(*ademco_data));
strcpy((char*)ademco_data->raw, "[]");
ademco_data->ademco_event = EVENT_INVALID_EVENT;
ademco_data->ademco_id = 0;
ademco_data->gg = 0;
ademco_data->zone = 0;
ademco_data->raw_len = 2;
return ADEMCO_PARSE_RESULT_OK;
} else if (packet_len >= ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN &&
packet[0] == '[' &&
packet[packet_len - 1] == ']') { // [#000000|1400 00 000]
const char* p = packet + 2;
size_t acct_len = packet_len - 15;
size_t ADEMCO_BUF_MEMORY_MODIFIER acct_len = packet_len - 15;
#if !ADEMCO_USE_UNIQUE_BUF
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX] = {0};
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX] = {0};
#endif
if (acct_len < 6) {
......@@ -470,6 +475,10 @@ ademco_parse_result_t ademco_parse_data(const ademco_char_t* packet, size_t pack
strncpy(buf, (const char*)p, acct_len);
buf[acct_len] = '\0';
ademco_data->ademco_id = (ademco_id_t)strtoul(buf, NULL, 16);
if (ademco_data->ademco_id > ADEMCO_ID_SENTINEL) {
// ademco_id maybe acct like "861234567890"
ademco_data->ademco_id = ADEMCO_ID_INVALID;
}
p += acct_len;
if (*p++ != '|') {
......@@ -532,11 +541,14 @@ size_t ademco_data_to_congwin_fe100(ademco_char_t* fe100, size_t fe100_len,
*p++ = '0';
*p++ = ' ';
snprintf(p,
fe100_len - (p - fe100),
"%08d",
ademco_data->ademco_id % 100000000);
p += 8;
*p++ = (uint8_t)(ademco_data->ademco_id / 10000000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 10000000) / 1000000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 1000000) / 100000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 100000) / 10000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 10000) / 1000) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 1000) / 100) + '0';
*p++ = (uint8_t)((ademco_data->ademco_id % 100) / 10) + '0';
*p++ = (uint8_t)(ademco_data->ademco_id % 10) + '0';
*p++ = ' '; // 18
*p++ = '1';
......@@ -559,11 +571,9 @@ size_t ademco_data_to_congwin_fe100(ademco_char_t* fe100, size_t fe100_len,
*p++ = 'B';
*p++ = '0';
} else {
snprintf(p,
fe100_len - (p - fe100),
"%03d",
ademco_data->ademco_event % 1000);
p += 3;
*p++ = '0' + (uint8_t)((ademco_data->ademco_event % 1000) / 100);
*p++ = '0' + ((ademco_data->ademco_event % 100) / 10);
*p++ = '0' + (ademco_data->ademco_event % 10);
}
*p++ = ' '; // FE100, gg === 0
......@@ -576,11 +586,9 @@ size_t ademco_data_to_congwin_fe100(ademco_char_t* fe100, size_t fe100_len,
else
*p++ = 'C'; // zone event
snprintf(p,
fe100_len - (p - fe100),
"%03d",
ademco_data->zone % 1000);
p += 3;
*p++ = '0' + (uint8_t)((ademco_data->zone % 1000) / 100);
*p++ = '0' + ((ademco_data->zone % 100) / 10);
*p++ = '0' + (ademco_data->zone % 10);
*p++ = ' ';
*p++ = '\r';
......@@ -593,27 +601,27 @@ void ademco_xdata_init(ademco_xdata_t* xdat) {
memset(xdat, 0, sizeof *xdat);
}
int ademco_xdata_convert(ademco_xdata_t* xdat,
bool ademco_xdata_convert(ademco_xdata_t* xdat,
ademco_xdata_length_format_t xlf) {
#if !ADEMCO_USE_UNIQUE_BUF
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_XDATA_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_XDATA_MAX_LEN];
#endif
size_t len;
size_t ADEMCO_BUF_MEMORY_MODIFIER len;
if (!xdat) {
return ADEMCO_ERR;
return false;
}
if (xdat->lenghFormat == xlf) {
return ADEMCO_OK;
return false;
}
len = ademco_xdata_get_valid_content_len(xdat);
if (xlf == ADEMCO_XDATA_LENGTH_FMT_TWO_HEX) {
if (len + 6 > ADEMCO_PACKET_XDATA_MAX_LEN)
return ADEMCO_ERR;
return false;
xdat->raw[5 + ademco_xdata_get_valid_content_len(xdat)] = '\0';
len = ademco_hex_str_to_array((uint8_t*)buf,
ademco_xdata_get_valid_content_addr(xdat),
......@@ -629,7 +637,7 @@ int ademco_xdata_convert(ademco_xdata_t* xdat,
ADEMCO_XDATA_TRANSFORM_TO_ASCII,
buf, len);
}
return ADEMCO_OK;
return true;
}
#ifdef SWIG
......@@ -646,13 +654,13 @@ const char* ademco_xdata_get_valid_content_addr(const ademco_xdata_t* xdat) {
return NULL;
}
int ademco_xdata_memcmp(const ademco_xdata_t* xdat,
bool ademco_xdata_memeq(const ademco_xdata_t* xdat,
const void* buf, size_t buf_len) {
const void* p;
if (ademco_xdata_get_valid_content_len(xdat) != buf_len) return 0;
if (ademco_xdata_get_valid_content_len(xdat) != buf_len) return false;
p = ademco_xdata_get_valid_content_addr(xdat);
if (!p) return 0;
return memcmp(p, buf, buf_len);
return memcmp(p, buf, buf_len) == 0;
}
size_t ademco_xdata_get_valid_content_len(const ademco_xdata_t* xdat) {
......@@ -675,7 +683,7 @@ size_t ademco_xdata_copy(ademco_xdata_t* dst, const ademco_xdata_t* src) {
return 0;
}
int ademco_make_xdata(ademco_xdata_t* xdat,
bool ademco_make_xdata(ademco_xdata_t* xdat,
ademco_xdata_length_format_t xlf,
ademco_xdata_transform_t xtr,
const ademco_char_t* content, size_t len) {
......@@ -683,9 +691,9 @@ int ademco_make_xdata(ademco_xdata_t* xdat,
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_XDATA_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_XDATA_MAX_LEN];
#endif
size_t translen;
uint32_t ADEMCO_BUF_MEMORY_MODIFIER translen;
len &= 0xFFFF;
translen = len & 0xFFFF;
......@@ -696,7 +704,7 @@ int ademco_make_xdata(ademco_xdata_t* xdat,
(const uint8_t*)content, len) &
0xFFFF;
else
return ADEMCO_ERR;
return false;
xdat->lenghFormat = xlf;
if (xlf == ADEMCO_XDATA_LENGTH_FMT_TWO_HEX &&
......@@ -709,93 +717,136 @@ int ademco_make_xdata(ademco_xdata_t* xdat,
p += translen;
*p++ = ']';
xdat->raw_len = p - xdat->raw;
return ADEMCO_OK;
return true;
} else if (xlf == ADEMCO_XDATA_LENGTH_FMT_FOUR_DECIMAL &&
translen + 6 < ADEMCO_PACKET_XDATA_MAX_LEN) {
ademco_char_t* p = xdat->raw;
char temp[5];
*p++ = '[';
snprintf(temp, sizeof(temp), "%04zX", translen & 0xFFFF);
memcpy(p, temp, 4);
p += 4;
p += ademco_dec_to_hex_str(p, translen, 4);
memcpy(p, buf, translen);
p += translen;
*p++ = ']';
xdat->raw_len = p - xdat->raw;
return ADEMCO_OK;
return true;
} else
return ADEMCO_ERR;
return false;
}
int ademco_is_valid_packet_id(const char* standard, const char* id, size_t len) {
size_t standard_len = strlen(standard);
len = standard_len < len ? standard_len : len;
return strncmp(standard, id, len) == 0;
bool ademco_is_valid_packet_id(const char* standard, const char* id, size_t len) {
while (*standard && len--) {
if (*standard++ != *id++)
return false;
}
return true;
}
static const char* const ids[AID_COUNT] = {
ADEMCO_PACKET_ID_NULL,
ADEMCO_PACKET_ID_ACK,
ADEMCO_PACKET_ID_NAK,
ADEMCO_PACKET_ID_DUH,
ADEMCO_PACKET_ID_HB,
ADEMCO_PACKET_ID_ADM_CID,
ADEMCO_PACKET_ID_MOD_REG,
ADEMCO_PACKET_ID_REG_RSP,
};
ademco_packet_id_t ademco_packet_id_from_string(const char* id, size_t len) {
uint8_t i;
for (i = 0; i < AID_COUNT; i++)
if (ademco_is_valid_packet_id(ids[i], id, len))
return (ademco_packet_id_t)(i);
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_NULL, id, len))
return AID_NULL;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_ACK, id, len))
return AID_ACK;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_HB, id, len))
return AID_HB;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_ADM_CID, id, len))
return AID_ADM_CID;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_NAK, id, len))
return AID_NAK;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_DUH, id, len))
return AID_DUH;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_MOD_REG, id, len))
return AID_MOD_REG;
if (ademco_is_valid_packet_id(ADEMCO_PACKET_ID_REG_RSP, id, len))
return AID_REG_RSP;
return AID_INVALID;
}
const char* ademco_packet_id_to_string(ademco_packet_id_t id) {
if (0 <= id && id < AID_COUNT)
return ids[id];
else
return "Unkown ademco_packet_id_t";
switch (id) {
case AID_NULL:
return ADEMCO_PACKET_ID_NULL;
case AID_ACK:
return ADEMCO_PACKET_ID_ACK;
case AID_NAK:
return ADEMCO_PACKET_ID_NAK;
case AID_DUH:
return ADEMCO_PACKET_ID_DUH;
case AID_HB:
return ADEMCO_PACKET_ID_HB;
case AID_ADM_CID:
return ADEMCO_PACKET_ID_ADM_CID;
case AID_MOD_REG:
return ADEMCO_PACKET_ID_MOD_REG;
case AID_REG_RSP:
return ADEMCO_PACKET_ID_REG_RSP;
default:
return NULL;
}
}
static void getNowTimestamp(char* buf) {
#ifdef ADEMCO_USE_CUSTOM_TIME_T
time_t now = ademco_get_time_t(NULL);
#else
time_t now = time(NULL);
#endif
time_t ADEMCO_BUF_MEMORY_MODIFIER now = time(NULL);
#ifdef __ARMCC_VERSION
struct tm tm = {0};
#if ADEMCO_DISABLE_GMTIME
struct tm ADEMCO_BUF_MEMORY_MODIFIER tm = {0};
_localtime_r(&now, &tm);
snprintf(buf, ADEMCO_PACKET_TIMESTAMP_LEN + 1,
"_%02d:%02d:%02d,%02d-%02d-%04d",
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900);
#else
struct tm* tm = localtime(&now);
snprintf(buf, ADEMCO_PACKET_TIMESTAMP_LEN + 1,
"_%02d:%02d:%02d,%02d-%02d-%04d",
tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
#endif
struct tm ADEMCO_BUF_MEMORY_MODIFIER tm = *localtime(&now);
#endif // ADEMCO_DISABLE_GMTIME
tm.tm_mon += 1;
tm.tm_year += 1900;
*buf++ = '_';
*buf++ = (uint8_t)(tm.tm_hour / 10) + '0';
*buf++ = (uint8_t)(tm.tm_hour % 10) + '0';
*buf++ = ':';
*buf++ = (uint8_t)(tm.tm_min / 10) + '0';
*buf++ = (uint8_t)(tm.tm_min % 10) + '0';
*buf++ = ':';
*buf++ = (uint8_t)(tm.tm_sec / 10) + '0';
*buf++ = (uint8_t)(tm.tm_sec % 10) + '0';
*buf++ = ',';
*buf++ = (uint8_t)(tm.tm_mon / 10) + '0';
*buf++ = (uint8_t)(tm.tm_mon % 10) + '0';
*buf++ = '-';
*buf++ = (uint8_t)(tm.tm_mday / 10) + '0';
*buf++ = (uint8_t)(tm.tm_mday % 10) + '0';
*buf++ = '-';
*buf++ = (uint8_t)(tm.tm_year / 1000) + '0';
*buf++ = (uint8_t)((tm.tm_year % 1000) / 100) + '0';
*buf++ = (uint8_t)((tm.tm_year % 100) / 10) + '0';
*buf++ = (uint8_t)(tm.tm_year % 10) + '0';
*buf = '\0';
}
static void getGmtTimestamp(char* buf) {
#ifdef ADEMCO_DISABLE_GMTIME
getNowTimestamp(buf);
#else
#ifdef ADEMCO_USE_CUSTOM_TIME_T
time_t now = ademco_get_time_t(NULL);
#else
time_t now = time(NULL);
#endif
struct tm* tm = gmtime(&now);
snprintf(buf, ADEMCO_PACKET_TIMESTAMP_LEN + 1,
"_%02d:%02d:%02d,%02d-%02d-%04d",
tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
time_t ADEMCO_BUF_MEMORY_MODIFIER now = time(NULL);
struct tm ADEMCO_BUF_MEMORY_MODIFIER tm = *gmtime(&now);
tm.tm_mon += 1;
tm.tm_year += 1900;
*buf++ = '_';
*buf++ = (uint8_t)(tm.tm_hour / 10) + '0';
*buf++ = (uint8_t)(tm.tm_hour % 10) + '0';
*buf++ = ':';
*buf++ = (uint8_t)(tm.tm_min / 10) + '0';
*buf++ = (uint8_t)(tm.tm_min % 10) + '0';
*buf++ = ':';
*buf++ = (uint8_t)(tm.tm_sec / 10) + '0';
*buf++ = (uint8_t)(tm.tm_sec % 10) + '0';
*buf++ = ',';
*buf++ = (uint8_t)(tm.tm_mon / 10) + '0';
*buf++ = (uint8_t)(tm.tm_mon % 10) + '0';
*buf++ = '-';
*buf++ = (uint8_t)(tm.tm_mday / 10) + '0';
*buf++ = (uint8_t)(tm.tm_mday % 10) + '0';
*buf++ = '-';
*buf++ = (uint8_t)(tm.tm_year / 1000) + '0';
*buf++ = (uint8_t)((tm.tm_year % 1000) / 100) + '0';
*buf++ = (uint8_t)((tm.tm_year % 100) / 10) + '0';
*buf++ = (uint8_t)(tm.tm_year % 10) + '0';
*buf = '\0';
#endif
}
......@@ -806,32 +857,35 @@ size_t ademco_make_empty_data_packet(ademco_char_t* dst_buff, size_t len,
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
char* p = buf;
char* pcrc = buf + 1;
char* plen = buf + 5;
char* pid = buf + 9;
char temp[5];
uint16_t crc;
size_t packet_len, ademco_len;
char ADEMCO_BUF_MEMORY_MODIFIER* p = buf;
char ADEMCO_BUF_MEMORY_MODIFIER* pcrc = buf + 1;
char ADEMCO_BUF_MEMORY_MODIFIER* plen = buf + 5;
char ADEMCO_BUF_MEMORY_MODIFIER* pid = buf + 9;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER packet_len, ademco_len;
uint8_t i;
buf[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, id, strlen(id));
p = pid + strlen(id);
snprintf((char*)p, 5, "%04d", seq);
p += 4;
seq %= 10000;
*p++ = (uint8_t)(seq / 1000) + '0';
*p++ = (uint8_t)((seq % 1000) / 100) + '0';
*p++ = (uint8_t)((seq % 100) / 10) + '0';
*p++ = (uint8_t)(seq % 10) + '0';
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL && strlen(acct) > 0) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
if (acct && acct[0]) {
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *acct; i++) {
*p++ = *acct++;
}
} else {
snprintf((char*)p, 7, "%06X", ademco_id);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_id, 6);
}
*p++ = '[';
*p++ = ']';
......@@ -839,14 +893,12 @@ size_t ademco_make_empty_data_packet(ademco_char_t* dst_buff, size_t len,
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
packet_len = p - buf;
packet_len = (p - buf) & 0xFFFF;
// \n crc len \r
ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
ademco_dec_to_hex_str(plen, ademco_len, 4);
crc = ademco_crc16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
ademco_dec_to_hex_str(pcrc, crc, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buf, packet_len);
......@@ -863,32 +915,36 @@ size_t ademco_make_adm_empty_data_packet(ademco_char_t* dst_buff, size_t len,
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
char* p = buf;
char* pcrc = buf + 1;
char* plen = buf + 5;
char* pid = buf + 9;
char temp[5];
uint16_t crc;
size_t packet_len, ademco_len;
char ADEMCO_BUF_MEMORY_MODIFIER* p = buf;
char ADEMCO_BUF_MEMORY_MODIFIER* pcrc = buf + 1;
char ADEMCO_BUF_MEMORY_MODIFIER* plen = buf + 5;
char ADEMCO_BUF_MEMORY_MODIFIER* pid = buf + 9;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER packet_len, ademco_len;
uint8_t i;
buf[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, id, strlen(id));
p = pid + strlen(id);
snprintf((char*)p, 5, "%04d", seq);
seq %= 10000;
*p++ = (uint8_t)(seq / 1000) + '0';
*p++ = (uint8_t)((seq % 1000) / 100) + '0';
*p++ = (uint8_t)((seq % 100) / 10) + '0';
*p++ = (uint8_t)(seq % 10) + '0';
p += 4;
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL && strlen(acct) > 0) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
if (acct && acct[0]) {
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *acct; i++) {
*p++ = *acct++;
}
} else {
snprintf((char*)p, 7, "%06X", ademco_id);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_id, 6);
}
*p++ = '[';
*p++ = ']';
......@@ -896,14 +952,12 @@ size_t ademco_make_adm_empty_data_packet(ademco_char_t* dst_buff, size_t len,
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
packet_len = p - buf;
packet_len = (p - buf) & 0xFFFF;
// \n crc len \r
ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
ademco_dec_to_hex_str(plen, ademco_len, 4);
crc = ademco_crc16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
ademco_dec_to_hex_str(pcrc, crc, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buf, packet_len);
......@@ -946,32 +1000,36 @@ size_t ademco_make_hb_packet(ademco_char_t* dst_buff, size_t len,
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
char* p = buf;
char* pcrc = buf + 1;
char* plen = buf + 5;
char* pid = buf + 9;
char temp[5];
uint16_t crc;
size_t packet_len, ademco_len;
char ADEMCO_BUF_MEMORY_MODIFIER* p = buf;
char ADEMCO_BUF_MEMORY_MODIFIER* pcrc = buf + 1;
char ADEMCO_BUF_MEMORY_MODIFIER* plen = buf + 5;
char ADEMCO_BUF_MEMORY_MODIFIER* pid = buf + 9;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER packet_len, ademco_len;
uint8_t i;
buf[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, ADEMCO_PACKET_ID_HB, strlen(ADEMCO_PACKET_ID_HB));
p = pid + strlen(ADEMCO_PACKET_ID_HB);
snprintf((char*)p, 5, "%04d", seq);
p += 4;
seq %= 10000;
*p++ = (uint8_t)(seq / 1000) + '0';
*p++ = (uint8_t)((seq % 1000) / 100) + '0';
*p++ = (uint8_t)((seq % 100) / 10) + '0';
*p++ = (uint8_t)(seq % 10) + '0';
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
if (acct && acct[0]) {
char ADEMCO_BUF_MEMORY_MODIFIER* src = (char*)acct;
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *src; i++) {
*p++ = *src++;
}
} else {
snprintf(p, 7, "%06X", ademco_id);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_id, 6);
}
p += ademco_append_data(p, acct, ademco_id, ademco_event, gg, zone);
if (xdat && xdat->raw_len > 0) {
......@@ -982,14 +1040,12 @@ size_t ademco_make_hb_packet(ademco_char_t* dst_buff, size_t len,
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
packet_len = p - buf;
packet_len = (p - buf) & 0xFFFF;
// \n crc len \r
ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
ademco_dec_to_hex_str(plen, ademco_len, 4);
crc = ademco_crc16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
ademco_dec_to_hex_str(pcrc, crc, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buf, packet_len);
......@@ -1009,32 +1065,36 @@ size_t ademco_make_adm_packet(ademco_char_t* dst_buff, size_t len,
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
char* p = buf;
char* pcrc = buf + 1;
char* plen = buf + 5;
char* pid = buf + 9;
char temp[5];
uint16_t crc;
size_t packet_len, ademco_len;
char ADEMCO_BUF_MEMORY_MODIFIER* p = buf;
char ADEMCO_BUF_MEMORY_MODIFIER* pcrc = buf + 1;
char ADEMCO_BUF_MEMORY_MODIFIER* plen = buf + 5;
char ADEMCO_BUF_MEMORY_MODIFIER* pid = buf + 9;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER packet_len, ademco_len;
uint8_t i;
buf[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, ADEMCO_PACKET_ID_ADM_CID, strlen(ADEMCO_PACKET_ID_ADM_CID));
p = pid + strlen(ADEMCO_PACKET_ID_ADM_CID);
snprintf((char*)p, 5, "%04d", seq);
p += 4;
seq %= 10000;
*p++ = (uint8_t)(seq / 1000) + '0';
*p++ = (uint8_t)((seq % 1000) / 100) + '0';
*p++ = (uint8_t)((seq % 100) / 10) + '0';
*p++ = (uint8_t)(seq % 10) + '0';
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (acct != NULL) {
memcpy(p, acct, strlen(acct));
p += strlen(acct);
if (acct && acct[0]) {
char ADEMCO_BUF_MEMORY_MODIFIER* src = (char*)acct;
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && *src; i++) {
*p++ = *src++;
}
} else {
snprintf(p, 7, "%06X", ademco_id);
p += 6;
p += ademco_dec_to_hex_str(p, ademco_id, 6);
}
p += ademco_append_data(p, acct, ademco_id, ademco_event, gg, zone);
if (xdat && xdat->raw_len > 0) {
......@@ -1045,14 +1105,12 @@ size_t ademco_make_adm_packet(ademco_char_t* dst_buff, size_t len,
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
packet_len = p - buf;
packet_len = (p - buf) & 0xFFFF;
// \n crc len \r
ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
ademco_dec_to_hex_str(plen, ademco_len, 4);
crc = ademco_crc16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
ademco_dec_to_hex_str(pcrc, crc, 4);
if (dst_buff != NULL && len > packet_len) {
memcpy(dst_buff, buf, packet_len);
......@@ -1064,7 +1122,7 @@ size_t ademco_make_adm_packet(ademco_char_t* dst_buff, size_t len,
static void copyAcct2AdemcoPacket(ademco_packet_t* pkt, const char* acct) {
if (acct) {
size_t len = strlen(acct);
size_t ADEMCO_BUF_MEMORY_MODIFIER len = strlen(acct);
if (len > ADEMCO_PACKET_ACCT_MAX_LEN)
len = ADEMCO_PACKET_ACCT_MAX_LEN;
memcpy(pkt->acct, acct, len);
......@@ -1129,32 +1187,34 @@ size_t ademco_make_hb_packet3(ademco_packet_t* pkt) {
#if ADEMCO_USE_STATIC_BUF
static
#endif
char buf[ADEMCO_PACKET_MAX_LEN];
char ADEMCO_BUF_MEMORY_MODIFIER buf[ADEMCO_PACKET_MAX_LEN];
#endif
char* p = buf;
char* pcrc = buf + 1;
char* plen = buf + 5;
char* pid = buf + 9;
char temp[5];
uint16_t crc;
size_t packet_len, ademco_len;
char ADEMCO_BUF_MEMORY_MODIFIER* p = buf;
char ADEMCO_BUF_MEMORY_MODIFIER* pcrc = buf + 1;
char ADEMCO_BUF_MEMORY_MODIFIER* plen = buf + 5;
char ADEMCO_BUF_MEMORY_MODIFIER* pid = buf + 9;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER packet_len, ademco_len;
uint8_t i;
buf[0] = ADEMCO_PACKET_PREFIX;
memcpy(pid, ADEMCO_PACKET_ID_HB, strlen(ADEMCO_PACKET_ID_HB));
p = pid + strlen(ADEMCO_PACKET_ID_HB);
snprintf((char*)p, 5, "%04d", pkt->seq);
p += 4;
*p++ = (uint8_t)(pkt->seq / 1000) + '0';
*p++ = (uint8_t)((pkt->seq % 1000) / 100) + '0';
*p++ = (uint8_t)((pkt->seq % 100) / 10) + '0';
*p++ = (uint8_t)(pkt->seq % 10) + '0';
memcpy(p, ADEMCO_RRCVR_DEFAULT, strlen(ADEMCO_RRCVR_DEFAULT));
p += strlen(ADEMCO_RRCVR_DEFAULT);
memcpy(p, ADEMCO_LPREF_DEFAULT, strlen(ADEMCO_LPREF_DEFAULT));
p += strlen(ADEMCO_LPREF_DEFAULT);
*p++ = '#';
if (pkt->acct[0] != '\0') {
memcpy(p, pkt->acct, strlen(pkt->acct));
p += strlen(pkt->acct);
for (i = 0; i < ADEMCO_PACKET_ACCT_MAX_LEN && pkt->acct[i]; i++) {
*p++ = pkt->acct[i];
}
} else {
snprintf(p, 7, "%06X", pkt->dat.ademco_id);
p += 6;
p += ademco_dec_to_hex_str(p, pkt->dat.ademco_id, 6);
}
ademco_append_data3(&pkt->dat, pkt->acct);
memcpy(p, pkt->dat.raw, pkt->dat.raw_len);
......@@ -1167,14 +1227,12 @@ size_t ademco_make_hb_packet3(ademco_packet_t* pkt) {
p += ADEMCO_PACKET_TIMESTAMP_LEN;
*p++ = ADEMCO_PACKET_SUFIX;
packet_len = p - buf;
packet_len = (p - buf) & 0xFFFF;
// \n crc len \r
ademco_len = packet_len - 1 - 4 - 4 - 1;
snprintf(temp, 5, "%04zX", ademco_len);
memcpy(plen, temp, 4);
ademco_dec_to_hex_str(plen, ademco_len, 4);
crc = ademco_crc16(pid, ademco_len);
snprintf(temp, 5, "%04X", crc);
memcpy(pcrc, temp, 4);
ademco_dec_to_hex_str(pcrc, crc, 4);
memcpy(pkt->raw, buf, packet_len);
pkt->raw[packet_len] = '\0'; // for debug convenience
......@@ -1208,9 +1266,9 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
size_t* cb_commited,
ademco_parse_error_t* err) {
const char *p, *q, *pid, *pend, *pacct, *pdat;
uint8_t h;
uint16_t crc;
size_t len_needed;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER h;
uint16_t ADEMCO_BUF_MEMORY_MODIFIER crc;
size_t ADEMCO_BUF_MEMORY_MODIFIER len_needed;
if (len < 9) {
ADEMCO_FILL_PARSE_ERROR(err, 0, "ADEMCO_PARSE_RESULT_NOT_ENOUGH");
......@@ -1239,7 +1297,7 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
// crc
crc = 0;
for (q = p; p - q < 4; p++) {
h = char2hex(*p);
h = ademco_char2hex(*p);
if (h == 0xFF) {
ADEMCO_FILL_PARSE_ERROR(err, p - buf, "crc contains non-hex characters");
*cb_commited += p - buf;
......@@ -1251,7 +1309,7 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
// len
pkt->len = 0;
for (q = p; p - q < 4; p++) {
h = char2hex(*p);
h = ademco_char2hex(*p);
if (h == 0xFF) {
ADEMCO_FILL_PARSE_ERROR(err, p - buf, "len contains non-hex characters");
*cb_commited += p - buf;
......@@ -1406,18 +1464,18 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
// *xdat
if (*p == '[') { // xdat exists
const char* pxdata = p++;
ademco_xdata_length_format_t xlf = ADEMCO_XDATA_LENGTH_FMT_FOUR_DECIMAL;
size_t valid_len = 0;
uint8_t i;
ademco_xdata_length_format_t ADEMCO_BUF_MEMORY_MODIFIER xlf = ADEMCO_XDATA_LENGTH_FMT_FOUR_DECIMAL;
size_t ADEMCO_BUF_MEMORY_MODIFIER valid_len = 0;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER i;
for (i = 0; i < 4; i++)
if (!isxdigit(*(uint8_t*)(p + i)))
xlf = ADEMCO_XDATA_LENGTH_FMT_TWO_HEX;
if (xlf == ADEMCO_XDATA_LENGTH_FMT_FOUR_DECIMAL) {
valid_len = (char2hex(*(pxdata + 1)) << 12) |
(char2hex(*(pxdata + 2)) << 8) |
(char2hex(*(pxdata + 3)) << 4) |
(char2hex(*(pxdata + 4)));
valid_len = (ademco_char2hex(*(pxdata + 1)) << 12) |
(ademco_char2hex(*(pxdata + 2)) << 8) |
(ademco_char2hex(*(pxdata + 3)) << 4) |
(ademco_char2hex(*(pxdata + 4)));
p += 4 + valid_len;
} else {
valid_len = (pxdata[1] << 8) | pxdata[2];
......@@ -1439,46 +1497,46 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
// timestamp, _%02d:%02d:%02d,%02d-%02d-%04d
// only check lengh, if format is incorrect, use local time instead
if (pend - p == ADEMCO_PACKET_TIMESTAMP_LEN) {
struct tm tm = {0};
struct tm ADEMCO_BUF_MEMORY_MODIFIER tm = {0};
pkt->timestamp = 0;
do {
if (*p++ != '_') {
break;
}
tm.tm_hour = char2hex(*p++);
tm.tm_hour = tm.tm_hour * 10 + char2hex(*p++);
tm.tm_hour = ademco_char2hex(*p++);
tm.tm_hour = tm.tm_hour * 10 + ademco_char2hex(*p++);
if (*p++ != ':') {
break;
}
tm.tm_min = char2hex(*p++);
tm.tm_min = tm.tm_min * 10 + char2hex(*p++);
tm.tm_min = ademco_char2hex(*p++);
tm.tm_min = tm.tm_min * 10 + ademco_char2hex(*p++);
if (*p++ != ':') {
break;
}
tm.tm_sec = char2hex(*p++);
tm.tm_sec = tm.tm_sec * 10 + char2hex(*p++);
tm.tm_sec = ademco_char2hex(*p++);
tm.tm_sec = tm.tm_sec * 10 + ademco_char2hex(*p++);
if (*p++ != ',') {
break;
}
tm.tm_mon = char2hex(*p++);
tm.tm_mon = tm.tm_mon * 10 + char2hex(*p++);
tm.tm_mon = ademco_char2hex(*p++);
tm.tm_mon = tm.tm_mon * 10 + ademco_char2hex(*p++);
if (*p++ != '-') {
break;
}
tm.tm_mday = char2hex(*p++);
tm.tm_mday = tm.tm_mday * 10 + char2hex(*p++);
tm.tm_mday = ademco_char2hex(*p++);
tm.tm_mday = tm.tm_mday * 10 + ademco_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++);
tm.tm_year = ademco_char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + ademco_char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + ademco_char2hex(*p++);
tm.tm_year = tm.tm_year * 10 + ademco_char2hex(*p++);
tm.tm_year -= 1900;
tm.tm_mon--;
......@@ -1487,11 +1545,7 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
} while (0);
if (pkt->timestamp <= 0) { // use local time instead
#ifdef ADEMCO_USE_CUSTOM_TIME_T
pkt->timestamp = ademco_get_time_t(NULL);
#else
pkt->timestamp = time(NULL);
#endif
p = pend;
}
} else {
......@@ -1511,11 +1565,23 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
return ADEMCO_PARSE_RESULT_OK;
}
size_t ademco_hilo_array_to_dec_str(ademco_char_t* str, const uint8_t* arr, size_t len) {
size_t ademco_dec_to_hex_str(char* str, uint32_t dec, uint8_t hex_len) {
char* p = str;
size_t i;
uint8_t i;
for (i = 0; i < hex_len; i++) {
*p++ = ademco_hex2char((dec >> (4 * (hex_len - i - 1))) & 0x0F);
}
return p - str;
}
size_t ademco_hilo_array_to_dec_str(ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* str,
const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len) {
char ADEMCO_BUF_MEMORY_MODIFIER* p = str;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
char ADEMCO_BUF_MEMORY_MODIFIER c;
for (i = 0; i < len; i++) {
char c = (arr[i] >> 4) & 0x0F;
c = (arr[i] >> 4) & 0x0F;
if (c > 9) {
return p - str;
}
......@@ -1529,11 +1595,13 @@ size_t ademco_hilo_array_to_dec_str(ademco_char_t* str, const uint8_t* arr, size
return p - str;
}
size_t ademco_hilo_array_to_hex_str(ademco_char_t* str, const uint8_t* arr, size_t len) {
char* p = str;
size_t i;
size_t ademco_hilo_array_to_hex_str(ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* str,
const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len) {
char ADEMCO_BUF_MEMORY_MODIFIER* p = str;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
for (i = 0; i < len; i++) {
char c = (arr[i] >> 4) & 0x0F;
char ADEMCO_BUF_MEMORY_MODIFIER c = (arr[i] >> 4) & 0x0F;
if (c > 9) {
if (i < 6) {
*p++ = c - 10 + 'A';
......@@ -1558,17 +1626,20 @@ size_t ademco_hilo_array_to_hex_str(ademco_char_t* str, const uint8_t* arr, size
return p - str;
}
size_t ademco_dec_str_to_hilo_array(uint8_t* arr, size_t len, const char* str) {
char* p = (char*)arr;
size_t i;
size_t slen = str ? strlen(str) : 0;
size_t ademco_dec_str_to_hilo_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len,
const char ADEMCO_BUF_MEMORY_MODIFIER* str) {
char ADEMCO_BUF_MEMORY_MODIFIER* p = (char ADEMCO_BUF_MEMORY_MODIFIER*)arr;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
size_t ADEMCO_BUF_MEMORY_MODIFIER slen = str ? strlen(str) : 0;
char ADEMCO_BUF_MEMORY_MODIFIER hi, lo;
if (slen > len * 2)
slen = len * 2;
for (i = 0; i < slen; i += 2) {
char hi = str[i];
hi = str[i];
if ('0' <= hi && hi <= '9') {
if (i + 1 < slen) {
char lo = str[i + 1];
lo = str[i + 1];
if ('0' <= lo && lo <= '9')
*p++ = (hi << 4) | (lo & 0x0F);
else {
......@@ -1582,64 +1653,68 @@ size_t ademco_dec_str_to_hilo_array(uint8_t* arr, size_t len, const char* str) {
} else
break;
}
while ((char*)arr + len > p)
while ((char ADEMCO_BUF_MEMORY_MODIFIER*)arr + len > p)
*p++ = 0xFF;
return len;
}
size_t ademco_hex_str_to_hilo_array(uint8_t* arr, size_t len, const char* str) {
char* p = (char*)arr;
size_t i;
size_t slen = str ? strlen(str) : 0;
size_t ademco_hex_str_to_hilo_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len,
const char ADEMCO_BUF_MEMORY_MODIFIER* str) {
char ADEMCO_BUF_MEMORY_MODIFIER* p = (char ADEMCO_BUF_MEMORY_MODIFIER*)arr;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
size_t ADEMCO_BUF_MEMORY_MODIFIER slen = str ? strlen(str) : 0;
char ADEMCO_BUF_MEMORY_MODIFIER hi, lo;
if (slen > len * 2)
slen = len * 2;
for (i = 0; i < slen; i += 2) {
char hi = str[i];
hi = str[i];
if (isxdigit(hi)) {
if (i + 1 < slen) {
char lo = str[i + 1];
lo = str[i + 1];
if (isxdigit(lo))
*p++ = (char2hex(hi) << 4) | (char2hex(lo) & 0x0F);
*p++ = (ademco_char2hex(hi) << 4) | (ademco_char2hex(lo) & 0x0F);
else {
*p++ = (char2hex(hi) << 4) | 0x0F;
*p++ = (ademco_char2hex(hi) << 4) | 0x0F;
break;
}
} else {
*p++ = (char2hex(hi) << 4) | 0x0F;
*p++ = (ademco_char2hex(hi) << 4) | 0x0F;
break;
}
} else {
break;
}
}
while ((char*)arr + len > p)
while ((char ADEMCO_BUF_MEMORY_MODIFIER*)arr + len > p)
*p++ = 0xFF;
return len;
}
size_t ademco_hex_array_to_str(char* str, const uint8_t* arr, size_t len) {
char* p = str;
size_t i;
size_t ademco_hex_array_to_str(char ADEMCO_BUF_MEMORY_MODIFIER* str, const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr, size_t len) {
char ADEMCO_BUF_MEMORY_MODIFIER* p = str;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
for (i = 0; i < len; i++) {
*p++ = hex2char((arr[i] >> 4) & 0x0F);
*p++ = hex2char(arr[i] & 0x0F);
*p++ = ademco_hex2char((arr[i] >> 4) & 0x0F);
*p++ = ademco_hex2char(arr[i] & 0x0F);
}
return p - str;
}
size_t ademco_hex_str_to_array(uint8_t* arr, const char* str, uint8_t padding) {
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
size_t i;
size_t slen = str ? strlen(str) : 0;
size_t ademco_hex_str_to_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr, const char ADEMCO_BUF_MEMORY_MODIFIER* str, uint8_t padding) {
uint8_t ADEMCO_BUF_MEMORY_MODIFIER* p = arr;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER hi = 0, lo = 0;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
size_t ADEMCO_BUF_MEMORY_MODIFIER slen = str ? strlen(str) : 0;
char ADEMCO_BUF_MEMORY_MODIFIER c;
padding &= 0x0F;
for (i = 0; i < slen / 2; i++) {
char c = str[i * 2];
if ((hi = char2hex(c)) == 0xFF)
c = str[i * 2];
if ((hi = ademco_char2hex(c)) == 0xFF)
return 0;
if (i * 2 + 1 < slen) {
c = str[i * 2 + 1];
if ((lo = char2hex(c)) == 0xFF)
if ((lo = ademco_char2hex(c)) == 0xFF)
return 0;
} else
lo = padding;
......@@ -1648,19 +1723,21 @@ size_t ademco_hex_str_to_array(uint8_t* arr, const char* str, uint8_t padding) {
return p - arr;
}
size_t ademco_hex_str_to_array_n(uint8_t* arr, const char* str,
size_t ademco_hex_str_to_array_n(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
const char ADEMCO_BUF_MEMORY_MODIFIER* str,
size_t len, uint8_t padding) {
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
size_t i;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER* p = arr;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER hi = 0, lo = 0;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
char ADEMCO_BUF_MEMORY_MODIFIER c;
padding &= 0x0F;
for (i = 0; i < len / 2; i++) {
char c = str[i * 2];
if ((hi = char2hex(c)) == 0xFF)
c = str[i * 2];
if ((hi = ademco_char2hex(c)) == 0xFF)
return 0;
if (i * 2 + 1 < len) {
c = str[i * 2 + 1];
if ((lo = char2hex(c)) == 0xFF)
if ((lo = ademco_char2hex(c)) == 0xFF)
return 0;
} else
lo = padding;
......@@ -1669,21 +1746,22 @@ size_t ademco_hex_str_to_array_n(uint8_t* arr, const char* str,
return p - arr;
}
size_t ademco_hex_str_to_array_n_allow_non_hex_str(uint8_t* arr,
const char* str,
size_t ademco_hex_str_to_array_n_allow_non_hex_str(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
const char ADEMCO_BUF_MEMORY_MODIFIER* str,
size_t len,
uint8_t padding) {
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
size_t i;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER* p = arr;
uint8_t ADEMCO_BUF_MEMORY_MODIFIER hi = 0, lo = 0;
size_t ADEMCO_BUF_MEMORY_MODIFIER i;
char ADEMCO_BUF_MEMORY_MODIFIER c;
padding &= 0x0F;
for (i = 0; i < len / 2; i++) {
char c = str[i * 2];
if ((hi = char2hex(c)) == 0xFF)
c = str[i * 2];
if ((hi = ademco_char2hex(c)) == 0xFF)
hi = padding;
if (i * 2 + 1 < len) {
c = str[i * 2 + 1];
if ((lo = char2hex(c)) == 0xFF)
if ((lo = ademco_char2hex(c)) == 0xFF)
lo = padding;
} else
lo = padding;
......
#ifndef __ADEMCO_H__
#define __ADEMCO_H__
#include <stdint.h>
#include <time.h>
#include "ademco_config.h"
#include "ademco_version.h"
......@@ -16,9 +13,6 @@ typedef uint32_t ademco_id_t;
typedef uint8_t ademco_gg_t;
typedef uint16_t ademco_zone_t;
#define ADEMCO_OK 0
#define ADEMCO_ERR -1
#define ADEMCO_PACKET_ACCT_MIN_LEN 6 // #acct之acct最小长度
#define ADEMCO_PACKET_ACCT_MAX_LEN 18 // #acct之acct最大长度
#define ADEMCO_PACKET_ACCT_MAC_LEN 12 // WiFi主机账号使用MAC地址
......@@ -30,7 +24,7 @@ typedef uint16_t ademco_zone_t;
#define ADEMCO_PACKET_MAX_LEN 256 // 安定宝协议最大长度,包括前缀、后缀、data段、xdata段
#define CONGWIN_FE100_PACKET_LEN 31 // 丛文FE100协议长度
#define ADEMCO_PACKET_TIMESTAMP_LEN 20 // 时间戳长度
#define ADEMCO_PACKET_XDATA_MAX_LEN 64 // xdata段最大长度
#define ADEMCO_PACKET_XDATA_MAX_LEN 128 // xdata段最大长度
// 安定宝ID范围
#define ADEMCO_ID_INVALID 0
......@@ -69,107 +63,107 @@ typedef uint16_t ademco_zone_t;
// 主机状态
#define ADEMCO_STATUS_EVENTS_MAP(XX) \
XX(ARM_AWAY, 3400, "离家布防") \
XX(DISARM, 1400, "撤防") \
XX(ARM_STAY, 3456, "留守布防") \
XX(ARM_STAY_1456, 1456, "留守布防")
XX(3400, ARM_AWAY, "离家布防") \
XX(1400, DISARM, "撤防") \
XX(3456, ARM_STAY, "留守布防") \
XX(1456, ARM_STAY_1456, "留守布防")
// 防区报警
#define ADEMCO_ALARM_EVENTS_MAP(XX) \
XX(EMERGENCY, 1120, "紧急报警") \
XX(BURGLAR, 1130, "盗警") \
XX(DOOR_RING, 1134, "门铃") \
XX(FIRE, 1110, "火警") \
XX(DURESS, 1121, "胁迫") \
XX(GAS, 1151, "煤气") \
XX(WATER, 1113, "水警") \
XX(TAMPER, 1137, "主机防拆") \
XX(ZONE_TAMPER, 1383, "防区防拆") \
XX(BYPASS, 1570, "旁路")
XX(1120, EMERGENCY, "紧急报警") \
XX(1130, BURGLAR, "盗警") \
XX(1134, DOOR_RING, "门铃") \
XX(1110, FIRE, "火警") \
XX(1121, DURESS, "胁迫") \
XX(1151, GAS, "煤气") \
XX(1113, WATER, "水警") \
XX(1137, TAMPER, "主机防拆") \
XX(1383, ZONE_TAMPER, "防区防拆") \
XX(1570, BYPASS, "旁路")
// 防区报警恢复
#define ADEMCO_ALARM_RECOVER_EVENTS_MAP(XX) \
XX(EMERGENCY_RECOVER, 3120, "紧急恢复") \
XX(BURGLAR_RECOVER, 3130, "盗警恢复") \
XX(DOOR_RING_RECOVER, 3134, "门铃恢复") \
XX(FIRE_RECOVER, 3110, "火警恢复") \
XX(DURESS_RECOVER, 3121, "胁迫恢复") \
XX(GAS_RECOVER, 3151, "煤气恢复") \
XX(WATER_RECOVER, 3113, "水警恢复") \
XX(TAMPER_RECOVER, 3137, "主机防拆恢复") \
XX(ZONE_TAMPER_RECOVER, 3383, "防区防拆恢复") \
XX(BYPASS_RECOVER, 3570, "解除旁路")
XX(3120, EMERGENCY_RECOVER, "紧急恢复") \
XX(3130, BURGLAR_RECOVER, "盗警恢复") \
XX(3134, DOOR_RING_RECOVER, "门铃恢复") \
XX(3110, FIRE_RECOVER, "火警恢复") \
XX(3121, DURESS_RECOVER, "胁迫恢复") \
XX(3151, GAS_RECOVER, "煤气恢复") \
XX(3113, WATER_RECOVER, "水警恢复") \
XX(3137, TAMPER_RECOVER, "主机防拆恢复") \
XX(3383, ZONE_TAMPER_RECOVER, "防区防拆恢复") \
XX(3570, BYPASS_RECOVER, "解除旁路")
// 防区异常
#define ADEMCO_EXEPTION_EVENTS_MAP(XX) \
XX(AC_BROKE, 1301, "主机AC掉电") \
XX(LOW_BATTERY, 1302, "低电") \
XX(BAD_BATTERY, 1311, "坏电") \
XX(SOLAR_DISTURB, 1387, "光扰") \
XX(DISCONNECT, 1381, "失效") \
XX(LOST, 1393, "失联") \
XX(POWER_EXCEPTION, 1384, "电源故障") \
XX(OTHER_EXCEPTION, 1380, "其他故障")
XX(1301, AC_BROKEN, "主机AC掉电") \
XX(1302, LOW_BATTERY, "低电") \
XX(1311, BAD_BATTERY, "坏电") \
XX(1387, SOLAR_DISTURB, "光扰") \
XX(1381, DISCONNECT, "失效") \
XX(1393, LOST, "失联") \
XX(1384, POWER_EXCEPTION, "电源故障") \
XX(1380, OTHER_EXCEPTION, "其他故障")
// 防区异常恢复
#define ADEMCO_EXEPTION_RECOVER_EVENTS_MAP(XX) \
XX(AC_RECOVER, 3301, "主机AC复电") \
XX(LOW_BATTERY_RECOVER, 3302, "低电恢复") \
XX(BAD_BATTERY_RECOVER, 3311, "坏电恢复") \
XX(SOLAR_DISTURB_RECOVER, 3387, "光扰恢复") \
XX(DISCONNECT_RECOVER, 3381, "失效恢复") \
XX(LOST_RECOVER, 3393, "失联恢复") \
XX(POWER_EXCEPTION_RECOVER, 3384, "电源故障恢复") \
XX(OTHER_EXCEPTION_RECOVER, 3380, "其他故障恢复") \
XX(CLEAR_EXCPTION, 3100, "清除异常指示")
XX(3301, AC_RECOVER, "主机AC复电") \
XX(3302, LOW_BATTERY_RECOVER, "低电恢复") \
XX(3311, BAD_BATTERY_RECOVER, "坏电恢复") \
XX(3387, SOLAR_DISTURB_RECOVER, "光扰恢复") \
XX(3381, DISCONNECT_RECOVER, "失效恢复") \
XX(3393, LOST_RECOVER, "失联恢复") \
XX(3384, POWER_EXCEPTION_RECOVER, "电源故障恢复") \
XX(3380, OTHER_EXCEPTION_RECOVER, "其他故障恢复") \
XX(3100, CLEAR_EXCPTION, "清除异常指示")
// 恒博自定义安定宝事件码
#define ADEMCO_HB_EVENTS_MAP(XX) \
XX(SERIAL_485_DIS, 1485, "485断开") \
XX(SERIAL_485_RECOVER, 3485, "485连接") \
XX(CONN_HANGUP, 1700, "链路挂起") \
XX(CONN_RECOVER, 3700, "链路恢复") \
XX(DISARM_PWD_ERR, 1701, "撤防密码错误") \
XX(SUB_MACHINE_SENSOR_EXCEPTION, 1702, "分机探头异常") \
XX(SUB_MACHINE_SENSOR_RECOVER, 3702, "分机探头恢复") \
XX(SUB_MACHINE_POWER_EXCEPTION, 1703, "分机电源异常") \
XX(SUB_MACHINE_POWER_RECOVER, 3703, "分机电源恢复") \
XX(COM_PASSTHROUGH, 1704, "串口透传") \
XX(ENTER_SET_MODE, 2704, "进入设置状态") \
XX(EXIT_SET_MODE, 3704, "退出设置状态") \
XX(QUERY_SUB_MACHINE, 1705, "查询分机信息") \
XX(WRITE_TO_MACHINE, 1706, "写入主机信息") \
XX(I_AM_NET_MODULE, 1707, "主机类型--网络模块") \
XX(I_AM_GPRS, 1717, "主机类型--GPRS主机") \
XX(I_AM_LCD, 1727, "主机类型--液晶主机") \
XX(I_AM_WIRE, 1737, "主机类型--网线主机") \
XX(I_AM_WIFI, 1747, "主机类型--WiFi主机(停用)") \
XX(I_AM_3_SECTION, 1757, "主机类型--三区段主机") \
XX(I_AM_IOT, 1767, "主机类型--物联卡主机") \
XX(I_AM_TRUE_COLOR, 1777, "主机类型--真彩主机") \
XX(I_AM_GPRS_IOT, 1787, "主机类型--物联卡主机") \
XX(I_AM_GPRS_PHONE, 1797, "主机类型--GRPS主机带电话功能") \
XX(I_AM_NB, 1807, "主机类型--NB报警接收主机") \
XX(I_AM_WIFI2, 1817, "主机类型--WiFi主机(新版)") \
XX(PHONE_USER_SOS, 1709, "手机用户SOS") \
XX(PHONE_USER_CANCLE_ALARM, 1711, "手机用户消警") \
XX(ENTER_SETTING_MODE, 1712, "主机进入设置状态") \
XX(EXIT_SETTING_MODE, 3712, "主机退出设置状态") \
XX(RESTORE_FACTORY_SETTINGS_710, 1710, "主机恢复出厂设置") \
XX(RESTORE_FACTORY_SETTINGS, 1713, "主机恢复出厂设置") \
XX(SIM_IS_IOT_CARD, 1756, "物联卡") \
XX(SIM_IS_IOT_PLATFORM_CARD, 2756, "平台物联卡") \
XX(SIM_IS_NOT_IOT_CARD, 3756, "非物联卡") \
XX(WHAT_IS_YOUR_TYPE, 1798, "索要主机类型") \
XX(SIGNAL_STRENGTH_CHANGED, 1799, "信号强度") \
XX(OFFLINE, 1944, "主机断线") \
XX(ONLINE, 1946, "主机上线")
XX(1485, SERIAL_485_DIS, "485断开") \
XX(3485, SERIAL_485_RECOVER, "485连接") \
XX(1700, CONN_HANGUP, "链路挂起") \
XX(3700, CONN_RECOVER, "链路恢复") \
XX(1701, DISARM_PWD_ERR, "撤防密码错误") \
XX(1702, SUB_MACHINE_SENSOR_EXCEPTION, "分机探头异常") \
XX(3702, SUB_MACHINE_SENSOR_RECOVER, "分机探头恢复") \
XX(1703, SUB_MACHINE_POWER_EXCEPTION, "分机电源异常") \
XX(3703, SUB_MACHINE_POWER_RECOVER, "分机电源恢复") \
XX(1704, COM_PASSTHROUGH, "串口透传") \
XX(2704, ENTER_SET_MODE, "进入设置状态") \
XX(3704, EXIT_SET_MODE, "退出设置状态") \
XX(1705, QUERY_SUB_MACHINE, "查询分机信息") \
XX(1706, WRITE_TO_MACHINE, "写入主机信息") \
XX(1707, I_AM_NET_MODULE, "主机类型--网络模块") \
XX(1717, I_AM_GPRS, "主机类型--GPRS主机") \
XX(1727, I_AM_LCD, "主机类型--液晶主机") \
XX(1737, I_AM_WIRE, "主机类型--网线主机") \
XX(1747, I_AM_WIFI, "主机类型--WiFi主机(停用)") \
XX(1757, I_AM_3_SECTION, "主机类型--三区段主机") \
XX(1767, I_AM_IOT, "主机类型--物联卡主机") \
XX(1777, I_AM_TRUE_COLOR, "主机类型--真彩主机") \
XX(1787, I_AM_GPRS_IOT, "主机类型--物联卡主机") \
XX(1797, I_AM_GPRS_PHONE, "主机类型--GRPS主机带电话功能") \
XX(1807, I_AM_NB, "主机类型--NB报警接收主机") \
XX(1817, I_AM_WIFI2, "主机类型--WiFi主机(新版)") \
XX(1709, PHONE_USER_SOS, "手机用户SOS") \
XX(1711, PHONE_USER_CANCLE_ALARM, "手机用户消警") \
XX(1712, ENTER_SETTING_MODE, "主机进入设置状态") \
XX(3712, EXIT_SETTING_MODE, "主机退出设置状态") \
XX(1710, RESTORE_FACTORY_SETTINGS_710, "主机恢复出厂设置") \
XX(1713, RESTORE_FACTORY_SETTINGS, "主机恢复出厂设置") \
XX(1756, SIM_IS_IOT_CARD, "物联卡") \
XX(2756, SIM_IS_IOT_PLATFORM_CARD, "平台物联卡") \
XX(3756, SIM_IS_NOT_IOT_CARD, "非物联卡") \
XX(1798, WHAT_IS_YOUR_TYPE, "索要主机类型") \
XX(1799, SIGNAL_STRENGTH_CHANGED, "信号强度") \
XX(1944, OFFLINE, "主机断线") \
XX(1946, ONLINE, "主机上线")
// Ademco events
typedef enum ademco_event_t {
EVENT_INVALID_EVENT = 0,
#define XX(name, code, zh) EVENT_##name = code,
#define XX(code, name, zh) EVENT_##name = code,
// ----标准安定宝协议事件----
// 主机状态
......@@ -285,39 +279,42 @@ typedef struct ademco_packet_t {
} ademco_packet_t;
/* control source defs
* 范围 0~255
* 0: 主机
* 1~50: 遥控器
* 51~97: 智能家居
* 范围 0-255
* 0: 主机(布撤防来源目前只有键盘,紧急报警可以是键盘,也可以是遥控器)
* 1-10: 遥控器
* 11-50: 保留
* 51-96: 智能家居
* 97: 定时器自动控制
* 98: 中转接警中心
* 99: 直连接警中心
* 100~199: 手机APP,末二位为手机尾号
* 100-199: 手机APP,末二位为手机尾号
* 200: web用户,web端包括 网页,H5, 公众号,小程序等
* 201~255: web分享用户
* 特别注意:三区段主机,0 代表主机,1~255 都是遥控器
* 201-255: web分享用户
* 特别注意:三区段主机,0 代表主机,1-255 都是遥控器
*/
#define ADEMCO_CONTROL_SOURCES_MAP(XX) \
XX(MACHINE, 0, "主机") \
XX(REMOTE, 1, "遥控器") \
XX(REMOTE_MAX, 50, "遥控器MAX") \
XX(SMART_HOME_ALEXA, 51, "Amazon Alexa") \
XX(SMART_HOME_GOOGLE, 52, "Google Home") \
XX(SMART_HOME_APPLE, 54, "Apple Homekit") \
XX(SMART_HOME_SAMSUNG, 55, "Samsung Smartthings") \
XX(SMART_HOME_ALI_GENIE, 56, "阿里天猫精灵") \
XX(SMART_HOME_MI_AI, 57, "小米小爱同学") \
XX(SMART_HOME_BAIDU, 58, "百度小度") \
XX(SMART_HOME_MAX, 97, "智能家居MAX") \
XX(CENTER_TRANSMIT, 98, "中转接警中心") \
XX(CENTER_DIRECT, 99, "直连接警中心") \
XX(PHONE_APP, 100, "手机APP") \
XX(PHONE_APP_MAX, 199, "手机APP_MAX") \
XX(OWNER, 200, "web用户") \
XX(SHAREE, 201, "web分享用户") \
XX(SHAREE_MAX, 255, "web分享用户MAX")
XX(0, MACHINE, "主机") \
XX(1, REMOTE, "遥控器") \
XX(10, REMOTE_MAX, "遥控器MAX") \
XX(51, SMART_HOME_ALEXA, "Amazon Alexa") \
XX(52, SMART_HOME_GOOGLE, "Google Home") \
XX(54, SMART_HOME_APPLE, "Apple Homekit") \
XX(55, SMART_HOME_SAMSUNG, "Samsung Smartthings") \
XX(56, SMART_HOME_ALI_GENIE, "阿里天猫精灵") \
XX(57, SMART_HOME_MI_AI, "小米小爱同学") \
XX(58, SMART_HOME_BAIDU, "百度小度") \
XX(96, SMART_HOME_MAX, "智能家居MAX") \
XX(97, TIMER, "定时器") \
XX(98, CENTER_TRANSMIT, "中转接警中心") \
XX(99, CENTER_DIRECT, "直连接警中心") \
XX(100, PHONE_APP, "手机APP") \
XX(199, PHONE_APP_MAX, "手机APP_MAX") \
XX(200, OWNER, "web用户") \
XX(201, SHAREE, "web分享用户") \
XX(255, SHAREE_MAX, "web分享用户MAX")
typedef enum ademco_control_source_t {
#define XX(name, code, zh) ADEMCO_CONTROL_SOURCE_##name = code,
#define XX(code, name, zh) ADEMCO_CONTROL_SOURCE_##name = code,
ADEMCO_CONTROL_SOURCES_MAP(XX)
#undef XX
} ademco_control_source_t;
......@@ -327,6 +324,14 @@ typedef enum ademco_control_source_t {
#define bcd_encode(x) (((x) / 10) << 4 | ((x) % 10))
#define bcd_decode(x) (((x) >> 4) * 10 + ((x) & 0x0F))
/////////////////// reverse //////////////////
#define rev16(u) (uint16_t)((((uint16_t)(u) & 0xFF) << 8) | (((uint16_t)(u) & 0xFF00) >> 8))
#define rev32(u) (uint32_t)((((uint32_t)(u) & 0xFF) << 24) | \
(((uint32_t)(u) & 0xFF00) << 8) | \
(((uint32_t)(u) & 0xFF0000) >> 8) | \
(((uint32_t)(u) & 0xFF000000) >> 24))
//////////////////////// Functions ////////////////////////
ADEMCO_EXPORT_SYMBOL
......@@ -348,25 +353,25 @@ uint8_t ademco_decode_signal_strength(uint8_t bcd_strength);
// 是否合法主机账号
ADEMCO_EXPORT_SYMBOL
int ademco_is_valid_account(const char* acct);
bool ademco_is_valid_account(const char* acct);
// 是否合法主机密码
ADEMCO_EXPORT_SYMBOL
int ademco_is_valid_password(const char* pwd);
bool ademco_is_valid_password(const char* pwd);
//////////////////////// ademco_event_t functions ////////////////////////
// 是否主机状态事件
ADEMCO_EXPORT_SYMBOL
int ademco_is_machine_status_event(ademco_event_t ademco_event);
bool ademco_is_machine_status_event(ademco_event_t ademco_event);
// 是否主机类型事件
ADEMCO_EXPORT_SYMBOL
int ademco_is_machine_type_event(ademco_event_t ademco_event);
bool ademco_is_machine_type_event(ademco_event_t ademco_event);
// 事件是否需要控制源
ADEMCO_EXPORT_SYMBOL
int ademco_is_event_need_control_source(ademco_event_t ademco_event);
bool ademco_is_event_need_control_source(ademco_event_t ademco_event);
// 获取安定宝事件级别
ADEMCO_EXPORT_SYMBOL
......@@ -430,9 +435,8 @@ size_t ademco_data_to_congwin_fe100(ademco_char_t* fe100,
ADEMCO_EXPORT_SYMBOL
void ademco_xdata_init(ademco_xdata_t* xdat);
// return ADEMCO_OK for success, ADEMCO_ERR for failed
ADEMCO_EXPORT_SYMBOL
int ademco_xdata_convert(ademco_xdata_t* xdat, ademco_xdata_length_format_t xlf);
bool ademco_xdata_convert(ademco_xdata_t* xdat, ademco_xdata_length_format_t xlf);
#ifndef SWIG
// get valid content address of xdat (except [len])
......@@ -446,7 +450,7 @@ size_t ademco_xdata_get_valid_content_len(const ademco_xdata_t* xdat);
// return 0 if xdat's valid content is exactly the same as [buf, buf+buf_len)
ADEMCO_EXPORT_SYMBOL
int ademco_xdata_memcmp(const ademco_xdata_t* xdat,
bool ademco_xdata_memeq(const ademco_xdata_t* xdat,
const void* buf,
size_t buf_len);
......@@ -455,9 +459,8 @@ ADEMCO_EXPORT_SYMBOL
size_t ademco_xdata_copy(ademco_xdata_t* dst,
const ademco_xdata_t* src);
// return ADEMCO_OK for success, return ADEMCO_ERR for len is too long
ADEMCO_EXPORT_SYMBOL
int ademco_make_xdata(ademco_xdata_t* xdat,
bool ademco_make_xdata(ademco_xdata_t* xdat,
ademco_xdata_length_format_t xlf,
ademco_xdata_transform_t xtr,
const ademco_char_t* content,
......@@ -466,7 +469,7 @@ int ademco_make_xdata(ademco_xdata_t* xdat,
//////////////////////// ademco_packet_id_t functions ////////////////////////
ADEMCO_EXPORT_SYMBOL
int ademco_is_valid_packet_id(const char* standard,
bool ademco_is_valid_packet_id(const char* standard,
const char* id,
size_t len);
......@@ -593,7 +596,7 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
ademco_packet_t* pkt,
size_t* cb_commited,
ademco_parse_error_t* err);
#ifndef ADEMCO_USE_EXTERNAL_CRC16
/* CRC16 implementation according to ARC
* Name : CRC-16/ARC
* Alias : ARC, CRC-16, CRC-16/LHA, CRC-IBM
......@@ -606,7 +609,19 @@ ademco_parse_result_t ademco_parse_packet(const ademco_char_t* buf,
* Output for "123456789" : 0xBB3D
*/
ADEMCO_EXPORT_SYMBOL
uint16_t ademco_crc16(const ademco_char_t* buf, size_t len);
uint16_t ademco_crc16(const ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* buf, size_t len);
#endif
// 0~9, A~F to '0'~'9', 'A'~'F'
ADEMCO_EXPORT_SYMBOL uint8_t ademco_hex2char(uint8_t h);
// '0'~'9', 'A'~'F', 'a'~'f' to 0~9, A~F
ADEMCO_EXPORT_SYMBOL uint8_t ademco_char2hex(uint8_t c);
// like snprintf(str, hex_len * 2 + 1, "%0`hex_len`X", dec)
// caller should make sure `str` has enough space
// e.g. ademco_dec_to_hex_str(buf, 0x12345678, 3) => buf = "678"
ADEMCO_EXPORT_SYMBOL size_t ademco_dec_to_hex_str(char* str, uint32_t dec, uint8_t hex_len);
// 将一串以高低字节表示的十六进制数组转换为10进制数字符串
// 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则停止
......@@ -615,8 +630,8 @@ uint16_t ademco_crc16(const ademco_char_t* buf, size_t len);
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
ADEMCO_EXPORT_SYMBOL
size_t ademco_hilo_array_to_dec_str(ademco_char_t* str,
const uint8_t* arr,
size_t ademco_hilo_array_to_dec_str(ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* str,
const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len);
// 将一串以高低字节表示的十六进制数组转换为字符串
......@@ -628,8 +643,8 @@ size_t ademco_hilo_array_to_dec_str(ademco_char_t* str,
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
// 示例:输入数组:0x24 0x94 0x94 0x4c 0x48 0x15 0xff,输出字符串"2494944C4815"
ADEMCO_EXPORT_SYMBOL
size_t ademco_hilo_array_to_hex_str(ademco_char_t* str,
const uint8_t* arr,
size_t ademco_hilo_array_to_hex_str(ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* str,
const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len);
// 将一个10进制数字符串转为高低字节表示的数组,节省空间
......@@ -645,9 +660,9 @@ size_t ademco_hilo_array_to_hex_str(ademco_char_t* str,
// return 9
// 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL
size_t ademco_dec_str_to_hilo_array(uint8_t* arr,
size_t ademco_dec_str_to_hilo_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len,
const char* str);
const char ADEMCO_BUF_MEMORY_MODIFIER* str);
// 将一个16进制数字符串转为高低字节表示的数组,节省空间
// str应只包含'0'~'9', 'A'~'F', 'a'~'f',否则失败返回0
......@@ -662,9 +677,9 @@ size_t ademco_dec_str_to_hilo_array(uint8_t* arr,
// return 9
// 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL
size_t ademco_hex_str_to_hilo_array(uint8_t* arr,
size_t ademco_hex_str_to_hilo_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len,
const char* str);
const char ADEMCO_BUF_MEMORY_MODIFIER* str);
// 将一串字节流转换为可打印形式
// 返回str长度(len * 2)
......@@ -673,8 +688,8 @@ size_t ademco_hex_str_to_hilo_array(uint8_t* arr,
// 示例:输入 arr=[0xEB 0xBA 0x3F], len=3, 则str = "EBBA3F",返回6
// 示例:输入 ary="123", len=3, 则str = "313233",返回6
ADEMCO_EXPORT_SYMBOL
size_t ademco_hex_array_to_str(char* str,
const uint8_t* arr,
size_t ademco_hex_array_to_str(char ADEMCO_BUF_MEMORY_MODIFIER* str,
const uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
size_t len);
// 将一串字符串(内容为'0'~'9', 'A'~'F', 'a' ~'f')转为字节流
......@@ -685,16 +700,16 @@ size_t ademco_hex_array_to_str(char* str,
// 示例:输入字符串str="ABC", padding = 0, 输出arr=[0xAB, 0xC0],返回2
// 示例:输入字符串str="ABC", padding = 0x0F, 输出arr=[0xAB, 0xCF],返回2
ADEMCO_EXPORT_SYMBOL
size_t ademco_hex_str_to_array(uint8_t* arr,
const char* str,
size_t ademco_hex_str_to_array(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
const char ADEMCO_BUF_MEMORY_MODIFIER* str,
uint8_t padding);
// 功能同ademcoHexStrToArray
// 若strlen(str) > len, str[len]及之后的内容将被舍弃以避免溢出
// 示例:输入字符串str="ABCDE", len = 4 padding = 0x0F, 输出arr=[0xAB, 0xCD], return 2
ADEMCO_EXPORT_SYMBOL
size_t ademco_hex_str_to_array_n(uint8_t* arr,
const char* str,
size_t ademco_hex_str_to_array_n(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
const char ADEMCO_BUF_MEMORY_MODIFIER* str,
size_t len, uint8_t padding);
// 同ademcoHexStrToArrayN,但允许str包含非hex字符,
......@@ -702,8 +717,8 @@ size_t ademco_hex_str_to_array_n(uint8_t* arr,
// 示例:str="AB\xFFD", len=4, padding=0x0F, 则 arr=[ 0xAB, 0xFD ], return 2
// 网线主机 0d 00 命令,接警中心账号部分,有可能是这种
ADEMCO_EXPORT_SYMBOL
size_t ademco_hex_str_to_array_n_allow_non_hex_str(uint8_t* arr,
const char* str,
size_t ademco_hex_str_to_array_n_allow_non_hex_str(uint8_t ADEMCO_BUF_MEMORY_MODIFIER* arr,
const char ADEMCO_BUF_MEMORY_MODIFIER* str,
size_t len,
uint8_t padding);
......
......@@ -40,6 +40,14 @@ typedef char ademco_char_t;
#define ADEMCO_ENABLE_PARSE_ERROR 1
#endif
#ifndef UNUSED
#ifdef __C51__
#define UNUSED(x) ((x) = (x))
#else
#define UNUSED(x) ((void)(x))
#endif // __C51__
#endif // UNUSED
#if ADEMCO_ENABLE_PARSE_ERROR
#define ADEMCO_FILL_PARSE_ERROR(err, offset_, msg_) \
do { \
......@@ -51,25 +59,125 @@ typedef char ademco_char_t;
} \
} while (0);
#else
#define ADEMCO_FILL_PARSE_ERROR(err, offset_, msg_)
#define ADEMCO_FILL_PARSE_ERROR(err, offset_, msg_) \
do { \
UNUSED(err); \
} while (0)
#endif // ADEMCO_ENABLE_PARSE_ERROR
#ifdef ADEMCO_USE_CUSTOM_TIME_T
extern time_t ademco_get_time_t(time_t* t);
#endif // ADEMCO_USE_CUSTOM_TIME_T
// armclang v6 `gmtime` always return NULL
#ifndef ADEMCO_DISABLE_GMTIME
#ifdef __ARMCC_VERSION
#define ADEMCO_DISABLE_GMTIME 1
#else // __ARMCC_VERSION
#define ADEMCO_DISABLE_GMTIME 0
#endif
#endif // __ARMCC_VERSION
#endif // ADEMCO_DISABLE_GMTIME
// embedded system may not have enough stack space
// declare these macros to use static/unique buffer for parse/make functions
#ifndef ADEMCO_USE_STATIC_BUF
#define ADEMCO_USE_STATIC_BUF 0
#endif
#ifndef ADEMCO_USE_UNIQUE_BUF
#define ADEMCO_USE_UNIQUE_BUF 0
#endif
// under C51, we need to use xdata for buffer
#if defined(__C51__) && !defined(ADEMCO_BUF_MEMORY_MODIFIER)
#define ADEMCO_BUF_MEMORY_MODIFIER xdata
#else
#define ADEMCO_BUF_MEMORY_MODIFIER
#endif
// under C51, we may need to use code for const data
#if defined(__C51__) && !defined(ADEMCO_CONST_MODIFIER)
#define ADEMCO_CONST_MODIFIER code
#else
#define ADEMCO_CONST_MODIFIER
#endif
// make this lib can be used in C51
#ifdef __C51__
#define INTERRUPT(n) interrupt n
#define USING(n) using n
#define declare_sbit(pin, name) sbit name = pin
#ifdef VSCODE
// make vscode happy
// in the .vscode/c_cpp_properties.json, add "defines": ["VSCODE"]
// to suppress the warning
#define data
#define xdata
#define bdata
#define idata
#define pdata
#define code
#define small
#define sfr unsigned char
#define sbit unsigned char
#define bit unsigned char
#define reentrant
#define INTERRUPT(n)
#define USING(n)
#define declare_sbit(pin, name) sbit name = 0
#endif // VSCODE
#endif
// Keil C51 and ICCAVR do not have stdint.h, time.h, stdbool.h, that's all we need
#if defined(__C51__) || defined(_AVR)
// stdint
#include "ademco_stdint.h"
// bool
#ifndef __bool_true_false_are_defined
#ifdef __C51__ // C51 can use bit as bool
typedef bit bool;
#else // AVR can use unsigned char as bool
typedef unsigned char bool;
#endif
#define true 1
#define false 0
#define __bool_true_false_are_defined
#endif // __bool_true_false_are_defined
// NULL
#ifndef NULL
#define NULL ((void*)0)
#endif
// we need our own implementation of time.h
#define ADMECO_ENABLE_CUSTOM_TIME
#include "ademco_time.h"
#else // suppose we are in a normal environment, and these headers are available
// gcc-avr has these headers
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#endif // __C51__ || _AVR
// C51 doesn't have the with `n` version functions in stdio.h
#if defined(__C51__) && defined(ADEMCO_ENABLE_STDIO)
#define ADEMCO_ENABLE_CUSTOM_STDIO
#include "ademco_stdio.h"
#endif // defined(__C51__) && defined(ADEMCO_ENABLE_STDIO)
// CRC16 table maybe too big for embedded system, user can use external CRC16 function,
// like read it from e2prom or flash to save code space.
// to enable this featuer, define `ADEMCO_USE_EXTERNAL_CRC16`, and implement `ademco_crc16` function.
#ifdef ADEMCO_USE_EXTERNAL_CRC16
#ifdef __cplusplus
extern "C" {
#endif
uint16_t ademco_crc16(const ademco_char_t ADEMCO_BUF_MEMORY_MODIFIER* buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif // ADEMCO_USE_EXTERNAL_CRC16
#endif // __ADEMCO_CONFIG_H__
......@@ -6,9 +6,9 @@
* evolve between minor releases, but only in a backwards compatible way.
*/
#define ADEMCO_VERSION_MAJOR 2
#define ADEMCO_VERSION_MINOR 7
#define ADEMCO_VERSION_PATCH 0
#define ADEMCO_VERSION_MAJOR 3
#define ADEMCO_VERSION_MINOR 2
#define ADEMCO_VERSION_PATCH 2
#define ADEMCO_VERSION_IS_RELEASE 1
#define ADEMCO_VERSION_SUFFIX ""
......
......@@ -23,32 +23,32 @@ const char* print_bool(bool b) {
}
ademco_event_t statusEvents[] = {
#define XX(name, code, zh) EVENT_##name,
#define XX(code, name, zh) EVENT_##name,
ADEMCO_STATUS_EVENTS_MAP(XX)
#undef XX
};
ademco_event_t alarmEvents[] = {
#define XX(name, code, zh) EVENT_##name,
#define XX(code, name, zh) EVENT_##name,
ADEMCO_ALARM_EVENTS_MAP(XX)
#undef XX
};
ademco_event_t excepEvents[] = {
#define XX(name, code, zh) EVENT_##name,
#define XX(code, name, zh) EVENT_##name,
ADEMCO_EXEPTION_EVENTS_MAP(XX)
ADEMCO_EXEPTION_RECOVER_EVENTS_MAP(XX)
#undef XX
};
ademco_event_t privateEvents[] = {
#define XX(name, code, zh) EVENT_##name,
#define XX(code, name, zh) EVENT_##name,
ADEMCO_HB_EVENTS_MAP(XX)
#undef XX
};
ademco_event_t allEvents[] = {
#define XX(name, code, zh) EVENT_##name,
#define XX(code, name, zh) EVENT_##name,
ADEMCO_STATUS_EVENTS_MAP(XX)
ADEMCO_ALARM_EVENTS_MAP(XX)
ADEMCO_ALARM_RECOVER_EVENTS_MAP(XX)
......@@ -59,7 +59,7 @@ ademco_event_t allEvents[] = {
};
hb_zone_property_t allZoneProperties[] = {
#define XX(name, value, str) HZP_##name,
#define XX(value, name, str) HZP_##name,
HB_ZONE_PROPERTY_MAP(XX)
#undef XX
};
......@@ -391,7 +391,7 @@ void gen_sources() {
printf("%s\n", comment);
printf("|zone|name|source|\n");
printf("|----|----|------|\n");
#define XX(name, code, zh) \
#define XX(code, name, zh) \
printf("|%d|%s|%s|\n", code, #name, zh);
ADEMCO_CONTROL_SOURCES_MAP(XX)
#undef XX
......
......@@ -111,6 +111,7 @@ end:
void on_tcp_connection(uv_tcpserver_client_context_t* client, int connected) {
if (connected) {
machine_info_t* machine = malloc(sizeof(machine_info_t));
fatal_if_null(machine);
memset(machine->acct, '\0', sizeof(machine->acct));
machine->ademco_id = 0;
machine->type = HMT_INVALID;
......
#ifndef __HB_CONFIG_H__
#define __HB_CONFIG_H__
#include "ademco_config.h"
#ifdef HB_EXPORTS
#if defined __GNUC__
......@@ -38,4 +40,8 @@
#define HB_ENABLE_CHINESE 0
#endif // HB_ENABLE_TO_STRING
#endif
#ifndef HB_ENABLE_TIMER_ARM_STAY
#define HB_ENABLE_TIMER_ARM_STAY 1
#endif // HB_ENABLE_TIMER_ARM_STAY
#endif // __HB_CONFIG_H__
......@@ -12,7 +12,7 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
case HMT_GPRS_IOT:
case HMT_GPRS:
case HMT_WIFI2: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR,
HZP_EMERGENCY,
HZP_FIRE,
......@@ -25,7 +25,7 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_NETMOD: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR,
HZP_EMERGENCY,
HZP_FIRE,
......@@ -35,23 +35,23 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
HZP_SUB_MACHINE,
HZP_REMOTE_CONTROL,
HZP_BURGLAR_HALF,
HZP_SHIELD,
HZP_BYPASS,
HZP_DOOR_RING,
};
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_LCD: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_SUB_MACHINE,
HZP_REMOTE_CONTROL, HZP_BURGLAR_HALF, HZP_SHIELD,
HZP_REMOTE_CONTROL, HZP_BURGLAR_HALF,
HZP_DOOR_RING, HZP_BYPASS};
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_WIRED: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR,
HZP_EMERGENCY,
HZP_FIRE,
......@@ -64,31 +64,31 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_TRUE_COLOR: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
HZP_DOOR_RING, HZP_BYPASS};
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_THREE_SECTION: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
HZP_DOOR_RING, HZP_BYPASS};
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_IOT: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR, HZP_EMERGENCY, HZP_FIRE,
HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL,
HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS};
HZP_DOOR_RING, HZP_BYPASS};
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_GPRS_PHONE: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR,
HZP_EMERGENCY,
HZP_FIRE,
......@@ -101,7 +101,7 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
return sizeof(hzps) / sizeof(hb_zone_property_t);
}
case HMT_NB: {
hb_zone_property_t hzps[] = {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER hzps[] = {
HZP_BURGLAR,
HZP_EMERGENCY,
HZP_FIRE,
......@@ -119,6 +119,17 @@ uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
return 0;
}
bool hb_machine_supports_zone_property(hb_machine_type_t type, hb_zone_property_t prop) {
hb_zone_property_t ADEMCO_BUF_MEMORY_MODIFIER props[HZP_COUNT];
uint8_t count = hb_get_available_zone_properties_by_type(type, props), i;
for (i = 0; i < count; i++) {
if (props[i] == prop) {
return true;
}
}
return false;
}
uint16_t hb_get_max_zone_by_type(hb_machine_type_t type) {
switch (type) {
case HMT_GPRS_IOT:
......@@ -152,16 +163,16 @@ uint16_t hb_get_max_zone_by_type(hb_machine_type_t type) {
}
}
uint8_t hb_is_valid_zone_by_type(hb_machine_type_t type, uint16_t zone) {
bool hb_is_valid_zone_by_type(hb_machine_type_t type, uint16_t zone) {
return 0 <= zone &&
zone <= hb_get_max_zone_by_type(type);
}
uint8_t hb_is_valid_zone_by_type_strict(hb_machine_type_t type, uint16_t zone) {
bool hb_is_valid_zone_by_type_strict(hb_machine_type_t type, uint16_t zone) {
return 1 <= zone && zone <= hb_get_max_zone_by_type(type);
}
uint8_t hb_is_machine_on_sale(hb_machine_type_t type) {
bool hb_is_machine_on_sale(hb_machine_type_t type) {
return type == HMT_GPRS_IOT ||
type == HMT_NETMOD ||
type == HMT_GPRS ||
......@@ -175,23 +186,23 @@ uint8_t hb_is_machine_on_sale(hb_machine_type_t type) {
type == HMT_WIFI2;
}
uint8_t hb_machine_can_arm_away(hb_machine_type_t type) {
bool hb_machine_can_arm_away(hb_machine_type_t type) {
return hb_is_machine_on_sale(type) && (type != HMT_NB);
}
uint8_t hb_machine_can_disarm(hb_machine_type_t type) {
bool hb_machine_can_disarm(hb_machine_type_t type) {
return hb_is_machine_on_sale(type) && (type != HMT_NB);
}
uint8_t hb_machine_can_config(hb_machine_type_t type) {
bool hb_machine_can_config(hb_machine_type_t type) {
return hb_is_machine_on_sale(type);
}
uint8_t hb_machine_can_arm_stay(hb_machine_type_t type) {
bool hb_machine_can_arm_stay(hb_machine_type_t type) {
return type == HMT_NETMOD || type == HMT_LCD;
}
uint8_t hb_machine_can_report_signal_strength(hb_machine_type_t type) {
bool hb_machine_can_report_signal_strength(hb_machine_type_t type) {
return type == HMT_GPRS ||
type == HMT_GPRS_IOT ||
type == HMT_IOT ||
......@@ -203,7 +214,7 @@ uint8_t hb_machine_can_report_signal_strength(hb_machine_type_t type) {
type == HMT_WIFI2;
}
uint8_t hb_machine_can_report_by_sms(hb_machine_type_t type) {
bool hb_machine_can_report_by_sms(hb_machine_type_t type) {
return type == HMT_GPRS ||
type == HMT_LCD ||
type == HMT_TRUE_COLOR ||
......@@ -211,7 +222,7 @@ uint8_t hb_machine_can_report_by_sms(hb_machine_type_t type) {
type == HMT_GPRS_PHONE;
}
uint8_t hb_machine_has_wired_zones(hb_machine_type_t type) {
bool hb_machine_has_wired_zones(hb_machine_type_t type) {
return type == HMT_NETMOD ||
type == HMT_TRUE_COLOR ||
type == HMT_THREE_SECTION;
......@@ -243,15 +254,15 @@ uint16_t hb_wired_zone_max(hb_machine_type_t type) {
}
}
uint8_t hb_machine_can_write_zone(hb_machine_type_t type) {
bool hb_machine_can_write_zone(hb_machine_type_t type) {
return type == HMT_NETMOD;
}
uint8_t hb_machine_can_link_sub_machine(hb_machine_type_t type) {
bool hb_machine_can_link_sub_machine(hb_machine_type_t type) {
return type == HMT_NETMOD;
}
uint8_t hb_zone_can_report_lost(hb_zone_property_t zp) {
bool hb_zone_can_report_lost(hb_zone_property_t zp) {
switch (zp) {
case HZP_BURGLAR:
case HZP_EMERGENCY:
......@@ -273,32 +284,36 @@ void hb_machine_timer_init(hb_machine_timer_t* timer) {
memset(timer->dat, 0xFF, sizeof(*timer));
}
uint8_t hb_is_valid_time_point(hb_machine_time_point_t* tp) {
uint8_t hb_is_valid_time_point(const hb_machine_time_point_t* tp) {
return tp &&
tp->hour < 24 &&
tp->minute < 60;
}
uint8_t hb_time_point_equal(hb_machine_time_point_t* tp1, hb_machine_time_point_t* tp2) {
uint8_t hb_time_point_equal(const hb_machine_time_point_t* tp1, const hb_machine_time_point_t* tp2) {
return tp1->hour == tp2->hour && tp1->minute == tp2->minute;
}
uint8_t hb_is_valid_timer_one(hb_machine_timer_one_t* timer) {
uint8_t hb_is_valid_timer_one(const hb_machine_timer_one_t* timer) {
return timer &&
#if HB_ENABLE_TIMER_ARM_STAY
(timer->arm_what == HB_TIMER_ARM_WHAT_ARM_AWAY || timer->arm_what == HB_TIMER_ARM_WHAT_ARM_STAY) &&
#endif
hb_is_valid_time_point(&timer->arm_at) &&
hb_is_valid_time_point(&timer->disarm_at) &&
!hb_time_point_equal(&timer->arm_at, &timer->disarm_at);
}
uint8_t hb_is_valid_machine_timer(hb_machine_timer_t* timer) {
uint8_t hb_is_valid_machine_timer(const hb_machine_timer_t* timer) {
return timer &&
hb_is_valid_timer_one(&timer->timer[0]) &&
hb_is_valid_timer_one(&timer->timer[1]);
}
#if HB_ENABLE_TO_STRING
const char* hb_machine_status_to_string(hb_machine_status_t status) {
switch (status) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HMS_##name: \
return #name;
HB_MACHINE_STATUS_MAP(XX)
......@@ -310,7 +325,7 @@ const char* hb_machine_status_to_string(hb_machine_status_t status) {
const char* hb_machine_type_to_string(hb_machine_type_t type) {
switch (type) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HMT_##name: \
return #name;
HB_MACHINE_TYPE_MAP(XX)
......@@ -323,7 +338,7 @@ const char* hb_machine_type_to_string(hb_machine_type_t type) {
const char* hb_zone_property_to_string(hb_zone_property_t zp) {
switch (zp) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HZP_##name: \
return #name;
HB_ZONE_PROPERTY_MAP(XX)
......@@ -337,7 +352,7 @@ const char* hb_zone_property_to_string(hb_zone_property_t zp) {
#if HB_ENABLE_CHINESE
const char* hb_machine_status_to_string_chinese(hb_machine_status_t status) {
switch (status) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HMS_##name: \
return str;
HB_MACHINE_STATUS_MAP(XX)
......@@ -350,7 +365,7 @@ const char* hb_machine_status_to_string_chinese(hb_machine_status_t status) {
const char* hb_machine_type_to_string_chinese(hb_machine_type_t type) {
switch (type) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HMT_##name: \
return str;
HB_MACHINE_TYPE_MAP(XX)
......@@ -363,7 +378,7 @@ const char* hb_machine_type_to_string_chinese(hb_machine_type_t type) {
const char* hb_zone_property_to_string_chinese(hb_zone_property_t zp) {
switch (zp) {
#define XX(name, value, str) \
#define XX(value, name, str) \
case HZP_##name: \
return str;
HB_ZONE_PROPERTY_MAP(XX)
......@@ -384,3 +399,4 @@ const char* hb_get_zone_format_str(hb_machine_type_t type) {
else
return "%d";
}
#endif // HB_ENABLE_TO_STRING
#ifndef __HB_CORE_H__
#define __HB_CORE_H__
#include <stdint.h>
#include "hb_config.h"
#ifdef __cplusplus
......@@ -20,10 +18,10 @@ extern "C" {
// 主机状态表
#define HB_MACHINE_STATUS_MAP(XX) \
XX(ARM_AWAY, 0, "离家布防") \
XX(ARM_STAY, 1, "留守布防") \
XX(DISARM, 2, "撤防") \
XX(SETTING, 3, "设置")
XX(0, ARM_AWAY, "ARM_AWAY") \
XX(1, ARM_STAY, "ARM_STAY") \
XX(2, DISARM, "DISARM") \
XX(3, SETTING, "SETTING")
// 主机状态与安定宝事件码对照表
#define HMS_EVENT_MAP(XX) \
......@@ -34,7 +32,7 @@ extern "C" {
// 主机状态
typedef enum hb_machine_status_t {
#define XX(name, value, str) HMS_##name = value,
#define XX(value, name, str) HMS_##name = value,
HB_MACHINE_STATUS_MAP(XX)
#undef XX
// valid count
......@@ -45,38 +43,23 @@ typedef enum hb_machine_status_t {
// 主机类型表
#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) \
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) \
XX(HMT_WIRED, EVENT_I_AM_WIRE) \
XX(HMT_TRUE_COLOR, EVENT_I_AM_TRUE_COLOR) \
XX(HMT_THREE_SECTION, EVENT_I_AM_3_SECTION) \
XX(HMT_IOT, EVENT_I_AM_IOT) \
XX(HMT_GPRS_PHONE, EVENT_I_AM_GPRS_PHONE) \
XX(HMT_NB, EVENT_I_AM_NB) \
XX(HMT_WIFI2, EVENT_I_AM_WIFI2)
XX(0, WIFI, "WiFi主机") \
XX(1, CAMERA, "摄像头主机") \
XX(2, GPRS_IOT, "简化物联卡主机") \
XX(3, NETMOD, "网络模块主机") \
XX(4, GPRS, "GPRS主机") \
XX(5, LCD, "液晶主机") \
XX(6, WIRED, "网线主机") \
XX(7, TRUE_COLOR, "真彩主机") \
XX(8, THREE_SECTION, "三区段主机") \
XX(9, IOT, "物联卡主机") \
XX(10, GPRS_PHONE, "GPRS主机可电话") \
XX(11, NB, "NB报警接收主机") \
XX(12, WIFI2, "WiFi主机新版")
// 主机类型
typedef enum hb_machine_type_t {
#define XX(name, value, str) HMT_##name = value,
#define XX(value, name, str) HMT_##name = value,
HB_MACHINE_TYPE_MAP(XX)
#undef XX
// valid count
......@@ -86,28 +69,28 @@ typedef enum hb_machine_type_t {
} hb_machine_type_t;
// 防区属性表
// 2024年8月2日21:37:14 删除 0x0F 旁路防区,修改 9 屏蔽防区为旁路防区:旁路即屏蔽
#define HB_ZONE_PROPERTY_MAP(XX) \
XX(BURGLAR, 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(BURGLAR_HALF, 8, "匪警半局") \
XX(SHIELD, 9, "屏蔽防区") \
XX(DOOR_RING, 0x0A, "门铃防区") \
XX(BYPASS, 0x0F, "旁路防区")
XX(0, BURGLAR, "匪警全局") \
XX(1, EMERGENCY, "匪警紧急") \
XX(2, FIRE, "火警防区") \
XX(3, DURESS, "胁迫防区") \
XX(4, GAS, "燃气防区") \
XX(5, WATER, "淹水防区") \
XX(6, SUB_MACHINE, "分机") \
XX(7, REMOTE_CONTROL, "遥控器") \
XX(8, BURGLAR_HALF, "匪警半局") \
XX(9, BYPASS, "旁路防区") \
XX(10, DOOR_RING, "门铃防区")
// 防区属性
typedef enum hb_zone_property_t {
#define XX(name, value, str) HZP_##name = value,
#define XX(value, name, str) HZP_##name = value,
HB_ZONE_PROPERTY_MAP(XX)
#undef XX
// valid count
HZP_COUNT = 12,
HZP_COUNT = 11,
// invalid
HZP_INVALID = 0xFF,
} hb_zone_property_t;
......@@ -124,66 +107,75 @@ typedef struct {
} hb_machine_time_point_t;
typedef struct {
#if HB_ENABLE_TIMER_ARM_STAY
uint8_t arm_what; // 0: arm away, 1: arm stay
#define HB_TIMER_ARM_WHAT_ARM_AWAY 0
#define HB_TIMER_ARM_WHAT_ARM_STAY 1
#endif
hb_machine_time_point_t arm_at;
hb_machine_time_point_t disarm_at;
} hb_machine_timer_one_t;
typedef union {
hb_machine_timer_one_t timer[2]; // 2 set of timer
uint8_t dat[8];
uint8_t dat[sizeof(hb_machine_timer_one_t) * 2];
} hb_machine_timer_t;
///////////////////////////// property functions //////////////////////////////
// return available count
// props must have at least HZP_COUNT items
// props must have at least HZP_COUNT slots
HB_EXPORT_SYMBOL
uint8_t hb_get_available_zone_properties_by_type(hb_machine_type_t type,
hb_zone_property_t props[HZP_COUNT]);
// 根据主机类型判断是否支持该属性
HB_EXPORT_SYMBOL
bool hb_machine_supports_zone_property(hb_machine_type_t type, hb_zone_property_t prop);
// 最大防区号根据型号不同而不同
HB_EXPORT_SYMBOL
uint16_t hb_get_max_zone_by_type(hb_machine_type_t type);
// 防区号是否合法(可以包含0防区)
HB_EXPORT_SYMBOL
uint8_t hb_is_valid_zone_by_type(hb_machine_type_t type, uint16_t zone);
bool hb_is_valid_zone_by_type(hb_machine_type_t type, uint16_t zone);
// 防区号是否合法(不可以可以包含0防区)
HB_EXPORT_SYMBOL
uint8_t hb_is_valid_zone_by_type_strict(hb_machine_type_t type, uint16_t zone);
bool hb_is_valid_zone_by_type_strict(hb_machine_type_t type, uint16_t zone);
// 主机是否已投产使用
HB_EXPORT_SYMBOL
uint8_t hb_is_machine_on_sale(hb_machine_type_t type);
bool hb_is_machine_on_sale(hb_machine_type_t type);
// 主机是否具有离家布防功能
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_arm_away(hb_machine_type_t type);
bool hb_machine_can_arm_away(hb_machine_type_t type);
// 主机是否具有撤防功能
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_disarm(hb_machine_type_t type);
bool hb_machine_can_disarm(hb_machine_type_t type);
// 主机是否可以进入设置状态
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_config(hb_machine_type_t type);
bool hb_machine_can_config(hb_machine_type_t type);
// 主机是否具有留守布防功能
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_arm_stay(hb_machine_type_t type);
bool hb_machine_can_arm_stay(hb_machine_type_t type);
// 主机是否可以报告信号强度
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_report_signal_strength(hb_machine_type_t type);
bool hb_machine_can_report_signal_strength(hb_machine_type_t type);
// 主机本身是否可以短信报警(不算通过服务如阿里语音等)
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_report_by_sms(hb_machine_type_t type);
bool hb_machine_can_report_by_sms(hb_machine_type_t type);
// 主机是否支持有线防区
HB_EXPORT_SYMBOL
uint8_t hb_machine_has_wired_zones(hb_machine_type_t type);
bool hb_machine_has_wired_zones(hb_machine_type_t type);
// 主机最小有线防区号
HB_EXPORT_SYMBOL
......@@ -195,16 +187,16 @@ uint16_t hb_wired_zone_max(hb_machine_type_t type);
// 主机是否可以直接写入防区数据(无需对码)
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_write_zone(hb_machine_type_t type);
bool hb_machine_can_write_zone(hb_machine_type_t type);
// 主机是否可以挂载分机
HB_EXPORT_SYMBOL
uint8_t hb_machine_can_link_sub_machine(hb_machine_type_t type);
bool hb_machine_can_link_sub_machine(hb_machine_type_t type);
// 根据防区属性判断是否支持失联报告
// 失联报告是主机侧实现的跟防区属性没关系,但是人为限制了只有以下属性的才可以设置
HB_EXPORT_SYMBOL
uint8_t hb_zone_can_report_lost(hb_zone_property_t zp);
bool hb_zone_can_report_lost(hb_zone_property_t zp);
///////////////////////////// timer functions /////////////////////////////////
......@@ -215,19 +207,20 @@ HB_EXPORT_SYMBOL
void hb_machine_timer_init(hb_machine_timer_t* timer);
HB_EXPORT_SYMBOL
uint8_t hb_is_valid_time_point(hb_machine_time_point_t* tp);
uint8_t hb_is_valid_time_point(const hb_machine_time_point_t* tp);
HB_EXPORT_SYMBOL
uint8_t hb_time_point_equal(hb_machine_time_point_t* tp1, hb_machine_time_point_t* tp2);
uint8_t hb_time_point_equal(const hb_machine_time_point_t* tp1, const hb_machine_time_point_t* tp2);
HB_EXPORT_SYMBOL
uint8_t hb_is_valid_timer_one(hb_machine_timer_one_t* timer);
uint8_t hb_is_valid_timer_one(const hb_machine_timer_one_t* timer);
HB_EXPORT_SYMBOL
uint8_t hb_is_valid_machine_timer(hb_machine_timer_t* timer);
uint8_t hb_is_valid_machine_timer(const hb_machine_timer_t* timer);
///////////////////////////// helper functions ////////////////////////////////
#if HB_ENABLE_TO_STRING
HB_EXPORT_SYMBOL
const char* hb_machine_status_to_string(hb_machine_status_t status);
......@@ -250,6 +243,7 @@ const char* hb_zone_property_to_string_chinese(hb_zone_property_t zp);
HB_EXPORT_SYMBOL
const char* hb_get_zone_format_str(hb_machine_type_t type);
#endif // HB_ENABLE_TO_STRING
#ifdef __cplusplus
}
......
......@@ -99,8 +99,8 @@ ademco_event_t hb_rf_code_to_ademco_event(uint8_t rf_code) {
case HB_RF_CODE_S_BATTERY_LOW:
case HB_RF_CODE_R_BATTERY_LOW:
return EVENT_LOW_BATTERY;
case HB_RF_CODE_S_BATTERY_BROKE:
case HB_RF_CODE_R_BATTERY_BROKE:
case HB_RF_CODE_S_BATTERY_BROKEN:
case HB_RF_CODE_R_BATTERY_BROKEN:
return EVENT_BAD_BATTERY;
case HB_RF_CODE_BATTERY_RECOVER:
return EVENT_LOW_BATTERY_RECOVER;
......@@ -122,8 +122,8 @@ ademco_event_t hb_rf_code_to_ademco_event(uint8_t rf_code) {
return EVENT_SUB_MACHINE_POWER_EXCEPTION;
case HB_RF_CODE_SM_POWER_RECOVER:
return EVENT_SUB_MACHINE_POWER_RECOVER;
case HB_RF_CODE_AC_BROKE:
return EVENT_AC_BROKE;
case HB_RF_CODE_AC_BROKEN:
return EVENT_AC_BROKEN;
case HB_RF_CODE_AC_RECOVER:
return EVENT_AC_RECOVER;
......
......@@ -9,6 +9,21 @@
extern "C" {
#endif
// 主机类型与安定宝事件码对照表
#define HMT_EVENT_MAP(XX) \
XX(HMT_WIFI, EVENT_I_AM_WIFI) \
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) \
XX(HMT_WIRED, EVENT_I_AM_WIRE) \
XX(HMT_TRUE_COLOR, EVENT_I_AM_TRUE_COLOR) \
XX(HMT_THREE_SECTION, EVENT_I_AM_3_SECTION) \
XX(HMT_IOT, EVENT_I_AM_IOT) \
XX(HMT_GPRS_PHONE, EVENT_I_AM_GPRS_PHONE) \
XX(HMT_NB, EVENT_I_AM_NB) \
XX(HMT_WIFI2, EVENT_I_AM_WIFI2)
// 防区属性与安定宝事件码对照表
#define HZP_EVENT_MAP(XX) \
XX(HZP_BURGLAR, EVENT_BURGLAR) \
......
#ifndef __HB_RF_H__
#define __HB_RF_H__
#include <stdint.h>
#include "hb_config.h"
#ifdef __cplusplus
extern "C" {
#endif
#define HB_INVALID_RF_ADDR 0xFFFF
#define hb_is_valid_rf_addr(addr) ((0 < (addr)) && ((addr) < 0xFFFF))
// 无线命令码
// Note: 工程主机删除所有探头会报 E0,其他都是探头无线码
#define HB_RF_CODE_MAP(XX) \
XX(0x00, BURGLAR, "报警") \
XX(0x01, ARM, "布防") \
......@@ -22,13 +25,13 @@ extern "C" {
XX(0x57, NIGHT, "夜间") \
XX(0x69, SENDER_REBOOT, "发送端重启") \
XX(0x75, DAY, "白天") \
XX(0xA5, R_BATTERY_BROKE, "收电池损坏") \
XX(0xA5, R_BATTERY_BROKEN, "收电池损坏") \
XX(0xA8, DOOR_RING, "门铃") \
XX(0xAB, S_BATTERY_LOW, "发低电") \
XX(0xAC, R_BATTERY_LOW, "收低电") \
XX(0xAD, BATTERY_RECOVER, "复电") \
XX(0xAE, S_BATTERY_BROKE, "发电池损坏") \
XX(0xB0, AC_BROKE, "AC掉电") \
XX(0xAE, S_BATTERY_BROKEN, "发电池损坏") \
XX(0xB0, AC_BROKEN, "AC掉电") \
XX(0xB1, AC_RECOVER, "AC恢复") \
XX(0xBA, TAMPER, "防拆") \
XX(0xBB, SLEEP, "电池电压小于3V,终端进入休眠") \
......@@ -42,6 +45,7 @@ extern "C" {
XX(0xCE, SM_EXCEPTION, "分机产生异常信息") \
XX(0xCF, SM_EXCEPT_RECOVER, "分机恢复异常信息") \
XX(0xDD, QUERY, "查询分机状态") \
XX(0xE0, DELETED_ALL_SENSOR, "已删除所有传感器") \
XX(0xED, SHUTDOWN, "关机")
// 无线命令码
......
......@@ -168,11 +168,11 @@ namespace CSharpDemo
replyAck(stream, pkt.seq, pkt.acct);
acct = pkt.acct;
ademco_id = pkt.dat.ademco_id;
if (libademco.ademco_is_machine_type_event(pkt.dat.ademco_event) != 0)
if (libademco.ademco_is_machine_type_event(pkt.dat.ademco_event))
{
type = libademco.hb_machine_type_from_ademco_event(pkt.dat.ademco_event);
}
if (libademco.ademco_is_machine_status_event(pkt.dat.ademco_event) != 0)
if (libademco.ademco_is_machine_status_event(pkt.dat.ademco_event))
{
status = libademco.hb_machine_status_from_ademco_event(pkt.dat.ademco_event);
}
......
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