Quick Start

Last Updated on : 2022-11-24 09:20:04

This topic describes how to create a gateway product on the Tuya IoT Development Platform and use the integrated SDK to build applications for a lightweight gateway to connect it to the cloud.

Create a product

To use the integrated SDK to build gateway applications, you need to create a gateway product on the platform first.

  1. Log in to the Tuya IoT Development Platform.

    If you do not have an account, register for an account.

  2. Click Create.

    Quick Start

  3. In the Standard Category tab, choose Gateway Control > Gateway.

    Quick Start

  4. Choose TuyaOS.

    Quick Start

  5. In the Custom Solution tab, choose Extend SDK if you use Tuya’s modules or Networking SDK otherwise.

    Quick Start

  6. Complete the required information and click Create.

    Quick Start

  7. You will be prompted to Add Standard Function. You can click OK to close the window and add the desired functions later.

    Quick Start

  8. On the page that appears, you can find the PID that the platform assigns to your gateway.

    Quick Start

  9. In the Function Definition tab, you can add Standard Functions and Custom Functions as needed. For more information, see Standard Function and Custom Function.

    Quick Start

  10. In the Device Panel tab, select the desired all-in-one app panel and click Apply. For more information, see Design App UI.

    Quick Start

  11. In the Hardware Development tab, select the desired module and then request the free licenses.

    We use Ubuntu as an example to describe the development process. For the hardware, choose General CPU. Click Get 2 Free Licenses and request the licenses as instructed on the page.

    The unique license can only be used on one device. The free license is for debugging purposes only. If your product is to be distributed in the market, you need to purchase the licenses for production.

    Quick Start

The creation of a gateway product is completed.

Get the SDK

Download the integrated SDK from GitHub. If you do not find the desired toolchain, contact Tuya’s technical support.

Development guide

This section describes how to code for a lightweight gateway and connect it to the cloud.

Lightweight model

With the SDK, we can build a lightweight model that implements the basic APIs used to fulfill the essential features of a gateway. The following diagram shows the sequence of API calls.

Quick Start

The service init and service start can be Tuya-specific generic services or your private services.

Create a project

The application code of each project should be stored in an individual folder under the apps directory. For this sample project, we create a folder named tuyaos_demo_mini_gw to store the sample code.

Create a makefile

Create a file named Makefile under the tuyaos_demo_mini_gw directory. You can copy the following sample to your Makefile file.

ROOT_DIR        ?= $(abspath ../../)
COMPILE_PREX    ?=
USER_LINK_FLAGS ?=

-include ./build/build_param

AR         = $(COMPILE_PREX)ar
CC         = $(COMPILE_PREX)gcc
NM         = $(COMPILE_PREX)nm
CPP        = $(COMPILE_PREX)g++
OBJCOPY    = $(COMPILE_PREX)objcopy
OBJDUMP    = $(COMPILE_PREX)objdump
APP_PACK   = ./build/pack.sh

LINKFLAGS  = -L$(ROOT_DIR)/sdk/lib \
             -lty_iot_sdk \
             -lty_module_gw_base \
             -lpthread -lm
LINKFLAGS += $(USER_LINK_FLAGS)
LINKFLAGS := -Wl,--start-group $(LINKFLAGS) -Wl,--end-group

CCFLAGS    = -g -fPIC -Werror=unused-function

DEFINES    = -DAPP_BIN_NAME=\"$(APP_BIN_NAME)\" \
             -DUSER_SW_VER=\"$(USER_SW_VER)\"

CFLAGS     = $(CCFLAGS) $(DEFINES) $(USER_INCS) $(USER_CFLAGS)

# The output variables
OUTPUT_DIR      = $(ROOT_DIR)/output/$(APP_BIN_NAME)_$(USER_SW_VER)
OUTPUT_DIR_OBJS = $(OUTPUT_DIR)/.objs

# The build variables
USER_SRC_BASE_DIR  = src

USER_INC_BASE_DIR  = include
USER_INC_BASE_DIR += $(shell find $(ROOT_DIR)/sdk -name include -type d)

# The build files
USER_SRC_DIRS      = $(shell find $(USER_SRC_BASE_DIR) -type d)
USER_SRCS         += $(foreach dir, $(USER_SRC_DIRS), $(wildcard $(dir)/*.c))
USER_SRCS         += $(foreach dir, $(USER_SRC_DIRS), $(wildcard $(dir)/*.cpp))
USER_SRCS         += $(foreach dir, $(USER_SRC_DIRS), $(wildcard $(dir)/*.s))
USER_SRCS         += $(foreach dir, $(USER_SRC_DIRS), $(wildcard $(dir)/*.S))

USER_INCS          = $(addprefix -I ,  $(shell find $(USER_INC_BASE_DIR) -type d) )
USER_OBJS          = $(addsuffix .o, $(USER_SRCS))
USER_OBJS_OUT      = $(addprefix $(OUTPUT_DIR_OBJS)/, $(USER_OBJS))

all: pack

pack: build_app
ifeq ($(APP_PACK),$(wildcard $(APP_PACK)))
	sh $(APP_PACK) $(OUTPUT_DIR) $(ROOT_DIR) $(APP_BIN_NAME) $(USER_SW_VER) $(COMPILE_PREX)
endif

build_app: $(USER_OBJS_OUT)
	$(CC) $(USER_OBJS_OUT) $(CFLAGS) $(LINKFLAGS) -o $(OUTPUT_DIR)/$(APP_BIN_NAME)
	@echo "Build APP Finish"

$(OUTPUT_DIR_OBJS)/%.c.o: %.c
	@mkdir -p $(dir $@);
	$(CC) $(CFLAGS) -o $@ -c $<

$(OUTPUT_DIR_OBJS)/%.cpp.o: %.cpp
	@mkdir -p $(dir $@);
	$(CC) $(CFLAGS) -o $@ -c $<

$(OUTPUT_DIR_OBJS)/%.s.o: %.s
	@mkdir -p $(dir $@);
	$(CC) $(CFLAGS) -o $@ -c $<

$(OUTPUT_DIR_OBJS)/%.S.o: %.S
	@mkdir -p $(dir $@);
	$(CC) $(CFLAGS) -D__ASSEMBLER__ -o $@ -c $<


.PHONY: all clean SHOWARGS build_app pack
clean:
	rm -rf $(OUTPUT_DIR)

Edit code

Create a folder named src under the tuyaos_demo_mini_gw directory to store the source code. In this src folder, create a file named main.c.

  1. Reference the header file.

    #include <unistd.h>
    
    #include "uni_log.h"
    #include "base_os_adapter.h"
    #include "tuya_iot_base_api.h"
    #include "tuya_iot_com_api.h"
    
    #include "tuya_iot_sdk_api.h"
    #include "tuya_iot_sdk_defs.h"
    
    #if defined(TY_BT_MOD) && (TY_BT_MOD == 1)
    #include "tuya_os_adapt_bt.h"
    #endif
    
  2. Define the PID and license that you have obtained in the step Create a product as a macro.

    #define PID       "fljmamufiym5fktz"                  // Replace it with your own PID.
    #define UUID      "tuya461dbc63aeeb991f"              // Replace it with your own UUID.
    #define AUTHKEY   "c8X4PR4wx1gMFaQlaZu5dfgVvVRwB8Ug"  // Replace it with your own AUTHKEY.
    
  3. In the main.c file, implement the following functions according to the sequence of API calls.

    int main(int argc, char **argv)
    {
        /* If your SDK supports Bluetooth pairing, you must call the Bluetooth registration function first. Otherwise, the startup will fail. */
    #if defined(TY_BT_MOD) && (TY_BT_MOD == 1)
        tuya_os_adapt_reg_bt_intf();
    #endif
    
        /* OS layer initialization */
        tuya_os_intf_init();
    
        /* IoT layer initialization */
        tuya_iot_init("./");
    
        /* Set the authorization information */
        prod_info.uuid     = UUID;
        prod_info.auth_key = AUTHKEY;
        tuya_iot_set_gw_prod_info(&prod_info));
    
        /* SDK pre-initialization */
        tuya_iot_sdk_pre_init(TRUE);  
    
        /* Service application initialization */
        TY_GW_INFRA_CBS_S gw_cbs = {
            .gw_reset_cb       = __gw_reset_cb,
            .gw_upgrade_cb     = __gw_upgrade_cb,
            .gw_active_stat_cb = __gw_active_stat_cb,
            .gw_reboot_cb      = __gw_reboot_cb,
        };
        tuya_user_svc_init(&gw_cbs);
    
        /* SDK initialization */
    #if defined(GW_SUPPORT_WIRED_WIFI) && (GW_SUPPORT_WIRED_WIFI==1)
        tuya_iot_wired_wf_sdk_init(IOT_GW_NET_WIRED_WIFI, GWCM_OLD, WF_START_AP_ONLY, PID, USER_SW_VER, NULL, 0);
    #elif defined(WIFI_GW) && (WIFI_GW==1)
        tuya_iot_wf_sdk_init(GWCM_OLD, WF_START_AP_ONLY, PID, USER_SW_VER, NULL, 0);
    #else
        tuya_iot_sdk_init(PID, USER_SW_VER, NULL, 0); // Specify the USER_SW_VER when you build the project.
    #endif
    
        /* Register the network status notification callback. */
        tuya_iot_sdk_reg_netstat_cb(__nw_stat_cb, __wired_stat_cb, NULL);
    
        /* Start the application. */
        tuya_user_svc_start(NULL);
    
        /* loop */
        while (1) {
            sleep(10);
        }
    
        return 0;
    }
    
  4. Implement the callbacks.

    /* The callback to invoke when the gateway is removed or removed with data erased. */
    STATIC VOID __gw_reset_cb(GW_RESET_TYPE_E type) {}
    
    /* The callback to invoke when an OTA firmware update is initiated. */
    STATIC VOID __gw_upgrade_cb(CONST FW_UG_S *fw) {}
    
    /* The callback to invoke when the gateway status changes. */
    STATIC VOID __gw_active_stat_cb(GW_STATUS_E status) {}
    
    /* The callback to invoke when the application is restarted. */
    STATIC VOID __gw_reboot_cb(VOID) {}
    
    /* The callback to invoke when the network status changes. */
    STATIC VOID __nw_stat_cb(IN CONST SDK_NW_STAT_T stat) {}
    
    /* The callback to invoke when the wired network status changes. */
    STATIC VOID __wired_stat_cb(IN CONST SDK_WIRED_NW_STAT_T stat) {}
    

Hardware adaptation

The network operations can vary depending on the systems. The SDK defines a suite of standard APIs to help you adapt your system to the desired network connection.

The files used for network adaptation:

Files Description
tuya_os_adapt_wired.h Wired network adaptation
tuya_os_adapt_wifi.h Wireless network adaptation
tuya_os_adapt_bt.h Bluetooth adaptation

We use Linux as an example to describe how to implement wired network adaptation. The code has been verified on Ubuntu so it can apply to most Linux systems.

  1. If you use the wired connection SDK, use the wired network adaptation specific file. Create a file named hal_wired.c under the tuyaos_demo_mini_gw/src directory. Copy the appendix hal_wired.c to this file.

    Replace the ETH_DEV in hal_wired.c with your network interface for use. Take care of this step. A wrong network interface will cause the gateway to fail the internet connection.

  2. If you use the wireless connection SDK, use the wireless network adaptation specific file. Since our example only describes the wired network, the implementation for wireless adaptation is empty. Create a file named hal_wifi.c under the tuyaos_demo_mini_gw/src directory. Copy the appendix hal_wifi.c to this file.

Build the project

After the coding is completed, build the tuyaos_demo_mini_gw project.

Run the following code in the SDK root directory:

$ ./build_app.sh apps/tuyaos_demo_mini_gw tuyaos_demo_mini_gw 1.0.0

The first parameter indicates the path where the sample code resides.

The second parameter indicates the name of the directory where the output resides.

The third parameter indicates the firmware version number, which is user-defined and in the format x.x.x.

You can see the output in the terminal window. If Build APP Finish is displayed, it means the build is finished.

Quick Start

Run the program

You can run the program on Ubuntu that can act as a gateway to be connected to the cloud.

The output executable file is stored in SDK directory>/output/tuyaos_demo_mini_gw_<version number>. The version number is the one you specify when building the project.

In this example, we specify the version number as 1.0.0 so we navigate to the directory <SDK directory>/output/tuyaos_demo_mini_gw_1.0.0 to run the executable.

$ cd output/tuyaos_demo_mini_gw_1.0.0
$ ./tuyaos_demo_mini_gw

Use the Smart Lift to activate the gateway. Choose cable as the pairing mode. For more information, see User Guide.

main.c execution is logged as the gateway activation is started.

...
Print SDK logs ==>
[01-01 18:12:15 TUYA D][user_main.c:104] SDK INFO: < TUYA IOT SDK V:1.1.0 BS:40.00_PT:2.2_LAN:3.4_CAD:1.0.4_CD:1.0.0 >
< BUILD AT:2021_12_28_16_21_47 BY ci_manage FOR ty_integrated_sdk AT linux-ubuntu-6.2.0_64Bit >
IOT DEFS < WIFI_GW:1 DEBUG:1 KV_FILE:1 SHUTDOWN_MODE:1 LITTLE_END:1 TLS_MODE:4 ENABLE_CLOUD_OPERATION:1 OPERATING_SYSTEM:100 ENABLE_SYS_RPC:1 RELIABLE_TRANSFER:1 ENABLE_LAN_ENCRYPTION:1 ENABLE_LAN_LINKAGE:1 ENABLE_LAN_DEV:1 >

...
The gateway is started for the first time. ==>
[01-01 18:12:15 TUYA D][main.c:50] gw active stat callback, status: 2

...
The gateway is activated. ==>
[01-01 18:12:30 TUYA D][main.c:50] gw active stat callback, status: 1

...
The gateway is connected to the internet. ==>
[01-01 18:12:30 TUYA D][main.c:66] network stat: 1

Appendix

main.c

#include <unistd.h>

#include "uni_log.h"
#include "base_os_adapter.h"
#include "tuya_iot_base_api.h"
#include "tuya_iot_com_api.h"

#include "tuya_iot_sdk_api.h"
#include "tuya_iot_sdk_defs.h"

#if defined(TY_BT_MOD) && (TY_BT_MOD == 1)
#include "tuya_os_adapt_bt.h"
#endif

#define PID       "fljmamufiym5fktz"                  // Replace it with your own PID.
#define UUID      "tuya461dbc63aeeb991f"              // Replace it with your own UUID.
#define AUTHKEY   "c8X4PR4wx1gMFaQlaZu5dfgVvVRwB8Ug"  // Replace it with your own AUTHKEY.

STATIC VOID __gw_reset_cb(GW_RESET_TYPE_E type)
{
    PR_DEBUG("gw reset callback, type: %d", type);

    if (GW_RESET_DATA_FACTORY != type) {
        exit(0);
    }

    return;
}

STATIC VOID __gw_upgrade_cb(CONST FW_UG_S *fw)
{
    PR_DEBUG("gw upgrade callback");

    if (fw == NULL) {
        PR_ERR("invalid param");
        return;
    }

    PR_DEBUG("        tp: %d", fw->tp);
    PR_DEBUG("    fw_url: %s", fw->fw_url);
    PR_DEBUG("    sw_ver: %s", fw->sw_ver);
    PR_DEBUG("   fw_hmac: %s", fw->fw_hmac);
    PR_DEBUG(" file_size: %u", fw->file_size);

    return;
}

STATIC VOID __gw_active_stat_cb(GW_STATUS_E status)
{
    PR_DEBUG("gw active stat callback, status: %d", status);

    return;
}

STATIC VOID __gw_reboot_cb(VOID)
{
    PR_DEBUG("gw reboot callback");

    exit(0);

    return;
}

STATIC VOID __nw_stat_cb(IN CONST SDK_NW_STAT_T stat)
{
    PR_DEBUG("network stat: %d", stat);

    return;
}

STATIC VOID __wired_stat_cb(IN CONST SDK_WIRED_NW_STAT_T stat)
{
    PR_DEBUG("wired stat: %d", stat);

    return;
}

int main(int argc, char **argv)
{
    OPERATE_RET rt = OPRT_OK;
    GW_PROD_INFO_S prod_info = {0};

    /* gw base callback */
    TY_GW_INFRA_CBS_S gw_cbs = {
        .gw_reset_cb       = __gw_reset_cb,
        .gw_upgrade_cb     = __gw_upgrade_cb,
        .gw_active_stat_cb = __gw_active_stat_cb,
        .gw_reboot_cb      = __gw_reboot_cb,
    };

#if defined(TY_BT_MOD) && (TY_BT_MOD == 1)
    tuya_os_adapt_reg_bt_intf();
#endif

    /* initiate os-layer service*/
    tuya_os_intf_init();

    /* initiate iot-layer service */
    TUYA_CALL_ERR_RETURN(tuya_iot_init("./"));

    /* set the logging level to debug */
    SET_PR_DEBUG_LEVEL(TY_LOG_LEVEL_DEBUG);

    PR_DEBUG("SDK INFO: %s", tuya_iot_get_sdk_info());

    /* set uuid and authkey */
    prod_info.uuid     = UUID;
    prod_info.auth_key = AUTHKEY;
    TUYA_CALL_ERR_RETURN(tuya_iot_set_gw_prod_info(&prod_info));

    /* pre-initiate sdk service */
    TUYA_CALL_ERR_RETURN(tuya_iot_sdk_pre_init(TRUE));  

    /* initiate application service, more service in here */
    TUYA_CALL_ERR_RETURN(tuya_user_svc_init(&gw_cbs));

    /* initiate sdk service */
#if defined(GW_SUPPORT_WIRED_WIFI) && (GW_SUPPORT_WIRED_WIFI==1)
    TUYA_CALL_ERR_RETURN(tuya_iot_wired_wf_sdk_init(IOT_GW_NET_WIRED_WIFI, GWCM_OLD, WF_START_AP_ONLY, PID, USER_SW_VER, NULL, 0));
#elif defined(WIFI_GW) && (WIFI_GW==1)
    TUYA_CALL_ERR_RETURN(tuya_iot_wf_sdk_init(GWCM_OLD, WF_START_AP_ONLY, PID, USER_SW_VER, NULL, 0));
#else
    TUYA_CALL_ERR_RETURN(tuya_iot_sdk_init(PID, USER_SW_VER, NULL, 0));
#endif

    /* register net stat notification callback */
    TUYA_CALL_ERR_RETURN(tuya_iot_sdk_reg_netstat_cb(__nw_stat_cb, __wired_stat_cb, NULL));

    /* start application service, more service in here */
    TUYA_CALL_ERR_RETURN(tuya_user_svc_start(NULL));

    while (1) {
        sleep(10);
    }

    return 0;
}

hal_wired.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>

#include "uni_log.h"
#include "tuya_os_adapt_wired.h"

#define ETH_DEV "enp0s3"

OPERATE_RET tuya_adapter_wired_get_ip(OUT NW_IP_S *ip)
{
    int sock = 0;
    char ipaddr[50] = {0};

    struct sockaddr_in *sin;
    struct ifreq ifr;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         PR_ERR("socket create failed");
         return OPRT_COM_ERROR;
    }

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, ETH_DEV, sizeof(ifr.ifr_name) - 1);

    if (ioctl(sock, SIOCGIFADDR, &ifr) < 0 ) {
         PR_ERR("ioctl failed");
         close(sock);
         return OPRT_COM_ERROR;
    }

    sin = (struct sockaddr_in *)&ifr.ifr_addr;
    strcpy(ip->ip,inet_ntoa(sin->sin_addr)); 
    close(sock);

    return OPRT_OK;
}

BOOL_T tuya_adapter_wired_station_conn(VOID)
{
    int sock;
    struct sockaddr_in *sin;
    struct ifreq ifr;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         PR_ERR("socket failed");
         return OPRT_COM_ERROR;
    }

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, ETH_DEV, sizeof(ifr.ifr_name) - 1);

    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
        PR_ERR("ioctl failed");
        close(sock);
        return FALSE;
    }

    close(sock);

    if ((ifr.ifr_flags & IFF_UP) == 0)
        return FALSE;

    return TRUE;
}

OPERATE_RET tuya_adapter_wired_get_mac(OUT NW_MAC_S *mac)
{
    int sock;
    struct sockaddr_in *sin;
    struct ifreq ifr;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         PR_ERR("socket failed");
         return OPRT_COM_ERROR;
    }

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, ETH_DEV, sizeof(ifr.ifr_name) - 1);

    if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
        PR_ERR("ioctl failed");
        close(sock);
        return FALSE;
    }

    memcpy(mac->mac, ifr.ifr_hwaddr.sa_data, sizeof(mac->mac));

    PR_DEBUG("WIFI MAC: %02X-%02X-%02X-%02X-%02X-%02X\r\n",
             mac->mac[0],mac->mac[1],mac->mac[2],mac->mac[3],mac->mac[4],mac->mac[5]);
    
    close(sock);

    return OPRT_OK;
}

/* Implementation is not needed. */
OPERATE_RET tuya_adapter_wired_set_mac(IN CONST NW_MAC_S *mac)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wired_if_connect_internet(BOOL_T *status)
{
    *status = TRUE;

    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wired_wifi_set_station_connect(IN CONST CHAR_T *ssid,IN CONST CHAR_T *passwd)
{
    /* return hal_wifi_connect_station(ssid, passwd); */
    return OPRT_OK;
}

BOOL_T tuya_adapter_wired_wifi_need_cfg(VOID)
{
    return FALSE;
}

OPERATE_RET tuya_adapter_wired_wifi_station_get_conn_ap_rssi(OUT SCHAR_T *rssi)
{
    /* return hal_wifi_get_station_rssi(rssi); */
    *rssi = 99;
    
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wired_get_nw_stat(GW_BASE_NW_STAT_T *stat)
{
    *stat = 0;

    return OPRT_OK;
}

hal_wifi.c

#include "tuya_os_adapt_wifi.h"

OPERATE_RET tuya_adapter_wifi_all_ap_scan(AP_IF_S **aps, UINT_T *num)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_assign_ap_scan(CONST SCHAR_T *ssid, AP_IF_S **ap)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_release_ap(AP_IF_S *ap)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_set_cur_channel(CONST UCHAR_T channel)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_cur_channel(UCHAR_T *chan)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_sniffer_set(CONST BOOL_T en, CONST SNIFFER_CALLBACK cb)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_ip(CONST WF_IF_E wf, NW_IP_S *ip)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_set_mac(CONST WF_IF_E wf, CONST NW_MAC_S *mac)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_mac(CONST WF_IF_E wf, NW_MAC_S *mac)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_set_work_mode(CONST WF_WK_MD_E mode)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_work_mode(WF_WK_MD_E *mode)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_ap_start(CONST WF_AP_CFG_IF_S *cfg)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_ap_stop(VOID_T)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_station_connect(CONST SCHAR_T *ssid, CONST SCHAR_T *passwd)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_station_disconnect(VOID_T)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_station_get_conn_ap_rssi(SCHAR_T *rssi)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_bssid(UCHAR_T *mac)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_station_get_status(WF_STATION_STAT_E *stat)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_set_country_code(CONST COUNTRY_CODE_E code)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_send_mgnt(CONST UCHAR_T *buf, CONST UINT_T len)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_register_recv_mgnt_callback(CONST BOOL_T enable, CONST WIFI_REV_MGNT_CB recv_cb)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_set_lp_mode(CONST BOOL_T en, CONST UCHAR_T dtim)
{
    return OPRT_OK;
}

OPERATE_RET tuya_adapter_wifi_get_connected_ap_info_v2(FAST_WF_CONNECTED_AP_INFO_V2_S **fast_ap_info)
{
    return OPRT_COM_ERROR;
}

OPERATE_RET tuya_adapter_wifi_fast_station_connect_v2(CONST FAST_WF_CONNECTED_AP_INFO_V2_S *fast_ap_info)
{
    return OPRT_COM_ERROR;
}

BOOL_T tuya_adapter_wifi_rf_calibrated(VOID_T)
{
    return FALSE;
}