0

我正在写关于如何从不同的健身乐队获取数据的论文。目前我正在使用蓝牙连接我的 PC 对 Mi Band 2 进行一些研究,不幸的是 BLE 对我来说是一个新领域。

通过查看Gadgetbridgemiband2-python-test 之类的项目,我试图理解协议。我了解了身份验证的工作原理以及如何提取电池或时间信息等数据。但是,我不了解获取过去数据的协议,例如从两天前到现在的微小步骤。

如果有人可以通过提供小费或解释协议步骤来帮助我,我会很高兴。提前致谢!

这是我现在的代码,据我了解协议:

UUID_CHAR_ACTIVITY_DATA = "00000005-0000-3512-2118-0009af100700"
UUID_CHAR_FETCH = "00000004-0000-3512-2118-0009af100700"
CCCD_UUID = 0x2902

class MiBand2(Peripheral):
    [...]
    self.char_activity_data =   self.getCharacteristics(uuid=UUID_CHAR_ACTIVITY_DATA)[0]
    self.char_fetch = self.getCharacteristics(uuid=UUID_CHAR_FETCH)[0]
    self.cccd_fetch = self.char_fetch.getDescriptors(forUUID=CCCD_UUID)[0]
    def fetch_activity_data(self):
        # \x01\x01  key?
        # \xe2\x07  2018 year
        # \x05      month
        # \x03      year
        # \x11      hour
        # \x2f      minute
        # \x00\x08 timezone
        value = b'\x01\x01\xe2\x07\x05\x03\x11\x2f\x00\x08'     
        self.cccd_fetch.write(b'\x01\x00', False)
        self.char_fetch.write(value_from_wireshark, False)
        for i in range(30):
            self.waitForNotifications(1.0)


class AuthenticationDelegate(DefaultDelegate):
    [...]
    def handleNotification(self, hnd, data):
        [...]
        if hnd == self.device.char_fetch.getHandle():
            if data[:3] == b'\x10\x01\x01':
                self.device.char_activity_data.write(b'\x01\x00', False)
                # After \x02 I receive \x10\x02\x01 instead of fitness data as I thought
                self.device.char_fetch.write(b'\x02', False)
4

1 回答 1

0

需要分析btsnoop_hci.log

设备每 30 分钟从 00000010-0000-3512-2118-0009af100700 发送一个通知值 0x0e。然后你必须开始获取你过去的数据。首先,您需要为 UUID_CHAR_ACTIVITY_DATA 启用通知描述符,即所谓的 UUID_CHAR_FETCH。然后,您需要从上次成功获取数据中获取包数。因此,您将值 0x0101+datatime+tz 发送到 UUID_CHAR_FETCH。如果 1st_package_datetimetz 没有间隙,则设备对您的响应值为 0x100101+packages_count+1st_package_datetimetz 是您之前发送的。现在您需要开始传输过去的数据,只需向 UUID_CHAR_FETCH 发送一个字节值 0x02,设备将从 UUID_CHAR_ACTIVITY_DATA 发送通知。每个活动数据通知值在第一个字节中都有一个队列号,在剩余字节中最多有 4 个数据包。每个过去的数据包都由 4 个字节组成,格式如下:activity_type,intensity,steps,heart_rate。该设备每分钟存储一次数据。因此,通常在每个 0x0e 事件中,您将在 8 个通知消息值中获得 30 个包,大部分时间是 4 个包。在收到最后一个通知后,设备将从 UUID_CHAR_FETCH 发送成功通知 0x100201。我不知道为什么,但需要在最后第三步完成:将单个字节 0x03 发送到 UUID_CHAR_FETCH,然后获得成功响应 0x100301。这实际上是您所需要的,但 Mi Fit 会检查新数据包,然后计数为零,然后执行最后 3 步。现在它需要使用值 0x0000 设置通知描述符。毕竟,您的成功同步数据时间将因您获得的过去数据包的计数而增加 * 60 秒。

如果您在 0x0101 命令之后有响应包计数 = 0,则设备显然不会在命令 0x02 之后向您发送任何内容,然后发送成功 0x100201 :)

我不知道 0x0102+datatimetz 是什么。它总是在我的 btsnoop_hci.logs 中响应包计数 = 0。

我认为没有必要通过 0x0e 事件进行同步。

https://gist.github.com/Roxxor91/0d3ff17153270e447d01e7afd0c54e0f

于 2018-10-17T08:09:48.010 回答