API

更新时间:2022-11-24 09:20:11下载pdf

涂鸦蓝牙 SDK(Tuya BLE SDK)提供封装好的 API,用于开发物联网蓝牙设备应用程序相关的管理和通信等。API 函数定义在 tuya_ble_api.ctuya_ble_api.h 文件中,您无需更改相关代码实现,但如果有兴趣,可以阅读源码理解实现原理。

tuya_ble_main_tasks_exec

函数名 tuya_ble_main_tasks_exec
函数原型 void tuya_ble_main_tasks_exec(void);
功能概述 在不使用 RTOS(Real-time operating system) 的芯片平台架构下,作为涂鸦蓝牙 SDK 的事件主调度器,应用程序必须在主循环中调用
参数
返回值
备注 这个函数必须在主循环中调用。它将执行自上次调用后计划的所有事件

例如,在 nrf52832 平台下的调用位置如下所示:

/**@brief Function for handling the idle state (main loop).
*
* @details If there is no pending log operation, then sleep until next the next event occurs.
*/
static void idle_state_handle(void)
{
	tuya_ble_main_tasks_exec();

	if (NRF_LOG_PROCESS() == false)
	{
		nrf_pwr_mgmt_run();
	}

}

tuya_ble_gatt_receive_data

函数名 tuya_ble_gatt_receive_data
函数原型 tuya_ble_status_t tuya_ble_gatt_receive_data(uint8_t*p_data,uint16_t len);
功能概述 通过调用该函数将蓝牙收到的 GATT 数据发送至涂鸦蓝牙 SDK
参数 p_data[in]:指向要发送的数据
len[in]:要发送的数据长度,不能超过 TUYA_BLE_DATA_MTU_MAX
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INTERNAL:发送失败
备注 该 API 用于将蓝牙底层收到的数据发送给涂鸦蓝牙 SDK,必须在涂鸦 Write Characteristic UUID 00000001-0000-1001-8001-00805F9B07D0 的写回调函数中调用

示例(nrf52832 示例 Demo):

/**@brief Function for handling the data from the Nordic UART Service.
*
* @details This function will process the data received from the Nordic UART BLE Service and send
*          it to the UART module.
*
* @param[in] p_evt       Nordic UART Service event.
*/
/**@snippet [Handling the data received over BLE] */
static void nus_commdata_handler(ble_nus_evt_t * p_evt)
{

	if (p_evt->type == BLE_NUS_EVT_RX_DATA)
	{
		tuya_ble_gatt_receive_data((uint8_t*)(p_evt->params.rx_data.p_data),p_evt->params.rx_data.length);  //发送给 SDK
		TUYA_BLE_HEXDUMP("nus_commdata_handler :",20,(uint8_t*)(p_evt->params.rx_data.p_data),p_evt->params.rx_data.length);  //打印接收数据
	}

}

tuya_ble_sdk_init

函数名 tuya_ble_sdk_init
函数原型 tuya_ble_status_t tuya_ble_sdk_init(tuya_ble_device_param_t * param_data);
功能概述 涂鸦蓝牙 SDK 初始化函数
参数 param_data [in]:初始化参数
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数无效
备注 涂鸦蓝牙 SDK 初始化函数,应用程序必须调用此函数初始化 SDK,否则 SDK 不能运行

参数说明

tuya_ble_device_param_t 结构体如下所示:

typedef struct {
uint8_t use_ext_license_key;   /**< If use the license key stored by theSDK,initialized to 0, Otherwise 1.*/
  uint8_t device_id_len;      /**<if 20,Compressed into 16.*/
  uint8_t device_id[DEVICE_ID_LEN_MAX];
uint8_t auth_key[AUTH_KEY_LEN];
tuya_ble_gap_addr_t mac_addr;
  uint8_t mac_addr_string[MAC_STRING_LEN];
  tuya_ble_product_id_type_t p_type;
  uint8_t product_id_len;
  uint8_t product_id[TUYA_BLE_PRODUCT_ID_MAX_LEN];
uint8_t adv_local_name_len;
  uint8_t adv_local_name[TUYA_BLE_ADV_LOCAL_NAME_MAX_LEN]; /**< Onlysupported when TUYA_BLE_PROTOCOL_VERSION_HIGN >= 4. */
uint32_t firmware_version;               /**< 0x00010102 :v1.1.2 */
  uint32_t hardware_version;
  uint8_t device_vid[DEVICE_VIRTUAL_ID_LEN];  
  uint8_t login_key[LOGIN_KEY_LEN];
  uint8_t beacon_key[BEACON_KEY_LEN];  
  uint8_t bound_flag;
 
  uint8_t reserve_1;
  uint8_t reserve_2;
} tuya_ble_device_param_t;

各成员变量含义:

变量 说明
use_ext_license_key 是否使用应用程序传入的授权信息(license),包括 device id 、 auth key 和 mac地址。TUYA_BLE_DEVICE_AUTH_SELF_MANAGEMENT 定义为 1 时,
  • 如果 use_ext_license_key 为 1,涂鸦蓝牙 SDK 将会使用传入的 device id 、auth key以及mac地址(必须传入,否则将不能被涂鸦app绑定),但是仍然会自行管理和存储其他绑定信息。
  • 如果 use_ext_license_key 为 0,涂鸦蓝牙 SDK 将会使用自行存储管理的 license 和绑定信息,License 通过涂鸦产测工具授权获得。此时,不需要传入 license,将 device_id_len 赋值为 0 即可。
TUYA_BLE_DEVICE_AUTH_SELF_MANAGEMENT 定义为0时,表示应用程序自行管理 License 和绑定信息,SDK 不做任何管理。则初始化 SDK 时必须传入这些信息,use_ext_license_key 也就必须赋值为 1。
device_id 、auth_key、mac_addr 、mac_addr_string 是涂鸦分配给设备的唯一 License,在产测授权时通过产测工具写入。并且一一对应,单蓝牙设备经过产测授权后,涂鸦蓝牙 SDK 会自动管理 License,device id 和 auth key 上面已有介绍,该 License 的使用,请参照下文的代码示例。
product id 即产品 ID,简称 PID。PID 是在 涂鸦 IoT 平台 新建产品时自动生成的。PID 生成后不会改变,需要应用代码以常量的形式保存,并且在初始化涂鸦蓝牙 SDK 时传入。
p_type PID 的类型,目前支持TUYA_BLE_PRODUCT_ID_TYPE_PID 类型。
adv_local_name adv_local_nameadv_local_name_len 是应用程序自定义蓝牙广播名字的变量。如果 adv_local_name_len 为 0 ,那么涂鸦蓝牙 SDK 将默认使用 TY 作为蓝牙广播名字,应用程序在初始化蓝牙 GAP(Generic Access Profile)时,设置的蓝牙名字必须和 传给 SDK 的 adv_local_name 一致,最多支持 5 个字符。
firmware_versionhardware_version 固件版本号和 PCBA 硬件版本号,为四字节。例如,0x00010102 表示 v1.1.2,0x0101 表示 v1.1 。
device_vid 设备虚拟 ID。设备注册绑定后由 IoT 平台生成。主要作用是设备绑定解绑再绑定时,通过该 ID 来查找云端对该设备的历史数据记录。对于单蓝牙设备来说,赋值为 0 即可,对于 Wi-Fi 和蓝牙双协议设备需要代入。
login key beacon key 和 bound flag:对于单蓝牙设备,赋值为 0 即可,对于双协议设备需要代入。

nrf52832 平台的涂鸦蓝牙 SDK 初始化示例:

static const char auth_key_test[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
static const char device_id_test[] = "yyyyyyyyyyyyyyyy";
static const char mac_test[]  = "112233445566"; //The actual MAC address is :11:22:33:44:55:66
static const char device_local_name[] = "SDK20";  //Maximum support 5 characters
#define APP_PRODUCT_ID "vvvvvvvv"
#define TY_APP_VER_NUM    0x0101
#define TY_APP_VER_STR   "1.1"
#define TY_HARD_VER_NUM   0x0100
#define TY_HARD_VER_STR   "1.0"
void tuya_ble_app_init(void)
{
tuya_ble_device_param_t device_param = {0};
device_param.p_type = TUYA_BLE_PRODUCT_ID_TYPE_PID;
  device_param.product_id_len = 8;
  memcpy(device_param.product_id,APP_PRODUCT_ID,8);
  device_param.firmware_version = TY_APP_VER_NUM;
  device_param.hardware_version = TY_HARD_VER_NUM;
device_param.adv_local_name_len = strlen(device_local_name);
  
memcpy(device_param.adv_local_name,device_local_name,device_param.adv_local_name
_len);
device_param.use_ext_license_key = 1; //If use the license stored by the
SDK,initialized to 0, Otherwise 1.
    
  if(device_param.use_ext_license_key==1)
 {
    device_param.device_id_len = 16;
    memcpy(device_param.auth_key,(void *)auth_key_test,32);
    memcpy(device_param.device_id,(void *)device_id_test,16);
    memcpy(device_param.mac_addr_string,mac_test,12);
    device_param.mac_addr.addr_type = TUYA_BLE_ADDRESS_TYPE_RANDOM;
 }
  tuya_ble_sdk_init(&device_param);
  tuya_ble_callback_queue_register(tuya_cb_handler);
  tuya_ota_init();
}
/*nrf52832示例*/
int main(void)
{
  bool erase_bonds;
  // Initialize.
  uart_init();
  app_log_init();
  timers_init();
  buttons_leds_init(&erase_bonds);
  power_management_init();
  ble_stack_init();
  gap_params_init();
  gatt_init();
  services_init();
  advertising_init();
  conn_params_init();
 
  tuya_ble_app_init();  //
  advertising_start();
 
 
  // Enter main loop.
  for (;;)
 {
    idle_state_handle();
 }
}

tuya_ble_common_uart_receive_data

函数名 tuya_ble_common_uart_receive_data
函数原型 tuya_ble_status_t tuya_ble_common_uart_receive_data (uint8_t *p_data,uint16_t len);
功能概述 通过调用该函数将 UART 接收数据发送至 SDK,UART 接口主要用于产测授权
如果不使用涂鸦蓝牙 SDK 提供的产测授权功能模块,那么就不需要调用该函数
参数 p_data[in]:指向要发送的数据
len[in]:要发送的数据长度
返回值 TUYA_BLE_SUCCESS:发送成功
其他:发送失败
备注 该函数内部有调用 malloc 申请内存,如果应用配置使用的是平台提供的 malloc 接口,要确认平台 malloc 是否支持中断调用。如果不支持,一定不能在 UART 中断里调用 tuya_ble_common_uart_receive_data()

tuya_ble_common_uart_send_full_instruction_received

函数名 tuya_ble_common_uart_send_full_instruction_received
函数原型 tuya_ble_status_t
tuya_ble_common_uart_send_full_instruction_received (uint8_t *p_data,uint16_t len);
功能概述 通过调用该函数将通过 UART 接收并并解析好的完整涂鸦产测协议指令,包含 cmd/data/checksum,发送至涂鸦蓝牙 SDK。如果应用程序不使用涂鸦蓝牙 SDK 提供的协议解析函数 tuya_ble_common_uart_receive_data(),而是使用自定义的UART接收解析函数来解析产测协议数据,那么解析完成后,需要调用该函数将解析好的完成产测指令发送给涂鸦蓝牙 SDK
参数 p_data[in]:指向要发送的完整指令数据
len[in]:要发送的指令数据长度
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数有误
TUYA_BLE_ERR_NO_MEM:内存申请失败
TUYA_BLE_ERR_BUSY:蓝牙 SDK内部忙
备注 该函数内部有调用 malloc,如果应用配置使用的是平台提供的 malloc 接口,要确认平台 malloc 是否支持中断调用,如果不支持,一定不能在 UART 中断里调用 tuya_ble_common_uart_send_full_instruction_received()
  • 涂鸦蓝牙 SDK 集成产测授权功能模块,产测授权模块通过 UART 和电脑端的产测授权工具进行通信,UART 通信有一套完整的指令格式,具体参考《蓝牙通用产测授权协议》。
  • 涂鸦蓝牙 SDK 包含 UART 通信指令解析功能,应用只需要在收到 UART 的数据的地方调用 tuya_ble_common_uart_receive_data() 函数即可,当然应用也可以自己解析出完整的 UART 通信指令,然后通过调用 tuya_ble_common_uart_send_full_instruction_received() 函数发送完整指令给涂鸦蓝牙 SDK。

tuya_ble_device_update_product_id

函数名 tuya_ble_device_update_product_id
函数原型 tuya_ble_status_t tuya_ble_device_update_product_id
(tuya_ble_product_id_type_t type, uint8_t len, uint8_t* p_buf);
功能概述 更新 product ID 函数
参数 type [in]:ID 类型
len[in]:ID 长度
p_buf[in]:ID 数据
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数有误
TUYA_BLE_ERR_INTERNAL:内部错误
备注 在基于蓝牙 SDK 的 SoC 开发方案中,一般不需要调用此函数,因为 Product ID 一般不会变

tuya_ble_device_update_login_key

函数名 tuya_ble_device_update_login_key
函数原型 tuya_ble_status_t tuya_ble_device_update_login_key(uint8_t* p_buf, uint8_t len);
功能概述 更新 login_key 函数
参数 len[in]:长度。
p_buf[in]:loginkey
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数有误
TUYA_BLE_ERR_INTERNAL:内部错误
备注 该 API 主要用于 Wi-Fi 和蓝牙双协议设备中。通过蓝牙发送配网信息给 Wi-Fi,设备通过 Wi-Fi 向云端注册设备,并将注册成功后的 login_key 调用此函数发送给涂鸦蓝牙 SDK,同时也需要更新绑定状态

tuya_ble_device_update_beacon_key

函数名 tuya_ble_device_update_beacon_key
函数原型 tuya_ble_status_t tuya_ble_device_update_beacon_key(uint8_t* p_buf, uint8_t len);
功能概述 更新 beacon key 函数
参数 len[in]:长度
p_buf[in]:beacon_key
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数有误
TUYA_BLE_ERR_INTERNAL:内部错误
备注 该 API 主要用于 Wi-Fi 和蓝牙双协议设备中。通过蓝牙发送配网信息给 Wi-Fi,设备通过 Wi-Fi 向云端注册设备,并将注册成功后的 beacon_key 调用此函数发送给涂鸦蓝牙 SDK,同时也需要更新绑定状态

tuya_ble_device_update_bound_state

函数名 tuya_ble_device_update_bound_state
函数原型 tuya_ble_status_t tuya_ble_device_update_bound_state(uint8_t state);
功能概述 更新注册绑定状态
参数 state[in] :
1-设备已注册绑定
0-设备未注册绑定
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数有误
TUYA_BLE_ERR_INTERNAL:内部错误
备注 该 API 主要用于 Wi-Fi 和蓝牙双协议设备中。设备通过 Wi-Fi 链路注册绑定成功后,调用此函数更新绑定状态给涂鸦蓝牙 SDK。同时也需要更新 login_key

tuya_ble_device_update_mcu_version

函数名 tuya_ble_device_update_mcu_version
函数原型 tuya_ble_status_t tuya_ble_device_update_mcu_version(uint32_t mcu_firmware_version, uint32_t mcu_hardware_version);
功能概述 更新外部mcu版本号
参数 mcu_firmware_version [in]:MCU 固件版本号,例如0x010101表示v1.1.1
mcu_hardware_version [in]:MCU 硬件版本号(PCBA版本号)
返回值 TUYA_BLE_SUCCESS:发送成功
其他:失败
备注 该 API 主要用于开发蓝牙模组,SoC 开发方案不需要使用

tuya_ble_dp_data_send

函数名 tuya_ble_dp_data_send
函数原型 tuya_ble_status_t tuya_ble_dp_data_send(
uint32_t sn,
tuya_ble_dp_data_send_type_t type,
tuya_ble_dp_data_send_mode_t mode,
tuya_ble_dp_data_send_ack_t ack,
uint8_t *p_dp_data,
uint32_t dp_data_len
) ;
功能概述 发送 DP 数据
参数 sn[in]:发送序号
type[in]:发送类型,分为主动发送和应答查询发送
mode[in]:发送模式
ack[in]:是否需要应答标志
p_dp_data [in]:DP 数据
dp_data_len[in]:数据长度,最大不能超过 TUYA_BLE_SEND_MAX_DATA_LEN-7。其中 TUYA_BLE_SEND_MAX_DATA_LEN 可配置
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数无效
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_NO_MEM:内存申请失败
TUYA_BLE_ERR_INVALID_LENGTH:数据长度错误
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 应用程序通过调用该函数上报 DP 数据到 App。

p_dp_data 参数说明

涂鸦 IoT 平台是以 DP 模型管理数据。任何设备产生的数据都需要抽象为 DP 数据形式,一个 DP 数据由四部分组成。更多详情,请参考 自定义功能

  • Dp_id:1 个字节,在涂鸦 IoT 平台注册的 dp_id 序号。

  • Dp_type:1 个字节,DP 类型。根据上报的 DP 类型来选择

    • #define DT_RAW 0: Raw 类型。
    • #define DT_BOOL 1: 布尔类型。
    • #define DT_VALUE 2: 数值类型,其范围在iot平台注册时指定。
    • #define DT_STRING 3: 字符串类型。
    • #define DT_ENUM 4: 枚举类型。
    • #define DT_BITMAP 5: 位映射类型。
  • Dp_len:DP 数据长度,两个字节,每个 DP 数据类型的最大数据长度在涂鸦 IoT平台定义时指定

    • Dp_type =1, 则 Dp_len 必须为 1。
    • Dp_type =2, 则 Dp_len 可以为1、2、4。
    • Dp_type =4, 则 Dp_len 必须为 1。
    • Dp_type =5, 则 Dp_len 可以为1、2、4。
    • Dp_type =0 或 3, 则 Dp_len 数值自定义,但必须小于在涂鸦 IoT平台定义时的最大长度。
  • Dp_data:数据,dp_len 个字节数据。

    该 DP 上报函数的参数 Dp_data 指向的数据必须以下表格式组装上报:

    Dp点1的数据 ~ Dp点n的数据
    1 2 3-4 5~ ~ n n+1 n+2-n+3 n+4~
    Dp_id Dp_type Dp_len Dp_data ~ Dp_id Dp_type Dp_len Dp_data

    一次可发送多个dp数据,只要总长度不超过限制即可,最大长度为
    TUYA_BLE_SEND_MAX_DATA_LEN-7 ,其中 TUYA_BLE_SEND_MAX_DATA_LEN 可配置。

其余参数说明

  • sn:由应用程序自行定义管理的序号,一般从0开始,每发送一次,则递增1。sn 用于应用程序统计发送次数以及管理 App 的发送响应,典型应用场景是:应用程序定时或者连续调用多次该函数发送 DP 数据后,在 SDK 回调函数中通过该 sn 来判断哪一次发送是成功的。sn 可以和下面的tuya_ble_dp_data_with_time_send() 共用,因为 tuya_ble_dp_data_with_time_send()
    tuya_ble_dp_data_send() 使用不同的回调事件ID。

  • type:表示本次发送是应用程序的主动行为还是对 App 查询 DP 数据指令的响应,如下所示定义:

    typedef enum {
      DP_SEND_TYPE_ACTIVE = 0,    // The device actively sends dp data.
      DP_SEND_TYPE_PASSIVE,      // The device passively sends dp data. For
    example, in order to answer the dp query command of the mobile app. Currently
    only applicable to WIFI+BLE combo devices.
    } tuya_ble_dp_data_send_type_t;
    

    至于发送 DP 数据时,是带 DP_SEND_TYPE_ACTIVE 还是 DP_SEND_TYPE_PASSIVE,由具体业务功能定义。响应手机 App 的查询指令的发送时,不一定要带 DP_SEND_TYPE_PASSIVE 参数。

  • mode:定义如下所示:

    typedef enum {
      DP_SEND_FOR_CLOUD_PANEL = 0,  // The mobile app uploads the received dp
    data to the cloud and also sends it to the panel for display.
      DP_SEND_FOR_CLOUD,       // The mobile app will only upload the
    received dp data to the cloud.
      DP_SEND_FOR_PANEL,       // The mobile app will only send the received
    dp data to the panel display.
      DP_SEND_FOR_NONE,        // Neither uploaded to the cloud nor sent to
    the panel display.
    } tuya_ble_dp_data_send_mode_t;
    

    App 的面板可以认为是某一个设备的 UI 界面,同时还负责具体产品定义的业务功能逻辑。有些产品定义的某一个 DP 数据只是用来表示临时数据,只需要发送到手机 App 面板显示,不需要发送到云端存储,例如智能体脂秤称重过程中的动态数据,此时,您只需要带 DP_SEND_FOR_PANEL 参数发送。

  • ack:表示是否需要 App 的响应,定义如下所示:

    typedef enum {
      DP_SEND_WITH_RESPONSE = 0,   // Need a mobile app to answer.
      DP_SEND_WITHOUT_RESPONSE,   // No need for mobile app to answer.
    } tuya_ble_dp_data_send_ack_t;
    

    是否需要 App 响应也是由具体的产品业务功能逻辑决定的,响应主要是为了反馈给设备应用程序,手机 App 收到了发送的 DP 数据。

tuya_ble_dp_data_with_time_send

函数名 tuya_ble_dp_data_with_time_send
函数原型 tuya_ble_status_t tuya_ble_dp_data_with_time_send
(uint32_t sn,
tuya_ble_dp_data_send_mode_t mode,
tuya_ble_dp_data_send_time_type_t time_type,
uint8_t *p_time_data,
uint8_t *p_dp_data,
uint32_t dp_data_len
);
功能概述 发送带时间戳的 DP 数据
参数 sn[in]:发送序号
mode[in]:发送模式
time_type[in]:时间类型
p_time_data[in]:时间数据
p_dp_data [in]:dp数据
dp_data_len[in]:数据长度,最大不能超过TUYA_BLE_SEND_MAX_DATA_LEN-21 ,其中TUYA_BLE_SEND_MAX_DATA_LEN 可配置
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数无效
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_NO_MEM:内存申请失败
TUYA_BLE_ERR_INVALID_LENGTH:数据长度错误
TUYA_BLE_ERR_NO_EVENT:其他错误
  • snmodep_dp_datadp_data_len:上文已有介绍,请参考 tuya_ble_dp_data_send() 的说明。其中,该函数的 dp_data_len 最大不能超过 TUYA_BLE_SEND_MAX_DATA_LEN-21TUYA_BLE_SEND_MAX_DATA_LEN 可配置。

  • 该函数没有 ack 参数,因为带时间戳的 DP 数据发送必须要有手机 App 的响应。

  • time_typep_time_data:时间类型和时间数据指针,时间类型定义如下所示:

    typedef enum {
      DP_TIME_TYPE_MS_STRING = 0,
      DP_TIME_TYPE_UNIX_TIMESTAMP,
    } tuya_ble_dp_data_send_time_type_t;
    
    • DP_TIME_TYPE_MS_STRING:表示参数 p_time_data 指向的时间数据是毫秒级字符串数据。必须是13个字符,例如 1600777955000 单位是毫秒。

    • DP_TIME_TYPE_UNIX_TIMESTAMP:表示参数 p_time_data 指向的时间数据是四字节的 Unix 时间戳,采用大端格式。例如 1600777955 = 0x5F69EEE3,那么 p_time_data 指向数组是 {0x5F,0x69,0xEE,0xE3}。无论是 DP_TIME_TYPE_MS_STRING 类型的时间还是 DP_TIME_TYPE_UNIX_TIMESTAMP 类型的时间,都必须是 UTC 时间。

tuya_ble_connected_handler

函数名 tuya_ble_connected_handler
函数原型 void tuya_ble_connected_handler(void);
功能概述 蓝牙被连接的回调函数
参数
返回值
备注 应用代码需要在芯片平台 SDK 的蓝牙连接回调处调用此函数,涂鸦蓝牙 SDK 是基于该函数来管理内部蓝牙连接状态的

tuya_ble_disconnected_handler

函数名 tuya_ble_disconnected_handler
函数原型 void tuya_ble_disconnected_handler(void);
功能概述 蓝牙断开连接的回调函数
参数
返回值
备注 应用代码需要在芯片平台 SDK 的蓝牙断开连接回调处调用此函数,涂鸦蓝牙 SDK 是根据此函数的执行来管理内部蓝牙连接状态的

nrf52832 平台调用 tuya_ble_connected_handlertuya_ble_disconnected_handler 的示例:

/**@brief Function for handling BLE events.
*
* @param[in]   p_ble_evt   Bluetooth stack event.
* @param[in]   p_context   Unused.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
	uint32_t err_code;

	switch (p_ble_evt->header.evt_id)
	{
	case BLE_GAP_EVT_CONNECTED:

		NRF_LOG_INFO("Connected");

		tuya_ble_connected_handler();

		err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
		APP_ERROR_CHECK(err_code);
		m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
		err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
		APP_ERROR_CHECK(err_code);

		break;

	case BLE_GAP_EVT_DISCONNECTED:

		NRF_LOG_INFO("Disconnected");

		tuya_ble_disconnected_handler();

		tuya_ota_init_disconnect();
		// LED indication will be changed when advertising starts.
		m_conn_handle = BLE_CONN_HANDLE_INVALID;
		break;

	case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
	{
		NRF_LOG_DEBUG("PHY update request.");
		ble_gap_phys_t const phys =
		{
			.rx_phys = BLE_GAP_PHY_AUTO,
			.tx_phys = BLE_GAP_PHY_AUTO,
		};
		err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
		APP_ERROR_CHECK(err_code);
	}
	break;

	case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
		// Pairing not supported
		err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTS_EVT_SYS_ATTR_MISSING:
		// No system attributes have been stored.
		err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTC_EVT_TIMEOUT:
		// Disconnect on GATT Client timeout event.
		err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
										BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		APP_ERROR_CHECK(err_code);
		break;

	case BLE_GATTS_EVT_TIMEOUT:
		// Disconnect on GATT Server timeout event.
		err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
										BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		APP_ERROR_CHECK(err_code);
		break;

	default:
		// No implementation needed.
		break;
	}
}

tuya_ble_link_encrypted_handler

函数名 tuya_ble_link_encrypted_handler
函数原型 void tuya_ble_link_encrypted_handler(void);
功能概述 蓝牙 Link 层加密回调函数
参数
返回值
备注 应用程序需要在芯片平台 SDK 的蓝牙 Link 层加密成功回调处调用此函数。涂鸦蓝牙 SDK 是根据此函数的执行来管理内部蓝牙连接状态。函数主要用于开启蓝牙 Link 层加密机制的场景,否则不需要调用该函数

nordic 平台示例如下:

/**@brief Function for handling Peer Manager events.
*
* @param[in] p_evt Peer Manager event.
*/
static void pm_evt_handler(pm_evt_t const * p_evt)
{
  pm_handler_on_pm_evt(p_evt);
  pm_handler_flash_clean(p_evt);
  switch (p_evt->evt_id)
 {
case PM_EVT_BONDED_PEER_CONNECTED:
     
  TUYA_APP_LOG_DEBUG("Bonded peer CONNECTED!");
      break;
case PM_EVT_CONN_SEC_SUCCEEDED:
tuya_ble_link_encrypted_handler();
  TUYA_APP_LOG_DEBUG("The link has been encrypted!");
  break;
    case PM_EVT_PEERS_DELETE_SUCCEEDED:
      //advertising_start();
  TUYA_APP_LOG_DEBUG("Erase bonds SUCCEED!");
      break;
    default:
      break;
 }
}

tuya_ble_adv_data_connecting_request_set

函数名 tuya_ble_adv_data_connecting_request_set
函数原型 tuya_ble_status_t tuya_ble_adv_data_connecting_request_set(uint8_t on_off);
功能概述 请求连接标志置位函数
参数 on_off[in]:0 表示清除标志,1 表示置位标志
返回值
备注 本函数暂未开放使用,具体应用方法请咨询涂鸦技术支持工程师

tuya_ble_data_passthrough

函数名 tuya_ble_data_passthrough
函数原型 tuya_ble_status_t tuya_ble_data_passthrough(uint8_t *p_data,uint32_t len);
功能概述 透传数据
参数 p_data [in]:需要透传的数据
Len[in]:数据长度,最大不能超过 TUYA_BLE_SEND_MAX_DATA_LEN
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开TUYA_BLE_ERR_INVALID_LENGTH:数据长度错误
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 应用代码通过调用该函数透传数据到手机 App,透传的数据格式是由设备和手机 App 端协商定义,涂鸦蓝牙 SDK 不做解析

tuya_ble_production_test_asynchronous_response

函数名 tuya_ble_production_test_asynchronous_response
函数原型 tuya_ble_status_t tuya_ble_production_test_asynchronous_response
(uint8_t channel,uint8_t *p_data,uint32_t len);
功能概述 产测指令异步响应函数
参数 Channel[in]:传输通道,0 表示 UART,1 表示蓝牙
p_data [in]:需要响应的完整指令数据
len[in]:数据长度
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_INVALID_LENGTH:数据长度错误
TUYA_BLE_ERR_NO_MEM:申请内存失败
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 在进行产测时(产测授权是通过UART,整机测试通过蓝牙),有些测试项是不能立即响应结果给上位机产测工具的,或者有些测试项需要应用程序来处理,这个时候就需要调用该函数将测试结果发送给上位机产测工具

tuya_ble_net_config_response

函数名 tuya_ble_net_config_response
函数原型 tuya_ble_status_t tuya_ble_net_config_response(int16_t result_code);
功能概述 Wi-Fi 配网响应函数
参数 Result_code[in]:配网状态码
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 适用于 Wi-Fi 和蓝牙双协议设备

tuya_ble_ubound_response

函数名 tuya_ble_ubound_response
函数原型 tuya_ble_status_t tuya_ble_ubound_response(uint8_t result_code);
功能概述 多协议 combo 设备解绑响应函数
参数 Result_code[in]:状态码,0 表示成功,1 表示失败
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 适用于 Wi-Fi 和蓝牙双协议设备

tuya_ble_anomaly_ubound_response

函数名 tuya_ble_anomaly_ubound_response
函数原型 tuya_ble_status_t tuya_ble_anomaly_ubound_response (uint8_t result_code);
功能概述 多协议设备解绑响应函数
参数 Result_code[in]:状态,0 表示成功,1 表示失败
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开
TUYA_BLE_ERR_NO_EVENT:其他错误
备注 适用于 Wi-Fi 和蓝牙双协议设备

tuya_ble_device_reset_response

函数名 tuya_ble_device_reset_response
函数原型 tuya_ble_status_t tuya_ble_device_reset_response (uint8_t result_code);
功能概述 多协议combo设备恢复出厂设置响应函数
参数 Result_code[in]:状态,0 表示成功,1 表示失败
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:当前状态不支持发送,例如蓝牙断开TUYA_BLE_ERR_NO_EVENT:其他错误
备注 适用于 Wi-Fi 和蓝牙双协议设备

tuya_ble_connect_status_get

函数名 tuya_ble_connect_status_get
函数原型 tuya_ble_connect_status_t tuya_ble_connect_status_get(void);
功能概述 获取当前蓝牙的连接状态
参数
返回值 tuya_ble_connect_status_t详见下面返回值说明

连接状态定义如下所示:

typedef enum
{
  UNBONDING_UNCONN = 0, //未绑定未连接  
  UNBONDING_CONN,    //未绑定已连接已认证  
  BONDING_UNCONN,    //已绑定未连接  
  BONDING_CONN,     //已绑定已连接已认证  
  BONDING_UNAUTH_CONN,  //已绑定已连接未认证  
  UNBONDING_UNAUTH_CONN, //未绑定已连接未认证  
  UNKNOW_STATUS
}tuya_ble_connect_status_t;

各状态流程如下所示:

API

tuya_ble_device_unbind

函数名 tuya_ble_device_unbind
函数原型 tuya_ble_status_t tuya_ble_device_unbind(void);
功能概述 设备主动解绑
参数 无。
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INTERNAL:其他错误
备注 对于定义外部按键重置解绑功能的设备,按键触发重置解绑后,应用程序需要调用该函数通知涂鸦蓝牙 SDK 清除相关信息,例如清除绑定信息
该函数不会清除涂鸦蓝牙 SDK 绑定信息中的设备虚拟 ID,虚拟ID 管理着云端历史数据

tuya_ble_device_factory_reset

函数名 tuya_ble_device_factory_reset
函数原型 tuya_ble_status_t tuya_ble_device_factory_reset(void);
功能概述 设备重置,并清除虚拟设备 ID 信息
参数 无。
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INTERNAL:其他错误
备注 对于定义外部按键重置解绑功能的设备,按键触发重置解绑后应用程序需要调用该函数通知涂鸦蓝牙 SDK 清除相关信息,例如清除绑定信息
该函数会清除涂鸦蓝牙 SDK 绑定信息中的设备虚拟 ID,虚拟ID 管理着云端历史数据

tuya_ble_time_req

函数名 tuya_ble_time_req
函数原型 tuya_ble_status_t tuya_ble_time_req(uint8_t time_type);
功能概述 请求云端时间
参数 time_type[in]:
0:表示请求 13 字节 ms 级字符串格式的时间
1:表示请求云端年月日时分秒星期格式的时间
2:表示请求手机本地的年月日时分秒星期格式的时间
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_PARAM:参数错误
TUYA_BLE_ERR_INTERNAL:其他错误
备注 13 字节字符串时间格式:0000000123456 表示123456 ms时间戳
格式示例:0x13,0x04,0x1C,0x0C,0x17,0x19,0x02
对应时间:表示2019 年 4 月 28 日 12:23:25 星期二
蓝牙 SDK 收到请求后会发送相应指令给 App,蓝牙 SDK 收到 App 返回的时间后将会以消息的方式发送给设备应用程序

tuya_ble_ota_response

函数名 tuya_ble_ota_response
函数原型 tuya_ble_status_t tuya_ble_ota_response(tuya_ble_ota_response_t *p_data);
功能概述 OTA 响应指令
参数 p_data[in]:OTA 响应数据
返回值 TUYA_BLE_SUCCESS:发送成功
TUYA_BLE_ERR_INVALID_STATE:状态错误
TUYA_BLE_ERR_INVALID_LENGTH:数据长度错误
TUYA_BLE_ERR_NO_MEM:内存申请失败
TUYA_BLE_ERR_INTERNAL:其他错误
备注 具体格式见 OTA 介绍章节

tuya_ble_custom_event_send

函数名 tuya_ble_custom_event_send
函数原型 uint8_t tuya_ble_custom_event_send(tuya_ble_custom_evt_t evt);
功能概述 发送应用自定义消息及回调给涂鸦蓝牙 SDK
参数 evt[in]:自定义事件
返回值 0:发送成功。
1:失败
数据结构 typedef struct{
void *data;
void (*custom_event_handler)(void*data);
} tuya_ble_custom_evt_t;

如果应用程序想使用涂鸦蓝牙 SDK 内部的消息调度器,来处理应用程序的消息事件,则可以使用该函数实现。

tuya_ble_custom_event_send 应用示例:

#define APP_CUSTOM_EVENT_1  1
#define APP_CUSTOM_EVENT_2  2
#define APP_CUSTOM_EVENT_3  3
#define APP_CUSTOM_EVENT_4  4
#define APP_CUSTOM_EVENT_5  5

typedef struct {
	uint8_t data[50];
} custom_data_type_t;

void custom_data_process(int32_t evt_id,void *data)
{
	custom_data_type_t *event_1_data;
	TUYA_BLE_LOG_DEBUG("custom event id = %d",evt_id);
	switch (evt_id)
	{
		case APP_CUSTOM_EVENT_1:
			event_1_data = (custom_data_type_t *)data;
			TUYA_BLE_LOG_HEXDUMP_DEBUG("received APP_CUSTOM_EVENT_1 data:",event_1_data->data,50);
			break;
		case APP_CUSTOM_EVENT_2:
			break;
		case APP_CUSTOM_EVENT_3:
			break;
		case APP_CUSTOM_EVENT_4:
			break;
		case APP_CUSTOM_EVENT_5:
			break;
		default:
			break;

	}
}

custom_data_type_t custom_data;

void custom_evt_1_send_test(uint8_t data)
{
	tuya_ble_custom_evt_t event;

	for(uint8_t i=0; i<50; i++)
	{
		custom_data.data[i] = data;
	}
	event.evt_id = APP_CUSTOM_EVENT_1;
	event.custom_event_handler = (void *)custom_data_process;
	event.data = &custom_data;
	tuya_ble_custom_event_send(event);
}

tuya_ble_callback_queue_register

函数名 tuya_ble_callback_queue_register
函数原型 原型1:tuya_ble_status_t tuya_ble_callback_queue_register(void *cb_queue);
原型2:tuya_ble_status_t tuya_ble_callback_queue_register(tuya_ble_callback_t cb);
功能概述 RTOS 架构下,注册用于接收蓝牙 SDK 消息的消息队列时,使用原型1
无 RTOS 架构下,注册用于蓝牙 SDK 消息的回调函数时,使用原型2
参数 cb_queue [in]:消息队列
cb[in]:callback函数地址
返回值 TUYA_BLE_ERR_RESOURCES:注册失败
TUYA_BLE_SUCCESS:注册成功
  • RTOS 平台下应用示例:

    void *tuya_custom_queue_handle;
    
    os_msg_queue_create(&tuya_custom_queue_handle, MAX_NUMBER_OF_TUYA_CUSTOM_MESSAGE, sizeof(tuya_ble_cb_evt_param_t));
    
    tuya_ble_callback_queue_register(tuya_custom_queue_handle);
    
  • 无 RTOS 平台下应用示例:

    void tuya_cb_handler(tuya_ble_cb_evt_param_t* event)。
    
    tuya_ble_callback_queue_register(tuya_cb_handler);
    

tuya_ble_event_response

函数名 tuya_ble_event_response
函数原型 tuya_ble_status_t tuya_ble_event_response(tuya_ble_cb_evt_param_t *param);
功能概述 RTOS 架构下用于响应蓝牙 SDK 的消息
参数 param [in]:消息指针
返回值 TUYA_BLE_SUCCESS:成功
其他:失败
备注 RTOS 架构下,应用代码处理完蓝牙 SDK 发送来的消息后,必须调用此函数给与蓝牙 SDK 反馈

应用示例

/*处理ble sdk消息的应用task*/
void app_custom_task(void *p_param)
{
	tuya_ble_cb_evt_param_t event;

	while (true)
	{
		if (os_msg_recv(tuya_custom_queue_handle, &event, 0xFFFFFFFF) == true)
		{
			switch (event.evt)
			{
			case TUYA_BLE_CB_EVT_CONNECTE_STATUS:
				break;
			case TUYA_BLE_CB_EVT_DP_WRITE:
				break;
			case TUYA_BLE_CB_EVT_DP_DATA_REPORT_RESPONSE:
				break;
			case TUYA_BLE_CB_EVT_DP_DATA_WTTH_TIME_REPORT_RESPONSE:
				break;
			case TUYA_BLE_CB_EVT_UNBOUND:
				break;
			case TUYA_BLE_CB_EVT_ANOMALY_UNBOUND:
				break;
			case TUYA_BLE_CB_EVT_DEVICE_RESET:
				break;
			case TUYA_BLE_CB_EVT_DP_QUERY:
				break;
			case TUYA_BLE_CB_EVT_OTA_DATA:
				break;
			case TUYA_BLE_CB_EVT_NETWORK_INFO:
				break;
			case TUYA_BLE_CB_EVT_WIFI_SSID:
				break;
			case TUYA_BLE_CB_EVT_TIME_STAMP:
				break;
			case TUYA_BLE_CB_EVT_TIME_NORMAL:
				break;
			case TUYA_BLE_CB_EVT_DATA_PASSTHROUGH:
				break;
			default:
				break;
			}

			tuya_ble_event_response(&event);
		}
	}

}

tuya_ble_scheduler_queue_size_get

函数名 tuya_ble_scheduler_queue_size_get
函数原型 uint16_t tuya_ble_scheduler_queue_size_get(void);
功能概述 无 RTOS 架构下获取事件消息队列的大小
参数
返回值 消息队列的大小

tuya_ble_scheduler_queue_space_get

函数名 tuya_ble_scheduler_queue_space_get
函数原型 uint16_t tuya_ble_scheduler_queue_space_get(void);
功能概述 无 RTOS 架构下获取事件消息队列可用空间大小
参数
返回值 消息队列的可用空间大小

tuya_ble_scheduler_queue_events_get

函数名 tuya_ble_scheduler_queue_events_get
函数原型 uint16_t tuya_ble_scheduler_queue_events_get(void);
功能概述 在无 RTOS 平台下,获取涂鸦蓝牙 SDK 调度器队列未处理事件个数
参数
返回值 调度器队列未处理事件个数

tuya_ble_sleep_allowed_check

函数名 tuya_ble_sleep_allowed_check
函数原型 bool tuya_ble_sleep_allowed_check(void);
功能概述 查询涂鸦蓝牙 SDK 是否允许休眠
参数
返回值 true:允许休眠
false:不允许休眠
备注 应用程序在进入休眠前,必须调用该函数查询 SDK 是否允许休眠,否则可能会引起错误

tuya_ble_feature_scene_request

函数名 tuya_ble_feature_scene_request
函数原型 tuya_ble_status_t tuya_ble_feature_scene_request(tuya_ble_request_scene_t *req_data)
功能概述 请求场景数据或请求场景控制
参数 req_data[in]:请求数据
返回值 TUYA_BLE_SUCCESS:发送成功;
TUYA_BLE_ERR_INVALID_PARAM:参数无效;
TUYA_BLE_ERR_NO_MEM:内存申请失败;
TUYA_BLE_ERR_NO_EVENT:其他错误。

数据结构

/**@brief	Request scene cmd structure. */
typedef struct
{
	request_scene_cmd scene_cmd;					/**< request scene cmd. */

	union
	{
        request_scene_list_data_t  	scene_data;		/**< request scene list data info. */
        request_scene_control_t 	scene_control;	/**< request scene ctrl info. */
	};
} tuya_ble_request_scene_t;

/**@brief	Request scene type. */
typedef enum
{
	REQUEST_SCENE_DATA = 1,			/**< request scene list data. */
	REQUEST_SCENE_CONTROL,			/**< request scene control. */

	REQUEST_SCENE_CMD_MAX,
} request_scene_cmd;

/**@brief	Request scene list data structure. */
typedef struct
{
	uint8_t nums;					/**< request scene numbers, rang from [1-SUPPORT_REQUEST_SCENE_MAX_NUMS]. */
	uint16_t name_unicode_length;	/**< request scene name length, The encoding format is unicode, It must be a multiple of 2. */
	uint32_t check_code;			/**< scene check code, algorithm-crc32. */
} request_scene_list_data_t;

/**@brief	Request scene control structure. */
typedef struct
{
	uint8_t scene_id_length;				/**< scene id length. */
	uint8_t scene_id[SCENE_ID_MAX_LENGTH]; 	/**< scene id, Max length equal to SCENE_ID_MAX_LENGTH. */
} request_scene_control_t;

请求场景数据由一个结构体组成,包括请求命令与对应命令的具体数据,其中请求命令包括:

  • REQUEST_SCENE_DATA:请求场景列表数据
  • REQUEST_SCENE_CONTROL:请求场景控制

请求场景列表数据

命令的具体数据详见 request_scene_list_data_t,包括请求场景个数、场景名称长度(按unicode编码)与场景数据CRC32校验值。

  • Unicode 编码方式:2 字节表示1个字符。如汉字“今”unicode编码为\u4eca, 传输顺序为 0xCA, 0x4E

  • CRC32 校验值:主要用于差量同步,设备端每次在请求时带上上一次接收到校验码,处理方会对当前请求的场景最新数据做校验,通过比对从而告知设备是否需要更新。

  • 设备端存储场景数据:包括场景 ID,ID 长度以及校验值。

    场景ID 场景ID长度 场景名称长度(Unicode) 场景名称(Unicode)
    xx xx xx xx
    xx xx xx xx

请求场景控制

命令的具体数据详见 request_scene_control_t,包括场景 ID 长度与场景 ID。

应用示例

/* 请求场景列表数据,场景个数=1,场景名称unicode长度=10,设备本地场景校验码=0 */
tuya_ble_request_scene_t req_scene_data;

req_scene_data.cmd_type = REQUEST_SCENE_DATA;
req_scene_data.scene_data.nums = 1;
req_scene_data.scene_data.name_unicode_length = 10;
req_scene_data.scene_data.check_code = 0;

tuya_ble_feature_scene_request(&req_scene_data);


/* 请求场景控制 */
tuya_ble_request_scene_t req_scene_data;

static const char test_scene_id[] = "nRAfyPBArgTAPgUq";
req_scene_data.cmd_type = REQUEST_SCENE_CONTROL;
req_scene_data.scene_control.scene_id_length = 16;
memcpy(req_scene_data.scene_control.scene_id, test_scene_id, req_scene_data.scene_control.scene_id_length);

tuya_ble_feature_scene_request(&req_scene_data);