找回密码
 立即注册

使用微信账号登录

只需一步,快速开始

查看: 10|回复: 0

[Nordic] 谷歌查找我的设备配件(Google Find My Device Accessory)详解和应用(3)

[复制链接]
连续签到天数:1天
签到总天数:8天
签到总奖励:36金币
发表于 昨天 09:01 | 显示全部楼层 |阅读模式
1.4 配件配置后的主要状态
  • Synchronization mode:在已配置(Provisioned)状态下,配件在系统重启后(例如,因更换电池而重启)会尝试同步其信标时钟。在这种情况下,它会发起 Fast Pair not Discoverable Advertising,以表明安卓设备需要与定位标签进行同步。智能手机检测Fast Pair not Discoverable Advertising后,会连接到该配件,并交换必要的数据,以便将其信标时钟与已连接设备的当前时钟值进行同步。在成功同步之后,定位标签会停止Fast Pair not Discoverable Advertising。从这时起,该配件开始FMDN Beacon Advertising。另外,安卓设备采用了一种限流机制,以防止信标时钟同步在每 24 小时内发生超过一次。配置(Provisioning)操作也被视为一次时钟同步事件,并且在下一次同步尝试之前需要等待 24 小时的时间间隔。(同步是安卓设备发起的)
  • Identification mode: 在已配置状态下,可以在有限时间内进入识别模式。此模式允许已连接的设备从定位标签读取识别信息。这类识别信息的一个例子是通过蓝牙读取蓝牙通用访问配置文件(GAP)中的设备名称。识别模式还允许读取在《检测不必要的位置追踪器(DULT)》规范中定义的标识符有效载荷。识别模式的超时由 DULT 子系统处理,引入这一机制是为了提高用户隐私保护程度。
  • Recovery mode:在已配置状态下,可以在有限时间内进入恢复模式。此模式允许安卓设备从定位标签中找回丢失的配置密钥EIK
  • Motion detector mode:在已配置状态下, 配件可以激活《检测不必要的位置追踪器(DULT)》规范中定义的运动检测模式。当配件与所有者分离足够长的时间后(请参考配置选项:CONFIG_DULT_MOTION_DETECTOR_SEPARATED_UT_TIMEOUT_PERIOD_MIN 和 CONFIG_DULT_MOTION_DETECTOR_SEPARATED_UT_TIMEOUT_PERIOD_MAX),该模式将被激活。在这种状态下,如果检测到运动,配件就会启动响铃操作。发出的声音有助于提醒非所有者,他们携带了一个不属于自己的配件,并且原所有者可能会利用这个配件来追踪他们的位置。在DK上,可以通过按下按钮来模拟产生运动。在 Thingy:53 设备上,内置的加速度计被用于检测运动。在播放10次声音后,或者在检测到运动且过去20秒之后,运动检测器将在配置选项CONFIG_DULT_MOTION_DETECTOR_SEPARATED_UT_BACKOFF_PERIOD 中所设置的时间段内处于停用状态。如果配件再次出现在其所有者附近,运动检测器也会被停用。
  • factory reset:配件执行工厂复位操作后,发生工厂复位(factory reset),配置数据被删除,需要重新配置。配件启动(reset)的过程中按下Button4(nRF 52840 DK),执行factory reset。
1.5 配件必须包含的蓝牙服务
配件必须包含fast pair GATT service(UUID 0xFE2C)和Accessory non-owner GATT service(UUID 0x15190001-12F4-C226-88ED-2AC5579F2A85),如下图:
通过fast pair GATT service里面的Bluetooth LE特征可以完成对配件的配置以及实现所有者设备(如Android手机)对配件的操控;通过accessory non-owner GATT service里面的Bluetooth LE特征可以实现非所有者设备(如Android手机)对配件的操控。Accessory non-owner GATT service用于实现DULT(Detecting Unwanted Location Trackers )协议,用来解决非法跟踪的问题Unwanted tracking prevention。
关于配件的配置主要包含两个阶段(一次连接就可以完成):第一阶段是通过Google fast pair获取account key,第二阶段是做provisioning获取临时身份密钥EIK(Ephemeral identity key)。关于第一阶段的详细介绍可以参考前一篇博客:Google快速配对服务(Google Fast Pair Service)详解和应用;第二阶段的配置(provisioning)过程,通过Beacon actions这个Bluetooth LE特征作为逻辑通道,由所有者设备发送Beacon Provisioning Request命令开始触发配置(provisioning)过程。Beacon actions的定义如下:
基于Beacon actions通道的每一个命令的通信流程如下:
Seeker(所有者设备)进行Bluetooth LE读操作的目的是从Provider(配件)处获得一个Nonce随机数和协议主版本号,用来生成one-time authentication key,用于身份认证;
Seeker 通过Bluetooth LE写请求命令给Provider发送命令,Provider通过Notification的方式发送命令响应。Beacon actions特性的代码定义:
/* Beacon Actions GATT Characteristic definition for the Fast Pair service. */#define FP_FMDN_BEACON_ACTIONS_CHARACTERISTIC                                 \    BT_GATT_CHARACTERISTIC(BT_FAST_PAIR_UUID_BEACON_ACTIONS,              \        BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, \        BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,                       \        fp_fmdn_beacon_actions_read,                                  \        fp_fmdn_beacon_actions_write,                                 \        NULL),                                                        \    BT_GATT_CCC(fp_fmdn_beacon_actions_ccc_cfg_changed,                   \        BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)

Bluetooth LE读操作响应callback函数如下,函数里提供了Nonce随机数和协议主版本号
ssize_t fp_fmdn_beacon_actions_read(struct bt_conn *conn,                    const struct bt_gatt_attr *attr,                    void *buf,                    uint16_t len,                    uint16_t offset){    int err;    ssize_t res;    struct conn_context *conn_context;    uint8_t rsp[BEACON_ACTIONS_READ_RSP_LEN];    BUILD_ASSERT((sizeof(conn_context->random_nonce) +             BEACON_ACTIONS_READ_RSP_VERSION_LEN) ==             BEACON_ACTIONS_READ_RSP_LEN);    /* It is assumed that this callback executes in the cooperative thread context. */    __ASSERT_NO_MSG(!k_is_preempt_thread());    __ASSERT_NO_MSG(!k_is_in_isr());    LOG_DBG("Beacon Actions GATT Read Request");    /* Do not perform any action if Fast Pair is not ready. */    if (!bt_fast_pair_is_ready()) {        res = BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);        LOG_INF("Beacon Actions read: res=%d conn=%p, "            "Return error because Fast Pair is not enabled", res, (void *)conn);        return res;    }    conn_context = &conn_contexts[bt_conn_index(conn)];    err = sys_csrand_get(conn_context->random_nonce, sizeof(conn_context->random_nonce));    if (err) {        LOG_ERR("Beacon Actions: failed to generate random nonce: err=%d", err);        return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);    }    rsp[0] = CONFIG_BT_FAST_PAIR_FMDN_VERSION_MAJOR;    memcpy(&rsp[BEACON_ACTIONS_READ_RSP_VERSION_LEN],           conn_context->random_nonce,           sizeof(conn_context->random_nonce));    res = bt_gatt_attr_read(conn, attr, buf, len, offset, rsp, sizeof(rsp));    if (res == sizeof(rsp)) {        conn_context->is_challenge_valid = true;        LOG_HEXDUMP_DBG(conn_context->random_nonce, sizeof(conn_context->random_nonce),                "Beacon Actions: challenge-response enabled for the next write:");    }    LOG_DBG("Beacon Actions read: res=%d conn=%p", res, (void *)conn);    return res;}
1.6 基于Beacon actions特性的命令1.6.1 信标配置请求命令(Beacon provisioning request)
配置过程包括fast pair和provisioning两个阶段。Provisioning过程主要围绕Beacon provisioning request和response过程进行。信标配置请求命令格式如下:
信标配置请求命令含4个子命令:读取信标参数,读取配置状态,设置EIK和清除EIK
信标配置请求命令的一次性认证密钥(One-time authentication key)采用 HMAC-SHA256 算法计算结果并取结果的前 8 个字节的数据。HMAC(Hash - based Message Authentication Code,基于哈希的消息认证码)是一种通过使用哈希函数(这里是 SHA256)来生成消息认证码的机制。它结合了一个密钥(account key)和待认证的数据(协议主版本号 || 从该特性读取的最后一个随机数 || 数据 ID || 数据长度 || 附加数据,注:“||” 表示拼接操作),从而生成一个固定长度的哈希值。协议主版本号和随机数是对Beacon actions特征读操作过程中获取的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册  

×
楼主热帖
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

小黑屋|手机版|我爱蓝牙网 - 52Bluetooth

GMT+8, 2025-8-14 03:58 , Processed in 0.112734 second(s), 12 queries , Gzip On, MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表