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
6a75e9e7
Commit
6a75e9e7
authored
Nov 20, 2023
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
parse error
parent
1b5069a4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
121 additions
and
34 deletions
+121
-34
ademco.c
ademco.c
+91
-23
ademco.h
ademco.h
+21
-3
hb_com.c
hb_com.c
+9
-8
No files found.
ademco.c
View file @
6a75e9e7
...
...
@@ -437,8 +437,9 @@ size_t ademcoAppendDataSegment2(AdemcoDataSegment* dataSegment, const char* acct
ademcoEvent
,
gg
,
zone
);
}
AdemcoParseResult
ademcoParseDataSegment
(
const
ademco_char_t
*
packet
,
size_t
packet_len
,
AdemcoDataSegment
*
dataSegment
)
{
AdemcoDataSegment
*
dataSegment
,
AdemcoParseError
*
err
)
{
if
(
packet_len
==
ADEMCO_PACKET_DATA_SEGMENT_EMPTY_LEN
&&
packet
[
0
]
==
'['
&&
packet
[
1
]
==
']'
)
{
memset
(
dataSegment
,
0
,
sizeof
(
*
dataSegment
));
...
...
@@ -451,8 +452,10 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
do
{
const
char
*
p
=
packet
+
2
;
size_t
acct_len
=
packet_len
-
15
;
if
(
acct_len
<
6
)
if
(
acct_len
<
6
)
{
ADEMCO_FILL_PARSE_ERROR
(
err
,
"acct_len < 6"
);
break
;
}
char
temp
[
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX
]
=
{
0
};
strncpy
(
temp
,
(
const
char
*
)
p
,
acct_len
);
...
...
@@ -460,13 +463,19 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
dataSegment
->
ademcoId
=
(
AdemcoId
)
strtoul
(
temp
,
NULL
,
16
);
p
+=
acct_len
;
if
(
*
p
++
!=
'|'
)
{
break
;
}
if
(
*
p
++
!=
'|'
)
{
ADEMCO_FILL_PARSE_ERROR
(
err
,
"*p++ != '|'"
);
break
;
}
strncpy
(
temp
,
(
const
char
*
)
p
,
4
);
temp
[
4
]
=
'\0'
;
dataSegment
->
ademcoEvent
=
(
AdemcoEvent
)(
atoi
(
temp
));
p
+=
4
;
if
(
*
p
++
!=
' '
)
{
break
;
}
if
(
*
p
++
!=
' '
)
{
ADEMCO_FILL_PARSE_ERROR
(
err
,
"*p++ != ' '"
);
break
;
}
if
(
*
p
==
'E'
&&
*
(
p
+
1
)
==
'E'
)
{
dataSegment
->
gg
=
0xEE
;
}
else
if
(
*
p
==
'C'
&&
*
(
p
+
1
)
==
'C'
)
{
...
...
@@ -476,7 +485,10 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
}
p
+=
2
;
if
(
*
p
++
!=
' '
)
{
break
;
}
if
(
*
p
++
!=
' '
)
{
ADEMCO_FILL_PARSE_ERROR
(
err
,
"*p++ != ' '"
);
break
;
}
strncpy
(
temp
,
(
const
char
*
)
p
,
3
);
temp
[
3
]
=
'\0'
;
dataSegment
->
zone
=
atoi
(
temp
);
...
...
@@ -489,6 +501,7 @@ AdemcoParseResult ademcoParseDataSegment(const ademco_char_t* packet, size_t pac
}
while
(
0
);
}
ADEMCO_FILL_PARSE_ERROR
(
err
,
"dig in source code for more info"
);
return
RESULT_ERROR
;
}
...
...
@@ -874,7 +887,6 @@ size_t ademcoMakeHbPacket(ademco_char_t* dst_buff, size_t len, uint16_t seq, con
return
0
;
}
size_t
ademcoMakeAdmPacket
(
ademco_char_t
*
dst_buff
,
size_t
len
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
{
char
buff
[
ADEMCO_PACKET_MAX_LEN
];
...
...
@@ -995,12 +1007,15 @@ size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, A
}
AdemcoParseResult
ademcoPacketParse
(
const
ademco_char_t
*
buff
,
size_t
len
,
AdemcoPacket
*
pkt
,
size_t
*
cb_commited
)
{
AdemcoPacket
*
pkt
,
size_t
*
cb_commited
,
AdemcoParseError
*
err
)
{
if
(
len
<
9
)
{
return
RESULT_NOT_ENOUGH
;
}
do
{
const
char
*
p
=
buff
;
if
(
*
p
++
!=
ADEMCO_PACKET_PREFIX
)
if
(
*
p
++
!=
ADEMCO_PACKET_PREFIX
)
{
ADEMCO_FILL_PARSE_ERROR
(
err
,
"*p++ != ADEMCO_PACKET_PREFIX"
);
break
;
}
char
temp
[
5
];
...
...
@@ -1020,6 +1035,7 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
return
RESULT_NOT_ENOUGH
;
if
(
len_needed
>=
ADEMCO_PACKET_MAX_LEN
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"len_needed >= ADEMCO_PACKET_MAX_LEN"
);
return
RESULT_ERROR
;
}
...
...
@@ -1028,30 +1044,45 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
if
(
pcr
>
buff
+
len
||
*
pcr
!=
ADEMCO_PACKET_SUFIX
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"pcr > buff + len || *pcr != ADEMCO_PACKET_SUFIX"
);
break
;
}
pkt
->
crc
=
ademcoCRC16
(
pid
,
pkt
->
len
);
if
(
pkt
->
crc
!=
crc
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"pkt->crc != crc"
);
break
;
}
// id
if
(
*
pid
!=
'\"'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"*pid != '
\"
'"
);
break
;
}
p
=
pid
+
1
;
while
(
p
<
pcr
&&
*
p
!=
'\"'
)
{
p
++
;
}
if
(
p
>=
pcr
||
*
p
!=
'\"'
)
{
dline
;
break
;
}
if
(
p
>=
pcr
||
*
p
!=
'\"'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"p >= pcr || *p != '
\"
'"
);
break
;
}
pkt
->
id
=
getAdemcoPacketId
((
const
char
*
)
pid
,
++
p
-
pid
);
if
(
pkt
->
id
==
AID_INVALID
)
{
dline
;
break
;
}
if
(
pkt
->
id
==
AID_INVALID
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"pkt->id == AID_INVALID"
);
break
;
}
// seq
const
char
*
pseq
=
p
;
while
(
p
<
pcr
&&
*
p
!=
'R'
&&
*
p
!=
'L'
)
{
p
++
;
}
if
(
p
-
pseq
!=
4
||
(
*
p
!=
'R'
&&
*
p
!=
'L'
))
{
dline
;
break
;
}
if
(
p
-
pseq
!=
4
||
(
*
p
!=
'R'
&&
*
p
!=
'L'
))
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"p - pseq != 4 || (*p != 'R' && *p != 'L')"
);
break
;
}
memcpy
(
temp
,
pseq
,
4
);
temp
[
4
]
=
'\0'
;
pkt
->
seq
=
strtoul
(
temp
,
NULL
,
10
)
&
0xFFFF
;
if
(
pkt
->
seq
>=
10000
)
{
pkt
->
seq
=
0
;
}
...
...
@@ -1060,32 +1091,53 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
if
(
*
p
==
'R'
)
{
// rrcvr exists
//const char* prcvr = p;
while
(
p
<
pcr
&&
*
p
!=
'L'
&&
*
p
!=
'#'
)
{
p
++
;
}
if
(
p
>=
pcr
||
(
*
p
!=
'L'
&&
*
p
!=
'#'
))
{
dline
;
break
;
}
if
(
p
>=
pcr
||
(
*
p
!=
'L'
&&
*
p
!=
'#'
))
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"p >= pcr || (*p != 'L' && *p != '#')"
);
break
;
}
// only check if format is correct, ignore it's content
}
else
if
(
*
p
==
'L'
)
{
// rrcvr not exits
// pass
}
else
{
dline
;
break
;
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"both LPREF and RRCVR not found"
);
break
;
}
// lpref
if
(
*
p
!=
'L'
)
{
dline
;
break
;
}
if
(
*
p
!=
'L'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"LPREF not found"
);
break
;
}
while
(
p
<
pcr
&&
*
p
!=
'#'
)
{
p
++
;
}
if
(
p
>=
pcr
||
*
p
!=
'#'
)
{
dline
;
break
;
}
// only check if format is correct, ignore it's content
// pass
if
(
p
>=
pcr
||
*
p
!=
'#'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"# not found"
);
break
;
}
// lpref passed
// #acct
const
char
*
pacct
=
++
p
;
while
(
p
<
pcr
&&
*
p
!=
'['
)
{
if
(
!
isxdigit
(
*
p
))
{
p
=
NULL
;
dline
;
break
;
}
if
(
!
isxdigit
(
*
p
))
{
p
=
NULL
;
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"acct contains non-hex characters"
);
break
;
}
p
++
;
}
if
(
p
==
NULL
||
p
>=
pcr
||
*
p
!=
'['
||
p
-
pacct
>=
ADEMCO_PACKET_ACCT_MAX_LEN
)
{
dline
;
break
;
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"data's [ not found"
);
break
;
}
strncpy
(
pkt
->
acct
,
(
const
char
*
)
pacct
,
p
-
pacct
);
pkt
->
acct
[
p
-
pacct
]
=
'\0'
;
...
...
@@ -1093,8 +1145,12 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
// data
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
;
}
if
(
p
>=
pcr
||
*
p
!=
']'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"data's ] not found"
);
break
;
}
if
(
ademcoParseDataSegment
(
pdata
,
++
p
-
pdata
,
&
pkt
->
data
,
err
)
!=
RESULT_OK
)
{
dline
;
break
;
}
// *xdata
if
(
*
p
==
'['
)
{
// xdata exists
...
...
@@ -1114,7 +1170,11 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
p
+=
2
+
valid_len
;
}
if
(
p
>=
pcr
||
*
p
!=
']'
||
*
(
p
+
1
)
!=
'_'
)
{
dline
;
break
;
}
if
(
p
>=
pcr
||
*
p
!=
']'
||
*
(
p
+
1
)
!=
'_'
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"xdata's ] not found or next char is not _"
);
break
;
}
pkt
->
xdata
.
lenghFormat
=
xlf
;
pkt
->
xdata
.
raw_len
=
++
p
-
pxdata
;
memcpy
(
pkt
->
xdata
.
raw
,
pxdata
,
pkt
->
xdata
.
raw_len
);
...
...
@@ -1123,7 +1183,11 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
}
// timestamp
if
(
pcr
-
p
!=
ADEMCO_PACKET_TIMESTAMP_LEN
)
{
dline
;
break
;
}
if
(
pcr
-
p
!=
ADEMCO_PACKET_TIMESTAMP_LEN
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"timestamp length not correct"
);
break
;
}
{
struct
tm
tm
;
int
ret
=
sscanf
((
const
char
*
)
p
,
"_%02d:%02d:%02d,%02d-%02d-%04d"
,
...
...
@@ -1143,7 +1207,11 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len,
p
+=
ADEMCO_PACKET_TIMESTAMP_LEN
;
}
if
(
p
++
!=
pcr
)
{
dline
;
break
;
}
if
(
p
++
!=
pcr
)
{
dline
;
ADEMCO_FILL_PARSE_ERROR
(
err
,
"packet length not correct"
);
break
;
}
pkt
->
raw_len
=
*
cb_commited
=
p
-
buff
;
if
(
pkt
->
raw
!=
buff
)
memcpy
(
pkt
->
raw
,
buff
,
pkt
->
raw_len
);
...
...
ademco.h
View file @
6a75e9e7
...
...
@@ -288,6 +288,20 @@ typedef enum AdemcoParseResult {
RESULT_ERROR
,
//! 解析到错误的数据,应当丢弃该数据包
}
AdemcoParseResult
;
// 安定宝协议解析错误信息
typedef
struct
AdemcoParseError
{
int
line
;
const
char
*
msg
;
// user do not free
}
AdemcoParseError
;
#define ADEMCO_FILL_PARSE_ERROR(err, msg_) \
do { \
if (err) { \
err->line = __LINE__; \
err->msg = (msg_); \
} \
} while (0);
// 安定宝协议data段
typedef
struct
AdemcoDataSegment
{
ademco_char_t
raw
[
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN_MAX
];
...
...
@@ -400,9 +414,11 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoAppendDataSegment2(AdemcoDataSegment* dataSegm
AdemcoZone
zone
);
//! parse `DATA` packet, if ok, `dataSegment`'s members will be useful
//! err can be NULL; caller should only check err on got RESULT_ERROR
ADEMCO_EXPORT_SYMBOL
AdemcoParseResult
ademcoParseDataSegment
(
const
ademco_char_t
*
packet
,
size_t
packet_len
,
AdemcoDataSegment
*
dataSegment
);
AdemcoDataSegment
*
dataSegment
,
AdemcoParseError
*
err
);
// return 0 for empty packet, CONGWIN_FE100_PACKET_LEN for success
ADEMCO_EXPORT_SYMBOL
size_t
ademcoDataSegmentToCongwinFe100
(
ademco_char_t
*
fe100
,
size_t
fe100_len
,
...
...
@@ -469,7 +485,7 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket(ademco_char_t* buff, size_t len,
const
AdemcoXDataSegment
*
xdata
);
// like upper funcs, store buff and len to pkt->raw, pkt->raw_len
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeNullPacket2
(
AdemcoPacket
*
pkt
,
uint16_t
seq
,
const
char
*
acct
,
AdemcoId
ademcoId
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoMakeAckPacket2
(
AdemcoPacket
*
pkt
,
...
...
@@ -489,8 +505,10 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoMakeAdmPacket2(AdemcoPacket* pkt,
const
AdemcoXDataSegment
*
xdata
);
//! parse a ademco packet, if everything is OK, cb_commited is the packet length
//! err can be NULL; caller should only check err on got RESULT_ERROR
ADEMCO_EXPORT_SYMBOL
AdemcoParseResult
ademcoPacketParse
(
const
ademco_char_t
*
buff
,
size_t
len
,
AdemcoPacket
*
pkt
,
size_t
*
cb_commited
);
AdemcoPacket
*
pkt
,
size_t
*
cb_commited
,
AdemcoParseError
*
err
);
/* CRC16 implementation according to ARC
* Name : CRC-16/ARC
...
...
hb_com.c
View file @
6a75e9e7
...
...
@@ -145,14 +145,15 @@ int hbMachineCanHalfArm(HbMachineType type) {
}
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
;
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
||
type
==
HMT_WIFI2
;
}
int
hbMachineCanReportBySMS
(
HbMachineType
type
)
{
...
...
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