bluetooth - 苹果心率监测实例及蓝牙心率测量特性字节序

标签 bluetooth bluetooth-lowenergy endianness

关于心率测量的特点:

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

编辑

链接现在在 https://www.bluetooth.com/specifications/gatt/characteristics/ 并寻找“心率测量”。

他们不再提供 XML 查看器,但您需要查看 XML directly .

还有关于服务的 this page .

结束编辑

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

编辑:

我被告知强制标志字段指示某些内容为 0,这意味着它不存在。例如,如果第一位是0,则C1是下一个字段,如果是1,则C2代替。

结束编辑

在苹果的 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 to unsigned char),它检查必填字段的第 0 位或第 8 位。

如果该位是第 8 位,则该位是保留供将来使用的,为什么要读到那里?

如果那个位是0,就是小端,不需要转换?但是如果是little-endian,按照规范第一位可以是1,1表示“心率值格式设置为UINT16。单位:每分钟心跳次数(bpm)”,不会看错了吧?

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

编辑: 我一直说有 C5,那是个错误。仅限 C4,我在上面进行了编辑。

最佳答案

Am I reading this document correctly?

恕我直言,你读错了。

C1到C4应该读作Conditional 1到Conditional 4。而在org.bluetooth.characteristic.heart_rate_measurement的表中,如果标志字节的最低位为0,则满足C1,否则满足C2。

你可以认为它是 C 编程语言中的运行时可配置联合类型(,它由 flag 决定。注意这并不总是正确的,因为 C3 和 C4 使情况变得复杂).

// 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; 

How does that bit checking work?

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

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

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

关于bluetooth - 苹果心率监测实例及蓝牙心率测量特性字节序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14038906/

相关文章:

android - 读取并通知 BLE android

c - 如何对64位寄存器的低32位进行BSWAP?

x86 - 为什么x86是小端字节序?

Java DatagramPacket 读取原始数据类型

android - 在外部蓝牙设备和 Android 手机之间传输音频

通过蓝牙的 HTTP

android - Android 中的 Gatt 服务器设备名称长度

java - 使用 Estimote SDK 的信标检测在 Android Lollipop 中崩溃

安卓蓝牙文件发送