Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
A
ademco_hb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
ademco_hb
Commits
dfb828a6
Commit
dfb828a6
authored
Feb 06, 2023
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
b3052b0c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
200 additions
and
173 deletions
+200
-173
ademco.c
ademco.c
+106
-96
ademco.h
ademco.h
+60
-43
server_demo.cpp
examples/server_demo/server_demo.cpp
+9
-9
hb_com.c
hb_com.c
+14
-14
hb_com.h
hb_com.h
+11
-11
No files found.
ademco.c
View file @
dfb828a6
...
...
@@ -17,23 +17,24 @@
#include <ctype.h>
#include <assert.h>
#ifdef DEBUG
#ifdef
_
DEBUG
#define dprintf printf
#else
#define dprintf(...)
#endif
#define dline dprintf("%
d\n"
, __LINE__);
#define dline dprintf("%
s %d\n", __FILE__
, __LINE__);
#define dmsg dline; dprintf
void
ademcoPrint
(
const
uint8_t
*
buff
,
in
t
len
)
void
ademcoPrint
(
const
char
*
p
,
size_
t
len
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
if
(
isprint
(
buff
[
i
]
))
{
p
rintf
(
"%c"
,
buff
[
i
]
);
while
(
len
--
)
{
if
(
isprint
(
*
(
const
uint8_t
*
)
p
))
{
p
utchar
(
*
p
);
}
else
{
printf
(
"
\\
x%02X"
,
buff
[
i
]
);
printf
(
"
\\
x%02X"
,
*
(
const
uint8_t
*
)
p
);
}
p
++
;
}
printf
(
"
\n
"
);
}
...
...
@@ -333,7 +334,7 @@ static const uint16_t crc16Table[256] = {
0x8201
,
0x42C0
,
0x4380
,
0x8341
,
0x4100
,
0x81C1
,
0x8081
,
0x4040
,
};
uint16_t
ademcoCRC16
(
const
uint8_t
*
buff
,
in
t
len
)
uint16_t
ademcoCRC16
(
const
char
*
buff
,
size_
t
len
)
{
uint16_t
crc
=
0
;
while
(
len
--
)
{
...
...
@@ -342,7 +343,7 @@ uint16_t ademcoCRC16(const uint8_t* buff, int len)
return
crc
;
}
int
ademcoAppendDataSegment
(
uint8_t
*
buff
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
size_t
ademcoAppendDataSegment
(
char
*
buff
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
char
*
p
=
(
char
*
)
buff
;
if
(
ademcoEvent
==
EVENT_INVALID_EVENT
)
{
...
...
@@ -389,7 +390,7 @@ int ademcoAppendDataSegment(uint8_t* buff, AdemcoId ademcoId, AdemcoEvent ademco
}
}
in
t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
size_
t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
dataSegment
->
ademcoId
=
ademcoId
;
dataSegment
->
ademcoEvent
=
ademcoEvent
;
...
...
@@ -398,7 +399,7 @@ int ademcoAppendDataSegment2(AdemcoDataSegment* dataSegment, AdemcoId ademcoId,
return
dataSegment
->
raw_len
=
ademcoAppendDataSegment
(
dataSegment
->
raw
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
}
AdemcoParseResult
ademcoParseDataSegment
(
const
uint8_t
*
packet
,
in
t
packet_len
,
AdemcoDataSegment
*
dataSegment
)
AdemcoParseResult
ademcoParseDataSegment
(
const
char
*
packet
,
size_
t
packet_len
,
AdemcoDataSegment
*
dataSegment
)
{
if
(
packet_len
==
ADEMCO_PACKET_DATA_SEGMENT_EMPTY_LEN
&&
packet
[
0
]
==
'['
&&
packet
[
1
]
==
']'
)
{
memset
(
dataSegment
,
0
,
sizeof
(
*
dataSegment
));
...
...
@@ -408,7 +409,7 @@ AdemcoParseResult ademcoParseDataSegment(const uint8_t* packet, int packet_len,
}
else
if
(
packet_len
>=
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN
&&
packet
[
0
]
==
'['
&&
packet
[
packet_len
-
1
]
==
']'
)
{
// [#000000|1400 00 000]
do
{
const
uint8_t
*
p
=
packet
+
2
;
in
t
acct_len
=
packet_len
-
15
;
size_
t
acct_len
=
packet_len
-
15
;
if
(
acct_len
<
6
)
{
break
;
}
...
...
@@ -451,34 +452,13 @@ AdemcoParseResult ademcoParseDataSegment(const uint8_t* packet, int packet_len,
return
RESULT_ERROR
;
}
int
ademcoXDataConvert
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
)
{
if
(
!
xdata
)
{
return
ADEMCO_ERR
;
}
if
(
xdata
->
lenghFormat
==
xlf
)
{
return
ADEMCO_OK
;
}
int
len
=
ademcoXDataGetValidContentLen
(
xdata
);
uint8_t
raw
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
if
(
xlf
==
TWO_HEX
)
{
// convert from TWO_HEX to FOUR_DECIMAL
if
(
len
+
6
>
ADEMCO_PACKET_XDATA_MAX_LEN
)
{
return
ADEMCO_ERR
;
}
memcpy
(
raw
,
ademcoXDataGetValidContentAddr
(
xdata
),
len
);
ademcoMakeXData
(
xdata
,
FOUR_DECIMAL
,
AdemcoXDataTransform_as_is
,
raw
,
len
);
}
else
{
memcpy
(
raw
,
ademcoXDataGetValidContentAddr
(
xdata
),
len
);
ademcoMakeXData
(
xdata
,
TWO_HEX
,
AdemcoXDataTransform_as_is
,
raw
,
len
);
}
return
ADEMCO_OK
;
}
int
ademcoDataSegmentToCongwinFe100
(
uint8_t
*
fe100
,
const
AdemcoDataSegment
*
dataSegment
)
size_t
ademcoDataSegmentToCongwinFe100
(
char
*
fe100
,
const
AdemcoDataSegment
*
dataSegment
)
{
if
(
dataSegment
->
raw_len
==
ADEMCO_PACKET_DATA_SEGMENT_EMPTY_LEN
)
{
return
0
;
}
else
if
(
dataSegment
->
raw_len
>=
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN
)
{
int
ndx
=
0
;
char
*
p
=
(
char
*
)
fe100
;
char
*
p
=
fe100
;
*
p
++
=
'\n'
;
*
p
++
=
' '
;
...
...
@@ -530,15 +510,42 @@ int ademcoDataSegmentToCongwinFe100(uint8_t* fe100, const AdemcoDataSegment* dat
*
p
++
=
' '
;
*
p
++
=
'\r'
;
return
p
-
(
char
*
)
fe100
;
return
p
-
fe100
;
}
return
0
;
}
void
ademcoXDataInit
(
AdemcoXDataSegment
*
xdata
)
{
memset
(
xdata
,
0
,
sizeof
*
xdata
);
}
int
ademcoXDataConvert
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
)
{
if
(
!
xdata
)
{
return
ADEMCO_ERR
;
}
if
(
xdata
->
lenghFormat
==
xlf
)
{
return
ADEMCO_OK
;
}
size_t
len
=
ademcoXDataGetValidContentLen
(
xdata
);
uint8_t
raw
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
if
(
xlf
==
TWO_HEX
)
{
if
(
len
+
6
>
ADEMCO_PACKET_XDATA_MAX_LEN
)
{
return
ADEMCO_ERR
;
}
xdata
->
raw
[
5
+
ademcoXDataGetValidContentLen
(
xdata
)]
=
'\0'
;
len
=
ademcoHexStrToArray
(
raw
,
ademcoXDataGetValidContentAddr
(
xdata
),
0x0F
);
ademcoMakeXData
(
xdata
,
TWO_HEX
,
AdemcoXDataTransform_as_is
,
raw
,
len
);
}
else
{
memcpy
(
raw
,
ademcoXDataGetValidContentAddr
(
xdata
),
len
);
ademcoMakeXData
(
xdata
,
FOUR_DECIMAL
,
AdemcoXDataTransform_to_ascii
,
raw
,
len
);
}
return
ADEMCO_OK
;
}
#ifdef SWIG
static
#endif
const
uint8_t
*
ademcoXDataGetValidContentAddr
(
const
AdemcoXDataSegment
*
xdata
)
const
char
*
ademcoXDataGetValidContentAddr
(
const
AdemcoXDataSegment
*
xdata
)
{
if
(
xdata
->
lenghFormat
==
TWO_HEX
&&
xdata
->
raw_len
>
4
)
{
return
xdata
->
raw
+
3
;
...
...
@@ -549,7 +556,7 @@ const uint8_t* ademcoXDataGetValidContentAddr(const AdemcoXDataSegment* xdata)
}
}
int
ademcoXDataMemcmp
(
const
AdemcoXDataSegment
*
xdata
,
const
void
*
buf
,
in
t
buf_len
)
int
ademcoXDataMemcmp
(
const
AdemcoXDataSegment
*
xdata
,
const
void
*
buf
,
size_
t
buf_len
)
{
if
(
ademcoXDataGetValidContentLen
(
xdata
)
!=
buf_len
)
return
0
;
const
uint8_t
*
p
=
ademcoXDataGetValidContentAddr
(
xdata
);
...
...
@@ -557,7 +564,7 @@ int ademcoXDataMemcmp(const AdemcoXDataSegment* xdata, const void* buf, int buf_
return
memcmp
(
p
,
buf
,
buf_len
);
}
in
t
ademcoXDataGetValidContentLen
(
const
AdemcoXDataSegment
*
xdata
)
size_
t
ademcoXDataGetValidContentLen
(
const
AdemcoXDataSegment
*
xdata
)
{
if
(
xdata
->
lenghFormat
==
TWO_HEX
&&
xdata
->
raw_len
>
4
)
{
return
xdata
->
raw_len
-
4
;
...
...
@@ -568,7 +575,7 @@ int ademcoXDataGetValidContentLen(const AdemcoXDataSegment* xdata)
}
}
in
t
ademcoXDataCopy
(
AdemcoXDataSegment
*
dst
,
const
AdemcoXDataSegment
*
src
)
size_
t
ademcoXDataCopy
(
AdemcoXDataSegment
*
dst
,
const
AdemcoXDataSegment
*
src
)
{
if
(
dst
&&
src
&&
src
->
raw_len
>
0
)
{
memcpy
(
dst
,
src
,
sizeof
(
AdemcoXDataSegment
));
...
...
@@ -577,15 +584,18 @@ int ademcoXDataCopy(AdemcoXDataSegment* dst, const AdemcoXDataSegment* src)
return
0
;
}
int
ademcoMakeXData
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
,
AdemcoXDataTransform
xtr
,
const
uint8_t
*
content
,
in
t
len
)
int
ademcoMakeXData
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
,
AdemcoXDataTransform
xtr
,
const
char
*
content
,
size_
t
len
)
{
uint8_t
transformed
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
uint16_t
translen
=
len
;
char
transformed
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
size_t
translen
;
len
&=
0xFFFF
;
translen
=
len
&
0xFFFF
;
if
(
xtr
==
AdemcoXDataTransform_as_is
)
{
memcpy
(
transformed
,
content
,
len
);
}
else
{
if
(
len
*
2
<
ADEMCO_PACKET_XDATA_MAX_LEN
)
{
translen
=
ademcoHexArrayToStr
(
(
char
*
)
transformed
,
content
,
len
)
;
translen
=
ademcoHexArrayToStr
(
transformed
,
content
,
len
)
&
0xFFFF
;
}
else
{
return
ADEMCO_ERR
;
}
...
...
@@ -606,7 +616,7 @@ int ademcoMakeXData(AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, Adem
uint8_t
*
p
=
xdata
->
raw
;
*
p
++
=
'['
;
char
temp
[
5
];
snprintf
(
temp
,
sizeof
(
temp
),
"%04
d
"
,
translen
&
0xFFFF
);
snprintf
(
temp
,
sizeof
(
temp
),
"%04
zX
"
,
translen
&
0xFFFF
);
memcpy
(
p
,
temp
,
4
);
p
+=
4
;
memcpy
(
p
,
transformed
,
translen
);
...
...
@@ -619,7 +629,7 @@ int ademcoMakeXData(AdemcoXDataSegment* xdata, AdemcoXDataLengthFormat xlf, Adem
}
}
int
isAdemcoPacketId
(
const
char
*
standard
,
const
char
*
id
,
in
t
len
)
int
isAdemcoPacketId
(
const
char
*
standard
,
const
char
*
id
,
size_
t
len
)
{
return
strncmp
(
standard
,
id
,
strlen
(
standard
))
==
0
;
}
...
...
@@ -635,7 +645,7 @@ static const char* const ids[AID_COUNT] = {
ADEMCO_PACKET_ID_REG_RSP
,
};
AdemcoPacketId
getAdemcoPacketId
(
const
char
*
id
,
in
t
len
)
AdemcoPacketId
getAdemcoPacketId
(
const
char
*
id
,
size_
t
len
)
{
for
(
int
i
=
0
;
i
<
AID_COUNT
;
i
++
)
{
if
(
isAdemcoPacketId
(
ids
[
i
],
id
,
len
))
{
...
...
@@ -664,7 +674,7 @@ static void getNowTimestamp(char* buff)
tm
->
tm_mon
+
1
,
tm
->
tm_mday
,
tm
->
tm_year
+
1900
);
}
int
ademcoMakeEmptyDataPacket
(
uint8_t
*
dst_buff
,
in
t
len
,
const
char
*
id
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_t
ademcoMakeEmptyDataPacket
(
char
*
dst_buff
,
size_
t
len
,
const
char
*
id
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
uint8_t
buff
[
ADEMCO_PACKET_MAX_LEN
];
uint8_t
*
p
=
buff
;
...
...
@@ -696,10 +706,10 @@ int ademcoMakeEmptyDataPacket(uint8_t* dst_buff, int len, const char* id, uint16
*
p
++
=
ADEMCO_PACKET_SUFIX
;
char
temp
[
5
];
in
t
packet_len
=
p
-
buff
;
size_
t
packet_len
=
p
-
buff
;
// \n crc len \r
in
t
ademco_len
=
packet_len
-
1
-
4
-
4
-
1
;
snprintf
(
temp
,
5
,
"%04X"
,
ademco_len
);
size_
t
ademco_len
=
packet_len
-
1
-
4
-
4
-
1
;
snprintf
(
temp
,
5
,
"%04
z
X"
,
ademco_len
);
memcpy
(
plen
,
temp
,
4
);
uint16_t
crc
=
ademcoCRC16
(
pid
,
ademco_len
);
snprintf
(
temp
,
5
,
"%04X"
,
crc
);
...
...
@@ -714,23 +724,23 @@ int ademcoMakeEmptyDataPacket(uint8_t* dst_buff, int len, const char* id, uint16
}
}
int
ademcoMakeNullPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_t
ademcoMakeNullPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
return
ademcoMakeEmptyDataPacket
(
buff
,
len
,
ADEMCO_PACKET_ID_NULL
,
seq
,
acct
,
ademcoId
);
}
int
ademcoMakeAckPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_t
ademcoMakeAckPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
return
ademcoMakeEmptyDataPacket
(
buff
,
len
,
ADEMCO_PACKET_ID_ACK
,
seq
,
acct
,
ademcoId
);
}
int
ademcoMakeNakPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_t
ademcoMakeNakPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
return
ademcoMakeEmptyDataPacket
(
buff
,
len
,
ADEMCO_PACKET_ID_NAK
,
seq
,
acct
,
ademcoId
);
}
int
ademcoMakeHbPacket
(
uint8_t
*
dst_buff
,
int
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
size_t
ademcoMakeHbPacket
(
char
*
dst_buff
,
size_t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
{
char
buff
[
ADEMCO_PACKET_MAX_LEN
];
char
*
p
=
buff
;
...
...
@@ -755,7 +765,7 @@ int ademcoMakeHbPacket(uint8_t* dst_buff, int len, uint16_t seq, const char* acc
snprintf
(
p
,
7
,
"%06X"
,
ademcoId
);
p
+=
6
;
}
p
+=
ademcoAppendDataSegment
(
(
uint8_t
*
)
p
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
p
+=
ademcoAppendDataSegment
(
p
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
if
(
xdata
&&
xdata
->
raw_len
>
0
)
{
memcpy
(
p
,
xdata
->
raw
,
xdata
->
raw_len
);
p
+=
xdata
->
raw_len
;
...
...
@@ -765,10 +775,10 @@ int ademcoMakeHbPacket(uint8_t* dst_buff, int len, uint16_t seq, const char* acc
*
p
++
=
ADEMCO_PACKET_SUFIX
;
char
temp
[
5
];
in
t
packet_len
=
p
-
buff
;
size_
t
packet_len
=
p
-
buff
;
// \n crc len \r
in
t
ademco_len
=
packet_len
-
1
-
4
-
4
-
1
;
snprintf
(
temp
,
5
,
"%04X"
,
ademco_len
);
size_
t
ademco_len
=
packet_len
-
1
-
4
-
4
-
1
;
snprintf
(
temp
,
5
,
"%04
z
X"
,
ademco_len
);
memcpy
(
plen
,
temp
,
4
);
uint16_t
crc
=
ademcoCRC16
((
const
uint8_t
*
)
pid
,
ademco_len
);
snprintf
(
temp
,
5
,
"%04X"
,
crc
);
...
...
@@ -785,7 +795,7 @@ int ademcoMakeHbPacket(uint8_t* dst_buff, int len, uint16_t seq, const char* acc
static
void
copyAcct2AdemcoPacket
(
AdemcoPacket
*
pkt
,
const
char
*
acct
)
{
if
(
acct
)
{
in
t
len
=
strlen
(
acct
);
size_
t
len
=
strlen
(
acct
);
if
(
len
>
ADEMCO_PACKET_ACCT_MAX_LEN
)
{
len
=
ADEMCO_PACKET_ACCT_MAX_LEN
;
}
...
...
@@ -796,7 +806,7 @@ static void copyAcct2AdemcoPacket(AdemcoPacket* pkt, const char* acct)
}
}
in
t
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_
t
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
pkt
->
seq
=
seq
;
copyAcct2AdemcoPacket
(
pkt
,
acct
);
...
...
@@ -804,7 +814,7 @@ int ademcoMakeNullPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Ade
return
pkt
->
raw_len
=
ademcoMakeNullPacket
(
pkt
->
raw
,
sizeof
(
pkt
->
raw
),
seq
,
acct
,
ademcoId
);
}
in
t
ademcoMakeAckPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_
t
ademcoMakeAckPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
pkt
->
seq
=
seq
;
copyAcct2AdemcoPacket
(
pkt
,
acct
);
...
...
@@ -812,7 +822,7 @@ int ademcoMakeAckPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Adem
return
pkt
->
raw_len
=
ademcoMakeAckPacket
(
pkt
->
raw
,
sizeof
(
pkt
->
raw
),
seq
,
acct
,
ademcoId
);
}
in
t
ademcoMakeNakPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
size_
t
ademcoMakeNakPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
)
{
pkt
->
seq
=
seq
;
copyAcct2AdemcoPacket
(
pkt
,
acct
);
...
...
@@ -820,8 +830,8 @@ int ademcoMakeNakPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Adem
return
pkt
->
raw_len
=
ademcoMakeNakPacket
(
pkt
->
raw
,
sizeof
(
pkt
->
raw
),
seq
,
acct
,
ademcoId
);
}
int
ademcoMakeHbPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
size_t
ademcoMakeHbPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
{
pkt
->
seq
=
seq
;
copyAcct2AdemcoPacket
(
pkt
,
acct
);
...
...
@@ -836,11 +846,11 @@ int ademcoMakeHbPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Ademc
return
pkt
->
raw_len
=
ademcoMakeHbPacket
(
pkt
->
raw
,
sizeof
(
pkt
->
raw
),
seq
,
acct
,
ademcoId
,
ademcoEvent
,
gg
,
zone
,
xdata
);
}
AdemcoParseResult
ademcoPacketParse
(
const
uint8_t
*
buff
,
int
len
,
AdemcoPacket
*
pkt
,
in
t
*
cb_commited
)
AdemcoParseResult
ademcoPacketParse
(
const
char
*
buff
,
size_t
len
,
AdemcoPacket
*
pkt
,
size_
t
*
cb_commited
)
{
if
(
len
<
9
)
{
return
RESULT_NOT_ENOUGH
;
}
do
{
const
uint8_t
*
p
=
buff
;
const
char
*
p
=
buff
;
if
(
*
p
++
!=
ADEMCO_PACKET_PREFIX
)
{
dline
;
break
;
...
...
@@ -859,7 +869,7 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
temp
[
4
]
=
'\0'
;
pkt
->
len
=
strtoul
(
temp
,
NULL
,
16
);
p
+=
4
;
in
t
len_needed
=
9
+
pkt
->
len
+
1
;
size_
t
len_needed
=
9
+
pkt
->
len
+
1
;
if
(
len
<
len_needed
)
{
return
RESULT_NOT_ENOUGH
;
}
...
...
@@ -868,10 +878,10 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
return
RESULT_ERROR
;
}
const
uint8_t
*
pid
=
p
;
const
uint8_t
*
pcr
=
pid
+
pkt
->
len
;
const
char
*
pid
=
p
;
const
char
*
pcr
=
pid
+
pkt
->
len
;
if
(
pcr
-
buff
>
len
||
*
pcr
!=
ADEMCO_PACKET_SUFIX
)
{
if
(
pcr
>
buff
+
len
||
*
pcr
!=
ADEMCO_PACKET_SUFIX
)
{
dline
;
break
;
}
...
...
@@ -894,7 +904,7 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
if
(
pkt
->
id
==
AID_INVALID
)
{
dline
;
break
;
}
// seq
const
uint8_t
*
pseq
=
p
;
const
char
*
pseq
=
p
;
while
(
p
<
pcr
&&
*
p
!=
'R'
&&
*
p
!=
'L'
)
{
p
++
;
}
if
(
p
-
pseq
!=
4
||
(
*
p
!=
'R'
&&
*
p
!=
'L'
))
{
dline
;
break
;
}
memcpy
(
temp
,
pseq
,
4
);
temp
[
4
]
=
'\0'
;
...
...
@@ -916,14 +926,14 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
// lpref
if
(
*
p
!=
'L'
)
{
dline
;
break
;
}
while
(
p
<
pcr
&&
*
p
!=
'#'
)
{
p
++
;
}
if
(
p
>=
pcr
||
*
p
!=
'#'
)
{
break
;
}
if
(
p
>=
pcr
||
*
p
!=
'#'
)
{
dline
;
break
;
}
// only check if format is correct, ignore it's content
// pass
// #acct
const
uint8_t
*
pacct
=
++
p
;
const
char
*
pacct
=
++
p
;
while
(
p
<
pcr
&&
*
p
!=
'['
)
{
if
(
!
isalnum
(
*
p
))
{
p
=
NULL
;
break
;
}
if
(
!
isalnum
(
*
p
))
{
p
=
NULL
;
dline
;
break
;
}
p
++
;
}
if
(
p
==
NULL
||
p
>=
pcr
||
*
p
!=
'['
||
p
-
pacct
>=
ADEMCO_PACKET_ACCT_MAX_LEN
)
{
dline
;
break
;
}
...
...
@@ -931,18 +941,18 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
pkt
->
acct
[
p
-
pacct
]
=
'\0'
;
// data
const
uint8_t
*
pdata
=
p
;
const
char
*
pdata
=
p
;
while
(
p
<
pcr
&&
*
p
!=
']'
)
{
p
++
;
}
if
(
p
>=
pcr
||
*
p
!=
']'
)
{
dline
;
break
;
}
if
(
ademcoParseDataSegment
(
pdata
,
++
p
-
pdata
,
&
pkt
->
data
)
!=
RESULT_OK
)
{
dline
;
break
;
}
// *xdata
if
(
*
p
==
'['
)
{
// xdata exists
const
uint8_t
*
pxdata
=
p
++
;
const
char
*
pxdata
=
p
++
;
AdemcoXDataLengthFormat
xlf
=
FOUR_DECIMAL
;
in
t
valid_len
;
size_
t
valid_len
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
if
(
!
isxdigit
(
*
(
p
+
i
)))
{
if
(
!
isxdigit
(
*
(
uint8_t
*
)(
p
+
i
)))
{
xlf
=
TWO_HEX
;
}
}
...
...
@@ -996,10 +1006,10 @@ AdemcoParseResult ademcoPacketParse(const uint8_t* buff, int len, AdemcoPacket*
return
RESULT_ERROR
;
}
int
ademcoHiLoArrayToDecStr
(
char
*
str
,
const
uint8_t
*
arr
,
in
t
len
)
size_t
ademcoHiLoArrayToDecStr
(
char
*
str
,
const
uint8_t
*
arr
,
size_
t
len
)
{
char
*
p
=
str
;
for
(
in
t
i
=
0
;
i
<
len
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
len
;
i
++
)
{
char
c
=
(
arr
[
i
]
>>
4
)
&
0x0F
;
if
(
c
>
9
)
{
return
p
-
str
;
}
*
p
++
=
c
+
'0'
;
...
...
@@ -1010,14 +1020,14 @@ int ademcoHiLoArrayToDecStr(char* str, const uint8_t* arr, int len)
return
p
-
str
;
}
int
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
in
t
len
,
const
char
*
str
)
size_t
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
size_
t
len
,
const
char
*
str
)
{
uint8_t
*
p
=
arr
;
in
t
slen
=
str
?
strlen
(
str
)
:
0
;
char
*
p
=
arr
;
size_
t
slen
=
str
?
strlen
(
str
)
:
0
;
if
(
slen
>
len
*
2
)
{
slen
=
len
*
2
;
}
for
(
in
t
i
=
0
;
i
<
slen
;
i
+=
2
)
{
for
(
size_
t
i
=
0
;
i
<
slen
;
i
+=
2
)
{
char
hi
=
str
[
i
];
if
(
'0'
<=
hi
&&
hi
<=
'9'
)
{
if
(
i
+
1
<
slen
)
{
...
...
@@ -1036,7 +1046,7 @@ int ademcoDecStrToHiLoArray(uint8_t* arr, int len, const char* str)
break
;
}
}
while
(
p
-
arr
<
len
)
{
while
(
arr
+
len
>
p
)
{
*
p
++
=
0xFF
;
}
return
len
;
...
...
@@ -1051,11 +1061,11 @@ static uint8_t hex2char(uint8_t h) {
}
}
int
ademcoHexArrayToStr
(
char
*
str
,
const
uint8_t
*
arr
,
in
t
len
)
size_t
ademcoHexArrayToStr
(
char
*
str
,
const
uint8_t
*
arr
,
size_
t
len
)
{
uint8_t
c
=
0
;
char
*
p
=
str
;
for
(
in
t
i
=
0
;
i
<
len
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
len
;
i
++
)
{
*
p
++
=
hex2char
((
arr
[
i
]
>>
4
)
&
0x0F
);
*
p
++
=
hex2char
(
arr
[
i
]
&
0x0F
);
}
...
...
@@ -1074,13 +1084,13 @@ static uint8_t char2hex(uint8_t c) {
}
}
in
t
ademcoHexStrToArray
(
uint8_t
*
arr
,
const
char
*
str
,
uint8_t
padding
)
size_
t
ademcoHexStrToArray
(
uint8_t
*
arr
,
const
char
*
str
,
uint8_t
padding
)
{
uint8_t
*
p
=
arr
;
uint8_t
hi
=
0
,
lo
=
0
;
in
t
slen
=
str
?
strlen
(
str
)
:
0
;
size_
t
slen
=
str
?
strlen
(
str
)
:
0
;
padding
&=
0x0F
;
for
(
in
t
i
=
0
;
i
<
slen
/
2
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
slen
/
2
;
i
++
)
{
char
c
=
str
[
i
*
2
];
if
((
hi
=
char2hex
(
c
))
==
0xFF
)
{
return
0
;
...
...
@@ -1098,12 +1108,12 @@ int ademcoHexStrToArray(uint8_t* arr, const char* str, uint8_t padding)
return
p
-
arr
;
}
int
ademcoHexStrToArrayN
(
uint8_t
*
arr
,
const
char
*
str
,
in
t
len
,
uint8_t
padding
)
size_t
ademcoHexStrToArrayN
(
uint8_t
*
arr
,
const
char
*
str
,
size_
t
len
,
uint8_t
padding
)
{
uint8_t
*
p
=
arr
;
uint8_t
hi
=
0
,
lo
=
0
;
padding
&=
0x0F
;
for
(
in
t
i
=
0
;
i
<
len
/
2
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
len
/
2
;
i
++
)
{
char
c
=
str
[
i
*
2
];
if
((
hi
=
char2hex
(
c
))
==
0xFF
)
{
return
0
;
...
...
@@ -1121,12 +1131,12 @@ int ademcoHexStrToArrayN(uint8_t* arr, const char* str, int len, uint8_t padding
return
p
-
arr
;
}
int
ademcoHexStrToArrayN_allow_non_hex_str
(
uint8_t
*
arr
,
const
char
*
str
,
in
t
len
,
uint8_t
padding
)
size_t
ademcoHexStrToArrayN_allow_non_hex_str
(
uint8_t
*
arr
,
const
char
*
str
,
size_
t
len
,
uint8_t
padding
)
{
uint8_t
*
p
=
arr
;
uint8_t
hi
=
0
,
lo
=
0
;
padding
&=
0x0F
;
for
(
in
t
i
=
0
;
i
<
len
/
2
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
len
/
2
;
i
++
)
{
char
c
=
str
[
i
*
2
];
if
((
hi
=
char2hex
(
c
))
==
0xFF
)
{
hi
=
padding
;
...
...
ademco.h
View file @
dfb828a6
...
...
@@ -281,8 +281,8 @@ typedef enum AdemcoParseResult {
// 安定宝协议data段
typedef
struct
AdemcoDataSegment
{
uint8_t
raw
[
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX
];
in
t
raw_len
;
char
raw
[
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX
];
size_
t
raw_len
;
AdemcoId
ademcoId
;
AdemcoEvent
ademcoEvent
;
AdemcoGG
gg
;
...
...
@@ -301,8 +301,8 @@ typedef enum AdemcoXDataTransform {
typedef
struct
AdemcoXDataSegment
{
AdemcoXDataLengthFormat
lenghFormat
;
uint8_t
raw
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
in
t
raw_len
;
char
raw
[
ADEMCO_PACKET_XDATA_MAX_LEN
];
size_
t
raw_len
;
}
AdemcoXDataSegment
;
#define ADEMCO_PACKET_ID_NULL "\"NULL\""
...
...
@@ -335,7 +335,7 @@ typedef enum AdemcoPacketId {
typedef
struct
AdemcoPacket
{
uint16_t
crc
;
in
t
len
;
size_
t
len
;
AdemcoPacketId
id
;
uint16_t
seq
;
char
acct
[
ADEMCO_PACKET_ACCT_MAX_LEN
+
1
];
...
...
@@ -343,15 +343,19 @@ typedef struct AdemcoPacket {
AdemcoXDataSegment
xdata
;
time_t
timestamp
;
uint8_t
raw
[
ADEMCO_PACKET_MAX_LEN
];
in
t
raw_len
;
char
raw
[
ADEMCO_PACKET_MAX_LEN
];
size_
t
raw_len
;
}
AdemcoPacket
;
//////////////////////// Functions ////////////////////////
ADEMCO_EXPORT_SYMBOL
void
ademcoPrint
(
const
uint8_t
*
buff
,
int
len
);
//////////////////////// AdemcoEvent functions
//! print as HEX
ADEMCO_EXPORT_SYMBOL
void
ademcoPrint
(
const
char
*
buff
,
size_t
len
);
//////////////////////// AdemcoEvent functions ////////////////////////
//! 是否主机状态事件
ADEMCO_EXPORT_SYMBOL
int
ademcoIsMachineStatusEvent
(
AdemcoEvent
ademcoEvent
);
//! 是否主机类型事件
...
...
@@ -365,32 +369,43 @@ ADEMCO_EXPORT_SYMBOL AdemcoEvent ademcoGetExceptionEventByResumeEvent(AdemcoEven
ADEMCO_EXPORT_SYMBOL
const
char
*
ademcoEventToString
(
AdemcoEvent
ademcoEvent
);
ADEMCO_EXPORT_SYMBOL
const
char
*
ademcoEventToStringChinese
(
AdemcoEvent
ademcoEvent
);
//////////////////////// AdemcoDataSegment functions ////////////////////////
ADEMCO_EXPORT_SYMBOL
int
ademcoAppendDataSegment
(
uint8_t
*
packet
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
);
ADEMCO_EXPORT_SYMBOL
int
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
);
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
);
//! make a `DATA` packet and store to `packet`, return length
ADEMCO_EXPORT_SYMBOL
size_t
ademcoAppendDataSegment
(
char
*
packet
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
);
//! make a `DATA` packet and store to `dataSegment`, return length
ADEMCO_EXPORT_SYMBOL
size_t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
);
//! parse `DATA` packet, if ok, `dataSegment`'s members will be useful
ADEMCO_EXPORT_SYMBOL
AdemcoParseResult
ademcoParseDataSegment
(
const
char
*
packet
,
size_t
packet_len
,
AdemcoDataSegment
*
dataSegment
);
// return 0 for empty packet, CONGWIN_FE100_PACKET_LEN for success
ADEMCO_EXPORT_SYMBOL
size_t
ademcoDataSegmentToCongwinFe100
(
char
*
fe100
,
const
AdemcoDataSegment
*
dataSegment
);
//////////////////////// AdemcoXDataSegment functions ////////////////////////
// init a empty xdata
ADEMCO_EXPORT_SYMBOL
void
ademcoXDataInit
(
AdemcoXDataSegment
*
xdata
);
// return ADEMCO_OK for success, ADEMCO_ERR for failed
ADEMCO_EXPORT_SYMBOL
int
ademcoXDataConvert
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
);
#ifndef SWIG
// get valid content address of xdata (except [len])
ADEMCO_EXPORT_SYMBOL
const
uint8_t
*
ademcoXDataGetValidContentAddr
(
const
AdemcoXDataSegment
*
xdata
);
ADEMCO_EXPORT_SYMBOL
const
char
*
ademcoXDataGetValidContentAddr
(
const
AdemcoXDataSegment
*
xdata
);
#endif
// get valid content length of xdata (except [len])
ADEMCO_EXPORT_SYMBOL
in
t
ademcoXDataGetValidContentLen
(
const
AdemcoXDataSegment
*
xdata
);
ADEMCO_EXPORT_SYMBOL
size_
t
ademcoXDataGetValidContentLen
(
const
AdemcoXDataSegment
*
xdata
);
// return 0 if xdata's valid content is exactly the same as [buf, buf+buf_len)
ADEMCO_EXPORT_SYMBOL
int
ademcoXDataMemcmp
(
const
AdemcoXDataSegment
*
xdata
,
const
void
*
buf
,
in
t
buf_len
);
ADEMCO_EXPORT_SYMBOL
int
ademcoXDataMemcmp
(
const
AdemcoXDataSegment
*
xdata
,
const
void
*
buf
,
size_
t
buf_len
);
// copy xdata content from src to dst, return copied length = src.raw_len
ADEMCO_EXPORT_SYMBOL
in
t
ademcoXDataCopy
(
AdemcoXDataSegment
*
dst
,
const
AdemcoXDataSegment
*
src
);
ADEMCO_EXPORT_SYMBOL
size_
t
ademcoXDataCopy
(
AdemcoXDataSegment
*
dst
,
const
AdemcoXDataSegment
*
src
);
// return ADEMCO_OK for success, return ADEMCO_ERR for len is too long
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeXData
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
,
AdemcoXDataTransform
xtr
,
const
uint8_t
*
content
,
int
len
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeXData
(
AdemcoXDataSegment
*
xdata
,
AdemcoXDataLengthFormat
xlf
,
AdemcoXDataTransform
xtr
,
const
char
*
content
,
size_t
len
);
//////////////////////// AdemcoPacketId functions ////////////////////////
ADEMCO_EXPORT_SYMBOL
int
isAdemcoPacketId
(
const
char
*
standard
,
const
char
*
id
,
int
len
);
ADEMCO_EXPORT_SYMBOL
AdemcoPacketId
getAdemcoPacketId
(
const
char
*
id
,
int
len
);
ADEMCO_EXPORT_SYMBOL
int
isAdemcoPacketId
(
const
char
*
standard
,
const
char
*
id
,
size_t
len
);
ADEMCO_EXPORT_SYMBOL
AdemcoPacketId
getAdemcoPacketId
(
const
char
*
id
,
size_t
len
);
ADEMCO_EXPORT_SYMBOL
const
char
*
admecoPacketIdToString
(
AdemcoPacketId
id
);
/*
...
...
@@ -399,21 +414,23 @@ ADEMCO_EXPORT_SYMBOL const char* admecoPacketIdToString(AdemcoPacketId id);
* otherwise return 0
*/
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeEmptyDataPacket
(
uint8_t
*
dst_buff
,
in
t
len
,
const
char
*
id
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeNullPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeAckPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeNakPacket
(
uint8_t
*
buff
,
in
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeHbPacket
(
uint8_t
*
buff
,
int
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeEmptyDataPacket
(
char
*
dst_buff
,
size_
t
len
,
const
char
*
id
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNullPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeAckPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNakPacket
(
char
*
buff
,
size_
t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeHbPacket
(
char
*
buff
,
size_t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
);
// like upper funcs, store buff and len to pkt->raw, pkt->raw_len
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeAckPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeNakPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
int
ademcoMakeHbPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeAckPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNakPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeHbPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
);
//! parse a ademco packet, if everything is OK, cb_commited is the packet length
ADEMCO_EXPORT_SYMBOL
AdemcoParseResult
ademcoPacketParse
(
const
char
*
buff
,
size_t
len
,
AdemcoPacket
*
pkt
,
size_t
*
cb_commited
);
ADEMCO_EXPORT_SYMBOL
AdemcoParseResult
ademcoPacketParse
(
const
uint8_t
*
buff
,
int
len
,
AdemcoPacket
*
pkt
,
int
*
cb_commited
);
/* CRC16 implementation according to ARC
* Name : CRC-16/ARC
...
...
@@ -426,7 +443,7 @@ ADEMCO_EXPORT_SYMBOL AdemcoParseResult ademcoPacketParse(const uint8_t* buff, in
* Xor constant to output CRC : 0x0000
* Output for "123456789" : 0xBB3D
*/
ADEMCO_EXPORT_SYMBOL
uint16_t
ademcoCRC16
(
const
uint8_t
*
buff
,
in
t
len
);
ADEMCO_EXPORT_SYMBOL
uint16_t
ademcoCRC16
(
const
char
*
buff
,
size_
t
len
);
// 将一串以高低字节表示的十六进制数组转换为10进制数字符串
// 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则停止
...
...
@@ -434,17 +451,17 @@ ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const uint8_t* buff, int len);
// 注意:函数不会在str末尾补 null terminator
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
ADEMCO_EXPORT_SYMBOL
int
ademcoHiLoArrayToDecStr
(
char
*
str
,
const
uint8_t
*
arr
,
in
t
len
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHiLoArrayToDecStr
(
char
*
str
,
const
uint8_t
*
arr
,
size_
t
len
);
// 将一个10进制数字符串转为高低字节表示的数组,节省空间
// str应只包含'0'~'9',否则失败返回0
// str长度若大于len * 2,str[len
*
]及之后的内容将被舍弃以避免溢出
// str长度若大于len * 2,str[len]及之后的内容将被舍弃以避免溢出
// 转换后的长度若不满len,则以0xF补满。
// 示例:输入字符串"123ABC",返回0
// 示例:输入字符串 "18240888101", len=9, 则arr内容为 0x18 0x24 0x08 0x88 0x10 0x1f 0xff 0xff 0xff, return 9
// 示例:输入字符串 "12345678901234567890", len=9, 则arr内容为 0x1
8 0x24 0x08 0x88 0x10 0x1f 0xff 0xff 0xff
, return 9
// 示例:输入字符串 "12345678901234567890", len=9, 则arr内容为 0x1
2 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78
, return 9
// 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL
int
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
in
t
len
,
const
char
*
str
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
size_
t
len
,
const
char
*
str
);
// 将一串字节流转换为可打印形式
// 返回str长度(len * 2)
...
...
@@ -452,7 +469,7 @@ ADEMCO_EXPORT_SYMBOL int ademcoDecStrToHiLoArray(uint8_t* arr, int len, const ch
// 注意:函数不会在str末尾补 null terminator
// 示例:输入 arr=[0xEB 0xBA 0x3F], len=3, 则str = "EBBA3F",返回6
// 示例:输入 ary="123", len=3, 则str = "313233",返回6
ADEMCO_EXPORT_SYMBOL
int
ademcoHexArrayToStr
(
char
*
str
,
const
uint8_t
*
arr
,
in
t
len
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHexArrayToStr
(
char
*
str
,
const
uint8_t
*
arr
,
size_
t
len
);
// 将一串字符串(内容为'0'~'9', 'A'~'F', 'a' ~'f')转为字节流
// 若strlen(str)为奇数,以padding补足arr, padding 应 <= 0x0F
...
...
@@ -461,17 +478,17 @@ ADEMCO_EXPORT_SYMBOL int ademcoHexArrayToStr(char* str, const uint8_t* arr, int
// 示例:输入字符串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
in
t
ademcoHexStrToArray
(
uint8_t
*
arr
,
const
char
*
str
,
uint8_t
padding
);
ADEMCO_EXPORT_SYMBOL
size_
t
ademcoHexStrToArray
(
uint8_t
*
arr
,
const
char
*
str
,
uint8_t
padding
);
// 功能同ademcoHexStrToArray
// 若strlen(str) > len, str[len]及之后的内容将被舍弃以避免溢出
// 示例:输入字符串str="ABCDE", len = 4 padding = 0x0F, 输出arr=[0xAB, 0xCD], return 2
ADEMCO_EXPORT_SYMBOL
int
ademcoHexStrToArrayN
(
uint8_t
*
arr
,
const
char
*
str
,
in
t
len
,
uint8_t
padding
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHexStrToArrayN
(
uint8_t
*
arr
,
const
char
*
str
,
size_
t
len
,
uint8_t
padding
);
// 同ademcoHexStrToArrayN,但允许str包含非hex字符,即'0'~'9','a'~'f','A'~'F'之外的内容,以 padding 替换
// 示例:str="AB\xFFD", len=4, padding=0x0F, 则arr=[ 0xAB, 0xFD ], return 2
// 示例:str="AB\xFFD", len=4, padding=0x0F, 则
arr=[ 0xAB, 0xFD ], return 2
// 网线主机 0d 00 命令,接警中心账号部分,有可能是这种
ADEMCO_EXPORT_SYMBOL
int
ademcoHexStrToArrayN_allow_non_hex_str
(
uint8_t
*
arr
,
const
char
*
str
,
in
t
len
,
uint8_t
padding
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHexStrToArrayN_allow_non_hex_str
(
uint8_t
*
arr
,
const
char
*
str
,
size_
t
len
,
uint8_t
padding
);
#ifdef __cplusplus
}
...
...
examples/server_demo/server_demo.cpp
View file @
dfb828a6
...
...
@@ -45,7 +45,7 @@ struct Buffer
{
size_t
rpos
;
size_t
wpos
;
uint8_t
buff
[
BUFF_SIZE
];
char
buff
[
BUFF_SIZE
];
Buffer
()
{
clear
();
}
void
clear
()
{
memset
(
this
,
0
,
sizeof
(
Buffer
));
}
...
...
@@ -139,7 +139,7 @@ int main(int argc, char** argv)
};
auto
do_handle
=
[]()
->
AdemcoParseResult
{
AdemcoPacket
pkt
;
in
t
cb
=
0
;
AdemcoPacket
pkt
;
size_
t
cb
=
0
;
AdemcoParseResult
result
=
ademcoPacketParse
(
clientBuffer
.
buff
+
clientBuffer
.
rpos
,
clientBuffer
.
wpos
-
clientBuffer
.
rpos
,
&
pkt
,
...
...
@@ -158,8 +158,8 @@ int main(int argc, char** argv)
case
AID_NULL
:
// reply ack
{
uint8_t
ack
[
1024
];
int
len
=
ademcoMakeAckPacket
(
(
uint8_t
*
)
ack
,
sizeof
(
ack
),
pkt
.
seq
,
pkt
.
acct
,
0
);
char
ack
[
1024
];
int
len
=
ademcoMakeAckPacket
(
ack
,
sizeof
(
ack
),
pkt
.
seq
,
pkt
.
acct
,
0
);
printf
(
"S:"
);
ademcoPrint
(
ack
,
len
);
send
(
clientSock
,
(
const
char
*
)
ack
,
len
,
0
);
break
;
...
...
@@ -174,8 +174,8 @@ int main(int argc, char** argv)
// reply ack
{
uint8_t
ack
[
1024
];
int
len
=
ademcoMakeAckPacket
(
(
uint8_t
*
)
ack
,
sizeof
(
ack
),
pkt
.
seq
,
pkt
.
acct
,
0
);
char
ack
[
1024
];
int
len
=
ademcoMakeAckPacket
(
ack
,
sizeof
(
ack
),
pkt
.
seq
,
pkt
.
acct
,
0
);
printf
(
"S:"
);
ademcoPrint
(
ack
,
len
);
send
(
clientSock
,
(
const
char
*
)
ack
,
len
,
0
);
}
...
...
@@ -218,7 +218,7 @@ int main(int argc, char** argv)
int
bRead
=
FD_ISSET
(
clientSock
,
&
fd_read
);
if
(
!
bRead
)
{
return
;
}
uint8_t
*
temp
=
clientBuffer
.
buff
+
clientBuffer
.
wpos
;
char
*
temp
=
clientBuffer
.
buff
+
clientBuffer
.
wpos
;
size_t
dwLenToRead
=
BUFF_SIZE
-
clientBuffer
.
wpos
;
int
bytes_transfered
=
recv
(
clientSock
,
(
char
*
)
temp
,
(
int
)
dwLenToRead
,
0
);
...
...
@@ -268,11 +268,11 @@ int main(int argc, char** argv)
if
(
clientSock
!=
INVALID_SOCKET
&&
!
evntsWaiting4Send
.
empty
())
{
std
::
lock_guard
<
std
::
mutex
>
lg
(
mutex
);
uint8_t
buf
[
1024
];
char
buf
[
1024
];
for
(
auto
e
:
evntsWaiting4Send
)
{
if
(
e
==
EVENT_DISARM
)
{
AdemcoXDataSegment
xdata
;
ademcoMakeXData
(
&
xdata
,
TWO_HEX
,
AdemcoXDataTransform
::
AdemcoXDataTransform_as_is
,
(
const
uint8_t
*
)
pwd
,
6
);
ademcoMakeXData
(
&
xdata
,
TWO_HEX
,
AdemcoXDataTransform
::
AdemcoXDataTransform_as_is
,
pwd
,
6
);
int
len
=
ademcoMakeHbPacket
(
buf
,
sizeof
(
buf
),
1
,
clientAcct
.
c_str
(),
clientAdemcoId
,
e
,
0
,
0
,
&
xdata
);
printf
(
"S:"
);
ademcoPrint
(
buf
,
len
);
send
(
clientSock
,
(
const
char
*
)
buf
,
len
,
0
);
...
...
hb_com.c
View file @
dfb828a6
...
...
@@ -467,7 +467,7 @@ const char* hbGetZoneFormatString(HbMachineType type)
if
(
10
<
zone
&&
zone
<
100
)
{
return
"%02d"
;
}
else
if
(
zone
<
1000
)
{
return
"%03d"
;
}
else
{
return
"%d"
;
}
}
void
hbSum
(
uint8_t
*
data
,
in
t
len
)
void
hbSum
(
uint8_t
*
data
,
size_
t
len
)
{
uint8_t
sum
=
0
;
uint8_t
*
p
=
data
;
...
...
@@ -477,7 +477,7 @@ void hbSum(uint8_t* data, int len)
*
p
=
sum
;
}
int
hbCheckSum
(
const
uint8_t
*
data
,
in
t
len
)
int
hbCheckSum
(
const
uint8_t
*
data
,
size_
t
len
)
{
uint8_t
sum
=
0
;
const
uint8_t
*
p
=
data
;
...
...
@@ -489,11 +489,11 @@ int hbCheckSum(const uint8_t* data, int len)
#define copy_data_to_com \
if (cd) { \
cd->len = len; \
memcpy(cd->data, data, len); \
cd->len = len
& 0xFF
; \
memcpy(cd->data, data, len
& 0xFF
); \
}
HbComRequestType
hbComParseRequest
(
const
uint8_t
*
data
,
in
t
len
,
HbComData
*
cd
)
HbComRequestType
hbComParseRequest
(
const
uint8_t
*
data
,
size_
t
len
,
HbComData
*
cd
)
{
do
{
if
(
len
<
5
)
{
break
;
}
...
...
@@ -614,7 +614,7 @@ ADEMCO_EXPORT_SYMBOL HbComRequestType hbComParseXDataRequest(const AdemcoXDataSe
return
hbComParseRequest
(
ademcoXDataGetValidContentAddr
(
xdata
),
ademcoXDataGetValidContentLen
(
xdata
),
cd
);
}
HbComResponseType
hbComParseResponse
(
const
uint8_t
*
data
,
in
t
len
,
HbComData
*
cd
)
HbComResponseType
hbComParseResponse
(
const
uint8_t
*
data
,
size_
t
len
,
HbComData
*
cd
)
{
do
{
if
(
len
<
7
)
{
break
;
}
// 所有的 response ,长度最小为 7
...
...
@@ -869,18 +869,18 @@ void hbComMakeRespA0_getMachineStatus(HbComData* data, HbMachineStatus status, H
hbSum
(
data
->
data
,
data
->
len
);
}
void
hbComMakeRespA2_getMachineZones
(
HbComData
*
data
,
in
t
count
,
AdemcoZone
*
zones
,
HbZoneProperty
*
props
,
HbComResp_A2_p1
p1
)
void
hbComMakeRespA2_getMachineZones
(
HbComData
*
data
,
size_
t
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
;
data
->
data
[
3
]
=
(
HbComResp_A2_len_min
+
count
*
2
)
&
0xFF
;
uint8_t
*
p
=
data
->
data
+
6
;
for
(
in
t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_
t
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
;
data
->
len
=
(
++
p
-
data
->
data
)
&
0xFF
;
hbSum
(
data
->
data
,
data
->
len
);
}
...
...
@@ -929,14 +929,14 @@ void hbComMakeRespAB_modifyMachineZoneLostConfig(HbComData* data, AdemcoZone zon
hbSum
(
data
->
data
,
data
->
len
);
}
void
hbComMakeRespAD_getMachineZoneLostConfig
(
HbComData
*
data
,
HbComResp_AD_p1
p1
,
in
t
count
,
AdemcoZone
*
zones
,
HbComResp_AD_p2
p2
)
void
hbComMakeRespAD_getMachineZoneLostConfig
(
HbComData
*
data
,
HbComResp_AD_p1
p1
,
size_
t
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
[
3
]
=
(
HbComResp_AD_len_min
+
(
p1
==
HbComResp_AD_p1_single
?
count
:
count
*
2
))
&
0xFF
;
data
->
data
[
6
]
=
p1
;
uint8_t
*
p
=
data
->
data
+
7
;
for
(
in
t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_
t
i
=
0
;
i
<
count
;
i
++
)
{
if
(
p1
==
HbComResp_AD_p1_single
)
{
*
p
++
=
zones
[
i
]
&
0xFF
;
}
else
{
...
...
@@ -945,7 +945,7 @@ void hbComMakeRespAD_getMachineZoneLostConfig(HbComData* data, HbComResp_AD_p1 p
}
}
*
p
++
=
(
count
>
0
)
?
p2
:
HbComResp_AD_p2_nomore
;
data
->
len
=
++
p
-
data
->
data
;
data
->
len
=
(
++
p
-
data
->
data
)
&
0xFF
;
hbSum
(
data
->
data
,
data
->
len
);
}
...
...
hb_com.h
View file @
dfb828a6
...
...
@@ -130,7 +130,7 @@ typedef union HbMachineTimer {
// 串口透传数据
typedef
struct
HbComData
{
uint8_t
data
[
HB_COM_DATA_MAX_LEN
];
in
t
len
;
uint8_
t
len
;
}
HbComData
;
// 发给主机
...
...
@@ -192,7 +192,7 @@ typedef enum HbComResp_A2_p1 {
#define HbComResp_A2_head "\xEB\xBA\x3F\x08\xCC\xA2"
typedef
struct
HbComResp_A2_Iter
{
HbComData
com
;
in
t
i
,
total
;
uint8_
t
i
,
total
;
HbComResp_A2_p1
p1
;
}
HbComResp_A2_Iter
;
...
...
@@ -222,9 +222,9 @@ typedef enum HbComReq_A3_p3 {
#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_ok
=
0x01
,
//! 成功
HbComResp_A4_p3_dup
=
0x02
,
//! 失败--重码
HbComResp_A4_p3_ne
=
0x03
,
//! 失败--防区未对码 not exists
}
HbComResp_A4_p3
;
//! 获取主机定时器 EB AB 3F A5 7A
...
...
@@ -397,13 +397,13 @@ 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
,
in
t
len
);
ADEMCO_EXPORT_SYMBOL
void
hbSum
(
uint8_t
*
data
,
size_
t
len
);
// 校验和是否正确, return 0 for incorrect, otherwise correct
ADEMCO_EXPORT_SYMBOL
int
hbCheckSum
(
const
uint8_t
*
data
,
in
t
len
);
ADEMCO_EXPORT_SYMBOL
int
hbCheckSum
(
const
uint8_t
*
data
,
size_
t
len
);
ADEMCO_EXPORT_SYMBOL
HbComRequestType
hbComParseRequest
(
const
uint8_t
*
buff
,
in
t
len
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
HbComRequestType
hbComParseRequest
(
const
uint8_t
*
buff
,
size_
t
len
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
HbComRequestType
hbComParseXDataRequest
(
const
AdemcoXDataSegment
*
xdata
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
HbComResponseType
hbComParseResponse
(
const
uint8_t
*
buff
,
in
t
len
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
HbComResponseType
hbComParseResponse
(
const
uint8_t
*
buff
,
size_
t
len
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
HbComResponseType
hbComParseXDataResponse
(
const
AdemcoXDataSegment
*
xdata
,
HbComData
*
cd
);
ADEMCO_EXPORT_SYMBOL
void
hbComMakeReqA0_getMachineStatus
(
HbComData
*
data
);
...
...
@@ -429,7 +429,7 @@ ADEMCO_EXPORT_SYMBOL HbComResp_A2_p1 hbComResp_A2_Iter_next(HbComResp_A2_Iter* i
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
,
in
t
count
,
AdemcoZone
*
zones
,
HbZoneProperty
*
props
,
HbComResp_A2_p1
p1
);
ADEMCO_EXPORT_SYMBOL
void
hbComMakeRespA2_getMachineZones
(
HbComData
*
data
,
size_
t
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
);
...
...
@@ -440,7 +440,7 @@ ADEMCO_EXPORT_SYMBOL void hbComMakeRespA8_reject(HbComData* data);
// 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
,
in
t
count
,
AdemcoZone
*
zones
,
HbComResp_AD_p2
p2
);
ADEMCO_EXPORT_SYMBOL
void
hbComMakeRespAD_getMachineZoneLostConfig
(
HbComData
*
data
,
HbComResp_AD_p1
p1
,
size_
t
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment