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
f5cb7bcf
Commit
f5cb7bcf
authored
Apr 03, 2023
by
captainwong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
兼容WiFi主机的MAC地址账号
parent
06734ec6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
122 additions
and
38 deletions
+122
-38
ademco.c
ademco.c
+92
-28
ademco.h
ademco.h
+22
-2
README.md
docs/README.md
+8
-8
No files found.
ademco.c
View file @
f5cb7bcf
...
...
@@ -20,6 +20,27 @@
#define dline dprintf("%s %d\n", __FILE__, __LINE__);
#define dmsg dline; dprintf
static
uint8_t
hex2char
(
uint8_t
h
)
{
h
&=
0x0F
;
if
(
h
>
9
)
return
'A'
+
h
-
10
;
else
return
'0'
+
h
;
}
static
uint8_t
char2hex
(
uint8_t
c
)
{
if
(
'0'
<=
c
&&
c
<=
'9'
)
return
c
-
'0'
;
else
if
(
'A'
<=
c
&&
c
<=
'F'
)
return
c
-
'A'
+
10
;
else
if
(
'a'
<=
c
&&
c
<=
'f'
)
return
c
-
'a'
+
10
;
else
return
0xFF
;
}
void
ademcoPrint
(
const
ademco_char_t
*
p
,
size_t
len
)
{
while
(
len
--
)
{
if
(
isprint
(
*
(
const
uint8_t
*
)
p
))
...
...
@@ -336,7 +357,7 @@ uint16_t ademcoCRC16(const ademco_char_t* buff, size_t len) {
return
crc
;
}
size_t
ademcoAppendDataSegment
(
ademco_char_t
*
buff
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
size_t
ademcoAppendDataSegment
(
ademco_char_t
*
buff
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
char
*
p
=
(
char
*
)
buff
;
if
(
ademcoEvent
==
EVENT_INVALID_EVENT
)
{
*
p
++
=
'['
;
...
...
@@ -346,8 +367,12 @@ size_t ademcoAppendDataSegment(ademco_char_t* buff, AdemcoId ademcoId, AdemcoEve
*
p
++
=
'['
;
*
p
++
=
'#'
;
snprintf
(
p
,
6
+
1
,
"%06X"
,
ademcoId
%
ADEMCO_ID_SENTINEL
);
p
+=
6
;
if
(
acct
&&
ademcoId
==
0
)
{
p
+=
snprintf
(
p
,
20
,
"%s"
,
acct
);
}
else
{
snprintf
(
p
,
6
+
1
,
"%06X"
,
ademcoId
%
ADEMCO_ID_SENTINEL
);
p
+=
6
;
}
*
p
++
=
'|'
;
...
...
@@ -374,20 +399,20 @@ size_t ademcoAppendDataSegment(ademco_char_t* buff, AdemcoId ademcoId, AdemcoEve
*
p
++
=
']'
;
assert
(
p
-
(
char
*
)
buff
==
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN
);
//
assert(p - (char*)buff == ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN);
*
p
++
=
'\0'
;
// for debug convenience
*
p
=
'\0'
;
// for debug convenience
return
ADEMCO_PACKET_DATA_SEGMENT_FULL_LEN
;
return
p
-
(
char
*
)
buff
;
}
}
size_t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
size_t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
const
char
*
acct
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
)
{
dataSegment
->
ademcoId
=
ademcoId
;
dataSegment
->
ademcoEvent
=
ademcoEvent
;
dataSegment
->
gg
=
gg
;
dataSegment
->
zone
=
zone
;
return
dataSegment
->
raw_len
=
ademcoAppendDataSegment
(
dataSegment
->
raw
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
return
dataSegment
->
raw_len
=
ademcoAppendDataSegment
(
dataSegment
->
raw
,
a
cct
,
a
demcoId
,
ademcoEvent
,
gg
,
zone
);
}
AdemcoParseResult
ademcoParseDataSegment
(
const
ademco_char_t
*
packet
,
size_t
packet_len
,
AdemcoDataSegment
*
dataSegment
)
{
...
...
@@ -725,7 +750,7 @@ size_t ademcoMakeHbPacket(ademco_char_t* dst_buff, size_t len, uint16_t seq, con
snprintf
(
p
,
7
,
"%06X"
,
ademcoId
);
p
+=
6
;
}
p
+=
ademcoAppendDataSegment
(
p
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
p
+=
ademcoAppendDataSegment
(
p
,
a
cct
,
a
demcoId
,
ademcoEvent
,
gg
,
zone
);
if
(
xdata
&&
xdata
->
raw_len
>
0
)
{
memcpy
(
p
,
xdata
->
raw
,
xdata
->
raw_len
);
p
+=
xdata
->
raw_len
;
...
...
@@ -788,7 +813,7 @@ size_t ademcoMakeHbPacket2(AdemcoPacket* pkt, uint16_t seq, const char* acct, Ad
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
,
const
AdemcoXDataSegment
*
xdata
)
{
pkt
->
seq
=
seq
;
copyAcct2AdemcoPacket
(
pkt
,
acct
);
ademcoAppendDataSegment2
(
&
pkt
->
data
,
ademcoId
,
ademcoEvent
,
gg
,
zone
);
ademcoAppendDataSegment2
(
&
pkt
->
data
,
a
cct
,
a
demcoId
,
ademcoEvent
,
gg
,
zone
);
if
(
xdata
&&
xdata
->
raw_len
>
0
)
{
pkt
->
xdata
.
lenghFormat
=
xdata
->
lenghFormat
;
memcpy
(
pkt
->
xdata
.
raw
,
xdata
->
raw
,
xdata
->
raw_len
);
...
...
@@ -882,7 +907,7 @@ AdemcoParseResult ademcoPacketParse(const ademco_char_t* buff, size_t len, Ademc
// #acct
const
char
*
pacct
=
++
p
;
while
(
p
<
pcr
&&
*
p
!=
'['
)
{
if
(
!
is
alnum
(
*
p
))
{
p
=
NULL
;
dline
;
break
;
}
if
(
!
is
xdigit
(
*
p
))
{
p
=
NULL
;
dline
;
break
;
}
p
++
;
}
if
(
p
==
NULL
||
p
>=
pcr
||
*
p
!=
'['
||
p
-
pacct
>=
ADEMCO_PACKET_ACCT_MAX_LEN
)
{
dline
;
break
;
}
...
...
@@ -965,6 +990,34 @@ size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, const uint8_t* arr, size_t le
return
p
-
str
;
}
size_t
ademcoHiLoArrayToDecStr2
(
ademco_char_t
*
str
,
const
uint8_t
*
arr
,
size_t
len
)
{
char
*
p
=
str
;
for
(
size_t
i
=
0
;
i
<
len
;
i
++
)
{
char
c
=
(
arr
[
i
]
>>
4
)
&
0x0F
;
if
(
c
>
9
)
{
if
(
i
<
6
)
{
*
p
++
=
c
-
10
+
'A'
;
}
else
{
return
p
-
str
;
}
}
else
{
*
p
++
=
c
+
'0'
;
}
c
=
(
arr
[
i
]
&
0x0F
);
if
(
c
>
9
)
{
if
(
i
<
6
)
{
*
p
++
=
c
-
10
+
'A'
;
}
else
{
return
p
-
str
;
}
}
else
{
*
p
++
=
c
+
'0'
;
}
}
return
p
-
str
;
}
size_t
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
size_t
len
,
const
char
*
str
)
{
char
*
p
=
(
char
*
)
arr
;
size_t
slen
=
str
?
strlen
(
str
)
:
0
;
...
...
@@ -993,14 +1046,36 @@ size_t ademcoDecStrToHiLoArray(uint8_t* arr, size_t len, const char* str) {
return
len
;
}
static
uint8_t
hex2char
(
uint8_t
h
)
{
h
&=
0x0F
;
if
(
h
>
9
)
return
'A'
+
h
-
10
;
else
return
'0'
+
h
;
size_t
ademcoDecStrToHiLoArray2
(
uint8_t
*
arr
,
size_t
len
,
const
char
*
str
)
{
char
*
p
=
(
char
*
)
arr
;
size_t
slen
=
str
?
strlen
(
str
)
:
0
;
if
(
slen
>
len
*
2
)
slen
=
len
*
2
;
for
(
size_t
i
=
0
;
i
<
slen
;
i
+=
2
)
{
char
hi
=
str
[
i
];
if
(
isxdigit
(
hi
))
{
if
(
i
+
1
<
slen
)
{
char
lo
=
str
[
i
+
1
];
if
(
isxdigit
(
lo
))
*
p
++
=
(
char2hex
(
hi
)
<<
4
)
|
(
char2hex
(
lo
)
&
0x0F
);
else
{
*
p
++
=
(
char2hex
(
hi
)
<<
4
)
|
0x0F
;
break
;
}
}
else
{
*
p
++
=
(
char2hex
(
hi
)
<<
4
)
|
0x0F
;
break
;
}
}
else
{
break
;
}
}
while
((
char
*
)
arr
+
len
>
p
)
*
p
++
=
0xFF
;
return
len
;
}
size_t
ademcoHexArrayToStr
(
char
*
str
,
const
uint8_t
*
arr
,
size_t
len
)
{
char
*
p
=
str
;
for
(
size_t
i
=
0
;
i
<
len
;
i
++
)
{
...
...
@@ -1010,17 +1085,6 @@ size_t ademcoHexArrayToStr(char* str, const uint8_t* arr, size_t len) {
return
p
-
str
;
}
static
uint8_t
char2hex
(
uint8_t
c
)
{
if
(
'0'
<=
c
&&
c
<=
'9'
)
return
c
-
'0'
;
else
if
(
'A'
<=
c
&&
c
<=
'F'
)
return
c
-
'A'
+
10
;
else
if
(
'a'
<=
c
&&
c
<=
'f'
)
return
c
-
'a'
+
10
;
else
return
0xFF
;
}
size_t
ademcoHexStrToArray
(
uint8_t
*
arr
,
const
char
*
str
,
uint8_t
padding
)
{
uint8_t
*
p
=
arr
;
uint8_t
hi
=
0
,
lo
=
0
;
...
...
ademco.h
View file @
f5cb7bcf
...
...
@@ -380,9 +380,9 @@ ADEMCO_EXPORT_SYMBOL const char* ademcoEventToStringChinese(AdemcoEvent ademcoEv
//////////////////////// AdemcoDataSegment functions ////////////////////////
//! make a `DATA` packet and store to `packet`, return length
ADEMCO_EXPORT_SYMBOL
size_t
ademcoAppendDataSegment
(
ademco_char_t
*
packet
,
AdemcoId
ademcoId
,
AdemcoEvent
ademcoEvent
,
AdemcoGG
gg
,
AdemcoZone
zone
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoAppendDataSegment
(
ademco_char_t
*
packet
,
const
char
*
acct
,
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
);
ADEMCO_EXPORT_SYMBOL
size_t
ademcoAppendDataSegment2
(
AdemcoDataSegment
*
dataSegment
,
const
char
*
acct
,
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
ademco_char_t
*
packet
,
size_t
packet_len
,
AdemcoDataSegment
*
dataSegment
);
// return 0 for empty packet, CONGWIN_FE100_PACKET_LEN for success
...
...
@@ -459,6 +459,16 @@ ADEMCO_EXPORT_SYMBOL uint16_t ademcoCRC16(const ademco_char_t* buff, size_t len)
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHiLoArrayToDecStr
(
ademco_char_t
*
str
,
const
uint8_t
*
arr
,
size_t
len
);
// 将一串以高低字节表示的十六进制数组转换为字符串
// 每个字节的高四位和低四位若不大于9,将该四位表示的数字以10进制ascii码填入str,否则:
// 若定长6字节包含a~f,说明是WiFi主机
// 返回字符串长度
// 注意:函数不会在str末尾补 null terminator
// 调用者应确保str有足够空间,至少len的2倍,否则会崩溃
// 示例:输入数组:0x18 0x24 0x08 0x88 0x10 0x1f 0xff,输出字符串"18240888101"
// 示例:输入数组:0x24 0x94 0x94 0x4c 0x48 0x15 0xff,输出字符串"2494944C4815"
ADEMCO_EXPORT_SYMBOL
size_t
ademcoHiLoArrayToDecStr2
(
ademco_char_t
*
str
,
const
uint8_t
*
arr
,
size_t
len
);
// 将一个10进制数字符串转为高低字节表示的数组,节省空间
// str应只包含'0'~'9',否则失败返回0
// str长度若大于len * 2,str[len]及之后的内容将被舍弃以避免溢出
...
...
@@ -469,6 +479,16 @@ ADEMCO_EXPORT_SYMBOL size_t ademcoHiLoArrayToDecStr(ademco_char_t* str, const ui
// 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL
size_t
ademcoDecStrToHiLoArray
(
uint8_t
*
arr
,
size_t
len
,
const
char
*
str
);
// 将一个16进制数字符串转为高低字节表示的数组,节省空间
// str应只包含'0'~'9', 'A'~'F', 'a'~'f',否则失败返回0
// str长度若大于len * 2,str[len]及之后的内容将被舍弃以避免溢出
// 转换后的长度若不满len,则以0xF补满。
// 示例:输入字符串"123ABC",len=6, 则 arr 内容为 0x12 0x3a 0xbc 0xff 0xff 0xff
// 示例:输入字符串 "18240888101", len=9, 则arr内容为 0x18 0x24 0x08 0x88 0x10 0x1f 0xff 0xff 0xff, return 9
// 示例:输入字符串 "12345678901234567890", len=9, 则arr内容为 0x12 0x34 0x56 0x78 0x90 0x12 0x34 0x56 0x78, return 9
// 示例:输入NULL,返回 9个 0xFF
ADEMCO_EXPORT_SYMBOL
size_t
ademcoDecStrToHiLoArray2
(
uint8_t
*
arr
,
size_t
len
,
const
char
*
str
);
// 将一串字节流转换为可打印形式
// 返回str长度(len * 2)
// 调用者应确保str有足够的容量,至少len*2
...
...
docs/README.md
View file @
f5cb7bcf
...
...
@@ -37,23 +37,23 @@
### **各字段说明:**
*
`LF`
固定起始符
0x0A
*
`crc16`
固定长度
4Bytes
, 表示从
`id`
的左引号开始,至
`timestamp`
的最后一个字节结束(长度为
`length`
)计算出的
`crc16`
值,以16进制数字的ASCII码表示
*
`length`
从
`id`
的左引号开始,至
`timestamp`
的最后一个字节结束的字符串长度,以16进制数字的ASCII码表示,定长
4Bytes
*
`LF`
固定起始符
`0x0A`
*
`crc16`
固定长度
`4 Bytes`
, 表示从
`id`
的左引号开始,至
`timestamp`
的最后一个字节结束(长度为
`length`
)计算出的
`crc16`
值,以16进制数字的ASCII码表示
*
`length`
从
`id`
的左引号开始,至
`timestamp`
的最后一个字节结束的字符串长度,以16进制数字的ASCII码表示,定长
`4 Bytes`
*
`"id"`
事件类型,分为
`NULL, ACK, DUH, ADM-CID, HENG-BO`
等,分别为心跳、回应、错误、主机事件、恒博事件。除事件
`ADM-CID/HENG-BO`
外,其他三种类型的
`data`
段都为空值
`[]`
。
*
`seq`
序号,定长
4 Bytes
,代表的十进制数字为主机发送命令字的序号,范围
`0001~9999`
,超过
`9999`
则从1开始再次循环。
`seq`
被用来判断主机发出的
`ADM-CID/HENG-BO`
类型命令字是否得到接警平台的正确处理。例:平台要对主机发出的
`NULL/ADM-CID/HENG-BO`
类型事件进行回应,回应的
`seq`
以接收到的
`seq`
为准。主机收到回应后会判断
`seq`
与之前发送的
`seq`
是否相同:相同则说明该事件已得到处理,否则会进行重发。
*
`seq`
序号,定长
`4 Bytes`
,代表的十进制数字为主机发送命令字的序号,范围
`0001~9999`
,超过
`9999`
则从1开始再次循环。
`seq`
被用来判断主机发出的
`ADM-CID/HENG-BO`
类型命令字是否得到接警平台的正确处理。例:平台要对主机发出的
`NULL/ADM-CID/HENG-BO`
类型事件进行回应,回应的
`seq`
以接收到的
`seq`
为准。主机收到回应后会判断
`seq`
与之前发送的
`seq`
是否相同:相同则说明该事件已得到处理,否则会进行重发。
*
`Rrcvr`
以R开头的一段十六进制数字字符串,数字长度范围
`1~6`
,暂时仅占位,无意义。字段总长度
`2~7`
Bytes。
*
`Lpref`
以L开头的一段十六进制数字字符串,数字长度范围
`1~6`
,暂时仅占位,无意义。字段总长度
`2~7`
Bytes。
*
`#acct`
以
`#`
开头,后跟有限位十
进制数字(SIM卡号或出厂编号)或安定宝ID,表示主机的账号(有SIM卡的主机为手机号,无SIM卡的是出厂编号,有些主机直连时使用了安定宝ID为
账号)
*
`data`
格式为
`[]`
(左右中括号,无空格,定长2Byte)或
`[#ademco_id|event gg zone]`
(有空格)。当事件类型为
`NULL/ACK/DUH`
时
`data`
段为
`[]`
;当事件类型为
`ADM-CID/HENG-BO`
时
`data`
段格式为
`[#a
cct
|event gg zone]`
:
*
`#acct`
以
`#`
开头,后跟有限位十
六进制数字(
`SIM`
卡号或出厂编号或
`MAC`
地址或安定宝ID),表示主机的账号(有SIM卡的主机为手机号,无
`SIM`
卡的是出厂编号,有些主机直连时使用了安定宝ID为账号,
`WiFi`
主机使用
`MAC`
地址作为主机
账号)
*
`data`
格式为
`[]`
(左右中括号,无空格,定长2Byte)或
`[#ademco_id|event gg zone]`
(有空格)。当事件类型为
`NULL/ACK/DUH`
时
`data`
段为
`[]`
;当事件类型为
`ADM-CID/HENG-BO`
时
`data`
段格式为
`[#a
demco_id
|event gg zone]`
:
*
`#ademco_id`
主机的安定宝ID,以
`#`
开头的4位或6位或8位十六进制数字,我司使用固定6位,如安定宝ID
`16`
编码为6位是
`000010`
,传输为
`#000010`
。
*
`event`
定长4Bytes,事件代码,具体含义见后文。
*
`gg`
定长2 Bytes, 一般为00,当非00时有特殊含义,参考下方
*4.1 事件报告与远程控制*
*
`zone`
防区号,范围
`0~999`
。
`zone`
为
`0`
表示主机自身事件,如布防、撤防、防拆等。
`1~999`
则为防区号,表示防区事件。定长3 Bytes。
*
`*xdata`
可选的字段,一般情况下留空,仅有限几种情况需要带
`xdata`
:撤防时使用
`xdata`
传输密码、索要防区信息时使用
`xdata`
做串口命令透传。具体格式参考下方
*4.2 xdata 段格式*
。
*
`timestamp`
时间戳字段,格式为
`_HH:MM:SS,mm-DD-YYYY`
,定长
20Bytes
*
`timestamp`
时间戳字段,格式为
`_HH:MM:SS,mm-DD-YYYY`
,定长
`20Bytes`
*
`CR`
固定结束符,
0x0D
*
`CR`
固定结束符,
`0x0D`
## 三、事件码
...
...
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