1)读取信标参数(Read beacon parameters):Seeker发送读取信标参数(Read beacon parameters)命令后,配件设备返回参数信息。参数定义如下: Calibrated power:在距离为 0 米处接收到的校准功率(取值范围在 [-100, 20] 之间)。以有符号整数表示,分辨率为 1 分贝毫瓦(dBm)。 Clock value:当前的时钟值(以秒为单位,大端字节序)。主要用于时间同步。 Curve selection:选择用于加密的椭圆曲线: - 0x00(默认值):SECP160R1
- 0x01:SECP256R1(需要扩展广播)
Components:能够发出响铃声音的组件数量: - 0x00:表示该设备无法发出响铃声音。
- 0x01:表示只有单个组件能够发出响铃声音。
- 0x02:表示左右耳塞这两个组件能够独立发出响铃声音。
- 0x03:表示左右耳塞以及充电盒这三个组件能够独立发出响铃声音。
Ringing capabilities:响铃能力: - 0x00:不支持响铃音量选择。
- 0x01:支持响铃音量选择。如果设置为此值,提供者必须接受并处理如 “响铃操作” 中所示的 3 种音量级别。
Calibrated power计算函数如下: int8_t fp_fmdn_state_tx_power_encode(void){ int32_t calibrated_tx_power; __ASSERT_NO_MSG(bt_fast_pair_is_ready()); calibrated_tx_power = fmdn_adv_set_tx_power; calibrated_tx_power += FMDN_TX_POWER_CORRECTION_VAL; __ASSERT(calibrated_tx_power >= FMDN_TX_POWER_CALIBRATED_MIN, "FMDN State: calibrated TX power is too low"); __ASSERT(calibrated_tx_power <= FMDN_TX_POWER_CALIBRATED_MAX, "FMDN State: calibrated TX power is too high"); return calibrated_tx_power;}FMDN_TX_POWER_CORRECTION_VAL的值可以通过如下配置选项进行配置。配置值与从蓝牙低功耗(Bluetooth LE)控制器读取的发射功率(TX power)相加,以此计算 “读取信标参数” 响应中包含的校准发射功率值(Calibrated power)。之所以需要进行这种校正,是为了考虑硬件带来的影响(例如,所使用的天线或设备外壳)。 config BT_FAST_PAIR_FMDN_TX_POWER_CORRECTION_VAL int "TX power correction value [dBm]" default 0 help The configured value is added to the TX power readout from Bluetooth LE controller to calculate the calibrated TX power value included in the Read Beacon Parameters response. The correction may be needed to take into acccount hardware configuration (for example, used antenna or device's casing). The calibrated TX power included in the Read Beacon Parameters response has to be in the following dBm range: [-100, 20].Clock value的读取函数如下:
static uint32_t fmdn_clock_read(void){ int64_t sys_uptime; uint32_t fmdn_clock; /* Calculate elapsed time since bootup. */ sys_uptime = k_uptime_get(); /* Convert from milliseconds to seconds. */ sys_uptime /= MSEC_PER_SEC; /* Cast the uptime value in seconds onto the uint32_t type. * The uint32_t type of clock value should allow over a hundred * years of operation without the overflow: * 2^32 / 3600 / 24 / 365 ~ 136 years */ fmdn_clock = sys_uptime; /* Calculate the absolute time using the checkpoint from NVM. */ fmdn_clock += storage_clock_boot_checkpoint; return fmdn_clock;}Curve selection的读取函数如下: uint8_t fp_fmdn_state_ecc_type_encode(void){ /* Define the encoding for the ECC configuration. */ enum ecc_type { ECC_TYPE_SECP160R1 = 0x00, ECC_TYPE_SECP256R1 = 0x01, ECC_TYPE_INVALID = 0xFF, }; __ASSERT_NO_MSG(bt_fast_pair_is_ready()); if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_ECC_SECP160R1)) { return ECC_TYPE_SECP160R1; } if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_ECC_SECP256R1)) { return ECC_TYPE_SECP256R1; } __ASSERT(0, "FMDN State: incorrect ECC type selection"); return ECC_TYPE_INVALID;}Components的读取函数如下: uint8_t fp_fmdn_ring_comp_num_encode(void){ /* Define the encoding for the ringing components configuration. */ enum ring_comp { RING_COMP_NONE = 0x00, RING_COMP_ONE = 0x01, RING_COMP_TWO = 0x02, RING_COMP_THREE = 0x03, }; __ASSERT_NO_MSG(bt_fast_pair_is_ready()); if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_RING_COMP_NONE)) { return RING_COMP_NONE; } else if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_RING_COMP_ONE)) { return RING_COMP_ONE; } else if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_RING_COMP_TWO)) { return RING_COMP_TWO; } else if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_RING_COMP_THREE)) { return RING_COMP_THREE; } __ASSERT(0, "FMDN Ring: incorrect Ringing Components selection"); return 0;}Ringing capabilities的读取函数如下: uint8_t fp_fmdn_ring_cap_encode(void){ /* Define the encoding for the ringing capabilities configuration. */ enum ring_cap { RING_CAP_NONE = 0x00, RING_CAP_VOLUME = 0x01, }; __ASSERT_NO_MSG(bt_fast_pair_is_ready()); if (IS_ENABLED(CONFIG_BT_FAST_PAIR_FMDN_RING_VOLUME)) { return RING_CAP_VOLUME; } return RING_CAP_NONE;Seeker除了配置过程需要发送读取信标参数命令外,同步模式(Synchronization mode)下也会发送读取信标参数命令,读取Clock Value,进行同步时钟。 2)读取配置状态(Read provisioning state):Seeker发送读取配置状态命令,来询问配件设备的配置状态。配件设备返回的数据格式如下: 设备(Provider)验证一次性认证密钥正确后,根据自己的状态(是否已存储EIK,和owner account key是否是当前account key),来设定响应的Provisioning state值,并填入当前的EID通过notify的方式发送给Seeker。 具体的处理过程可以参考函数: static ssize_t provisioning_state_read_handle(struct bt_conn *conn, const struct bt_gatt_attr *attr, struct net_buf_simple *req_data_buf)3)设置EIK(Set ephemeral identity key) 通常在配置期间或EIK被更新后,Seeker发出此命令将加密后的EIK值传递给Provider设备。Seeker传递数据的additional data部分的数据: 32 bytes that are the ephemeral identity key, AES-ECB-128 encrypted with the account key. If the Provider already has an ephemeral identity key set, also send the first 8 bytes of SHA256(current ephemeral identity key || the last nonce read from the characteristic) 32 个字节,即临时身份密钥EIK,使用账户密钥进行 AES-ECB-128 加密。如果Provider已经设置过了临时身份密钥,则同时发送 SHA256 的前 8 个字节(当前临时身份密钥 || 从特征中读取的最后一个随机数)。这种情况是更改EIK的情况,需要验证两次。一次性认证密钥认证一次,SHA256哈希值再验证一次。验证无误后,新的EIK需要写入到Provider设备中, 新的EIK在 Bluetooth LE连接终止后立即生效。 具体的处理过程可以参考函数: static ssize_t ephemeral_identity_key_set_handle(struct bt_conn *conn, const struct bt_gatt_attr *attr, struct net_buf_simple *req_data_buf)
|