pelco-d协议数据解析示例

前段时间写了有关pelco协议的一些笔记,后来,有个小模块是接收pelco格式的数据,然后解析出是什么命令,于是又写了个简单的解析函数。这个函数没什么技术含量。主要思路:

1、逐字节解析,保证每一字节都处理到;
2、找到0xff,此为命令头;
3、找到命令结束字符,方法是根据pelco命令组装的算法,——其实就是当某一字节的值是前面几个的校验和就结束,有一点要校验和正确但长度不符合pelco标准的情况,比如出现0x01,0x02,0x03,根据校验方法是正确的,但它不是正确的命令,pelco文档有提到命令都是7个字节的,但有的文档的命令多于7字节,于是,统一用7字节或以上为判断。
4、结束,找到了一个命令。 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
static void protocol_d(unsigned char* buffer, int len)
{
unsigned char* tmp = NULL;
int cksm = 0;
unsigned char ch = 0;
int tmp_len = len;

int cmd_len = 0;
unsigned char* cmd_ptr = NULL;

tmp = buffer;

while (tmp_len > 0)
{
while (*tmp != 0xff)
{
tmp++;
tmp_len--;
if (tmp_len <= 0)
goto end;
}

cmd_ptr = tmp;
// 第一个字节
ch = *(++tmp);
cksm += ch;
cmd_len = 2;
tmp_len--;

while (tmp_len > 0)
{
ch = *(++tmp);
cmd_len++;
tmp_len--;
if (ch == cksm && cmd_len >= 7)
{
dump_cmd(NULL, cmd_ptr, cmd_len);
//找到了命令,就可以做其它事情了。
cksm = 0;
break;
}
cksm += ch;
cksm %= 0x100;
}

end:
;
}
}

测试代码如下,特意加了些干扰的字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
int serial_simple_test()
{
#define LEN (5*7+2+2+2+3)
unsigned char buffer[LEN] = {
0x11, 0x8, 0xff, 0x01, 0x00, 0x08, 0x00, 0x01, 0x0a,
0xff, 0x01, 0x00, 0x08, 0x00, 0x02, 0x0b, 0x9,
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
0xff, 0x01, 0x00, 0x0c, 0x0d, 0x08, 0x22,0x9,
0xff, 0x01, 0x00, 0x01, 0x01, 0x03, 0x6, 0x01, 0x05,
};
protocol_d(buffer, LEN);
return 0;
}

李迟记于2014年8月14日