Commit bb722eae authored by captainwong's avatar captainwong

hb_com

parent ee9a946c
......@@ -514,7 +514,10 @@ int ademcoDataSegmentToCongwinFe100(uint8_t* fe100, const AdemcoDataSegment* dat
return 0;
}
static const uint8_t* ademcoXDataGetValidContentAddr(const AdemcoXDataSegment* xdata)
#ifdef SWIG
static
#endif
const uint8_t* ademcoXDataGetValidContentAddr(const AdemcoXDataSegment* xdata)
{
if (xdata->lenghFormat == TWO_HEX && xdata->raw_len > 4) {
return xdata->raw + 3;
......@@ -525,7 +528,7 @@ static const uint8_t* ademcoXDataGetValidContentAddr(const AdemcoXDataSegment* x
}
}
ADEMCO_EXPORT_SYMBOL int ademcoXDataMemcmp(const AdemcoXDataSegment* xdata, const void* buf, int buf_len)
int ademcoXDataMemcmp(const AdemcoXDataSegment* xdata, const void* buf, int buf_len)
{
if (ademcoXDataGetValidContentLen(xdata) != buf_len) return 0;
const uint8_t* p = ademcoXDataGetValidContentAddr(xdata);
......@@ -552,7 +555,7 @@ int ademcoMakeXData(AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, Adem
memcpy(transformed, content, len);
} else {
if (len * 2 < ADEMCO_PACKET_XDATA_MAX_LEN) {
translen = hbHexArrayToStr((char*)transformed, content, len);
translen = ademcoHexArrayToStr((char*)transformed, content, len);
} else {
return ADEMCO_ERR;
}
......@@ -592,14 +595,14 @@ int isAdemcoPacketId(const char* standard, const char* id, int len)
}
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_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,
};
AdemcoPacketId getAdemcoPacketId(const char* id, int len)
......@@ -958,853 +961,7 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
return RESULT_ERROR;
}
int hbGetAvailableZoneProperties(HbMachineType type, HbZoneProperty props[12])
{
switch (type) {
case HMT_WIFI:
break;
case HMT_CAMERA:
break;
case HMT_GPRS_IOT:
case HMT_GPRS:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_NETMOD:
{
HbZoneProperty hzps[] = { 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, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_LCD:
{
HbZoneProperty hzps[] = { 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 };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_WIRED:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_TRUE_COLOR:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_3_SECTION:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_IOT:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_GPRS_PHONE:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_NB:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_DOOR_RING, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
default: return 0;
}
return 0;
}
uint16_t hbZoneMax(HbMachineType type)
{
switch (type) {
case HMT_GPRS_IOT:
case HMT_GPRS:
case HMT_WIRED:
return 99;
case HMT_NETMOD:
case HMT_NB:
return 999;
case HMT_LCD:
return 249;
case HMT_TRUE_COLOR:
return 68;
case HMT_3_SECTION:
return 191;
case HMT_IOT:
case HMT_GPRS_PHONE:
return 60;
case HMT_WIFI:
case HMT_CAMERA:
default:
return 0;
break;
}
}
int hbIsValidZone(HbMachineType type, uint16_t zone)
{
return ADEMCO_ZONE_FOR_MACHINE_SELF <= zone && zone <= hbZoneMax(type);
}
int hbIsValidZoneStrict(HbMachineType type, uint16_t zone)
{
return ADEMCO_ZONE_MIN <= zone && zone <= hbZoneMax(type);
}
int hbMachineIsSelling(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_GPRS
|| type == HMT_GPRS_IOT
|| type == HMT_IOT
|| type == HMT_LCD
|| type == HMT_WIRED
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
|| type == HMT_NB
;
}
int hbMachineCanArm(HbMachineType type)
{
return hbMachineIsSelling(type) && (type != HMT_NB);
}
int hbMachineCanDisarm(HbMachineType type)
{
return hbMachineIsSelling(type) && (type != HMT_NB);
}
int hbMachineCanEnterSettings(HbMachineType type)
{
return hbMachineIsSelling(type);
}
int hbMachineCanHalfArm(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_LCD
;
}
int hbMachineCanReportSignalStrength(HbMachineType type)
{
return type == HMT_GPRS
|| type == HMT_GPRS_IOT
|| type == HMT_IOT
|| type == HMT_LCD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
|| type == HMT_NB
;
}
int hbMachineCanReportBySMS(HbMachineType type)
{
return type == HMT_GPRS
|| type == HMT_LCD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
;
}
int hbMachineHasWiredZone(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
;
}
AdemcoZone hbWiredZoneMin(HbMachineType type)
{
switch (type) {
case HMT_NETMOD: return 1;
case HMT_TRUE_COLOR: return 1;
case HMT_3_SECTION: return 61;
default: return 0;
}
}
AdemcoZone hbWiredZoneMax(HbMachineType type)
{
switch (type) {
case HMT_NETMOD: return 8;
case HMT_TRUE_COLOR: return 8;
case HMT_3_SECTION: return 68;
default: return 0;
}
}
int hbMachineCanDirectlyWriteZone(HbMachineType type)
{
return type == HMT_NETMOD;
}
int hbMachineCanLinkSubMachine(HbMachineType type)
{
return type == HMT_NETMOD;
}
int hbZonePropCanReportLost(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR:
case HZP_EMERGENCY:
case HZP_DURESS:
case HZP_SUB_MACHINE:
case HZP_BUGLAR_HALF:
case HZP_BYPASS:
return 1;
default:
return 0;
}
}
void hbInitMachineTimer(HbMachineTimer* timer)
{
memset(timer->data, 0xFF, sizeof(timer));
}
int hbIsValidTimer(HbTimer* timer)
{
return 0 <= timer->armAt.hour && timer->armAt.hour < 24 &&
0 <= timer->armAt.minute && timer->armAt.minute < 60 &&
0 <= timer->disarmAt.hour && timer->disarmAt.hour < 24 &&
0 <= timer->disarmAt.minute && timer->disarmAt.minute < 60;
}
AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return EVENT_ARM;
case HMS_DISARM: return EVENT_DISARM;
case HMS_HALF_ARM: return EVENT_HALFARM; // EVENT_HALFARM_1456
case HMS_SETTING: return EVENT_ENTER_SETTING_MODE; // EVENT_ENTER_SET_MODE
default: return EVENT_INVALID_EVENT;
}
}
HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent)
{
switch (ademcoEvent) {
case EVENT_ARM:
return HMS_ARM;
case EVENT_DISARM:
return HMS_DISARM;
case EVENT_HALFARM:
case EVENT_HALFARM_1456:
return HMS_HALF_ARM;
case EVENT_ENTER_SETTING_MODE:
case EVENT_ENTER_SET_MODE:
return HMS_SETTING;
default:
return HMS_INVALID;
}
}
AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return EVENT_I_AM_WIFI_MACHINE;
case HMT_GPRS_IOT: return EVENT_I_AM_GPRS_IOT;
case HMT_NETMOD: return EVENT_I_AM_NET_MODULE;
case HMT_GPRS: return EVENT_I_AM_GPRS;
case HMT_LCD: return EVENT_I_AM_LCD_MACHINE;
case HMT_WIRED: return EVENT_I_AM_WIRE_MACHINE;
case HMT_TRUE_COLOR: return EVENT_I_AM_TRUE_COLOR;
case HMT_3_SECTION: return EVENT_I_AM_3_SECTION_MACHINE;
case HMT_IOT: return EVENT_I_AM_IOT_MACHINE;
case HMT_GPRS_PHONE: return EVENT_I_AM_GPRS_PHONE;
case HMT_NB: return EVENT_I_AM_NB_MACHINE;
default: return EVENT_INVALID_EVENT;
}
}
HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent)
{
switch (ademcoEvent) {
case EVENT_I_AM_NET_MODULE: return HMT_NETMOD;
case EVENT_I_AM_GPRS: return HMT_GPRS;
case EVENT_I_AM_LCD_MACHINE: return HMT_LCD;
case EVENT_I_AM_WIRE_MACHINE: return HMT_WIRED;
case EVENT_I_AM_WIFI_MACHINE: return HMT_WIFI;
case EVENT_I_AM_3_SECTION_MACHINE: return HMT_3_SECTION;
case EVENT_I_AM_IOT_MACHINE: return HMT_IOT;
case EVENT_I_AM_TRUE_COLOR: return HMT_TRUE_COLOR;
case EVENT_I_AM_GPRS_IOT: return HMT_GPRS_IOT;
case EVENT_I_AM_GPRS_PHONE: return HMT_GPRS_PHONE;
case EVENT_I_AM_NB_MACHINE: return HMT_NB;
default: return HMT_INVALID;
}
}
AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR:
case HZP_BUGLAR_HALF: return EVENT_BURGLAR;
case HZP_EMERGENCY: return EVENT_EMERGENCY;
case HZP_FIRE: return EVENT_FIRE;
case HZP_DURESS: return EVENT_DURESS;
case HZP_GAS: return EVENT_GAS;
case HZP_WATER: return EVENT_WATER;
case HZP_DOOR_RING: return EVENT_DOORRINGING;
default: return EVENT_INVALID_EVENT;
}
}
const char* hbMachineStatusToString(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return "Arm";
case HMS_HALF_ARM: return "Half-Arm";
case HMS_DISARM: return "Disarm";
case HMS_SETTING: return "Setting";
default: return "InvalidMachineStatus";
}
}
const char* hbMachineStatusToStringChinese(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return "布防";
case HMS_HALF_ARM: return "半布防";
case HMS_DISARM: return "撤防";
case HMS_SETTING: return "设置";
default: return "InvalidMachineStatus";
}
}
const char* hbMachineTypeToString(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return "0 WiFi";
case HMT_CAMERA: return "1 Camera";
case HMT_GPRS_IOT: return "2 Gprs_IoT";
case HMT_NETMOD: return "3 NetMod";
case HMT_GPRS: return "4 GPRS";
case HMT_LCD: return "5 LCD";
case HMT_WIRED: return "6 Wired";
case HMT_TRUE_COLOR: return "7 TrueColor";
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";
default: return "Unknown HbMachineType";
}
}
const char* hbMachineTypeToStringChinese(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return "0 WiFi主机";
case HMT_CAMERA: return "1 摄像头主机";
case HMT_GPRS_IOT: return "2 简化的物联卡主机";
case HMT_NETMOD: return "3 网络模块+工程主机";
case HMT_GPRS: return "4 GPRS主机";
case HMT_LCD: return "5 液晶主机";
case HMT_WIRED: return "6 网线主机";
case HMT_TRUE_COLOR: return "7 真彩主机";
case HMT_3_SECTION: return "8 三区段主机";
case HMT_IOT: return "9 物联卡主机";
case HMT_GPRS_PHONE: return "10 GPRS主机能打电话";
case HMT_NB: return "11 NB报警接收主机";
default: return "未知主机";
}
}
const char* hbZonePropertyToString(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR: return "HZP_BUGLAR";
case HZP_EMERGENCY: return "HZP_EMERGENCY";
case HZP_FIRE: return "HZP_FIRE";
case HZP_DURESS: return "HZP_DURESS";
case HZP_GAS: return "HZP_GAS";
case HZP_WATER: return "HZP_WATER";
case HZP_SUB_MACHINE: return "HZP_SUB_MACHINE";
case HZP_REMOTE_CONTROL: return "HZP_REMOTE_CONTRO";
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";
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";
}
}
const char* hbZonePropertyToStringChinese(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR: return "匪警全局";
case HZP_EMERGENCY: return "匪警紧急";
case HZP_FIRE: return "火警防区";
case HZP_DURESS: return "胁迫防区";
case HZP_GAS: return "燃气防区";
case HZP_WATER: return "淹水防区";
case HZP_SUB_MACHINE: return "分机";
case HZP_REMOTE_CONTROL: 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 "无效属性";
}
}
const char* hbGetZoneFormatString(HbMachineType type)
{
uint16_t zone = hbZoneMax(type);
if (10 < zone && zone < 100) { return "%02d"; }
else if (zone < 1000) { return "%03d"; }
else { return "%d"; }
}
void hbSum(uint8_t* data, int len)
{
uint8_t sum = 0;
uint8_t* p = data;
while (p != data + len - 1) {
sum += *p++;
}
*p = sum;
}
int hbCheckSum(const uint8_t* data, int len)
{
uint8_t sum = 0;
const uint8_t* p = data;
while (p != data + len - 1) {
sum += *p;
}
return sum == *p;
}
HbComRequestType hbComParseRequest(const uint8_t* data, int len)
{
do {
if (len < 5) { break; }
if (data[0] != 0xEB) { break; }
switch (data[1]) {
case 0xAB:
{
if (data[2] != 0x3F) { break; }
switch (data[3]) {
case 0xA0: // EB AB 3F A0 75
{
if (len != HbComReq_A0_len) { break; }
if (memcmp(HbComReq_A0_data, data, len) != 0) { break; }
return HbComReq_A0;
}
case 0xA1: // EB AB 3F A1 76
{
if (len != HbComReq_A1_len) { break; }
if (memcmp(HbComReq_A1_data, data, len) != 0) { break; }
return HbComReq_A1;
}
case 0xA2: // EB AB 3F A2 77
{
if (len != HbComReq_A2_len) { break; }
if (memcmp(HbComReq_A2_data, data, len) != 0) { break; }
return HbComReq_A2;
}
case 0xA5: // EB AB 3F A5 7A
{
if (len != HbComReq_A5_len) { break; }
if (memcmp(HbComReq_A5_data, data, len) != 0) { break; }
return HbComReq_A5;
}
case 0xAC: // EB AB 3F AC 81
{
if (len != HbComReq_AC_len) { break; }
if (memcmp(HbComReq_AC_data, data, len) != 0) { break; }
return HbComReq_AC;
}
case 0xAD: // EB AB 3F AD 82
{
if (len != HbComReq_AD_len) { break; }
if (memcmp(HbComReq_AD_data, data, len) != 0) { break; }
return HbComReq_AD;
}
default:
break;
}
break;
}
case 0xBA:
{
if (data[2] != 0x3F) { break; }
if (len == HbComReq_RD_acct_len && memcmp(data, HbComReq_RD_acct_data, len) == 0) {
return HbComReq_RD_acct;
}
break;
}
case 0xCB:
{
if (data[2] != 0x3F) { break; }
if (data[3] == 0x09 && data[4] == 0xA3 && len == HbComReq_A3_len) { // EB CB 3F 09 A3 P1 P2 P3 SUM
if (hbCheckSum(data, len)) { return HbComReq_A3; }
} else if (data[3] == 0x0F && data[4] == 0x4D && len == HbComReq_WR_acct_len) {
if (hbCheckSum(data, len)) { return HbComReq_WR_acct; }
} else if (data[3] == 0x0E && data[4] == 0xA7 && len == HbComReq_A7_len) { // EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM
if (hbCheckSum(data, len)) { return HbComReq_A7; }
}
/*else if (data[3] == 0x08 && data[4] == 0xA9 && len == A9_len) {
A7 req; memcpy(req.data, data, req.len); sum(req);
if (data[len - 1] == req.data[len - 1]) { return A7; }
}*/
else if (data[3] == 0x08 && data[4] == 0xAA && len == HbComReq_AA_len) { // EB CB 3F 08 AA P1 P2 SUM
if (hbCheckSum(data, len)) { return HbComReq_AA; }
}
/*else if (data[3] == 0x08 && data[4] == 0xAE && len == AE_len) {
AA req; memcpy(req.data, data, req.len); sum(req);
if (data[len - 1] == req.data[len - 1]) { return AA; }
}*/
else if (data[3] == 0x06 && data[4] == 0xB0 && len == HbComReq_B0_len && memcmp(HbComReq_B0_data, data, len) == 0) { // EB CB 3F 06 B0 AB
return HbComReq_B0;
}
}
}
} while (0);
return HbComReq_Invalid;
}
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata)
{
if (!xdata) { return HbComReq_Invalid; }
return hbComParseRequest(ademcoXDataGetValidContentAddr(xdata), ademcoXDataGetValidContentLen(xdata));
}
HbComResponseType hbComParseResponse(const uint8_t* data, int len)
{
do {
if (len < 7) { break; } // ���е� response ��������СΪ 7
if (data[0] != 0xEB || data[1] != 0xBA || data[2] != 0x3F) { break; }
switch (data[5]) {
case 0xA0: // EB BA 3F 07 P0 A0 P1 P2 P3 SUM
{
if (len != HbComResp_A0_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A0; }
}
case 0xA2: // EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
{
if (len != data[3]) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A2; }
}
case 0xA3:
{
if (len != HbComResp_A3_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A3; }
}
case 0xA4:
{
if (len != HbComResp_A4_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A4; }
return HbComResp_A4;
}
case 0xA6:
{
if (len != HbComResp_A6_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A6; }
return HbComResp_A6;
}
case 0xA7:
{
if (len != HbComResp_A7_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A7; }
return HbComResp_A7;
}
case 0xA8:
{
if (len != HbComResp_A8_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A8; }
return HbComResp_A8;
}
case 0xA9:
{
// TODO
}
case 0xAB:
{
if (len != HbComResp_AB_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_AB; }
return HbComResp_AB;
}
case 0xAD: // EB BA 3F PN P0 AD P1 DATA P2 SUM
{
if (len != data[3]) { break; }
if (hbCheckSum(data, len)) { return HbComResp_AD; }
return HbComResp_AD;
}
case 0xAF: // TODO
{
break;
}
case 0xB1: // EB BA 3F 08 P0 B1 P1 SUM
{
if (len != HbComResp_B1_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_B1; }
return HbComResp_B1;
}
}
} while (0);
return HbComResp_Invalid;
}
void hbComMakeReqA0_getMachineStatus(HbComData* data)
{
memcpy(data->data, HbComReq_A0_data, HbComReq_A0_len);
data->len = HbComReq_A0_len;
}
void hbComMakeReqA1_getMachineZones(HbComData* data)
{
memcpy(data->data, HbComReq_A1_data, HbComReq_A1_len);
data->len = HbComReq_A1_len;
}
void hbComMakeReqA2_getMoreMachineZones(HbComData* data)
{
memcpy(data->data, HbComReq_A2_data, HbComReq_A2_len);
data->len = HbComReq_A2_len;
}
void hbComMakeReqA3_modifyMachineZone(HbComData* data, uint8_t zone, HbZoneProperty prop, HbComReq_A3_op op)
{
memcpy(data->data, HbComReq_A3_head, 5);
data->data[5] = zone;
data->data[6] = prop;
data->data[7] = op;
data->len = HbComReq_A3_len;
hbSum(data->data, data->len);
}
void hbComMakeReqA5_getMachineTimer(HbComData* data)
{
memcpy(data->data, HbComReq_A5_data, HbComReq_A5_len);
data->len = HbComReq_A5_len;
}
void hbComMakeReqA7_setMachineTimer(HbComData* data, HbMachineTimer* timer)
{
memcpy(data->data, HbComReq_A7_head, 5);
memcpy(data->data + 5, timer, sizeof(*timer));
data->len = HbComReq_A7_len;
hbSum(data->data, data->len);
}
void hbComMakeReqAA_modifyMachineZoneLostConfig(HbComData* data, uint8_t zone, int on)
{
memcpy(data->data, HbComReq_AA_head, 5);
data->data[5] = zone;
data->data[6] = !!on;
data->len = HbComReq_AA_len;
hbSum(data->data, data->len);
}
void hbComMakeReqAC_getMachineZoneLostConfig(HbComData* data)
{
memcpy(data->data, HbComReq_AC_data, HbComReq_AC_len);
data->len = HbComReq_AC_len;
}
void hbComMakeReqAD_getMoreMachineZoneLostConfig(HbComData* data)
{
memcpy(data->data, HbComReq_AD_data, HbComReq_AD_len);
data->len = HbComReq_AD_len;
}
void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status)
{
memcpy(data->data, HbComReq_AE_head, 5);
data->data[5] = p1;
data->data[6] = status;
data->len = HbComReq_AE_len;
hbSum(data->data, data->len);
}
void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data)
{
memcpy(data->data, HbComReq_B0_data, HbComReq_B0_len);
data->len = HbComReq_B0_len;
}
void hbComMakeReqRD_acct(HbComData* data)
{
memcpy(data->data, HbComReq_RD_acct_data, HbComReq_RD_acct_len);
data->len = HbComReq_RD_acct_len;
}
void hbComMakeReqWR_acct(HbComData* data, const char* acct)
{
memcpy(data->data, HbComReq_WR_acct_head, 5);
hbDecStrToHiLoArray(data->data + 5, 9, acct);
data->len = HbComReq_WR_acct_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA0_getMachineStatus(HbComData* data, HbMachineStatus status, HbMachineType type)
{
memcpy(data->data, HbComResp_A0_head, 6);
data->data[6] = status;
data->data[7] = type;
data->len = HbComResp_A0_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA2_getMachineZones(HbComData* data, int count, AdemcoZone* zones, HbZoneProperty* props, HbComResp_A2_p1 p1)
{
if (count > HbComResp_A2_max_zone) { return; }
memcpy(data->data, HbComResp_A2_head, 6);
data->data[3] = HbComResp_A2_len_min + count * 2;
uint8_t* p = data->data + 6;
for (int i = 0; i < count; i++) {
*p++ = zones[i] & 0xFF;
*p++ = props[i];
}
*p++ = (count > 0) ? p1 : HbComResp_A2_p1_nomore;
data->len = ++p - data->data;
hbSum(data->data, data->len);
}
void hbComMakeRespA3_waitingSignal(HbComData* data)
{
memcpy(data->data, HbComResp_A3_data, HbComResp_A3_len);
data->len = HbComResp_A3_len;
}
void hbComMakeRespA4_modifyMachineZone(HbComData* data, AdemcoZone zone, HbZoneProperty prop, HbComResp_A4_p3 p3)
{
memcpy(data->data, HbComResp_A4_head, 6);
data->data[6] = zone & 0xFF;
data->data[7] = prop;
data->data[8] = p3;
data->len = HbComResp_A4_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA6_getMachineTimer(HbComData* data, HbMachineTimer* timer)
{
memcpy(data->data, HbComResp_A6_head, 6);
memcpy(data->data + 6, timer, sizeof(*timer));
data->len = HbComResp_A6_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA7_setMachineTimer(HbComData* data)
{
memcpy(data->data, HbComResp_A7_data, HbComResp_A7_len);
data->len = HbComResp_A7_len;
}
void hbComMakeRespA8_reject(HbComData* data)
{
memcpy(data->data, HbComResp_A8_data, HbComResp_A8_len);
data->len = HbComResp_A8_len;
}
void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, AdemcoZone zone, HbComResp_AB_p2 p2)
{
memcpy(data->data, HbComResp_AB_head, 6);
data->data[6] = zone & 0xFF;
data->data[7] = p2;
data->len = HbComResp_AB_len;
hbSum(data->data, data->len);
}
void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, HbComResp_AD_p1 p1, int count, AdemcoZone* zones, HbComResp_AD_p2 p2)
{
if (count > HbComResp_AD_max_zone) { return; }
memcpy(data->data, HbComResp_AD_head, 6);
data->data[3] = HbComResp_AD_len_min + (p1 == HbComResp_AD_p1_single ? count : count * 2);
data->data[6] = p1;
uint8_t* p = data->data + 7;
for (int i = 0; i < count; i++) {
if (p1 == HbComResp_AD_p1_single) {
*p++ = zones[i] & 0xFF;
} else {
*p++ = zones[i] >> 8 & 0xFF;
*p++ = zones[i] & 0xFF;
}
}
*p++ = (count > 0) ? p2 : HbComResp_AD_p2_nomore;
data->len = ++p - data->data;
hbSum(data->data, data->len);
}
void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status)
{
memcpy(data->data, HbComResp_AF_head, 6);
data->data[6] = p1;
data->data[7] = status;
data->len = HbComResp_AF_len;
hbSum(data->data, data->len);
}
void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data, HbMachineStatus statusMachine,
HbMachineStatus statusSec1, HbMachineStatus statusSec2, HbMachineStatus statusSec3)
{
memcpy(data->data, HbComResp_B1_head, 6);
data->data[6] = (statusMachine << 6) | (statusSec1 << 4) | (statusSec2 << 2) | (statusSec3);
data->len = HbComResp_B1_len;
hbSum(data->data, data->len);
}
void hbComDataToAdemcoXData(const HbComData* const data, AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, AdemcoXDataTransform xtr)
{
ademcoMakeXData(xdata, xlf, xtr, data->data, data->len);
}
int hbHiLoArrayToDecStr(char* str, const uint8_t* arr, int len)
int ademcoHiLoArrayToDecStr(char* str, const uint8_t* arr, int len)
{
char* p = str;
for (int i = 0; i < len; i++) {
......@@ -1818,7 +975,7 @@ int hbHiLoArrayToDecStr(char* str, const uint8_t* arr, int len)
return p - str;
}
int hbDecStrToHiLoArray(uint8_t* arr, int len, const char* str)
int ademcoDecStrToHiLoArray(uint8_t* arr, int len, const char* str)
{
uint8_t* p = arr;
int slen = strlen(str);
......@@ -1859,7 +1016,7 @@ static uint8_t hex2char(uint8_t h) {
}
}
int hbHexArrayToStr(char* str, const uint8_t* arr, int len)
int ademcoHexArrayToStr(char* str, const uint8_t* arr, int len)
{
uint8_t c = 0;
char* p = str;
......@@ -1882,7 +1039,7 @@ static uint8_t char2hex(uint8_t c) {
}
}
int hbHexStrToArray(uint8_t* arr, const char* str, uint8_t padding)
int ademcoHexStrToArray(uint8_t* arr, const char* str, uint8_t padding)
{
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
......@@ -1906,7 +1063,7 @@ int hbHexStrToArray(uint8_t* arr, const char* str, uint8_t padding)
return p - arr;
}
int hbHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding)
int ademcoHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding)
{
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
......@@ -1929,7 +1086,7 @@ int hbHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding)
return p - arr;
}
int hbHexStrToArrayN_allow_non_hex_str(uint8_t* arr, const char* str, int len, uint8_t padding)
int ademcoHexStrToArrayN_allow_non_hex_str(uint8_t* arr, const char* str, int len, uint8_t padding)
{
uint8_t* p = arr;
uint8_t hi = 0, lo = 0;
......@@ -1951,5 +1108,3 @@ int hbHexStrToArrayN_allow_non_hex_str(uint8_t* arr, const char* str, int len, u
}
return p - arr;
}
......@@ -4,11 +4,9 @@
* 2022-6-13 rewrited this C version
*/
#ifndef __ADEMCO_H__
#define __ADEMCO_H__
#pragma once
......@@ -29,13 +27,14 @@
#endif
#include <stdint.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <time.h>
#define ADEMCO_OK 0
#define ADEMCO_ERR -1
......@@ -369,6 +368,10 @@ ADEMCO_EXPORT_SYMBOL int ademcoAppendDataSegment2(AdemcoDataSegment* dataSegment
ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoParseDataSegment(const uint8_t* packet, int packet_len, AdemcoDataSegment* dataSegment);
// return 0 for empty packet, CONGWIN_FE100_PACKET_LEN for non-empty packet
ADEMCO_EXPORT_SYMBOL int ademcoDataSegmentToCongwinFe100(uint8_t* fe100, const AdemcoDataSegment* dataSegment);
#ifndef SWIG
// get valid content address of xdata (except [len])
ADEMCO_EXPORT_SYMBOL const uint8_t* ademcoXDataGetValidContentAddr(const AdemcoXDataSegment* xdata);
#endif
// get valid content length of xdata (except [len])
ADEMCO_EXPORT_SYMBOL int ademcoXDataGetValidContentLen(const AdemcoXDataSegment* xdata);
// return 0 if xdata's valid content is exactly the same as [buf, buf+buf_len)
......@@ -415,421 +418,13 @@ ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const uint8_t* buff, in
*/
ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const uint8_t* buff, int len);
/* Hengbo */
//! 三防区主机状态GG范围 1~3
#define HB_3SECTION_MACHINE_GG_MIN 1
#define HB_3SECTION_MACHINE_GG_MAX 3
//! 是否合法的三防区主机状态GG
static inline int hbIsValid3SectionMachineGG(AdemcoGG gg) {
return HB_3SECTION_MACHINE_GG_MIN <= gg && gg <= HB_3SECTION_MACHINE_GG_MAX;
}
//! 主机状态
typedef enum HbMachineStatus {
HMS_ARM, // 布防
HMS_HALF_ARM, // 半布防
HMS_DISARM, // 撤防
HMS_SETTING, // 设置
HMS_COUNT,
HMS_INVALID = -1,
}HbMachineStatus;
typedef enum HbMachineType {
//! 0 WiFi主机 (已停用)
HMT_WIFI,
//! 1 网络摄像机 (未启用)
HMT_CAMERA,
//! 2 简化的物联卡主机 [ HB-5050G-4GW ]
HMT_GPRS_IOT,
//! 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,
HMT_COUNT,
HMT_INVALID = -1,
}HbMachineType;
typedef enum HbZoneProperty {
//! 匪警全局
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_RESERVED_0B,
//! 保留
HZP_RESERVED_0C,
//! 保留
HZP_RESERVED_0D,
//! 保留
HZP_RESERVED_0E,
//! 旁路防区
//! 2019年9月2日16:01:58 适配金建峰真彩主机
HZP_BYPASS,
HZP_COUNT,
HZP_INVALID = -1,
}HbZoneProperty;
typedef struct HbMachineTimePoint {
uint8_t hour;
uint8_t minute;
}HbMachineTimePoint;
typedef struct HbTimer {
HbMachineTimePoint armAt;
HbMachineTimePoint disarmAt;
}HbTimer;
typedef union HbMachineTimer {
HbTimer timer[2]; // 2 set of timer
uint8_t data[8];
}HbMachineTimer;
// 串口透传数据最大长度
#define HB_COM_DATA_MAX_LEN 64
// 串口透传数据
typedef struct HbComData {
uint8_t data[HB_COM_DATA_MAX_LEN];
int len;
}HbComData;
// 发给主机
typedef enum HbComRequestType {
HbComReq_A0, // 索要主机状态
HbComReq_A1, // 索要防区
HbComReq_A2, // 索要更多防区
HbComReq_A3, // 修改防区
HbComReq_A5, // 获取定时器
HbComReq_A7, // 设置定时器
HbComReq_A9, // TODO
HbComReq_AA, // 修改防区探头遗失/失联
HbComReq_AC, // 索要防区探头遗失/失联--第一次索要
HbComReq_AD, // 索要防区探头遗失/失联--继续索要
HbComReq_AE, // 三区段主机布撤防命令
HbComReq_B0, // 索要三区段主机状态
HbComReq_RD_acct, // 读取主机账号
HbComReq_WR_acct, // 写入主机账号
HbComReq_Invalid = -1,
}HbComRequestType;
// 主机回应
typedef enum HbComResponseType {
HbComResp_A0, // 索要主机状态回应
HbComResp_A2, // 索要防区回应
HbComResp_A3, // 学码开始回应
HbComResp_A4, // 修改防区回应
HbComResp_A6, // 获取主机定时器回应
HbComResp_A7, // 设置主机定时器回应
HbComResp_A8, // 拒绝设置或设置失败回应
HbComResp_A9, // TODO
HbComResp_AB, // 修改防区探头遗失/失联回应
HbComResp_AD, // 索要防区探头遗失/失联回应
HbComResp_AF, // 三区段主机布撤防命令回应
HbComResp_B1, // 三区段主机状态回应
HbComResp_Invalid = -1,
}HbComResponseType;
//! 索要主机状态 EB AB 3F A0 75
#define HbComReq_A0_len 5
#define HbComReq_A0_data "\xEB\xAB\x3F\xA0\x75"
//! 回应主机状态 EB BA 3F 07 P0 A0 P1 P2 P3 SUM
#define HbComResp_A0_len 9
#define HbComResp_A0_head "\xEB\xBA\x3F\x07\xCC\xA0"
//! 索要主机防区 EB AB 3F A1 76
#define HbComReq_A1_len 5
#define HbComReq_A1_data "\xEB\xAB\x3F\xA1\x76"
//! 回应主机防区 EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
#define HbComResp_A2_len_min 8 // 无防区数据时长度最小为8
#define HbComResp_A2_max_zone 20 // 最多可以包含 20 个防区
#define HbComResp_A2_len_max (HbComResp_A2_len_min + HbComResp_A2_max_zone * 2) // 一包数据最多有8+20*2=48个字节
typedef enum HbComResp_A2_p1 {
HbComResp_A2_p1_nomore = 0xFF, // 无更多防区
HbComResp_A2_p1_more = 0x00, // 还有更多防区
}HbComResp_A2_p1;
#define HbComResp_A2_head "\xEB\xBA\x3F\x08\xCC\xA2"
//! 索要更多主机防区 EB AB 3F A2 77
//! 仅应在收到ZoneResponse的param非0xFF时发送,以索要全部防区
#define HbComReq_A2_len 5
#define HbComReq_A2_data "\xEB\xAB\x3F\xA2\x77"
//! 修改主机防区 EB CB 3F 09 A3 P1 P2 P3 SUM
#define HbComReq_A3_len 9
#define HbComReq_A3_head "\xEB\xCB\x3F\x09\xA3"
typedef enum HbComReq_A3_p3 {
HbComReq_A3_p3_del = 0x00, //! 删除防区
HbComReq_A3_p3_learn = 0x01, //! 学码
HbComReq_A3_p3_stop = 0x02, //! 停止学码
HbComReq_A3_p3_modify = 0x04, //! 修改防区属性
}HbComReq_A3_op;
//! 学码开始回应 EB BA 3F 07 P0 A3 5A
//! 因为学码时主机要等待外部无线信号(用户触发探测器),因此先回应A3表示已经开始学码,学码成功时回 ZoneOpResponse A4
#define HbComResp_A3_len 7
#define HbComResp_A3_data "\xEB\xBA\x3F\x07\xCC\xA3\x5A"
//! 修改防区回应 EB BA 3F 0A P0 A4 P1 P2 P3 SUM
#define HbComResp_A4_len 10
#define HbComResp_A4_head "\xEB\xBA\x3F\x0A\xCC\xA4"
typedef enum HbComResp_A4_p3 {
HbComResp_A4_p3_fail = 0x00, //! 失败
HbComResp_A4_p3_ok = 0x01, //! 成功
HbComResp_A4_p3_dup = 0x02, //! 失败--重码
HbComResp_A4_p3_ne = 0x03, //! 失败--防区未对码 not exists
}HbComResp_A4_p3;
//! 获取主机定时器 EB AB 3F A5 7A
#define HbComReq_A5_len 5
#define HbComReq_A5_data "\xEB\xAB\x3F\xA5\x7A"
//! 获取主机定时器回应 EB BA 3F 0F P0 A6 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComResp_A6_len 15
#define HbComResp_A6_head "\xEB\xBA\x3F\x0F\xCC\xA6"
//! 设置主机定时器 EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComReq_A7_len 14
#define HbComReq_A7_head "\xEB\xCB\x3F\x0E\xA7"
//! 设置主机定时器回应 EB BA 3F 07 P0 A7 SUM
#define HbComResp_A7_len 7
#define HbComResp_A7_data "\xEB\xBA\x3F\x07\xCC\xA7\x5E"
//! 拒绝设置回应 EB BA 3F 07 P0 A8 SUM
//! 任何操作,主机如果认为非法,都可以用A8直接回复
#define HbComResp_A8_len 7
#define HbComResp_A8_data "\xEB\xBA\x3F\x07\xCC\xA8\x5F"
//! 修改防区探头遗失/失联 EB CB 3F 08 AA P1 P2 SUM
#define HbComReq_AA_len 8
#define HbComReq_AA_head "\xEB\xAB\x3F\x08\xAA"
//! 修改防区探头遗失/失联回应 EB BA 3F 09 P0 AB P1 P2 SUM
#define HbComResp_AB_len 9
#define HbComResp_AB_head "\xEB\xBA\x3F\x09\xCC\xAB"
typedef enum HbComResp_AB_p2 {
HbComResp_AB_p2_close = 0, // 防区失联关
HbComResp_AB_p2_open = 1, // 防区失联开
HbComResp_AB_p2_reject = 2, // 拒绝操作
}HbComResp_AB_p2;
//! 索要防区探头遗失/失联 第一次索要 EB AB 3F AC 81
#define HbComReq_AC_len 5
#define HbComReq_AC_data "\xEB\xAB\x3F\xAC\x81"
//! 索要防区探头遗失/失联 索要更多 EB AB 3F AD 82
#define HbComReq_AD_len 5
#define HbComReq_AD_data "\xEB\xAB\x3F\xAD\x82"
//! 索要防区探头遗失/失联回应 EB BA 3F PN P0 AD P1 DATA P2 SUM
#define HbComResp_AD_len_min 9 // 无防区失联数据时一包长度最小为9
#define HbComResp_AD_max_zone 20 // 一包最多包含20个防区
#define HbComResp_AD_len_max (HbComResp_AD_len_min + HbComResp_AD_max_zone * 2) // 一包最多有 9 + 20 *2 = 49 个字节
typedef enum HbComResp_AD_p1 {
HbComResp_AD_p1_single = 0xF0, // 防区号以单字节表示
HbComResp_AD_p1_double = 0xF1, // 防区号以双字节表示
}HbComResp_AD_p1;
typedef enum HbComResp_AD_p2 {
HbComResp_AD_p2_nomore = 0xFF, // 无更多防区
HbComResp_AD_p2_more = 0x00, // 还有更多防区
}HbComResp_AD_p2;
#define HbComResp_AD_head "\xEB\xBA\x3F\x09\xCC\xAD"
typedef enum HbCom_3sec_status {
HbCom_3sec_arm = 0x00, // 布防(成功)
HbCom_3sec_disarm = 0x01, // 撤防(成功)
}HbCom_3sec_status;
typedef enum HbCom_3sec_which {
HbCom_3sec_machine, // 主机
HbCom_3sec_section1, // 区段1
HbCom_3sec_section2, // 区段2
HbCom_3sec_section3, // 区段3
}HbCom_3sec_which;
//! 三区段主机布撤防命令 EB CB 3F 08 AE P1 P2 SUM
#define HbComReq_AE_len 8
#define HbComReq_AE_head "\xEB\xCB\x3F\x08\xAE"
//! 三区段主机布撤防命令回应 EB BA 3F 08 P0 AF P1 P2 SUM
#define HbComResp_AF_len 9
#define HbComResp_AF_head "\xEB\xBA\x3F\x08\xCC\xAF"
//! 三区段主机索要主机状态 EB CB 3F 06 B0 AB
#define HbComReq_B0_len 6
#define HbComReq_B0_data "\xEB\xCB\x3F\x06\xB0\xAB"
//! 三区段主机状态回应 EB BA 3F 08 P0 B1 P1 SUM
#define HbComResp_B1_len 8
#define HbComResp_B1_head "\xEB\xBA\x3F\x08\xCC\xB1"
//! 读取主机账号
#define HbComReq_RD_acct_len 7
#define HbComReq_RD_acct_data "\xEB\xBA\x3F\x07\x00\x4C\x37"
//! 读取主机账号回应
#define HbComResp_RD_acct_len 15
#define HbComResp_RD_acct_head "\xEB\xCB\x3F\x0F\x4C"
//! 写入主机账号
#define HbComReq_WR_acct_len 15
#define HbComReq_WR_acct_head "\xEB\xCB\x3F\x0F\x4D"
//! 写入主机账号回应(与读取主机账号命令相同)
#define HbComResp_WR_acct_len HbComReq_RD_acct_len
#define HbComResp_WR_acct_head HbComReq_WR_acct_head
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
ADEMCO_EXPORT_SYMBOL int hbGetAvailableZoneProperties(HbMachineType type, HbZoneProperty props[12]);
//! 最大防区号根据型号不同而不同
ADEMCO_EXPORT_SYMBOL uint16_t hbZoneMax(HbMachineType type);
//! 防区号是否合法(可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbIsValidZone(HbMachineType type, uint16_t zone);
//! 防区号是否合法(不可以可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbIsValidZoneStrict(HbMachineType type, uint16_t zone);
//! 主机是否已投产使用
ADEMCO_EXPORT_SYMBOL int hbMachineIsSelling(HbMachineType type);
//! 主机是否具有布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanArm(HbMachineType type);
//! 主机是否具有撤防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanDisarm(HbMachineType type);
//! 主机是否可以进入设置状态
ADEMCO_EXPORT_SYMBOL int hbMachineCanEnterSettings(HbMachineType type);
//! 主机是否具有半布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanHalfArm(HbMachineType type);
//! 主机是否可以报告信号强度
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportSignalStrength(HbMachineType type);
//! 主机本身是否可以短信报警(不算通过服务如阿里语音等)
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportBySMS(HbMachineType type);
//! 主机是否支持有线防区
ADEMCO_EXPORT_SYMBOL int hbMachineHasWiredZone(HbMachineType type);
//! 主机最小有线防区号
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMin(HbMachineType type);
//! 主机最大有线防区号
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMax(HbMachineType type);
//! 主机是否可以直接写入防区数据(无需对码)
ADEMCO_EXPORT_SYMBOL int hbMachineCanDirectlyWriteZone(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 hbIsValidTimer(HbTimer* 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* hbMachineStatusToStringChinese(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToString(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToStringChinese(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToString(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToStringChinese(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL const char* hbGetZoneFormatString(HbMachineType type);
// 累加校验,计算data[0] ~ data[len-2],校验和放在data[len-1]
ADEMCO_EXPORT_SYMBOL void hbSum(uint8_t* data, int len);
// 校验和是否正确, return 0 for incorrect, otherwise correct
ADEMCO_EXPORT_SYMBOL int hbCheckSum(const uint8_t* data, int len);
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseRequest(const uint8_t* buff, int len);
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL HbComResponseType hbComParseResponse(const uint8_t* buff, int len);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA0_getMachineStatus(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, HbZoneProperty prop, HbComReq_A3_op op);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA5_getMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA7_setMachineTimer(HbComData* data, HbMachineTimer* timer);
// TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeReqA9(HbComData* data, HbMachineStatus status, HbMachineType type);
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);
// p2 must be HbCom_3sec_arm or HbCom_3sec_disarm
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqRD_acct(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqWR_acct(HbComData* data, const char* acct);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA0_getMachineStatus(HbComData* data, HbMachineStatus status, HbMachineType type);
// zones and props length is count
// if count is 0, p1 wil be set to HbComResp_A2_p1_nomore
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA2_getMachineZones(HbComData* data, int count, AdemcoZone* zones, HbZoneProperty* props, HbComResp_A2_p1 p1);
// 学码开始,等待探测器无线信号中
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA3_waitingSignal(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA4_modifyMachineZone(HbComData* data, AdemcoZone zone, HbZoneProperty prop, HbComResp_A4_p3 p3);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA6_getMachineTimer(HbComData* data, HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA7_setMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA8_reject(HbComData* data);
// TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeRespA9_(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, AdemcoZone zone, HbComResp_AB_p2 p2);
// 返回所有失联开的防区
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, HbComResp_AD_p1 p1, int count, AdemcoZone* zones, HbComResp_AD_p2 p2);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data, HbMachineStatus statusMachine,
HbMachineStatus statusSec1, HbMachineStatus statusSec2, HbMachineStatus statusSec3);
ADEMCO_EXPORT_SYMBOL void hbComDataToAdemcoXData(const HbComData* const data, AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, AdemcoXDataTransform xtr);
// 将一串以高低字节表示的十六进制数组转换为10进制数字符串
// 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则停止
// 返回字符串长度
// 注意:函数不会在str末尾补 null terminator
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
ADEMCO_EXPORT_SYMBOL int hbHiLoArrayToDecStr(char* str, const uint8_t* arr, int len);
ADEMCO_EXPORT_SYMBOL int ademcoHiLoArrayToDecStr(char* str, const uint8_t* arr, int len);
// 将一个10进制数字符串转为高低字节表示的数组,节省空间
// str应只包含'0'~'9',否则失败返回0
......@@ -838,7 +433,7 @@ ADEMCO_EXPORT_SYMBOL int hbHiLoArrayToDecStr(char* str, const uint8_t* arr, int
// 示例:输入字符串"123ABC",返回0
// 示例:输入字符串 "18240888101", len=9, 则arr内容为 0x18 0x24 0x08 0x88 0x10 0x1f 0xff 0xff 0xff, return 9
// 示例:输入字符串 "12345678901234567890", len=9, 则arr内容为 0x18 0x24 0x08 0x88 0x10 0x1f 0xff 0xff 0xff, return 9
ADEMCO_EXPORT_SYMBOL int hbDecStrToHiLoArray(uint8_t* arr, int len, const char* str);
ADEMCO_EXPORT_SYMBOL int ademcoDecStrToHiLoArray(uint8_t* arr, int len, const char* str);
// 将一串字节流转换为可打印形式
// 返回str长度(len * 2)
......@@ -846,7 +441,7 @@ ADEMCO_EXPORT_SYMBOL int hbDecStrToHiLoArray(uint8_t* arr, int len, const char*
// 注意:函数不会在str末尾补 null terminator
// 示例:输入 arr=[0xEB 0xBA 0x3F], len=3, 则str = "EBBA3F",返回6
// 示例:输入 ary="123", len=3, 则str = "313233",返回6
ADEMCO_EXPORT_SYMBOL int hbHexArrayToStr(char* str, const uint8_t* arr, int len);
ADEMCO_EXPORT_SYMBOL int ademcoHexArrayToStr(char* str, const uint8_t* arr, int len);
// 将一串字符串(内容为'0'~'9', 'A'~'F', 'a' ~'f')转为字节流
// 若strlen(str)为奇数,以padding补足arr, padding 应 <= 0x0F
......@@ -855,17 +450,17 @@ ADEMCO_EXPORT_SYMBOL int hbHexArrayToStr(char* str, const uint8_t* arr, int len)
// 示例:输入字符串str="EBBA3F", 输出arr = [0xEB, 0xBA, 0x3F],返回 3
// 示例:输入字符串str="ABC", padding = 0, 输出arr=[0xAB, 0xC0],返回2
// 示例:输入字符串str="ABC", padding = 0x0F, 输出arr=[0xAB, 0xCF],返回2
ADEMCO_EXPORT_SYMBOL int hbHexStrToArray(uint8_t* arr, const char* str, uint8_t padding);
ADEMCO_EXPORT_SYMBOL int ademcoHexStrToArray(uint8_t* arr, const char* str, uint8_t padding);
// 功能同hbHexStrToArray
// 功能同ademcoHexStrToArray
// 若strlen(str) > len, str[len]及之后的内容将被舍弃以避免溢出
// 示例:输入字符串str="ABCDE", len = 4 padding = 0x0F, 输出arr=[0xAB, 0xCD], return 2
ADEMCO_EXPORT_SYMBOL int hbHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding);
ADEMCO_EXPORT_SYMBOL int ademcoHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding);
// 同hbHexStrToArrayN,但允许str包含非hex字符,即'0'~'9','a'~'f','A'~'F'之外的内容,以 padding 替换
// 同ademcoHexStrToArrayN,但允许str包含非hex字符,即'0'~'9','a'~'f','A'~'F'之外的内容,以 padding 替换
// 示例:str="AB\xFFD", len=4, padding=0x0F, 则arr=[ 0xAB, 0xFD ], return 2
// 网线主机 0d 00 命令,接警中心账号部分,有可能是这种
ADEMCO_EXPORT_SYMBOL int hbHexStrToArrayN_allow_non_hex_str(uint8_t* arr, const char* str, int len, uint8_t padding);
ADEMCO_EXPORT_SYMBOL int ademcoHexStrToArrayN_allow_non_hex_str(uint8_t* arr, const char* str, int len, uint8_t padding);
#ifdef __cplusplus
}
......
......@@ -152,10 +152,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\ademco.c" />
<ClCompile Include="..\..\hb_com.c" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\ademco.h" />
<ClInclude Include="..\..\hb_com.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -21,10 +21,16 @@
<ClCompile Include="..\..\ademco.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\hb_com.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\ademco.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\hb_com.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#include "../../ademco.h"
#include "../../ademco.h"
#include "../../hb_com.h"
#include <jlib/win32/UnicodeTool.h>
#include <jlib/win32/path_op.h>
#include <jlib/util/std_util.h>
#include <map>
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib, "../x64/Debug/ademco.lib")
......@@ -19,12 +21,12 @@
#endif
const char* print_bool(bool b) {
return b ? "√" : " "; // "×";
return b ? "√" : " "; // "×";
}
AdemcoEvent statusEvents[] = {
// 主机或分机状态报告
// 主机或分机状态报告
EVENT_ARM,
EVENT_DISARM,
EVENT_HALFARM_1456,
......@@ -34,7 +36,7 @@ AdemcoEvent statusEvents[] = {
AdemcoEvent alarmEvents[] = {
// 防区报警
// 防区报警
EVENT_BURGLAR,
EVENT_DOORRINGING,
EVENT_FIRE,
......@@ -50,7 +52,7 @@ AdemcoEvent alarmEvents[] = {
AdemcoEvent excepEvents[] = {
// 区异常
// 防区异常
EVENT_AC_BROKE,
EVENT_AC_RECOVER,
EVENT_LOWBATTERY,
......@@ -68,14 +70,14 @@ AdemcoEvent excepEvents[] = {
EVENT_LOST,
EVENT_LOST_RECOVER,
// 标准事件,但不做处理
// 标准事件,但不做处理
EVENT_3100,
};
AdemcoEvent privateEvents[] = {
// ------------------私有事件-----------------------------------------
// ------------------私有事件-----------------------------------------
EVENT_SERIAL485DIS,
EVENT_SERIAL485CONN,
......@@ -129,7 +131,7 @@ AdemcoEvent privateEvents[] = {
void printEvents(const AdemcoEvent* events, size_t len)
{
printf("|事件码|含义|en|\n|-----|----|--|\n");
printf("|事件码|含义|en|\n|-----|----|--|\n");
for (size_t i = 0; i < len; i++) {
auto e = events[i];
printf("|%04d|%s|%s|\n", e,
......@@ -206,10 +208,10 @@ std::vector<std::string> get_machine_brands(HbMachineType t)
std::string brand_to_path(const std::string& brand)
{
std::vector<std::string> exts = { "png", "jpg" };
std::string path = jlib::win32::utf16_to_mbcs(L"..\\..\\docs\\主机类型\\smartresize\\HB-") + brand;
std::string path = jlib::win32::utf16_to_mbcs(L"..\\..\\docs\\主机类型\\smartresize\\HB-") + brand;
for (auto ext : exts) {
if (jlib::win32::fileExists(path + "-web." + ext)) {
return jlib::win32::utf16_to_mbcs(L"./主机类型/smartresize/HB-") + brand + "-web." + ext;
return jlib::win32::utf16_to_mbcs(L"./主机类型/smartresize/HB-") + brand + "-web." + ext;
}
}
return {};
......@@ -230,11 +232,11 @@ void print_machine_brands(HbMachineType t)
void print_machineTypes()
{
printf("### *恒博主机类型对照表*\n\n");
printf("### *恒博主机类型对照表*\n\n");
printf("*SMS指主机自身是否可以拨打电话、发送短信,不是指通过阿里语音打电话*\n");
printf("*SMS指主机自身是否可以拨打电话、发送短信,不是指通过阿里语音打电话*\n");
printf("|事件码类型|主机类型|布防|撤防|半布防|设置|信号强度|防区|有线防区|SMS|内核|网络|型号|\n"
printf("|事件码类型|主机类型|布防|撤防|半布防|设置|信号强度|防区|有线防区|SMS|内核|网络|型号|\n"
"|---------|-------|----|----|-----|----|-------|----|-------|---|----|---|----|\n");
for (auto e : AdemcoEvents) {
......@@ -267,9 +269,9 @@ void print_machineTypes()
void print_imgs()
{
printf("\n\n### *恒博主机型号示例图片*\n\n");
printf("\n\n### *恒博主机型号示例图片*\n\n");
printf("|型号|示例图片|\n"
printf("|型号|示例图片|\n"
"|---|--------|\n");
std::map<std::string, std::string> imgs;
......@@ -302,7 +304,7 @@ bool zprop_is_contain(HbZoneProperty prop) {
void print_available_zone_props()
{
printf("### *恒博主机类型与支持的防区属性对照表*\n\n");
printf("### *恒博主机类型与支持的防区属性对照表*\n\n");
//auto all_props = getAvailableZoneProperties();
......@@ -314,7 +316,7 @@ void print_available_zone_props()
printf("* 防区属性是否支持失联报告\n\n");
printf("* 防区属性是否支持失联报告\n\n");
printf("|");
for (auto zp : hbZoneProperties) {
printf("|"); print_prop(zp);
......@@ -327,15 +329,15 @@ void print_available_zone_props()
}
printf("|\n");
printf("|失联支持");
printf("|失联支持");
for (auto zp : hbZoneProperties) {
printf("|%s", print_bool(hbZonePropCanReportLost(zp)));
}
printf("|\n\n");
printf("* 主机类型与支持的防区属性对照表\n\n");
printf("|事件码|类型|型号");
printf("* 主机类型与支持的防区属性对照表\n\n");
printf("|事件码|类型|型号");
for (auto zp : hbZoneProperties) {
//printf("|"); print_prop(zp);
printf("|%02X", (int)zp);
......@@ -371,16 +373,16 @@ void print_available_zone_props()
void print_g250_alarm_codes()
{
//printf("# 工程主机串口通信协议\n\n");
//printf("# 工程主机串口通信协议\n\n");
//printf("9600, N, 8, 1\n\n");
//printf("SUM = DATA(N) = DATA(0) + DATA(1) + ... + DATA(N-1)\n\n");
//// 按键码
//// 按键码
//printf("\n\n## EB AB addr data sum\n");
//printf("PC到主机,按键\n");
//printf("* addr: PC模拟键盘地址,1~4,暂时固定为3\n");
//printf("* data: 按键码\n\n");
//printf("|键码|按键|\n");
//printf("PC到主机,按键\n");
//printf("* addr: PC模拟键盘地址,1~4,暂时固定为3\n");
//printf("* data: 按键码\n\n");
//printf("|按键码|按键|\n");
//printf("|-----|----|\n");
//for (Key k = Key::Key_NULL; k <= Key::Key_STOP_ALARM; k = Key(k + 1)) {
// auto s = keyToString(k);
......@@ -390,15 +392,15 @@ void print_g250_alarm_codes()
//}
//// EB B1 报警码
//// EB B1 报警码
//printf("\n\n## EB B1 data0 data1 data2 code data4 sum\n");
//printf("主机到PC事件报告\n");
//printf("* data0: 命令字总字长,固定为8\n");
//printf("* data1: 防区号高位\n");
//printf("* data2: 防区号低位\n");
//printf("* data4: 00 表示data1与data2为主机直属防区号,01~F0 表示data1与data2为分机防区号(已废弃),EE 表示分机自身状态(已废弃)\n");
//printf("* code: 报警码\n\n");
//printf("|报警码|安定宝事件码|含义|\n");
//printf("主机到PC事件报告\n");
//printf("* data0: 命令字总字长,固定为8\n");
//printf("* data1: 防区号高位\n");
//printf("* data2: 防区号低位\n");
//printf("* data4: 00 表示data1与data2为主机直属防区号,01~F0 表示data1与data2为分机防区号(已废弃),EE 表示分机自身状态(已废弃)\n");
//printf("* code: 报警码\n\n");
//printf("|报警码|安定宝事件码|含义|\n");
//printf("|------|----------|----|\n");
//static Char codes[] = {
......@@ -439,16 +441,16 @@ void print_g250_alarm_codes()
int main()
{
if (0) {
printf("### 主机状态\n\n");
printf("### 主机状态\n\n");
printEvents(statusEvents, _countof(statusEvents));
printf("### 防区报警\n\n");
printf("### 防区报警\n\n");
printEvents(alarmEvents, _countof(alarmEvents));
printf("### 区异常\n\n");
printf("### 防区异常\n\n");
printEvents(excepEvents, _countof(excepEvents));
printf("### *恒博私有事件码*\n\n");
printf("### *恒博私有事件码*\n\n");
printEvents(privateEvents, _countof(privateEvents));
print_machineTypes();
......
#include "hb_com.h"
#include <string.h>
int hbGetAvailableZoneProperties(HbMachineType type, HbZoneProperty props[12])
{
switch (type) {
case HMT_WIFI:
break;
case HMT_CAMERA:
break;
case HMT_GPRS_IOT:
case HMT_GPRS:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_NETMOD:
{
HbZoneProperty hzps[] = { 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, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_LCD:
{
HbZoneProperty hzps[] = { 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 };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_WIRED:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_TRUE_COLOR:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_3_SECTION:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_IOT:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, HZP_SHIELD, HZP_DOOR_RING, HZP_BYPASS };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_GPRS_PHONE:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_REMOTE_CONTROL, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
case HMT_NB:
{
HbZoneProperty hzps[] = { HZP_BUGLAR, HZP_EMERGENCY, HZP_FIRE, HZP_DURESS, HZP_GAS, HZP_WATER, HZP_DOOR_RING, };
memcpy(props, hzps, sizeof(hzps));
return sizeof(hzps) / sizeof(HbZoneProperty);
}
default: return 0;
}
return 0;
}
uint16_t hbZoneMax(HbMachineType type)
{
switch (type) {
case HMT_GPRS_IOT:
case HMT_GPRS:
case HMT_WIRED:
return 99;
case HMT_NETMOD:
case HMT_NB:
return 999;
case HMT_LCD:
return 249;
case HMT_TRUE_COLOR:
return 68;
case HMT_3_SECTION:
return 191;
case HMT_IOT:
case HMT_GPRS_PHONE:
return 60;
case HMT_WIFI:
case HMT_CAMERA:
default:
return 0;
break;
}
}
int hbIsValidZone(HbMachineType type, uint16_t zone)
{
return ADEMCO_ZONE_FOR_MACHINE_SELF <= zone && zone <= hbZoneMax(type);
}
int hbIsValidZoneStrict(HbMachineType type, uint16_t zone)
{
return ADEMCO_ZONE_MIN <= zone && zone <= hbZoneMax(type);
}
int hbMachineIsSelling(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_GPRS
|| type == HMT_GPRS_IOT
|| type == HMT_IOT
|| type == HMT_LCD
|| type == HMT_WIRED
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
|| type == HMT_NB
;
}
int hbMachineCanArm(HbMachineType type)
{
return hbMachineIsSelling(type) && (type != HMT_NB);
}
int hbMachineCanDisarm(HbMachineType type)
{
return hbMachineIsSelling(type) && (type != HMT_NB);
}
int hbMachineCanEnterSettings(HbMachineType type)
{
return hbMachineIsSelling(type);
}
int hbMachineCanHalfArm(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_LCD
;
}
int hbMachineCanReportSignalStrength(HbMachineType type)
{
return type == HMT_GPRS
|| type == HMT_GPRS_IOT
|| type == HMT_IOT
|| type == HMT_LCD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
|| type == HMT_NB
;
}
int hbMachineCanReportBySMS(HbMachineType type)
{
return type == HMT_GPRS
|| type == HMT_LCD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
|| type == HMT_GPRS_PHONE
;
}
int hbMachineHasWiredZone(HbMachineType type)
{
return type == HMT_NETMOD
|| type == HMT_TRUE_COLOR
|| type == HMT_3_SECTION
;
}
AdemcoZone hbWiredZoneMin(HbMachineType type)
{
switch (type) {
case HMT_NETMOD: return 1;
case HMT_TRUE_COLOR: return 1;
case HMT_3_SECTION: return 61;
default: return 0;
}
}
AdemcoZone hbWiredZoneMax(HbMachineType type)
{
switch (type) {
case HMT_NETMOD: return 8;
case HMT_TRUE_COLOR: return 8;
case HMT_3_SECTION: return 68;
default: return 0;
}
}
int hbMachineCanDirectlyWriteZone(HbMachineType type)
{
return type == HMT_NETMOD;
}
int hbMachineCanLinkSubMachine(HbMachineType type)
{
return type == HMT_NETMOD;
}
int hbZonePropCanReportLost(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR:
case HZP_EMERGENCY:
case HZP_DURESS:
case HZP_SUB_MACHINE:
case HZP_BUGLAR_HALF:
case HZP_BYPASS:
return 1;
default:
return 0;
}
}
void hbInitMachineTimer(HbMachineTimer* timer)
{
memset(timer->data, 0xFF, sizeof(timer));
}
int hbIsValidTimer(HbTimer* timer)
{
return 0 <= timer->armAt.hour && timer->armAt.hour < 24 &&
0 <= timer->armAt.minute && timer->armAt.minute < 60 &&
0 <= timer->disarmAt.hour && timer->disarmAt.hour < 24 &&
0 <= timer->disarmAt.minute && timer->disarmAt.minute < 60;
}
AdemcoEvent hbMachineStatusToAdemcoEvent(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return EVENT_ARM;
case HMS_DISARM: return EVENT_DISARM;
case HMS_HALF_ARM: return EVENT_HALFARM; // EVENT_HALFARM_1456
case HMS_SETTING: return EVENT_ENTER_SETTING_MODE; // EVENT_ENTER_SET_MODE
default: return EVENT_INVALID_EVENT;
}
}
HbMachineStatus hbMachineStatusFromAdemcoEvent(AdemcoEvent ademcoEvent)
{
switch (ademcoEvent) {
case EVENT_ARM:
return HMS_ARM;
case EVENT_DISARM:
return HMS_DISARM;
case EVENT_HALFARM:
case EVENT_HALFARM_1456:
return HMS_HALF_ARM;
case EVENT_ENTER_SETTING_MODE:
case EVENT_ENTER_SET_MODE:
return HMS_SETTING;
default:
return HMS_INVALID;
}
}
AdemcoEvent hbMachineTypeToAdemcoEvent(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return EVENT_I_AM_WIFI_MACHINE;
case HMT_GPRS_IOT: return EVENT_I_AM_GPRS_IOT;
case HMT_NETMOD: return EVENT_I_AM_NET_MODULE;
case HMT_GPRS: return EVENT_I_AM_GPRS;
case HMT_LCD: return EVENT_I_AM_LCD_MACHINE;
case HMT_WIRED: return EVENT_I_AM_WIRE_MACHINE;
case HMT_TRUE_COLOR: return EVENT_I_AM_TRUE_COLOR;
case HMT_3_SECTION: return EVENT_I_AM_3_SECTION_MACHINE;
case HMT_IOT: return EVENT_I_AM_IOT_MACHINE;
case HMT_GPRS_PHONE: return EVENT_I_AM_GPRS_PHONE;
case HMT_NB: return EVENT_I_AM_NB_MACHINE;
default: return EVENT_INVALID_EVENT;
}
}
HbMachineType hbMachineTypeFromAdemcoEvent(AdemcoEvent ademcoEvent)
{
switch (ademcoEvent) {
case EVENT_I_AM_NET_MODULE: return HMT_NETMOD;
case EVENT_I_AM_GPRS: return HMT_GPRS;
case EVENT_I_AM_LCD_MACHINE: return HMT_LCD;
case EVENT_I_AM_WIRE_MACHINE: return HMT_WIRED;
case EVENT_I_AM_WIFI_MACHINE: return HMT_WIFI;
case EVENT_I_AM_3_SECTION_MACHINE: return HMT_3_SECTION;
case EVENT_I_AM_IOT_MACHINE: return HMT_IOT;
case EVENT_I_AM_TRUE_COLOR: return HMT_TRUE_COLOR;
case EVENT_I_AM_GPRS_IOT: return HMT_GPRS_IOT;
case EVENT_I_AM_GPRS_PHONE: return HMT_GPRS_PHONE;
case EVENT_I_AM_NB_MACHINE: return HMT_NB;
default: return HMT_INVALID;
}
}
AdemcoEvent hbZonePropertyToAdemcoEvent(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR:
case HZP_BUGLAR_HALF: return EVENT_BURGLAR;
case HZP_EMERGENCY: return EVENT_EMERGENCY;
case HZP_FIRE: return EVENT_FIRE;
case HZP_DURESS: return EVENT_DURESS;
case HZP_GAS: return EVENT_GAS;
case HZP_WATER: return EVENT_WATER;
case HZP_DOOR_RING: return EVENT_DOORRINGING;
default: return EVENT_INVALID_EVENT;
}
}
const char* hbMachineStatusToString(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return "Arm";
case HMS_HALF_ARM: return "Half-Arm";
case HMS_DISARM: return "Disarm";
case HMS_SETTING: return "Setting";
default: return "InvalidMachineStatus";
}
}
const char* hbMachineStatusToStringChinese(HbMachineStatus status)
{
switch (status) {
case HMS_ARM: return "布防";
case HMS_HALF_ARM: return "半布防";
case HMS_DISARM: return "撤防";
case HMS_SETTING: return "设置";
default: return "InvalidMachineStatus";
}
}
const char* hbMachineTypeToString(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return "0 WiFi";
case HMT_CAMERA: return "1 Camera";
case HMT_GPRS_IOT: return "2 Gprs_IoT";
case HMT_NETMOD: return "3 NetMod";
case HMT_GPRS: return "4 GPRS";
case HMT_LCD: return "5 LCD";
case HMT_WIRED: return "6 Wired";
case HMT_TRUE_COLOR: return "7 TrueColor";
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";
default: return "Unknown HbMachineType";
}
}
const char* hbMachineTypeToStringChinese(HbMachineType type)
{
switch (type) {
case HMT_WIFI: return "0 WiFi主机";
case HMT_CAMERA: return "1 摄像头主机";
case HMT_GPRS_IOT: return "2 简化的物联卡主机";
case HMT_NETMOD: return "3 网络模块+工程主机";
case HMT_GPRS: return "4 GPRS主机";
case HMT_LCD: return "5 液晶主机";
case HMT_WIRED: return "6 网线主机";
case HMT_TRUE_COLOR: return "7 真彩主机";
case HMT_3_SECTION: return "8 三区段主机";
case HMT_IOT: return "9 物联卡主机";
case HMT_GPRS_PHONE: return "10 GPRS主机能打电话";
case HMT_NB: return "11 NB报警接收主机";
default: return "未知主机";
}
}
const char* hbZonePropertyToString(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR: return "HZP_BUGLAR";
case HZP_EMERGENCY: return "HZP_EMERGENCY";
case HZP_FIRE: return "HZP_FIRE";
case HZP_DURESS: return "HZP_DURESS";
case HZP_GAS: return "HZP_GAS";
case HZP_WATER: return "HZP_WATER";
case HZP_SUB_MACHINE: return "HZP_SUB_MACHINE";
case HZP_REMOTE_CONTROL: return "HZP_REMOTE_CONTRO";
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";
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";
}
}
const char* hbZonePropertyToStringChinese(HbZoneProperty zp)
{
switch (zp) {
case HZP_BUGLAR: return "匪警全局";
case HZP_EMERGENCY: return "匪警紧急";
case HZP_FIRE: return "火警防区";
case HZP_DURESS: return "胁迫防区";
case HZP_GAS: return "燃气防区";
case HZP_WATER: return "淹水防区";
case HZP_SUB_MACHINE: return "分机";
case HZP_REMOTE_CONTROL: 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 "无效属性";
}
}
const char* hbGetZoneFormatString(HbMachineType type)
{
uint16_t zone = hbZoneMax(type);
if (10 < zone && zone < 100) { return "%02d"; } else if (zone < 1000) { return "%03d"; } else { return "%d"; }
}
void hbSum(uint8_t* data, int len)
{
uint8_t sum = 0;
uint8_t* p = data;
while (p != data + len - 1) {
sum += *p++;
}
*p = sum;
}
int hbCheckSum(const uint8_t* data, int len)
{
uint8_t sum = 0;
const uint8_t* p = data;
while (p != data + len - 1) {
sum += *p;
}
return sum == *p;
}
HbComRequestType hbComParseRequest(const uint8_t* data, int len)
{
do {
if (len < 5) { break; }
if (data[0] != 0xEB) { break; }
switch (data[1]) {
case 0xAB:
{
if (data[2] != 0x3F) { break; }
switch (data[3]) {
case 0xA0: // EB AB 3F A0 75
{
if (len != HbComReq_A0_len) { break; }
if (memcmp(HbComReq_A0_data, data, len) != 0) { break; }
return HbComReq_A0;
}
case 0xA1: // EB AB 3F A1 76
{
if (len != HbComReq_A1_len) { break; }
if (memcmp(HbComReq_A1_data, data, len) != 0) { break; }
return HbComReq_A1;
}
case 0xA2: // EB AB 3F A2 77
{
if (len != HbComReq_A2_len) { break; }
if (memcmp(HbComReq_A2_data, data, len) != 0) { break; }
return HbComReq_A2;
}
case 0xA5: // EB AB 3F A5 7A
{
if (len != HbComReq_A5_len) { break; }
if (memcmp(HbComReq_A5_data, data, len) != 0) { break; }
return HbComReq_A5;
}
case 0xAC: // EB AB 3F AC 81
{
if (len != HbComReq_AC_len) { break; }
if (memcmp(HbComReq_AC_data, data, len) != 0) { break; }
return HbComReq_AC;
}
case 0xAD: // EB AB 3F AD 82
{
if (len != HbComReq_AD_len) { break; }
if (memcmp(HbComReq_AD_data, data, len) != 0) { break; }
return HbComReq_AD;
}
default:
break;
}
break;
}
case 0xBA:
{
if (data[2] != 0x3F) { break; }
if (len == HbComReq_RD_acct_len && memcmp(data, HbComReq_RD_acct_data, len) == 0) {
return HbComReq_RD_acct;
}
break;
}
case 0xCB:
{
if (data[2] != 0x3F) { break; }
if (data[3] == 0x09 && data[4] == 0xA3 && len == HbComReq_A3_len) { // EB CB 3F 09 A3 P1 P2 P3 SUM
if (hbCheckSum(data, len)) { return HbComReq_A3; }
} else if (data[3] == 0x0F && data[4] == 0x4D && len == HbComReq_WR_acct_len) {
if (hbCheckSum(data, len)) { return HbComReq_WR_acct; }
} else if (data[3] == 0x0E && data[4] == 0xA7 && len == HbComReq_A7_len) { // EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM
if (hbCheckSum(data, len)) { return HbComReq_A7; }
}
/*else if (data[3] == 0x08 && data[4] == 0xA9 && len == A9_len) {
A7 req; memcpy(req.data, data, req.len); sum(req);
if (data[len - 1] == req.data[len - 1]) { return A7; }
}*/
else if (data[3] == 0x08 && data[4] == 0xAA && len == HbComReq_AA_len) { // EB CB 3F 08 AA P1 P2 SUM
if (hbCheckSum(data, len)) { return HbComReq_AA; }
}
/*else if (data[3] == 0x08 && data[4] == 0xAE && len == AE_len) {
AA req; memcpy(req.data, data, req.len); sum(req);
if (data[len - 1] == req.data[len - 1]) { return AA; }
}*/
else if (data[3] == 0x06 && data[4] == 0xB0 && len == HbComReq_B0_len && memcmp(HbComReq_B0_data, data, len) == 0) { // EB CB 3F 06 B0 AB
return HbComReq_B0;
}
}
}
} while (0);
return HbComReq_Invalid;
}
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata)
{
if (!xdata) { return HbComReq_Invalid; }
return hbComParseRequest(ademcoXDataGetValidContentAddr(xdata), ademcoXDataGetValidContentLen(xdata));
}
HbComResponseType hbComParseResponse(const uint8_t* data, int len)
{
do {
if (len < 7) { break; } // 所有的 response ,长度最小为 7
if (data[0] != 0xEB || data[1] != 0xBA || data[2] != 0x3F) { break; }
switch (data[5]) {
case 0xA0: // EB BA 3F 07 P0 A0 P1 P2 P3 SUM
{
if (len != HbComResp_A0_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A0; }
}
case 0xA2: // EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
{
if (len != data[3]) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A2; }
}
case 0xA3:
{
if (len != HbComResp_A3_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A3; }
}
case 0xA4:
{
if (len != HbComResp_A4_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A4; }
return HbComResp_A4;
}
case 0xA6:
{
if (len != HbComResp_A6_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A6; }
return HbComResp_A6;
}
case 0xA7:
{
if (len != HbComResp_A7_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A7; }
return HbComResp_A7;
}
case 0xA8:
{
if (len != HbComResp_A8_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_A8; }
return HbComResp_A8;
}
case 0xA9:
{
// TODO
}
case 0xAB:
{
if (len != HbComResp_AB_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_AB; }
return HbComResp_AB;
}
case 0xAD: // EB BA 3F PN P0 AD P1 DATA P2 SUM
{
if (len != data[3]) { break; }
if (hbCheckSum(data, len)) { return HbComResp_AD; }
return HbComResp_AD;
}
case 0xAF: // TODO
{
break;
}
case 0xB1: // EB BA 3F 08 P0 B1 P1 SUM
{
if (len != HbComResp_B1_len) { break; }
if (hbCheckSum(data, len)) { return HbComResp_B1; }
return HbComResp_B1;
}
}
} while (0);
return HbComResp_Invalid;
}
void hbComMakeReqA0_getMachineStatus(HbComData* data)
{
memcpy(data->data, HbComReq_A0_data, HbComReq_A0_len);
data->len = HbComReq_A0_len;
}
void hbComMakeReqA1_getMachineZones(HbComData* data)
{
memcpy(data->data, HbComReq_A1_data, HbComReq_A1_len);
data->len = HbComReq_A1_len;
}
void hbComMakeReqA2_getMoreMachineZones(HbComData* data)
{
memcpy(data->data, HbComReq_A2_data, HbComReq_A2_len);
data->len = HbComReq_A2_len;
}
void hbComMakeReqA3_modifyMachineZone(HbComData* data, uint8_t zone, HbZoneProperty prop, HbComReq_A3_op op)
{
memcpy(data->data, HbComReq_A3_head, 5);
data->data[5] = zone;
data->data[6] = prop;
data->data[7] = op;
data->len = HbComReq_A3_len;
hbSum(data->data, data->len);
}
void hbComMakeReqA5_getMachineTimer(HbComData* data)
{
memcpy(data->data, HbComReq_A5_data, HbComReq_A5_len);
data->len = HbComReq_A5_len;
}
void hbComMakeReqA7_setMachineTimer(HbComData* data, HbMachineTimer* timer)
{
memcpy(data->data, HbComReq_A7_head, 5);
memcpy(data->data + 5, timer, sizeof(*timer));
data->len = HbComReq_A7_len;
hbSum(data->data, data->len);
}
void hbComMakeReqAA_modifyMachineZoneLostConfig(HbComData* data, uint8_t zone, int on)
{
memcpy(data->data, HbComReq_AA_head, 5);
data->data[5] = zone;
data->data[6] = !!on;
data->len = HbComReq_AA_len;
hbSum(data->data, data->len);
}
void hbComMakeReqAC_getMachineZoneLostConfig(HbComData* data)
{
memcpy(data->data, HbComReq_AC_data, HbComReq_AC_len);
data->len = HbComReq_AC_len;
}
void hbComMakeReqAD_getMoreMachineZoneLostConfig(HbComData* data)
{
memcpy(data->data, HbComReq_AD_data, HbComReq_AD_len);
data->len = HbComReq_AD_len;
}
void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status)
{
memcpy(data->data, HbComReq_AE_head, 5);
data->data[5] = p1;
data->data[6] = status;
data->len = HbComReq_AE_len;
hbSum(data->data, data->len);
}
void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data)
{
memcpy(data->data, HbComReq_B0_data, HbComReq_B0_len);
data->len = HbComReq_B0_len;
}
void hbComMakeReqRD_acct(HbComData* data)
{
memcpy(data->data, HbComReq_RD_acct_data, HbComReq_RD_acct_len);
data->len = HbComReq_RD_acct_len;
}
void hbComMakeReqWR_acct(HbComData* data, const char* acct)
{
memcpy(data->data, HbComReq_WR_acct_head, 5);
ademcoDecStrToHiLoArray(data->data + 5, 9, acct);
data->len = HbComReq_WR_acct_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA0_getMachineStatus(HbComData* data, HbMachineStatus status, HbMachineType type)
{
memcpy(data->data, HbComResp_A0_head, 6);
data->data[6] = status;
data->data[7] = type;
data->len = HbComResp_A0_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA2_getMachineZones(HbComData* data, int count, AdemcoZone* zones, HbZoneProperty* props, HbComResp_A2_p1 p1)
{
if (count > HbComResp_A2_max_zone) { return; }
memcpy(data->data, HbComResp_A2_head, 6);
data->data[3] = HbComResp_A2_len_min + count * 2;
uint8_t* p = data->data + 6;
for (int i = 0; i < count; i++) {
*p++ = zones[i] & 0xFF;
*p++ = props[i];
}
*p++ = (count > 0) ? p1 : HbComResp_A2_p1_nomore;
data->len = ++p - data->data;
hbSum(data->data, data->len);
}
void hbComMakeRespA3_waitingSignal(HbComData* data)
{
memcpy(data->data, HbComResp_A3_data, HbComResp_A3_len);
data->len = HbComResp_A3_len;
}
void hbComMakeRespA4_modifyMachineZone(HbComData* data, AdemcoZone zone, HbZoneProperty prop, HbComResp_A4_p3 p3)
{
memcpy(data->data, HbComResp_A4_head, 6);
data->data[6] = zone & 0xFF;
data->data[7] = prop;
data->data[8] = p3;
data->len = HbComResp_A4_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA6_getMachineTimer(HbComData* data, HbMachineTimer* timer)
{
memcpy(data->data, HbComResp_A6_head, 6);
memcpy(data->data + 6, timer, sizeof(*timer));
data->len = HbComResp_A6_len;
hbSum(data->data, data->len);
}
void hbComMakeRespA7_setMachineTimer(HbComData* data)
{
memcpy(data->data, HbComResp_A7_data, HbComResp_A7_len);
data->len = HbComResp_A7_len;
}
void hbComMakeRespA8_reject(HbComData* data)
{
memcpy(data->data, HbComResp_A8_data, HbComResp_A8_len);
data->len = HbComResp_A8_len;
}
void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, AdemcoZone zone, HbComResp_AB_p2 p2)
{
memcpy(data->data, HbComResp_AB_head, 6);
data->data[6] = zone & 0xFF;
data->data[7] = p2;
data->len = HbComResp_AB_len;
hbSum(data->data, data->len);
}
void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, HbComResp_AD_p1 p1, int count, AdemcoZone* zones, HbComResp_AD_p2 p2)
{
if (count > HbComResp_AD_max_zone) { return; }
memcpy(data->data, HbComResp_AD_head, 6);
data->data[3] = HbComResp_AD_len_min + (p1 == HbComResp_AD_p1_single ? count : count * 2);
data->data[6] = p1;
uint8_t* p = data->data + 7;
for (int i = 0; i < count; i++) {
if (p1 == HbComResp_AD_p1_single) {
*p++ = zones[i] & 0xFF;
} else {
*p++ = zones[i] >> 8 & 0xFF;
*p++ = zones[i] & 0xFF;
}
}
*p++ = (count > 0) ? p2 : HbComResp_AD_p2_nomore;
data->len = ++p - data->data;
hbSum(data->data, data->len);
}
void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status)
{
memcpy(data->data, HbComResp_AF_head, 6);
data->data[6] = p1;
data->data[7] = status;
data->len = HbComResp_AF_len;
hbSum(data->data, data->len);
}
void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data, HbMachineStatus statusMachine,
HbMachineStatus statusSec1, HbMachineStatus statusSec2, HbMachineStatus statusSec3)
{
memcpy(data->data, HbComResp_B1_head, 6);
data->data[6] = (statusMachine << 6) | (statusSec1 << 4) | (statusSec2 << 2) | (statusSec3);
data->len = HbComResp_B1_len;
hbSum(data->data, data->len);
}
void hbComDataToAdemcoXData(const HbComData* const data, AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, AdemcoXDataTransform xtr)
{
ademcoMakeXData(xdata, xlf, xtr, data->data, data->len);
}
/*
* Hengbo COM library
* captainwong
* 2022-8-12 rewrited this C version
*/
#ifndef __HB_COM_H__
#define __HB_COM_H__
#pragma once
#include "ademco.h"
#ifdef __cplusplus
extern "C" {
#endif
//! 三防区主机状态GG范围 1~3
#define HB_3SECTION_MACHINE_GG_MIN 1
#define HB_3SECTION_MACHINE_GG_MAX 3
//! 是否合法的三防区主机状态GG
static inline int hbIsValid3SectionMachineGG(AdemcoGG gg) {
return HB_3SECTION_MACHINE_GG_MIN <= gg && gg <= HB_3SECTION_MACHINE_GG_MAX;
}
//! 主机状态
typedef enum HbMachineStatus {
HMS_ARM, // 布防
HMS_HALF_ARM, // 半布防
HMS_DISARM, // 撤防
HMS_SETTING, // 设置
HMS_COUNT,
HMS_INVALID = -1,
}HbMachineStatus;
typedef enum HbMachineType {
//! 0 WiFi主机 (已停用)
HMT_WIFI,
//! 1 网络摄像机 (未启用)
HMT_CAMERA,
//! 2 简化的物联卡主机 [ HB-5050G-4GW ]
HMT_GPRS_IOT,
//! 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,
HMT_COUNT,
HMT_INVALID = -1,
}HbMachineType;
typedef enum HbZoneProperty {
//! 匪警全局
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_RESERVED_0B,
//! 保留
HZP_RESERVED_0C,
//! 保留
HZP_RESERVED_0D,
//! 保留
HZP_RESERVED_0E,
//! 旁路防区
//! 2019年9月2日16:01:58 适配金建峰真彩主机
HZP_BYPASS,
HZP_COUNT,
HZP_INVALID = -1,
}HbZoneProperty;
typedef struct HbMachineTimePoint {
uint8_t hour;
uint8_t minute;
}HbMachineTimePoint;
typedef struct HbTimer {
HbMachineTimePoint armAt;
HbMachineTimePoint disarmAt;
}HbTimer;
typedef union HbMachineTimer {
HbTimer timer[2]; // 2 set of timer
uint8_t data[8];
}HbMachineTimer;
// 串口透传数据最大长度
#define HB_COM_DATA_MAX_LEN 64
// 串口透传数据
typedef struct HbComData {
uint8_t data[HB_COM_DATA_MAX_LEN];
int len;
}HbComData;
// 发给主机
typedef enum HbComRequestType {
HbComReq_A0, // 索要主机状态
HbComReq_A1, // 索要防区
HbComReq_A2, // 索要更多防区
HbComReq_A3, // 修改防区
HbComReq_A5, // 获取定时器
HbComReq_A7, // 设置定时器
HbComReq_A9, // TODO
HbComReq_AA, // 修改防区探头遗失/失联
HbComReq_AC, // 索要防区探头遗失/失联--第一次索要
HbComReq_AD, // 索要防区探头遗失/失联--继续索要
HbComReq_AE, // 三区段主机布撤防命令
HbComReq_B0, // 索要三区段主机状态
HbComReq_RD_acct, // 读取主机账号
HbComReq_WR_acct, // 写入主机账号
HbComReq_Invalid = -1,
}HbComRequestType;
// 主机回应
typedef enum HbComResponseType {
HbComResp_A0, // 索要主机状态回应
HbComResp_A2, // 索要防区回应
HbComResp_A3, // 学码开始回应
HbComResp_A4, // 修改防区回应
HbComResp_A6, // 获取主机定时器回应
HbComResp_A7, // 设置主机定时器回应
HbComResp_A8, // 拒绝设置或设置失败回应
HbComResp_A9, // TODO
HbComResp_AB, // 修改防区探头遗失/失联回应
HbComResp_AD, // 索要防区探头遗失/失联回应
HbComResp_AF, // 三区段主机布撤防命令回应
HbComResp_B1, // 三区段主机状态回应
HbComResp_Invalid = -1,
}HbComResponseType;
//! 索要主机状态 EB AB 3F A0 75
#define HbComReq_A0_len 5
#define HbComReq_A0_data "\xEB\xAB\x3F\xA0\x75"
//! 回应主机状态 EB BA 3F 07 P0 A0 P1 P2 P3 SUM
#define HbComResp_A0_len 9
#define HbComResp_A0_head "\xEB\xBA\x3F\x07\xCC\xA0"
//! 索要主机防区 EB AB 3F A1 76
#define HbComReq_A1_len 5
#define HbComReq_A1_data "\xEB\xAB\x3F\xA1\x76"
//! 回应主机防区 EB BA 3F PN P0 A2 [Z, P]xN P1 SUM
#define HbComResp_A2_len_min 8 // 无防区数据时长度最小为8
#define HbComResp_A2_max_zone 20 // 最多可以包含 20 个防区
#define HbComResp_A2_len_max (HbComResp_A2_len_min + HbComResp_A2_max_zone * 2) // 一包数据最多有8+20*2=48个字节
typedef enum HbComResp_A2_p1 {
HbComResp_A2_p1_nomore = 0xFF, // 无更多防区
HbComResp_A2_p1_more = 0x00, // 还有更多防区
}HbComResp_A2_p1;
#define HbComResp_A2_head "\xEB\xBA\x3F\x08\xCC\xA2"
//! 索要更多主机防区 EB AB 3F A2 77
//! 仅应在收到ZoneResponse的param非0xFF时发送,以索要全部防区
#define HbComReq_A2_len 5
#define HbComReq_A2_data "\xEB\xAB\x3F\xA2\x77"
//! 修改主机防区 EB CB 3F 09 A3 P1 P2 P3 SUM
#define HbComReq_A3_len 9
#define HbComReq_A3_head "\xEB\xCB\x3F\x09\xA3"
typedef enum HbComReq_A3_p3 {
HbComReq_A3_p3_del = 0x00, //! 删除防区
HbComReq_A3_p3_learn = 0x01, //! 学码
HbComReq_A3_p3_stop = 0x02, //! 停止学码
HbComReq_A3_p3_modify = 0x04, //! 修改防区属性
}HbComReq_A3_op;
//! 学码开始回应 EB BA 3F 07 P0 A3 5A
//! 因为学码时主机要等待外部无线信号(用户触发探测器),因此先回应A3表示已经开始学码,学码成功时回 ZoneOpResponse A4
#define HbComResp_A3_len 7
#define HbComResp_A3_data "\xEB\xBA\x3F\x07\xCC\xA3\x5A"
//! 修改防区回应 EB BA 3F 0A P0 A4 P1 P2 P3 SUM
#define HbComResp_A4_len 10
#define HbComResp_A4_head "\xEB\xBA\x3F\x0A\xCC\xA4"
typedef enum HbComResp_A4_p3 {
HbComResp_A4_p3_fail = 0x00, //! 失败
HbComResp_A4_p3_ok = 0x01, //! 成功
HbComResp_A4_p3_dup = 0x02, //! 失败--重码
HbComResp_A4_p3_ne = 0x03, //! 失败--防区未对码 not exists
}HbComResp_A4_p3;
//! 获取主机定时器 EB AB 3F A5 7A
#define HbComReq_A5_len 5
#define HbComReq_A5_data "\xEB\xAB\x3F\xA5\x7A"
//! 获取主机定时器回应 EB BA 3F 0F P0 A6 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComResp_A6_len 15
#define HbComResp_A6_head "\xEB\xBA\x3F\x0F\xCC\xA6"
//! 设置主机定时器 EB CB 3F 0E A7 H1 M1 H2 M2 H3 M3 H4 M4 SUM
#define HbComReq_A7_len 14
#define HbComReq_A7_head "\xEB\xCB\x3F\x0E\xA7"
//! 设置主机定时器回应 EB BA 3F 07 P0 A7 SUM
#define HbComResp_A7_len 7
#define HbComResp_A7_data "\xEB\xBA\x3F\x07\xCC\xA7\x5E"
//! 拒绝设置回应 EB BA 3F 07 P0 A8 SUM
//! 任何操作,主机如果认为非法,都可以用A8直接回复
#define HbComResp_A8_len 7
#define HbComResp_A8_data "\xEB\xBA\x3F\x07\xCC\xA8\x5F"
//! 修改防区探头遗失/失联 EB CB 3F 08 AA P1 P2 SUM
#define HbComReq_AA_len 8
#define HbComReq_AA_head "\xEB\xAB\x3F\x08\xAA"
//! 修改防区探头遗失/失联回应 EB BA 3F 09 P0 AB P1 P2 SUM
#define HbComResp_AB_len 9
#define HbComResp_AB_head "\xEB\xBA\x3F\x09\xCC\xAB"
typedef enum HbComResp_AB_p2 {
HbComResp_AB_p2_close = 0, // 防区失联关
HbComResp_AB_p2_open = 1, // 防区失联开
HbComResp_AB_p2_reject = 2, // 拒绝操作
}HbComResp_AB_p2;
//! 索要防区探头遗失/失联 第一次索要 EB AB 3F AC 81
#define HbComReq_AC_len 5
#define HbComReq_AC_data "\xEB\xAB\x3F\xAC\x81"
//! 索要防区探头遗失/失联 索要更多 EB AB 3F AD 82
#define HbComReq_AD_len 5
#define HbComReq_AD_data "\xEB\xAB\x3F\xAD\x82"
//! 索要防区探头遗失/失联回应 EB BA 3F PN P0 AD P1 DATA P2 SUM
#define HbComResp_AD_len_min 9 // 无防区失联数据时一包长度最小为9
#define HbComResp_AD_max_zone 20 // 一包最多包含20个防区
#define HbComResp_AD_len_max (HbComResp_AD_len_min + HbComResp_AD_max_zone * 2) // 一包最多有 9 + 20 *2 = 49 个字节
typedef enum HbComResp_AD_p1 {
HbComResp_AD_p1_single = 0xF0, // 防区号以单字节表示
HbComResp_AD_p1_double = 0xF1, // 防区号以双字节表示
}HbComResp_AD_p1;
typedef enum HbComResp_AD_p2 {
HbComResp_AD_p2_nomore = 0xFF, // 无更多防区
HbComResp_AD_p2_more = 0x00, // 还有更多防区
}HbComResp_AD_p2;
#define HbComResp_AD_head "\xEB\xBA\x3F\x09\xCC\xAD"
typedef enum HbCom_3sec_status {
HbCom_3sec_arm = 0x00, // 布防(成功)
HbCom_3sec_disarm = 0x01, // 撤防(成功)
}HbCom_3sec_status;
typedef enum HbCom_3sec_which {
HbCom_3sec_machine, // 主机
HbCom_3sec_section1, // 区段1
HbCom_3sec_section2, // 区段2
HbCom_3sec_section3, // 区段3
}HbCom_3sec_which;
//! 三区段主机布撤防命令 EB CB 3F 08 AE P1 P2 SUM
#define HbComReq_AE_len 8
#define HbComReq_AE_head "\xEB\xCB\x3F\x08\xAE"
//! 三区段主机布撤防命令回应 EB BA 3F 08 P0 AF P1 P2 SUM
#define HbComResp_AF_len 9
#define HbComResp_AF_head "\xEB\xBA\x3F\x08\xCC\xAF"
//! 三区段主机索要主机状态 EB CB 3F 06 B0 AB
#define HbComReq_B0_len 6
#define HbComReq_B0_data "\xEB\xCB\x3F\x06\xB0\xAB"
//! 三区段主机状态回应 EB BA 3F 08 P0 B1 P1 SUM
#define HbComResp_B1_len 8
#define HbComResp_B1_head "\xEB\xBA\x3F\x08\xCC\xB1"
//! 读取主机账号
#define HbComReq_RD_acct_len 7
#define HbComReq_RD_acct_data "\xEB\xBA\x3F\x07\x00\x4C\x37"
//! 读取主机账号回应
#define HbComResp_RD_acct_len 15
#define HbComResp_RD_acct_head "\xEB\xCB\x3F\x0F\x4C"
//! 写入主机账号
#define HbComReq_WR_acct_len 15
#define HbComReq_WR_acct_head "\xEB\xCB\x3F\x0F\x4D"
//! 写入主机账号回应(与读取主机账号命令相同)
#define HbComResp_WR_acct_len HbComReq_RD_acct_len
#define HbComResp_WR_acct_head HbComReq_WR_acct_head
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
ADEMCO_EXPORT_SYMBOL int hbGetAvailableZoneProperties(HbMachineType type, HbZoneProperty props[12]);
//! 最大防区号根据型号不同而不同
ADEMCO_EXPORT_SYMBOL uint16_t hbZoneMax(HbMachineType type);
//! 防区号是否合法(可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbIsValidZone(HbMachineType type, uint16_t zone);
//! 防区号是否合法(不可以可以包含0防区)
ADEMCO_EXPORT_SYMBOL int hbIsValidZoneStrict(HbMachineType type, uint16_t zone);
//! 主机是否已投产使用
ADEMCO_EXPORT_SYMBOL int hbMachineIsSelling(HbMachineType type);
//! 主机是否具有布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanArm(HbMachineType type);
//! 主机是否具有撤防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanDisarm(HbMachineType type);
//! 主机是否可以进入设置状态
ADEMCO_EXPORT_SYMBOL int hbMachineCanEnterSettings(HbMachineType type);
//! 主机是否具有半布防功能
ADEMCO_EXPORT_SYMBOL int hbMachineCanHalfArm(HbMachineType type);
//! 主机是否可以报告信号强度
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportSignalStrength(HbMachineType type);
//! 主机本身是否可以短信报警(不算通过服务如阿里语音等)
ADEMCO_EXPORT_SYMBOL int hbMachineCanReportBySMS(HbMachineType type);
//! 主机是否支持有线防区
ADEMCO_EXPORT_SYMBOL int hbMachineHasWiredZone(HbMachineType type);
//! 主机最小有线防区号
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMin(HbMachineType type);
//! 主机最大有线防区号
ADEMCO_EXPORT_SYMBOL AdemcoZone hbWiredZoneMax(HbMachineType type);
//! 主机是否可以直接写入防区数据(无需对码)
ADEMCO_EXPORT_SYMBOL int hbMachineCanDirectlyWriteZone(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 hbIsValidTimer(HbTimer* 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* hbMachineStatusToStringChinese(HbMachineStatus status);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToString(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbMachineTypeToStringChinese(HbMachineType type);
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToString(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL const char* hbZonePropertyToStringChinese(HbZoneProperty zp);
ADEMCO_EXPORT_SYMBOL const char* hbGetZoneFormatString(HbMachineType type);
// 累加校验,计算data[0] ~ data[len-2],校验和放在data[len-1]
ADEMCO_EXPORT_SYMBOL void hbSum(uint8_t* data, int len);
// 校验和是否正确, return 0 for incorrect, otherwise correct
ADEMCO_EXPORT_SYMBOL int hbCheckSum(const uint8_t* data, int len);
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseRequest(const uint8_t* buff, int len);
ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseXDataRequest(const AdemcoXDataSegment* xdata);
ADEMCO_EXPORT_SYMBOL HbComResponseType hbComParseResponse(const uint8_t* buff, int len);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA0_getMachineStatus(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, HbZoneProperty prop, HbComReq_A3_op op);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA5_getMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqA7_setMachineTimer(HbComData* data, HbMachineTimer* timer);
// TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeReqA9(HbComData* data, HbMachineStatus status, HbMachineType type);
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);
// p2 must be HbCom_3sec_arm or HbCom_3sec_disarm
ADEMCO_EXPORT_SYMBOL void hbComMakeReqAE_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqB0_get3SectionMachineStatus(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqRD_acct(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeReqWR_acct(HbComData* data, const char* acct);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA0_getMachineStatus(HbComData* data, HbMachineStatus status, HbMachineType type);
// zones and props length is count
// if count is 0, p1 wil be set to HbComResp_A2_p1_nomore
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA2_getMachineZones(HbComData* data, int count, AdemcoZone* zones, HbZoneProperty* props, HbComResp_A2_p1 p1);
// 学码开始,等待探测器无线信号中
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA3_waitingSignal(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA4_modifyMachineZone(HbComData* data, AdemcoZone zone, HbZoneProperty prop, HbComResp_A4_p3 p3);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA6_getMachineTimer(HbComData* data, HbMachineTimer* timer);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA7_setMachineTimer(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespA8_reject(HbComData* data);
// TODO
// ADEMCO_EXPORT_SYMBOL void hbComMakeRespA9_(HbComData* data);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, AdemcoZone zone, HbComResp_AB_p2 p2);
// 返回所有失联开的防区
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, HbComResp_AD_p1 p1, int count, AdemcoZone* zones, HbComResp_AD_p2 p2);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespAF_set3SectionMachineStatus(HbComData* data, HbCom_3sec_which p1, HbCom_3sec_status status);
ADEMCO_EXPORT_SYMBOL void hbComMakeRespB1_get3SectionMachineStatus(HbComData* data, HbMachineStatus statusMachine,
HbMachineStatus statusSec1, HbMachineStatus statusSec2, HbMachineStatus statusSec3);
ADEMCO_EXPORT_SYMBOL void hbComDataToAdemcoXData(const HbComData* const data, AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, AdemcoXDataTransform xtr);
#ifdef __cplusplus
}
#endif
#endif
......@@ -15,7 +15,7 @@
%{
/* Includes the header in the wrapper code */
#include "../ademco.h"
#include "../hb_com.h"
%}
#ifdef SWIGJAVA
......@@ -36,4 +36,5 @@ JAVA_ARRAYS_TYPEMAPS(uint8_t, byte, jbyte, Uint8, "[B")
/* Parse the header file to generate wrappers */
%include "../ademco.h"
%include "../hb_com.h"
......@@ -4,7 +4,7 @@ mkdir -p com/hb3344/ademco
swig -java -package com.hb3344.ademco -outdir com/hb3344/ademco -o libademco_java_wrap.c libademco.swig
JAVA_INCLUDE=${JAVA_HOME}/include
JAVA_INCLUDE_OS=${JAVA_INCLUDE}/linux
cc -fpic -c ../ademco.c libademco_java_wrap.c -I"../" -I${JAVA_INCLUDE} -I${JAVA_INCLUDE_OS}
ld -shared ademco.o libademco_java_wrap.o -o libademco_java.so
cc -fpic -c ../ademco.c ../hb_com.c libademco_java_wrap.c -I"../" -I${JAVA_INCLUDE} -I${JAVA_INCLUDE_OS}
ld -shared ademco.o hb_com.o libademco_java_wrap.o -o libademco_java.so
javac JavaDemo.java
# java -Djava.library.path=./ JavaDemo
\ No newline at end of file
......@@ -4,7 +4,7 @@ mkdir -p com/hb3344/ademco
/usr/local/bin/swig -java -package com.hb3344.ademco -outdir com/hb3344/ademco -o libademco_java_wrap.c libademco.swig
JAVA_INCLUDE=${JAVA_HOME}/include
JAVA_INCLUDE_OS=${JAVA_INCLUDE}/darwin
gcc -fpic -c ../ademco.c libademco_java_wrap.c -I"../" -I${JAVA_INCLUDE} -I${JAVA_INCLUDE_OS}
gcc -shared ademco.o libademco_java_wrap.o -o libademco_java.dylib
gcc -fpic -c ../ademco.c ../hb_com.c libademco_java_wrap.c -I"../" -I${JAVA_INCLUDE} -I${JAVA_INCLUDE_OS}
gcc -shared ademco.o hb_com.o libademco_java_wrap.o -o libademco_java.dylib
javac JavaDemo.java
# java -Djava.library.path=./ JavaDemo
mkdir com\hb3344\ademco
"C:\Users\Jack\Downloads\swigwin-3.0.12\swig.exe" -csharp -namespace com.hb3344.ademco -outdir com/hb3344/ademco -o libademco_csharp_wrap.c libademco.swig
cl -c ../ademco.c libademco_csharp_wrap.c -I"../"
cl -LD ademco.obj libademco_csharp_wrap.obj -o libademco.dll
"C:\Users\Jack\Downloads\swigwin-4.0.2\swig.exe" -csharp -namespace com.hb3344.ademco -outdir com/hb3344/ademco -o libademco_csharp_wrap.c libademco.swig
cl -c ../ademco.c ../hb_com.c libademco_csharp_wrap.c libhbcom_csharp_wrap.c -I"../"
cl -LD ademco.obj hb_com.obj libademco_csharp_wrap.obj -o libademco.dll
csc CSharpDemo.cs -recurse:com/hb3344/ademco/*.cs
rem CSharpDemo.exe
mkdir com\hb3344\ademco
"C:\Users\Jack\Downloads\swigwin-4.0.2\swig.exe" -java -package com.hb3344.ademco -outdir com/hb3344/ademco -o libademco_java_wrap.c libademco.swig
cl -c ../ademco.c libademco_java_wrap.c -I"../" -I"%JAVA_HOME%include" -I"%JAVA_HOME%include/win32"
cl -LD ademco.obj libademco_java_wrap.obj -o ademco_java.dll
cl -c ../ademco.c ../hb_com.c libademco_java_wrap.c -I"../" -I"%JAVA_HOME%include" -I"%JAVA_HOME%include/win32"
cl -LD ademco.obj hb_com.obj libademco_java_wrap.obj -o ademco_java.dll
javac -encoding utf-8 JavaDemo.java
rem java JavaDemo
#!/bin/bash
set -e
mkdir -p linux_java
cd linux_java
cp -r ../../swig/com/ .
......
#!/bin/bash
set -e
mkdir -p mac_java
cd mac_java
cp -r ../../swig/com .
......
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