GFPS扩展技术原理(十)-FMDN Notification
GATT Error code
前面一节,我们介绍了Seeker会对beacon action 特征值进行写操作,那么Provider收到之后,第一步就会对One-time authentication key进行校验,如果校验不过,那么会返回GATT error code:Unauthenticated,当然还定义了其他的Error code,如下:
code ID | 描述 | 备注 |
---|---|---|
0x80 | Unauthenticated | Returned in response to a write request when authentication fails (including the case where an old nonce was used). |
0x81 | Invalid value | Returned when any invalid value is provided or the data received has an unexpected number of bytes. |
0x82 | No user consent | Returned in response to a write request with data ID 0x04: Read ephemeral identity key with user consent when the device isn’t in pairing mode. |
Notification for beacon action
Seeker通过写beacon action特征值设置之前说到的九个命令,然后Provider需要回复一Notification,同样根据Data ID定义了九个Notification:
- Read beacon parameters:
Seeker发起Read beacon parameter写之后,Provider收到会先进行one-time authentication key校验,校验成功后会返回如下格式的Notification(数据需用account key通过AES-ECB-128方式加密):
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x0 |
1 | uint8 | Data length | 24 |
2 - 9 | byte array | One-time authentication key | 取前8个字节HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data after encryption || 0x01). |
10 | uint8 | Calibrated power | The calibrated power as received at 0m (a value in the range [-100, 20]). Represented as a signed integer, with 1 dBm resolution. |
11 - 14 | uint32 | Clock value | The current clock value in seconds (big endian). |
15 | uint8 | Curve selection | 椭圆曲线加密算法选择: 0x00 (default): SECP160R1 0x01: SECP256R1 (requires extended advertising) |
16 | uint8 | Components | The number of components capable of ringing: 0x00: Indicates that the device is incapable of ringing. 0x01: Indicates that only a single component is capable of ringing. 0x02: Indicates that two components, left and right buds, are capable of ringing independently. 0x03: Indicates that three components, left and right buds and the case, are capable of ringing independently. |
17 | uint8 | Ringing capabilities | The supported options are: 0x00: Ringing volume selection not available. 0x01: Ringing volume selection available. If set, the Provider must accept and handle 3 volume levels as indicated in Ring operation. |
18-25 | byte array | Padding | Zero padding for AES encryption. |
- Read provisioning state:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x1 |
1 | uint8 | Data length | 29或者41 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data || 0x01) |
10 | uint8 | Provisioning state | A bitmask having the following values: Bit 1 (0x01): Set if an ephemeral identity key is set for the device. Bit 2 (0x02): Set if the provided one-time authentication key matches the owner account key. |
11 - 30 or 42 | byte array | Current ephemeral identifier | 20 or 32 bytes (depending on the encryption method being used) indicating the current ephemeral ID advertised by the beacon, if one is set for the device. |
3 Set ephemeral identity key:
要配置Provider为FMDN beacon,就需要Seeker设置ephemeral identity key,Provider收到后,会做如下校验:
- 会校验one-time authentication key 是否匹配the owner account key.
- 如果是提供的ephemeral identity key的8字节哈希值,就要算出这个哈希值是否与当前的ephemeral identity key是否匹配
- 如果ephemeral identity key的哈希值没有提供,需要验证Provider已经没有被配置为FMDN beacon了。
上述校验通过后,Provider会利用account key通过AES-ECB-128方式进行解密ephemeral identity key,然后会保存在本地,从此刻开始Provider就需要开始广播FMDN帧数据。
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x2 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || 0x01). |
- Clear ephemeral identity key:
Provider收到clear ephemeral identity key写命令后,会进行One-time authentication key校验和EIK的哈希值毕竟,如果成功了就会停止广播FMDN数据。并且回复如下格式Notification:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x3 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(account key, protocol major version number || the last nonce read from the characteristic || data ID || data length || 0x01) |
- Recovery ephemeral identity key with user consent:
当EIK在Seeker上丢失并且想要恢复EIK,并且Provider处于配对模式或者通过按钮设置在特定时间内,Provider才会响应这个写命令,并且通过如下格式Notification发送给Seeker,Seeker收到后,需要讲EIK保存在本地,但不能上传云端。
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x4 |
1 | uint8 | Data length | 40 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(recovery key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data || 0x01) |
10-41 | byte array | EIK | 32 bytes that are the ephemeral identity key, AES-ECB-128 encrypted with the account key |
- Ring state change:
Seeker通过Ring命令要求Provider进行响铃,Provider收到后会进行如下校验:
1: one-time authentication key 能够匹配 the ring key.
2:要求响铃的component有响铃的能力
但是如果Provider的unwanted tracking protection模式被打开并且要求跳过ring key校验的时候,会跳过上面第一步校验
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x5 |
1 | uint8 | Data length | 12 |
2 - 9 | byte array | One-time authentication key | HMAC-SHA256(ring key, protocol major version number || the nonce used to initiate the ringing command || data ID || data length || additional data || 0x01) |
10 | uint8 | Ringing state | 0x00: Started 0x01: Failed to start or stop (all requested components are out of range) 0x02: Stopped (timeout) 0x03: Stopped (button press) 0x04: Stopped (GATT request) |
11 | uint8 | Ringing components | A bitmask having the following values: Bit 1 (0x01): Ring right Bit 2 (0x02): Ring left Bit 3 (0x04): Ring case 0xFF: Ring all components 0x00: Stop ringing |
12 - 13 | uint16 | Timeout | The remaining time for ringing in deciseconds. If the device has stopped ringing, 0x0000 should be returned. |
- Read ringing state:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x6 |
1 | uint8 | Data length | 11 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256 (ring key, protocol major version number || the last nonce read from the characteristic || data ID || data length || additional data || 0x01) |
10 | uint8 | Ringing components | A bitmask having the following values: Bit 1 (0x01): Ring right Bit 2 (0x02): Ring left Bit 3 (0x04): Ring case 0xFF: Ring all components 0x00: Stop ringing |
11 - 12 | uint16 | Timeout | The remaining time for ringing in deciseconds. Note that if the device isn’t ringing, 0x0000 should be returned. |
- Activate unwanted tracking protection mode:
Unwanted tracking protection 模式旨在让任何客户端在不与服务端交流的情况下能够识别滥用设备. Provider处于此模式下,会临时使用一个固定MAC地址,允许任何Seeker能够探测和给用户报警存在不必要的跟踪。
不被跟踪保护模式被激活后,Provider的RPA地址更新的速度要变慢,变成24小时一次更新,数据格式如下:
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x7 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(unwanted tracking protection key, protocol major version number || the last nonce read from the characteristic || data ID || data length || 0x01) |
- Deactivate unwanted tracking protection mode:
当我们关闭unwanted tracking protection模式后,FMDN广播的RPA地址就会按照1024秒的平均值进行地址更新,以防止被跟踪。
字节 | 数据类型 | 描述 | 值 |
---|---|---|---|
0 | uint8 | Data ID | 0x8 |
1 | uint8 | Data length | 8 |
2 - 9 | byte array | One-time authentication key | The first 8 bytes of HMAC-SHA256(unwanted tracking protection key, protocol major version number || the last nonce read from the characteristic || data ID || data length || 0x01)s |