Keep-Alive and Wake-Up in Low Power

Last Updated on : 2024-02-05 06:40:58download

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.

Description

The keep-alive mechanism on the IPC side is divided into three parts.

  • Establish a keep-alive channel (connection and authentication).
  • Send heartbeat packets.
  • Receive wake-up packets.

The following diagram shows how the keep-alive mechanism works.

Wi-Fi ModuleCloudConnectRequest authenticationRespond to authentication requestHeartbeat packetHeartbeat packetWake-up packetAfter the microcontroller getsconnected over MQTT, close the connection.Wi-Fi ModuleCloudConnection, authentication, keep-alive, and wake-up process

Protocol integration

Data format

The packet sent between the Wi-Fi module and the cloud is composed of a header and payload.

Keep-Alive and Wake-Up in Low Power
Field Description Bytes Valid values
version Protocol version number 1 The first version is 1.
type Command type 1
  • 0: Authentication request
  • 1: Authentication response
  • 2: Heartbeat packet
  • 3: Wake-up packet
flag Identifier 1
  • The upper four bits are reserved for later use.
  • The lower four bits indicate the encryption type of the data segment. The authentication payload is encrypted using AES-128-CBC with PKCS #7 padding. The flag is set to 0x1, indicating encryption is enabled. If the lower four bits are set to 0, no encryption is applied.
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.

Authentication process

  1. Establish a TCP connection between the Wi-Fi module and the cloud.
  2. The Wi-Fi module initiates an authentication request to the cloud.
  3. The cloud verifies the received data and responds with a message if the data is verified.
  4. The Wi-Fi module verifies the signature. If the verification succeeds, the secure data channel is opened for incoming data such as heartbeat packets.

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.

Keep-Alive and Wake-Up in Low Power
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:

Keep-Alive and Wake-Up in Low Power
  1. 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.

  2. 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.

  3. The IPC verifies data.

    The IPC verifies the received data.

    1. Use the iv and local_key in the returned payload to decrypt data using AES.

    2. Verify the consistency of the random in the response and request. If they do not match, the verification fails.

    3. 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.

    4. Compare the generated signature with the signature in the received message. If they do not match, the verification fails.

Heartbeat packet

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

Wake-up packet

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

Process overview

For more information, see tuyaos_demo_ipc/application_components/app_main/src/ty_sdk_lowpower.c/ TUYA_IPC_low_power_sample().

Yes
No
Enter sleep mode
Call tuya_ipc_low_power_server_connect to establish keep-alive link
Call tuya_ipc_low_power_socket_fd_get to get the handle to the keep-alive link
Call tuya_ipc_low_power_heart_beat_get to get the raw heartbeat data
Call tuya_ipc_low_power_wakeup_data_get to get the raw wake-up data
Send heartbeat packet regularly
Wake-up packet received?
Start service

API description

Get the cloud IP address and port number

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 device ID

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);

Get the 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

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 service handle

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

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

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);

FAQs

How can I get the demo?

In the development kit, the demo file is named ty_sdk_lowpower.c which you can refer to for development.

How does the cloud respond to an IPC heartbeat packet?

The content is the same as what is sent from the IPC, which is 0x1 0x2 0x0 0x0 0x0.

What are the requirements for data encrypted with AES-128-CBC?

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.

Should the device proactively close the keep-alive and MQTT in low power mode?

  • When the device receives a wake-up packet from the cloud in keep-alive low power mode, it only needs to start the requested service without terminating the TCP keep-alive.
  • When the device establishes a TCP connection in non-keep-alive low power mode, it does not need to proactively close the MQTT connection.