更新时间:2024-11-20 08:51:21下载pdf
涂鸦蓝牙 SDK(Tuya BLE SDK)提供封装好的 API,用于开发物联网蓝牙设备应用程序相关的管理和通信等。API 函数定义在 tuya_ble_api.c
和 tuya_ble_api.h
文件中,您无需更改相关代码实现,但如果有兴趣,可以阅读源码理解实现原理。
函数名 | 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_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_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 时,
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 是在 涂鸦开发者平台 新建产品时自动生成的。PID 生成后不会改变,需要应用代码以常量的形式保存,并且在初始化涂鸦蓝牙 SDK 时传入。 |
p_type |
PID 的类型,目前支持TUYA_BLE_PRODUCT_ID_TYPE_PID 类型。 |
adv_local_name |
adv_local_name 和 adv_local_name_len 是应用程序自定义蓝牙广播名字的变量。如果 adv_local_name_len 为 0 ,那么涂鸦蓝牙 SDK 将默认使用 TY 作为蓝牙广播名字,应用程序在初始化蓝牙 GAP(Generic Access Profile)时,设置的蓝牙名字必须和 传给 SDK 的 adv_local_name 一致,最多支持 5 个字符。 |
firmware_version 和 hardware_version |
固件版本号和 PCBA 硬件版本号,为四字节。例如,0x00010102 表示 v1.1.2,0x0101 表示 v1.1 。 |
device_vid |
设备虚拟 ID。设备注册绑定后由开发者平台生成。主要作用是设备绑定解绑再绑定时,通过该 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_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_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() |
tuya_ble_common_uart_receive_data()
函数即可,当然应用也可以自己解析出完整的 UART 通信指令,然后通过调用 tuya_ble_common_uart_send_full_instruction_received()
函数发送完整指令给涂鸦蓝牙 SDK。函数名 | 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_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_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_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_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_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 参数说明
涂鸦开发者平台是以 DP 模型管理数据。任何设备产生的数据都需要抽象为 DP 数据形式,一个 DP 数据由四部分组成。更多详情,请参考 自定义功能。
Dp_id:1 个字节,在涂鸦开发者平台注册的 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 数据类型的最大数据长度在涂鸦开发者平台定义时指定
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
数值自定义,但必须小于在涂鸦开发者平台定义时的最大长度。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_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 :其他错误 |
sn
、mode
、p_dp_data
和 dp_data_len
:上文已有介绍,请参考 tuya_ble_dp_data_send()
的说明。其中,该函数的 dp_data_len
最大不能超过 TUYA_BLE_SEND_MAX_DATA_LEN-21
,TUYA_BLE_SEND_MAX_DATA_LEN
可配置。
该函数没有 ack
参数,因为带时间戳的 DP 数据发送必须要有手机 App 的响应。
time_type
和 p_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 |
---|---|
函数原型 | void tuya_ble_connected_handler(void); |
功能概述 | 蓝牙被连接的回调函数 |
参数 | 无 |
返回值 | 无 |
备注 | 应用代码需要在芯片平台 SDK 的蓝牙连接回调处调用此函数,涂鸦蓝牙 SDK 是基于该函数来管理内部蓝牙连接状态的 |
函数名 | tuya_ble_disconnected_handler |
---|---|
函数原型 | void tuya_ble_disconnected_handler(void); |
功能概述 | 蓝牙断开连接的回调函数 |
参数 | 无 |
返回值 | 无 |
备注 | 应用代码需要在芯片平台 SDK 的蓝牙断开连接回调处调用此函数,涂鸦蓝牙 SDK 是根据此函数的执行来管理内部蓝牙连接状态的 |
nrf52832 平台调用 tuya_ble_connected_handler
和 tuya_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 |
---|---|
函数原型 | 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_status_t tuya_ble_adv_data_connecting_request_set(uint8_t on_off); |
功能概述 | 请求连接标志置位函数 |
参数 | on_off[in]:0 表示清除标志,1 表示置位标志 |
返回值 | 无 |
备注 | 本函数暂未开放使用,具体应用方法请咨询涂鸦技术支持工程师 |
函数名 | 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_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_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_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_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_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_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;
各状态流程如下所示:
函数名 | 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_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_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_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 |
---|---|
函数原型 | 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 |
---|---|
函数原型 | 原型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_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 |
---|---|
函数原型 | uint16_t tuya_ble_scheduler_queue_size_get(void); |
功能概述 | 无 RTOS 架构下获取事件消息队列的大小 |
参数 | 无 |
返回值 | 消息队列的大小 |
函数名 | tuya_ble_scheduler_queue_space_get |
---|---|
函数原型 | uint16_t tuya_ble_scheduler_queue_space_get(void); |
功能概述 | 无 RTOS 架构下获取事件消息队列可用空间大小 |
参数 | 无 |
返回值 | 消息队列的可用空间大小 |
函数名 | tuya_ble_scheduler_queue_events_get |
---|---|
函数原型 | uint16_t tuya_ble_scheduler_queue_events_get(void); |
功能概述 | 在无 RTOS 平台下,获取涂鸦蓝牙 SDK 调度器队列未处理事件个数 |
参数 | 无 |
返回值 | 调度器队列未处理事件个数 |
函数名 | tuya_ble_sleep_allowed_check |
---|---|
函数原型 | bool tuya_ble_sleep_allowed_check(void); |
功能概述 | 查询涂鸦蓝牙 SDK 是否允许休眠 |
参数 | 无 |
返回值 | true:允许休眠 false:不允许休眠 |
备注 | 应用程序在进入休眠前,必须调用该函数查询 SDK 是否允许休眠,否则可能会引起错误 |
函数名 | 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);
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈