苹果心率监测示例及蓝牙心率测量特性的字节序 [英] Apple's heart rate monitoring example and byte order of bluetooth heart rate measurement characteristics

查看:20
本文介绍了苹果心率监测示例及蓝牙心率测量特性的字节序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于心率测量特性:

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 直接.

对于服务,它也位于此页面.

结束编辑

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

我被告知强制标志字段表明某物为 0,这意味着它不存在.例如,如果第一位为 0,则 C1 为下一个字段,如果为 1,则为 C2.

结束编辑

在 Apple 的 OSX 心率监测器示例:

- (void) updateWithHRMData:(NSData *)data{const uint8_t *reportData = [数据字节];uint16_t bpm = 0;如果 ((reportData[0] & 0x01) == 0){/* uint8 bpm */bpm = 报告数据[1];}别的{/* uint16 bpm */bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));}...//为简单起见,我忽略其余代码}

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

那个位检查是如何工作的?我不完全确定字节序.是说无论大小,第一个字节总是必填字段,第二个字节是C1,等等?由于 reportData 是一个 8 位指针(typedef to unsigned char),它会检查必填字段的第 0 位或第 8 位.

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

如果那个位是 0,它是小端的,不需要转换?但如果是小端,根据规范,第一位可能是 1,1 表示心率值格式设置为 UINT16.单位:每分钟心跳次数 (bpm)",这不会被误读吗?

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

我一直说有C5,那是个错误.仅由 C4 决定,我在上面进行了编辑.

解决方案

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

恕我直言,你读错了.

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

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

//注意:这个结构体只是为了让你更好地理解一个简化的情况.//您仍然应该坚持要实现的配置文件文档.类型定义结构{uint8_t 标志;联合{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 的预防措施只是为了确保代码的最大可移植性,因为他们无法保证未来产品中使用的架构的字节序.

On the heart rate measurement characteristics:

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

EDIT

Link is now at https://www.bluetooth.com/specifications/gatt/characteristics/ and look for "heart rate measurement".

They no longer offer an XML viewer, but instead you need to view XML directly.

Also for services it's on this page.

END EDIT

I want to make sure I'm reading it correctly. Does that actually says 5 fields? The mandatory, C1, C2, C3, and C4? And the mandatory is at the first byte, and C4 is at the last two bytes, C1 and C2 are 8-bit fields, and C3 to C4 are 16-bit each. That's a total of 8 bytes. Am I reading this document correctly?

EDIT:

I'm informed that the mandatory flag fields indicate something is 0, it means it's just not there. For example, if the first bit is 0, C1 is the next field, if 1, C2 follows instead.

END EDIT

In Apple's 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
}

It checks the first bit as zero, and if it isn't, it's changing the little endianness to whatever the host byte order is, by applying CFSwapInt16LittleToHost to reportData[1].

How does that bit checking work? I'm not entirely certain of endianess. Is it saying that whether it's little or big, the first byte is always the mandatory field, the second byte is the C1, etc? And since reportData is an 8-bit pointer (typedef to unsigned char), it's checking either bit 0 or bit 8 of the mandatory field.

If that bit is bit 8, the bit is reserved for future use, why is it reading in there?

If that bit is 0, it's little-endian and no transformation is required? But if it's little-endian, the first bit could be 1 according to the spec, 1 means "Heart Rate Value Format is set to UINT16. Units: beats per minute (bpm)", couldn't that be mis-read?

I don't understand how it does the checking.

EDIT: I kept on saying there was C5, that was a blunder. It's up to C4 only and I edited above.

解决方案

Am I reading this document correctly?

IMHO, you are reading it a little wrong.

C1 to C4 should be read as Conditional 1 to Conditional 4. And in the table for org.bluetooth.characteristic.heart_rate_measurement, if the lowest bit of the flag byte is 0, then C1 is met, otherwise, C2 is.

You can think it a run-time configurable union type in the C programming language(, which is determined by the flag. Beware this is not always true because the situation got complicated by C3 and 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) effectively checks the bit with bitwise AND operator. Go and find a C/C++ programming intro book if any doubt.

The first byte is always the flag, in this case. The value of flag dynamically determines how should the rest of the bytes should be dealt with. C3 and C4 are both optional, and can be omitted if the corresponding bits in the flag were set zeroes. C1 and C2 are mutual exclusive.

There is no endianness ambiguity in the Bluetooth standard, as it has been well addressed that little-endian should be used all the time. You should always assume that those uint16_t fields are transferred as little endian. Apple's precaution is just to reassure the most portability of the code, since they would not guarantee the endianness of architectures used in their future products.

这篇关于苹果心率监测示例及蓝牙心率测量特性的字节序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆