139 lines
3.0 KiB
JavaScript
139 lines
3.0 KiB
JavaScript
import { toFullUuid } from '../utils/uuid'
|
|
|
|
// ED713 / ED719 当前协议共用的服务与特征 UUID。
|
|
const COMMON_UUIDS = Object.freeze({
|
|
SERVICE: '00F4',
|
|
WIFI: 'F401',
|
|
KEY: 'F402',
|
|
CMD: 'F403',
|
|
MSG: 'F501',
|
|
STATE: 'F301',
|
|
RADAR: 'F302'
|
|
})
|
|
|
|
// UUID_STATE 常用状态码语义映射。
|
|
const COMMON_STATE_MAP = Object.freeze({
|
|
1: 'WIFI_PARAM_INVALID',
|
|
2: 'WIFI_CONNECT_FAILED',
|
|
3: 'WIFI_CONNECT_SUCCESS',
|
|
4: 'WIFI_CONNECTING',
|
|
5: 'BIND_SUCCESS',
|
|
6: 'BIND_FAILED',
|
|
7: 'KEY_MATCH_SUCCESS',
|
|
8: 'KEY_MATCH_FAILED'
|
|
})
|
|
|
|
export const DEVICE_PROFILE = Object.freeze({
|
|
UNKNOWN: 'UNKNOWN',
|
|
ED713: 'ED713',
|
|
ED719: 'ED719'
|
|
})
|
|
|
|
/**
|
|
* 生成设备 profile 模板:
|
|
* 包含 UUID、分包规则、鉴权策略、WiFi 校验、雷达命令能力。
|
|
*/
|
|
function buildCommonProfile(id) {
|
|
return {
|
|
id,
|
|
uuids: {
|
|
service: toFullUuid(COMMON_UUIDS.SERVICE),
|
|
wifi: toFullUuid(COMMON_UUIDS.WIFI),
|
|
key: toFullUuid(COMMON_UUIDS.KEY),
|
|
cmd: toFullUuid(COMMON_UUIDS.CMD),
|
|
msg: toFullUuid(COMMON_UUIDS.MSG),
|
|
state: toFullUuid(COMMON_UUIDS.STATE),
|
|
radar: toFullUuid(COMMON_UUIDS.RADAR)
|
|
},
|
|
stateMap: { ...COMMON_STATE_MAP },
|
|
packet: {
|
|
head: 0xA7,
|
|
chunkSize: 18,
|
|
maxChunk: 15
|
|
},
|
|
auth: {
|
|
keyLength: 16,
|
|
supportsUnboundState: false,
|
|
unboundStateCode: null
|
|
},
|
|
wifi: {
|
|
maxSsidLength: 32,
|
|
minPasswordLength: 8,
|
|
maxPasswordLength: 63,
|
|
invalidChars: ['+', '#', '&', '=', '|', '<', '>', '^', '"', '\\']
|
|
},
|
|
radar: {
|
|
notifySignature: null,
|
|
startCommand: 0xA1,
|
|
stopCommand: 0xA2,
|
|
parseMode: 'GENERIC'
|
|
},
|
|
cmd: {
|
|
supportsNarrowMode: false,
|
|
supportsFallParam67: false
|
|
}
|
|
}
|
|
}
|
|
|
|
const unknownProfile = buildCommonProfile(DEVICE_PROFILE.UNKNOWN)
|
|
|
|
const ed713Profile = {
|
|
...buildCommonProfile(DEVICE_PROFILE.ED713),
|
|
auth: {
|
|
keyLength: 16,
|
|
supportsUnboundState: true,
|
|
unboundStateCode: -1
|
|
},
|
|
radar: {
|
|
notifySignature: 0x7C,
|
|
startCommand: 0xA1,
|
|
stopCommand: 0xA2,
|
|
parseMode: 'ED713'
|
|
},
|
|
cmd: {
|
|
supportsNarrowMode: true,
|
|
supportsFallParam67: false
|
|
}
|
|
}
|
|
|
|
const ed719Profile = {
|
|
...buildCommonProfile(DEVICE_PROFILE.ED719),
|
|
radar: {
|
|
notifySignature: 0x67,
|
|
startCommand: 0xA1,
|
|
stopCommand: 0xA2,
|
|
parseMode: 'ED719'
|
|
},
|
|
cmd: {
|
|
supportsNarrowMode: false,
|
|
supportsFallParam67: true
|
|
}
|
|
}
|
|
|
|
export const BLE_PROFILE_MAP = Object.freeze({
|
|
[DEVICE_PROFILE.UNKNOWN]: unknownProfile,
|
|
[DEVICE_PROFILE.ED713]: ed713Profile,
|
|
[DEVICE_PROFILE.ED719]: ed719Profile
|
|
})
|
|
|
|
export function getBleProfile(profileId = DEVICE_PROFILE.UNKNOWN) {
|
|
return BLE_PROFILE_MAP[profileId] || BLE_PROFILE_MAP[DEVICE_PROFILE.UNKNOWN]
|
|
}
|
|
|
|
/**
|
|
* 根据雷达帧签名字节粗略推断设备类型。
|
|
*/
|
|
export function guessProfileByRadarFrame(frame = new Uint8Array()) {
|
|
const signature = frame[3]
|
|
|
|
if (signature === 0x7C) {
|
|
return DEVICE_PROFILE.ED713
|
|
}
|
|
|
|
if (signature === 0x67) {
|
|
return DEVICE_PROFILE.ED719
|
|
}
|
|
|
|
return DEVICE_PROFILE.UNKNOWN
|
|
}
|