Send Motion Control Commands over P2P Channel

Last Updated on : 2026-05-11 06:43:40Copy for LLMView as MarkdownDownload PDF

The P2P Biz Command module sends business commands over a P2P channel. It supports motion control scenarios, such as pan-tilt-zoom (PTZ) control, mobile camera rotation, and cruise plans. The app sends motion commands to the device over a P2P connection. The device parses the commands, controls motors, and returns execution results to the app.

Process

Mobile app                           Device
  |                                   |
  |--- Skill query ------------------>|  (Query motion capabilities.)
  |<-- Skill response ----------------|  (Return supported motors and capabilities.)
  |                                   |
  |--- Action command --------------->|  (Send motion commands.)
  |<-- Execution result --------------|  (Report execution status.)
  |                                   |
  |--- Cancel or Clean -------------->|  (Cancel or clean commands.)
  |<-- Cancel result -----------------|

Import header files

#include "tuya_ipc_p2p_biz_cmd.h"

Data structures

Command type BIZ_CMD_E

Enum value Description
BIZ_CMD_SKILL_QUERY Query the device’s motion capabilities.
BIZ_CMD_ACTION Execute a motion command.
BIZ_CMD_ACTION_CANCEL Cancel a specific motion command.
BIZ_CMD_ACTION_CLEAN Clean all pending commands in a session.

Direction enum BIZ_DIR_E

Enum value Description
BIZ_DIR_FRONT Front
BIZ_DIR_RIGHT_FRONT Front right
BIZ_DIR_RIGHT Right
BIZ_DIR_RIGHT_BACK Back right
BIZ_DIR_BACK Back
BIZ_DIR_LEFT_BACK Back left
BIZ_DIR_LEFT Left
BIZ_DIR_LEFT_FRONT Front left

Use bitwise operations to combine directions. For example, BIZ_DIR_FRONT | BIZ_DIR_BACK enables both front and back.

Motor type BIZ_MOTOR_TYPE_E

Enum value Description
BIZ_MOTOR_TYPE_PTZ PTZ rotation
BIZ_MOTOR_TYPE_MOVE_IPC 360-degree mobile camera movement
BIZ_MOTOR_TYPE_CRUISE_PLAN Cruise plan control

Command status BIZ_CMD_STATUS_E

Enum value Description
BIZ_CMD_STATUS_RECVED Received
BIZ_CMD_STATUS_FINISH Finished
BIZ_CMD_STATUS_FAIL Failed

Direction command DIRECTION_T

typedef struct {
    BOOL_T valid;     // Indicates whether the command is valid.
    INT_T  angle;     // Rotation angle in degrees.
    INT_T  direction; // Rotation direction. See BIZ_DIR_E.
    INT_T  speed;     // Rotation speed.
    INT_T  time;      // Rotation time.
} DIRECTION_T;

Use angle and direction exclusively. Specify either a direction or an angle.

Movement command MOVE_T

typedef struct {
    BOOL_T valid;     // Indicates whether the command is valid.
    INT_T  angle;     // Movement angle in degrees.
    INT_T  direction; // Movement direction. See BIZ_DIR_E.
    INT_T  speed;     // Movement speed.
    INT_T  time;      // Movement duration (-1: Continuous movement. 0: Stop movement.)
    INT_T  distance;  // Movement distance.
} MOVE_T;

Action description ACTION_T

typedef struct {
    BOOL_T           is_valid;     // Indicates whether the command is valid.
    INT_T            motor_id;    // Motor ID.
    BIZ_MOTOR_TYPE_E motor_type;  // Motor type.
    DIRECTION_T      direction;   // Direction command.
    MOVE_T           move;        // Movement command.
} ACTION_T;

Motion command MOTION_CMD_T

typedef struct {
    UINT_T   cmd_id;      // Command sequence number. Increments with each new command.
    INT_T   motor_id;     // Motor ID.
    INT_T   actions_cnt;  // Action count.
    ACTION_T actions[0];  // Flexible array member for actions.
} MOTION_CMD_T;

Cancel command MOTION_CANCEL_CMD_T

typedef struct {
    UINT_T cmd_id;          // Sequence number of the current command.
    UINT_T target_cmd_id;   // ID of the command to cancel.
} MOTION_CANCEL_CMD_T;

API description

Initialization

Register the business command callback by setting the on_biz_cmd_recv_cb parameter in tuya_ipc_media_stream_init.

When the SDK receives a P2P business command, it passes the parsed struct to this callback.

Callback function prototype:

typedef OPERATE_RET (*BIZ_CMD_CB)(
    UINT_T session_id,    // P2P session ID.
    BIZ_CMD_E cmd_type,   // Command type.
    VOID *cmds,           // Command data. Cast to the struct that matches cmd_type.
    VOID *rets,           // Return data. Used only for SKILL_QUERY.
    INT_T *rets_len       // Return data length.
);

Deinitialization

No settings are required.

Send execution results

OPERATE_RET tuya_ipc_p2p_biz_cmd_send_resp(
    UINT_T session_id,       // P2P session ID.
    UINT_T cmd_id,           // Command ID from MOTION_CMD_T.cmd_id.
    BIZ_CMD_E cmd,           // Command type.
    BIZ_CMD_STATUS_E status, // Execution status: FINISH or FAIL.
    CHAR_T *reason           // Failure reason. Pass NULL on success.
);

After a motion command finishes, you must call this API to return the execution result to the app.

Integration steps

Initialize the module and register the callback

// Register Biz cmd callback.
Set on_biz_cmd_recv_cb when you call tuya_ipc_media_stream_init.

Implement the skill query callback

After the app connects to the device, it first queries motion capabilities. Fill in MOTORS_SKILL_T based on the actual hardware capabilities of your product.

STATIC OPERATE_RET on_skill_query(VOID *rets, INT_T *rets_len)
{
    ...
}

Allocate memory for MOTORS_SKILL_T with tal_malloc. The SDK frees the memory.

Implement the motion command callback (core)

Process different command types based on cmd_type in the callback:

OPERATE_RET ty_app_p2p_biz_cmd_process(UINT_T session_id, BIZ_CMD_E cmd_type,
                                        VOID *cmds, VOID *rets, INT_T *rets_len)
{
    ...
}

Do not block the callback. Put commands into a queue asynchronously, and use a separate thread to execute motion actions. Blocking the callback delays later commands.

Process action commands

When the device receives BIZ_CMD_ACTION, add the command to the pending queue and overwrite previous commands in the same session.

STATIC OPERATE_RET on_motion_action(UINT_T session_id, VOID *cmds)
{
    ...
}

Process cancel and clean commands

// Cancel a specific command.
STATIC OPERATE_RET on_motion_cancel(UINT_T session_id, VOID *cmds)
{
    ...
}

// Clean all pending commands in a session.
STATIC OPERATE_RET on_motion_clean(UINT_T session_id)
{
    ...
}

Execute motion and return results

In a separate thread, fetch commands from the queue and call the actual motor control APIs. After the action finishes, call tuya_ipc_p2p_biz_cmd_send_resp to return the result:

// Execute the motion.


// Return the execution result.
tuya_ipc_p2p_biz_cmd_send_resp(
    entry->session_id,
    entry->motion_cmd.cmd_id,
    BIZ_CMD_ACTION,
    BIZ_CMD_STATUS_FINISH,  // Or BIZ_CMD_STATUS_FAIL.
    NULL                     // On failure, pass the reason string.
);

Key design considerations

Asynchronous processing architecture

Callback function (SDK thread)      Motion processing thread
    |                                       |
    |-- Add to command queue -------------->|
    |  (Return immediately, non-blocking)   |-- Fetch command
    |                                       |-- Execute motor actions
    |                                       |-- Send result
    |                                       |-- Release node memory

Command overwrite mechanism

When the app sends multiple motion commands in sequence in the same session, the new command overwrites the previous one:

  • Mark the previous command status as COVERED.
  • Send a Finish response and release the node when the motion thread finds a node in the COVERED status.
  • Add the new command to the head of the queue to run it first.

Thread safety

Use tal_mutex_lock and tal_mutex_unlock to protect all operations on the cmd_list command queue, including:

  • Add or modify nodes in the callback.
  • Read or delete nodes in the motion thread.

Customization checklist

During integration, update the following items based on your product:

Item Description
MOTOR_CNT Motor count. Keep it consistent with the hardware.
motor_type Motor type. See BIZ_MOTOR_TYPE_E.
direction capability Direction support such as angle, direction, speed, and duration.
move capability Movement support, such as direction combinations, duration, and distance.
Motor driver call Replace with your motor control API in the motion thread.
Motion thread stack size Adjust stackDepth based on actual requirements. The default value is 512 KB.

Error code reference

Error code Description
OPRT_OK Success.
OPRT_INVALID_PARM Invalid parameter.
OPRT_MALLOC_FAILED Memory allocation failed.

For more information about the error code, see tuya_error_code.h.