CRC蓝牙低功耗4.2

问题描述 投票:1回答:2

在核心蓝牙4.2文档here中,它讨论了数据完整性的CRC校验(P2456)。详情如下:

enter image description here

以下是一个例子:

01 02 03 04 05 06 07 08 09

生产CRC:6d d2

我尝试了许多不同的方法,但似乎无法重现这个例子。任何人都可以提供一些示例代码来生成上面的CRC。

bluetooth bluetooth-lowenergy checksum crc
2个回答
0
投票

我不知道这与BLE有什么关系,但是我们走了:示例是在C ++中,但很容易移植到任何编程语言。

unsigned short crc16(data_p, length)
char *data_p;
unsigned short length;
{
       unsigned char i;
       unsigned int data;
       unsigned int crc;

       crc = 0xffff;

       if (length == 0)
              return (~crc);

       do {
              for (i = 0 data = (unsigned int)0xff & *data_p++;
                  i < 8;
                  i++, data >>= 1) {
                    if ((crc & 0x0001) ^ (data & 0x0001))
                           crc = (crc >> 1) ^ POLY;
                    else
                           crc >>= 1;
              }
       } while (--length);

       crc = ~crc;

       data = crc;
       crc = (crc << 8) | (data >> 8 & 0xFF);

       return (crc);
}

0
投票

您遗漏了文档中示例的关键部分,即示例中使用的UAP是0x47。需要使用UAP初始化CRC。 (奇怪的是,相对于进入的数据位,位反转并且在高字节中。)

下面的代码计算了这个例子。结果是d26d。 CRC首先发送最低有效位,因此它被发送到6d d2。在接收端,使用CRC计算整个事物的相同CRC,结果为零,这是接收端应该如何检查发送的内容。

#include <stdio.h>

static unsigned crc_blue(unsigned char *payload, size_t len) {
    unsigned crc = 0xe200;      // UAP == 0x47
    while (len--) {
        crc ^= *payload++;
        for (int k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0x8408 : crc >> 1;
    }
    return crc;
}

int main(void) {
    unsigned char payload[] = {
        0x4e, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
    printf("%04x\n", crc_blue(payload, sizeof(payload)));
    unsigned char recvd[] = {
        0x4e, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x6d, 0xd2};
    printf("%04x\n", crc_blue(recvd, sizeof(recvd)));
    return 0;
}

您的代码需要为该设备适当地初始化UAP。

© www.soinside.com 2019 - 2024. All rights reserved.