Apple的心率监测示例和蓝牙心率测量特征的字节顺序

时间:2012-12-26 09:59:15

标签: bluetooth bluetooth-lowenergy endianness

关于心率测量特征:

http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

我想确保我正确地阅读它。这实际上是说5个字段吗?强制性的C1,C2,C3和C4?强制性位于第一个字节,C4位于最后两个字节,C1和C2为8位字段,C3至C4各为16位。这总共是8个字节。我是否正确阅读了这份文件?

编辑:

我被告知强制标志字段表示某事为0,这意味着它不在那里。例如,如果第一个位为0,则C1为下一个字段,如果为1,则代之以C2。

结束编辑

在Apple的OSX heart rate monitor example

- (void) updateWithHRMData:(NSData *)data 
{
    const uint8_t *reportData = [data bytes];
    uint16_t bpm = 0;

    if ((reportData[0] & 0x01) == 0) 
    {
        /* uint8 bpm */
        bpm = reportData[1];
    } 
    else 
    {
        /* uint16 bpm */
        bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));
    }

    ... // I ignore rest of the code for simplicity
}

它将第一位检查为零,如果不是,则通过将CFSwapInt16LittleToHost应用于reportData[1],将小端字节变为主机字节顺序。

该位检查如何工作?我不完全确定结束。是说它是小还是大,第一个字节总是强制字段,第二个字节是C1等?由于reportData是一个8位指针(typedef到unsigned char),它检查必填字段的第0位或第8位。

如果该位为8位,则该位保留供将来使用,为什么要在那里读取?

如果该位为0,那么它是little-endian并且不需要转换?但如果它是小端,根据规范,第一位可能是1,1表示“心率值格式设置为UINT16。单位:每分钟节拍(bpm)”,不能被误读?< / p>

我不明白它是如何进行检查的。

编辑: 我继续说有C5,这是一个大错。它仅限于C4,我在上面编辑过。

2 个答案:

答案 0 :(得分:4)

  

我是否正确阅读了这份文件?

恕我直言,你读的有点不对劲。

C1到C4应该被读作条件1到条件4.并且在org.bluetooth.characteristic.heart_rate_measurement的表中,如果标志字节的最低位是0,则满足C1,否则,C2是。

您可以将它视为C编程语言中的运行时可配置联合类型(由flag确定。请注意,这并非总是如此,因为C3和C4使情况变得复杂。)< / p>

// Note: this struct is only for you to better understand a simplified case.
// You should still stick to the profile documentations to implement.

typedef struct {
    uint8_t flag;
    union {
        uint8_t bpm1;
        uint16_t bpm2;
    }bpm;
} MEASUREMENT_CHAR; 
  

该位检查是如何工作的?

if ((reportData[0] & 0x01) == 0)使用按位AND运算符有效地检查该位。如果有任何疑问,请去找一个C / C ++编程介绍书。

在这种情况下,第一个字节始终是标志。 flag的值动态地确定应该如何处理其余字节。 C3和C4都是可选的,如果标志中的相应位被设置为零,则可以省略。 C1和C2是互斥的。

蓝牙标准中没有字节序歧义,因为已经很好地解决了小端应该一直使用的问题。您应该始终假设这些uint16_t字段作为小端传输。 Apple的预防措施只是为了保证代码的最大可移植性,因为它们不能保证未来产品中使用的架构的字节序。

答案 1 :(得分:2)

我知道它是怎么回事。它没有测试Endianness。相反,它测试的是字段是8位还是16位,而在16位的情况下,它将从小端字节转换为主机顺序。但我看到在转换之前和转换之后它是相同的数字。所以我想这个系统开始时是小端的,所以我不知道重点是什么。