更新时间:2024-11-19 08:15:03下载pdf
IPC 低功耗保活唤醒,是涂鸦为低功耗设备提供的基于 TCP 协议的设备与云端之间的保活方法。设备在休眠期间可以实现与云端之间的交互,从而达到休眠唤醒的目的。
低功耗保活唤醒 在设备端主要分为三个部分:
低功耗保活唤醒 的交互流程如下图所示:
Wi-Fi 模组与云端之间的数据通信统一由消息头(Header)和消息载体(Payload)组成,如下:
字段 | 解释 | 字节数 | 取值说明 |
---|---|---|---|
version | 协议号 | 1 | 第一版为 1 。 |
type | 命令号 | 1 |
|
flag | 标识符 | 1 |
|
size | 数据长度 | 2 | payload 字段总的长度,不包含 version 、type 、flag 三个字段的长度。 |
payload | 实际数据 | N | 加载的具体数据,该字段是否需要加密根据 flag 类别确定。 |
鉴权的数据交互采用前述的 数据格式,Payload 部分包括 iv
、devid
、data
三部分,以上三个字段采用 LV 形式组织,即长度加实际有效数据,如下图所示:
字段 | 字节数 | 说明 |
---|---|---|
iv_len | 2 | iv 长度。 |
devid_len | 2 | devid 长度。 |
data_len | 2 | data 长度。 |
iv | 16 | 用于解密使用,用户自定义随机生成一个 16 字节数据。 |
devid | N | 加密后的设备标识,云端用来查询解密需要使用的 key 。 |
data | N | 交互数据,需要采用 AES CBC 128 加密。data 的加密使用 local_key 和 payload 里的 iv 。 |
原始 devid
使用 tuya_ipc_device_id_get()
接口获取。出于安全考虑,原始 devId
需要使用 AES CBC 128 加密,需要做 PKCS7 padding。并且最后进行 Base64 加密,加密使用的 key
和 iv
固定如下:
发起握手请求。
Wi-Fi 模组向云端发起握手请求,data
参数格式如下:
{
"type": 1,
"method": 1,
"authorization": "time=138993455,random=sdfsjijweiwemkejitejwitetopwejriew",
"signature": "i2je8fjsesfjeijfiejwifheuhfuwefiweif",
}
type
:表示发起请求的是 Wi-Fi 模组(0
),还是 SDK(1
)。固定为 1
。
method
:签名算法类型,默认为 1
。
authorization
:
time
:设备的 UTC 时间,云端不做校验random
:随机的 32 字节signature
:按照 devid:time:random
格式拼接,对拼接后的数据先进行 HMac SHA256 加密,然后进行 Base64 加密,计算得出。tuya_ipc_get_local_key
接口获取加密 key
。
云端消息返回。
云端按照签名算法计算出 signature
,同时生成相应的参数返回给设备,云端返回的格式如下:
{
"err": 0,
"interval": 60,
"random": "sdfsiiiweiwemkeiiteiwitetopweiniew",
"authorization": "time=138993455,random=qwertyuikfhkof18458yeiurur",
"signature": "i2je8fjsesfjeijfiejwifheuhfuwefiweif",
}
err
:错误码,0 表示成功,其它表示失败。
interval
:心跳间隔时间,该值为固定值,不支持修改。
random
:IPC 发送给云端的随机数,云端原样返回。
authorization
:认证参数,包含时间和随机数。
signature
:签名数据。
数据检验认证。
IPC 设备对接受到的数据进行校验认证:
使用云端返回 payload
中的 iv
和 local_key
,对 data
进行 AES 解密。
将 random
和请求中的 random
进行比较,若不一致则校验失败。
将 authrization
中的 time
和 random
使用与请求中 devid:time:random
相同的方式计算签名。
将上一步计算出的签名与报文中的 signature
进行对比,若不一致则校验失败。
心跳数据内容固定,没有 payload
,第一版 version
为 1,type
为 2,flag
为 0,size
字段为 0,最后组装的数据如下:
0x1 0x2 0x0 0x0 0x0
唤醒数据包,第一版 version
为 1,type
为 3,flag
为 0,size
字段为 4,playload
字段由 SDK 提供 tuya_ipc_get_local_key()
获取 local_key
,通过计算 local_key
的 Hash CRC32 值而来。
0x1 0x3 0x0 0x0 0x4 0x11 0x23 0xab 0xbf
以涂鸦低功耗方案为例。使用此类方案的设备由四个部分组成,分别是主控芯片、Wi-Fi 芯片、低功耗保活服务器和 MQTT 服务器。作用分别如下:
在唤醒过程中,设备交互流程如下:
在休眠过程中,设备交互流程如下:
在休眠情况下,主控下电,设备不再直接连接 MQTT 服务器,转而连接保活服务器。
在非必要情况下,设备侧不要主动断开 MQTT 和保活链路的 TCP 连接,因为设备侧主动断开的行为会在云端产生一个离线消息。
参考 tuyaos_demo_ipc/application_components/app_main/src/ty_sdk_lowpower.c/ TUYA_IPC_low_power_sample()
。
获取低功耗云端 IP 和端口信息,成功返回 OPRT_OK
。
/**
* @brief get low power server info v2
*
* @param[out] domain: server domain
* @param[in] domain_len: domain length
* @param[out] ip: server IP address
* @param[out] port: server port
*
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*/
OPERATE_RET tuya_ipc_get_low_power_server_v2(OUT CHAR_T *domain, IN INT_T domain_len, OUT UINT_T *ip, OUT UINT_T *port);
获取设备的 devid,以及 devid 长度,成功返回 OPRT_OK
/**
* \fn OPERATE_RET tuya_ipc_get_device_id
* \brief get device ID
* \
* \return OPRT_OK if get device ID success .other is failed;
*/
OPERATE_RET tuya_ipc_get_device_id(IN OUT CHAR_T *devid, IN OUT INT_T * id_len);
获取设备的 local_key
,成功返回 OPRT_OK
。
/**
* \fn OPERATE_RET tuya_ipc_get_local_key
* \brief Get signatrue key from ipc SDK.
* \ make destKeyBuf len >=17;
* \return OPRT_OK if get key success
*/
OPERATE_RET tuya_ipc_get_local_key(OUT CHAR_T * destKeybuf,OUT UINT_T * len);
构建加密通道,成功返回 OPRT_OK
。
/**
* \fn OPERATE_RET tuya_ipc_low_power_server_connect
* \brief connect lowpower server.
* \ serverIp:云端服务器 IP;
* \ port:端口号
* \ pdevId:设备 ID
* \ idLen:设备 ID 长度
* \ pkey:local_key
* \ keyLen:local_key 长度
* \return OPRT_OK if get key success
*/
OPERATE_RET tuya_ipc_low_power_server_connect(UNW_IP_ADDR_T serverIp,INT_T port,char* pdevId, int idLen, char* pkey, int keyLen);
获取低功耗服务句柄。
/**
* \fn OPERATE_RET tuya_ipc_low_power_socket_fd_get
* \brief get lowpower socket fd.
* \return fd handle
*/
OPERATE_RET tuya_ipc_low_power_socket_fd_get();
获取低功耗服务心跳包内容。
/**
* \fn OPERATE_RET tuya_ipc_low_power_heart_beat_get
* \brief get lowpower heart beat info.
* \return OPRT_OK if get key success
*/
OPERATE_RET tuya_ipc_low_power_heart_beat_get(OUT CHAR_T * pdata,OUT UINT_T *plen);
获取低功耗服务唤醒包内容。
/**
* \fn OPERATE_RET tuya_ipc_low_power_wakeup_data_get
* \brief get lowpower wakeup info.
* \return OPRT_OK if get key success
*/
OPERATE_RET tuya_ipc_low_power_wakeup_data_get(OUT CHAR_T* pdata, OUT UINT_T* plen);
在开发包中,Demo 文件名为 ty_sdk_lowpower.c
,您可以参考 Demo 进行开发。
和设备端发送的一致:0x1、0x2、0x0、0x0,0x0
AES 128 CBC 进行加密后的数据一定是 16 字节的倍数,如果不足 16 字节或者 16 字节的倍数需要用 PKcs7 的方式进行填充。
如果 TCP 连接失败,可以尝试通过 tuya_ipc_get_low_power_server_v2
获取到的域名信息,重新请求获取 IP 地址信息,进行 TCP 连接保活尝试。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈