更新时间:2024-07-30 03:09:48下载pdf
智能门锁、智能手表和手环等设备需要更新语音文件、表盘文件等数据,这些数据通常需要 App 下发到智能设备。为了确保文件下发统一,TuyaOS Bluetooth LE SDK 提供固件下发通道接口,应用层只需通过 SDK 提供的文件下发通信接口,按照本文所述的文件下发协议实现即可。
下图展示了文件传输流程。
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT8_T id_len;
UINT8_T *id_buf;
UINT32_T file_ver;
UINT32_T file_len;
UINT8_T file_md5[TUYA_BLE_FILE_MD5_LEN];
UINT32_T data_len;
UINT16_T pkt_id;
UINT16_T pkt_len;
UINT16_T pkt_crc16;
} TAL_BLE_FILE_INFO_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT8_T status;
UINT16_T pkt_maxlen;
UINT32_T stored_len;
UINT8_T stored_md5[TUYA_BLE_FILE_MD5_LEN];
} TAL_BLE_FILE_INFO_RSP_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT32_T offset;
} TAL_BLE_FILE_OFFSET_REQ_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT32_T offset;
} TAL_BLE_FILE_OFFSET_REP_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT16_T pkt_id;
UINT16_T pkt_len;
UINT16_T pkt_crc16;
UINT8_T *data;
} TAL_BLE_FILE_DATA_REQ_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT8_T status;
} TAL_BLE_FILE_DATA_RSP_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
} TAL_BLE_FILE_END_REQ_T;
typedef struct {
UINT8_T type;
UINT16_T file_id;
UINT8_T status;
} TAL_BLE_FILE_END_RSP_T;
typedef struct {
UINT32_T file_addr; /*file store next addr, cur_file_addr = (file_addr -(file_len/0x1000+1)*0x1000*/
UINT8_T type; /*cur file info */
UINT16_T file_id;
UINT32_T file_ver;
UINT32_T file_len;
UINT8_T file_md5[TUYA_BLE_MD5_LEN];
UINT8_T id_len;
UINT8_T *id_buf;
} TAL_BLE_FILE_INFO_DATA_T;
typedef struct {
mbedtls_md5_context ctx_storage; //md5 loop cac.
UINT16_T cur_file_id; //operation data.
} TAL_BLE_FILE_MD5_INFO_T;
应用层通过注册的回调函数 tuya_ble_handle_ble_data_evt
接收数据。
通过 Event ID 为 TUYA_BLE_EVT_BLE_CMD
的命令,调用 tuya_ble_handle_ble_cmd_evt
进行数据解析。
以上第 1 步和第 2 步为通用的数据接收解析过程,根据 cmd 进行文件下发数据处理。
通过 Event ID 为 TUYA_BLE_CB_EVT_FILE_DATA
的命令,调用 tuya_ble_sdk_callback
进行文件下发数据处理,解析数据并准备回复包。
最后,回复包调用 Event ID 为 TUYA_BLE_EVT_CUSTOM
的通用回调事件进行数据回复。
由于第 1 步和第 2 步为通用接口,故不在此赘述。文件下发 API 接口主要针对第 3 步和第 4 步进行说明。
tuya_ble_handle_file_req
函数名 | tuya_ble_handle_file_req |
---|---|
函数原型 | void tuya_ble_handle_file_req(uint16_t cmd,uint8_t*p_recv_data,uint32_t recv_data_len) |
功能概述 | 读取文件下发数据 |
参数 |
|
返回值 | 无 |
备注 | 无 |
示例:
void tuya_ble_handle_file_req(uint16_t cmd, uint8_t *recv_data, uint32_t recv_len)
{
......
switch (cmd)
{
case FRM_FILE_INFOR_REQ:
cmd_type = TUYA_BLE_FILE_INFO;
break;
case FRM_FILE_OFFSET_REQ:
cmd_type = TUYA_BLE_FILE_OFFSET_REQ;
break;
case FRM_FILE_DATA_REQ:
cmd_type = TUYA_BLE_FILE_DATA;
break;
case FRM_FILE_END_REQ:
cmd_type = TUYA_BLE_FILE_END;
break;
default:
cmd_type = TUYA_BLE_FILE_UNKONWN;
break;
}
event.evt = TUYA_BLE_CB_EVT_FILE_DATA;
event.file_data.type = cmd_type;
event.file_data.data_len = data_len;
event.file_data.p_data = ble_cb_evt_buffer;
if (tuya_ble_cb_event_send(&event) != 0)
{
tuya_ble_free(ble_cb_evt_buffer);
TUYA_BLE_LOG_ERROR("tuya_ble_handle_file_req-tuya ble send cb event failed.");
}
......
}
tuya_ble_file_response
函数名 | tuya_ble_file_response |
---|---|
函数原型 | tuya_ble_status_t tuya_ble_file_response(tuya_ble_file_response_t *p_data) |
功能概述 | 文件下发数据响应 |
参数 | p_data[in] :文件下发响应数据 |
返回值 |
|
备注 | 在设备接收到 App 的文件下发数据命令后,需要调用该 API 进行响应。 |
示例:
tuya_ble_status_t tuya_ble_file_response(tuya_ble_file_response_t *p_data)
{
......
p_buffer = tuya_ble_malloc(sizeof(tuya_ble_file_response_t) + p_data->data_len);
if(p_buffer)
{
p_res_data = (tuya_ble_file_response_t*)p_buffer;
p_res_data->p_data = p_buffer + sizeof(tuya_ble_file_response_t);
p_res_data->data_len = p_data->data_len;
p_res_data->type = p_data->type;
memcpy(p_res_data->p_data,p_data->p_data,p_data->data_len);
}
else
{
return TUYA_BLE_ERR_NO_MEM;
}
custom_evt.evt_id = 0;//res
custom_evt.data = p_res_data;
custom_evt.custom_event_handler = tuya_ble_handle_file_response_evt;
TUYA_BLE_LOG_HEXDUMP_DEBUG("custom_data",(uint8_t*)p_res_data->p_data,p_res_data->data_len);
if (tuya_ble_custom_event_send(custom_evt) != 0)
{
tuya_ble_free(p_buffer);
return TUYA_BLE_ERR_NO_EVENT;
}
return TUYA_BLE_SUCCESS;
}
if (rsp_flag)
{
tuya_ble_bulk_data_response(&rsp_data);
}
}
tuya_ble_sdk
通过消息(RTOS 架构下)或者应用层注册的回调函数(无 RTOS 架构下)向应用层发送消息(状态、数据等)。
当 App 向设备下发文件数据命令后,tuya_ble_sdk
会向应用层发送如下的文件下发回调事件。
TUYA_BLE_CB_EVT_FILE_DATA
Event | TUYA_BLE_CB_EVT_FILE_DATA |
---|---|
对应数据结构 | tuya_ble_bulk_data_request_t |
描述 | 文件下发通道数据请求回调事件 |
备注 | 用户可在该回调事件下,处理文件下发数据命令 |
数据结构:
typedef enum
{
TUYA_BLE_FILE_INFO, /**< 下发文件信息*/
TUYA_BLE_FILE_OFFSET_REQ, /**< 下发文件偏移*/
TUYA_BLE_FILE_DATA, /**< 下发文件数据*/
TUYA_BLE_FILE_END, /**< 下发文件完成*/
TUYA_BLE_FILE_UNKONWN, /**< 其他*/
} tuya_ble_file_data_type_t;
typedef struct {
tuya_ble_file_data_type_t type;
uint16_t data_len;
uint8_t *p_data;
} tuya_ble_file_response_t;
示例:
static void tuya_ble_sdk_callback(tuya_ble_cb_evt_param_t *event)
{
switch (event->evt)
{
//...
case TUYA_BLE_CB_EVT_FILE_DATA: {
#if (TUYA_BLE_FILE_ENABLE != 0)
TUYA_APP_LOG_INFO("TUYA_BLE_CB_EVT_FILE_DATA");
tuya_ble_file_handler(&event->file_data);
#endif
} break;
//...
}
}
void tuya_ble_file_handler(tuya_ble_file_data_t *file)
{
tuya_ble_file_response_t rsp;
rsp.type = file->type;
if(file->type != TUYA_BLE_FILE_DATA) {
TUYA_APP_LOG_INFO("file_type: %d", file->type);
TUYA_APP_LOG_HEXDUMP_INFO("file_data", file->p_data, file->data_len);
}
switch (file->type)
{
case TUYA_BLE_FILE_INFO: {
tuya_ble_file_info_handler(file->p_data, file->data_len, &rsp);
} break;
case TUYA_BLE_FILE_OFFSET_REQ: {
tuya_ble_file_offset_handler(file->p_data, file->data_len, &rsp);
} break;
case TUYA_BLE_FILE_DATA: {
tuya_ble_file_data_handler(file->p_data, file->data_len, &rsp);
} break;
case TUYA_BLE_FILE_END: {
tuya_ble_file_end_handler(file->p_data, file->data_len, &rsp);
} break;
case TUYA_BLE_FILE_UNKONWN: {
} break;
default: {
} break;
}
}
ndhihx1m
进入设备面板,单击 设置 选项。
门锁语言 选项显示 未设置语言状态,单击该选项进入语言状态选择。
选择想要的语言,下载并使用。
传输开始,等待传输结束。
传输完成后,语音包显示为 使用中,表示文件下发流程已经成功完成。
在开发过程遇到问题,您可以登录 TuyaOS 开发者论坛 TuyaOS-蓝牙设备开发 版块进行沟通咨询。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈