Last Updated on : 2024-11-19 08:02:14download
The TCP-based keep-alive mechanism allows a low-power IPC to maintain communication with the cloud. The IPC can exchange data with the cloud while in sleep mode to enable wake-up functionality.
The keep-alive mechanism on the IPC side is divided into three parts.
The following diagram shows how the keep-alive mechanism works.
The packet sent between the Wi-Fi module and the cloud is composed of a header and payload.
Field | Description | Bytes | Valid values |
---|---|---|---|
version | Protocol version number | 1 | The first version is 1 . |
type | Command type | 1 |
|
flag | Identifier | 1 |
|
size | Data length | 2 | The total length of the payload field, excluding the length of the version , type , and flag fields. |
payload | Actual data | N | The payload contains the actual data that is being sent. The encryption of this field depends on the flag field. |
The authentication process follows the data format defined above. The payload includes iv
, devid
, and data
, which are structured in LV format (length plus the actual data), as shown in the following figure.
Field | Bytes | Description |
---|---|---|
iv_len | 2 | The length of IV . |
devid_len | 2 | The length of devid . |
data_len | 2 | The length of data . |
iv | 16 | A 16-byte randomly-generated data, used to decrypt data. |
devid | N | The encrypted device identifier that the cloud uses to request the key for decryption. |
data | N | The actual data being transmitted, which is encrypted with AES-128-CBC. data is encrypted using the local_key and iv in the payload . |
You can get the plaintext devid
using tuya_ipc_get_device_id()
. For security purposes, the plaintext devId
is encrypted using AES-128-CBC with PKCS #7 padding. Finally, the data is encoded to base64. The key
and iv
used for encryption are fixed as follows:
The Wi-Fi module initiates a handshake.
The Wi-Fi module sends a handshake request to the cloud, with the data
in the following format.
{
"type": 1,
"method": 1,
"authorization": "time=138993455,random=sdfsjijweiwemkejitejwitetopwejriew",
"signature": "i2je8fjsesfjeijfiejwifheuhfuwefiweif",
}
type
: indicates whether the request is initiated by the Wi-Fi module (0
) or the SDK (1
). It is fixed to 1
.
method
: the signature algorithm, defaulting to 1
.
authorization
:
time
: the UTC time of the device, which will not be verified in the cloud.random
: a 32-byte random value.signature
: created by encrypting the concatenation of devid:time:random
with HMAC-SHA256 and encoding it to base64. tuya_ipc_get_local_key
is used to get the encrypted key
.
The cloud returns a message.
The cloud generates a signature
and corresponding parameters to send back to the device.
{
"err": 0,
"interval": 60,
"random": "sdfsiiiweiwemkeiiteiwitetopweiniew",
"authorization": "time=138993455,random=qwertyuikfhkof18458yeiurur",
"signature": "i2je8fjsesfjeijfiejwifheuhfuwefiweif",
}
err
: the error code. 0
: success. Other values: failure.
interval
: the heartbeat interval, which is a fixed value and cannot be modified.
random
: the random number the IPC sends to the cloud, which is returned unchanged.
authorization
: the authentication parameters, including time
and random
.
signature
: the signature data.
The IPC verifies data.
The IPC verifies the received data.
Use the iv
and local_key
in the returned payload
to decrypt data
using AES.
Verify the consistency of the random
in the response and request. If they do not match, the verification fails.
Generate a signature by concatenating and encrypting the time
and random
in the received authorization
, in the same way as done in the handshake request.
Compare the generated signature with the signature
in the received message. If they do not match, the verification fails.
The heartbeat packet has fixed content and no payload
. The first version
is 1, type
is 2, flag
is 0, and size
is 0. Here is the assembled data:
0x1 0x2 0x0 0x0 0x0
For the wake-up packet, the first version
is 1, type
is 3, flag
is 0, and size
is 4. The payload
is the CRC32 hash of local_key
returned by tuya_ipc_get_local_key()
.
0x1 0x3 0x0 0x0 0x4 0x11 0x23 0xab 0xbf
For more information, see tuyaos_demo_ipc/application_components/app_main/src/ty_sdk_lowpower.c/ TUYA_IPC_low_power_sample()
.
Get the cloud IP address and port number of the low-power IPC. OPRT_OK
is returned on success.
/**
* \fn OPERATE_RET tuya_ipc_get_low_power_server
* \brief get low power server info
*
* \return OPRT_OK if get IP, port success. Others are failed;
*/
OPERATE_RET tuya_ipc_get_low_power_server(OUT UINT_T *ip,OUT UINT_T *port);
Get the devid
of the IPC and the length of devid
. OPRT_OK
is returned on success.
/**
* \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
Get the local_key
of the device. OPRT_OK
is returned on success.
/**
* \fn OPERATE_RET tuya_ipc_get_local_key
* \brief Get signature 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);
Establish an encrypted channel. OPRT_OK
is returned on success.
/**
* \fn OPERATE_RET tuya_ipc_lowpower_server_connect
* \brief connect low-power server.
* \ serverIp: The IP address of the cloud server;
* \ port: Port number
* \ pdevId: The device ID
* \ idLen: The length of the device ID
* \ pkey: The local_key
* \ keyLen: The length of the 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);
Get the handle to the low-power service.
/**
* \fn OPERATE_RET tuya_ipc_low_power_socket_fd_get
* \brief get low-power socket fd.
* \return fd handle
*/
OPERATE_RET tuya_ipc_low_power_socket_fd_get();
Get the heartbeat packet content of the low-power service.
/**
* \fn OPERATE_RET tuya_ipc_low_power_heart_beat_get
* \brief get low-power heartbeat 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);
Get the wake-up packet content of the low-power service.
/**
* \fn OPERATE_RET tuya_ipc_low_power_wakeup_data_get
* \brief get low-power 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);
In the development kit, the demo file is named ty_sdk_lowpower.c
which you can refer to for development.
The content is the same as what is sent from the IPC, which is 0x1 0x2 0x0 0x0 0x0
.
The encrypted data must be a multiple of 16 bytes. If it is less than 16 bytes or not a multiple of 16 bytes, it needs to be padded using PKCS #7.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback