在逗猫棒的基础上实现蓝牙转USB功能,目前功能已经实现,还需裁剪掉之前逗猫棒的业务程序

This commit is contained in:
2026-07-24 11:41:08 +08:00
commit b3f06697a6
1569 changed files with 515355 additions and 0 deletions
@@ -0,0 +1,422 @@
#include "tuya_ble_stdlib.h"
#include "tuya_ble_type.h"
#include "tuya_ble_heap.h"
#include "tuya_ble_mem.h"
#include "tuya_ble_api.h"
#include "tuya_ble_port.h"
#include "tuya_ble_main.h"
#include "tuya_ble_secure.h"
#include "tuya_ble_data_handler.h"
#include "tuya_ble_storage.h"
#include "tuya_ble_sdk_version.h"
#include "tuya_ble_utils.h"
#include "tuya_ble_event.h"
#include "tuya_ble_app_demo.h"
//#include "tuya_ble_demo_version.h"
#include "tuya_ble_log.h"
#include "tuya_ota.h"
#include "system/generic/printf.h"
#include "log.h"
#include "system/includes.h"
//#include "ota.h"
tuya_ble_device_param_t device_param = {0};
#define LED_PIN IO_PORTA_01
static bool tuya_led_state = 0;
//烧写器烧写三元组时这里置零
#define TUYA_INFO_TEST 0
#if TUYA_INFO_TEST
static const char device_id_test[] = "tuya58253f7c8ed1";
static const char auth_key_test[] = "I9ikbTKVMhfvEDgARBCtFbAWUpZIRdyv";
static const uint8_t mac_test[6] = {0xDC, 0x23, 0x4D, 0x65, 0xB0, 0x66}; //The actual MAC address is : 66:55:44:33:22:11
#endif /* TUYA_INFO_TEST */
#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
static uint8_t dp_data_array[255 + 3];
static uint16_t dp_data_len = 0;
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_APP_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_APP_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);
}
static uint16_t sn = 0;
static uint32_t time_stamp = 1587795793;
void tuya_data_init()
{
struct {
uint8_t id;
uint8_t type;
uint16_t len;
uint8_t data;
} p_dp_data;
p_dp_data.id = 1;
p_dp_data.type = 1;
p_dp_data.len = 0x0100;
p_dp_data.data = tuya_led_state;
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x03)
tuya_ble_dp_data_report(&p_dp_data, 5); //1
#endif
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x04)
tuya_ble_dp_data_send(sn, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITH_RESPONSE, &p_dp_data, 5);
#endif
}
void tuya_data_parse(tuya_ble_cb_evt_param_t *event)
{
uint8_t *buf = event->dp_received_data.p_data;
uint32_t sn = event->dp_received_data.sn;
put_buf(buf, event->dp_received_data.data_len);
struct {
uint8_t id;
uint8_t type;
uint16_t len;
uint8_t data;
} p_dp_data;
p_dp_data.id = buf[0];
p_dp_data.type = buf[1];
p_dp_data.len = 0x0100;
p_dp_data.data = buf[4];
printf("\n\n<-------------- tuya_data_parse -------------->");
printf("sn = %d, id = %d, type = %d, len = %d, data = %d", sn, p_dp_data.id, p_dp_data.type, p_dp_data.len, p_dp_data.data);
switch (buf[0]) {
case 1:
printf("tuya switch control, onoff set to: %d\n", p_dp_data.data);
tuya_led_state = p_dp_data.data;
gpio_direction_output(LED_PIN, tuya_led_state);
break;
//case 2:
//printf("tuya mode control, mode set to: %d\n", buf[3]);
//break;
default:
printf("unknow control msg len = %d, data:", buf[2]);
break;
}
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x03)
tuya_ble_dp_data_report(&p_dp_data, 5); //1
#endif
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x04)
tuya_ble_dp_data_send(sn, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITH_RESPONSE, &p_dp_data, 5);
#endif
}
static void tuya_cb_handler(tuya_ble_cb_evt_param_t *event)
{
int16_t result = 0;
printf("tuya cb_handler event->evt=0x%x\n", event->evt);
switch (event->evt) {
case TUYA_BLE_CB_EVT_CONNECTE_STATUS:
TUYA_APP_LOG_INFO("received tuya ble conncet status update event,current connect status = %d", event->connect_status);
break;
case TUYA_BLE_CB_EVT_DP_DATA_RECEIVED:
tuya_data_parse(event);
break;
case TUYA_BLE_CB_EVT_DP_DATA_REPORT_RESPONSE:
TUYA_APP_LOG_INFO("received dp data report response result code =%d", event->dp_response_data.status);
break;
case TUYA_BLE_CB_EVT_DP_DATA_WTTH_TIME_REPORT_RESPONSE:
TUYA_APP_LOG_INFO("received dp data report response result code =%d", event->dp_response_data.status);
break;
case TUYA_BLE_CB_EVT_DP_DATA_WITH_FLAG_REPORT_RESPONSE:
TUYA_APP_LOG_INFO("received dp data with flag report response sn = %d , flag = %d , result code =%d", event->dp_with_flag_response_data.sn, event->dp_with_flag_response_data.mode
, event->dp_with_flag_response_data.status);
break;
case TUYA_BLE_CB_EVT_DP_DATA_WITH_FLAG_AND_TIME_REPORT_RESPONSE:
TUYA_APP_LOG_INFO("received dp data with flag and time report response sn = %d , flag = %d , result code =%d", event->dp_with_flag_and_time_response_data.sn,
event->dp_with_flag_and_time_response_data.mode, event->dp_with_flag_and_time_response_data.status);
break;
case TUYA_BLE_CB_EVT_UNBOUND:
TUYA_APP_LOG_INFO("received unbound req");
break;
case TUYA_BLE_CB_EVT_ANOMALY_UNBOUND:
TUYA_APP_LOG_INFO("received anomaly unbound req");
break;
case TUYA_BLE_CB_EVT_DEVICE_RESET:
TUYA_APP_LOG_INFO("received device reset req");
break;
case TUYA_BLE_CB_EVT_DP_QUERY:
TUYA_APP_LOG_INFO("received TUYA_BLE_CB_EVT_DP_QUERY event");
if (dp_data_len > 0) {
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x03)
tuya_ble_dp_data_report(dp_data_array, dp_data_len);
#endif
#if (TUYA_BLE_PROTOCOL_VERSION_HIGN == 0x04)
tuya_ble_dp_data_send(sn, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITH_RESPONSE, dp_data_array, dp_data_len);
#endif
}
break;
case TUYA_BLE_CB_EVT_OTA_DATA:
tuya_ota_proc(event->ota_data.type, event->ota_data.p_data, event->ota_data.data_len);
break;
case TUYA_BLE_CB_EVT_NETWORK_INFO:
TUYA_APP_LOG_INFO("received net info : %s", event->network_data.p_data);
tuya_ble_net_config_response(result);
break;
case TUYA_BLE_CB_EVT_WIFI_SSID:
break;
case TUYA_BLE_CB_EVT_TIME_STAMP:
TUYA_APP_LOG_INFO("received unix timestamp : %s ,time_zone : %d", event->timestamp_data.timestamp_string, event->timestamp_data.time_zone);
tuya_data_init();
break;
case TUYA_BLE_CB_EVT_TIME_NORMAL:
break;
case TUYA_BLE_CB_EVT_DATA_PASSTHROUGH:
TUYA_APP_LOG_HEXDUMP_DEBUG("received ble passthrough data :", event->ble_passthrough_data.p_data, event->ble_passthrough_data.data_len);
tuya_ble_data_passthrough(event->ble_passthrough_data.p_data, event->ble_passthrough_data.data_len);
break;
default:
TUYA_APP_LOG_WARNING("app_tuya_cb_queue msg: unknown event type 0x%04x", event->evt);
break;
}
tuya_ble_inter_event_response(event);
}
#define TUYA_LEGAL_CHAR(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
static u16 tuya_get_one_info(const u8 *in, u8 *out)
{
int read_len = 0;
const u8 *p = in;
while (TUYA_LEGAL_CHAR(*p) && *p != ',') { //read product_uuid
*out++ = *p++;
read_len++;
}
return read_len;
}
typedef struct __flash_of_lic_para_head {
s16 crc;
u16 string_len;
const u8 para_string[];
} __attribute__((packed)) _flash_of_lic_para_head;
#define LIC_PAGE_OFFSET 80
static bool license_para_head_check(u8 *para)
{
_flash_of_lic_para_head *head;
//fill head
head = (_flash_of_lic_para_head *)para;
///crc check
u8 *crc_data = (u8 *)(para + sizeof(((_flash_of_lic_para_head *)0)->crc));
u32 crc_len = sizeof(_flash_of_lic_para_head) - sizeof(((_flash_of_lic_para_head *)0)->crc)/*head crc*/ + (head->string_len)/*content crc,include end character '\0'*/;
s16 crc_sum = 0;
crc_sum = CRC16(crc_data, crc_len);
if (crc_sum != head->crc) {
printf("license crc error !!! %x %x \n", (u32)crc_sum, (u32)head->crc);
return false;
}
return true;
}
const u8 *tuya_get_license_ptr(void)
{
u32 flash_capacity = sdfile_get_disk_capacity();
u32 flash_addr = flash_capacity - 256 + LIC_PAGE_OFFSET;
u8 *lic_ptr = NULL;
_flash_of_lic_para_head *head;
printf("flash capacity:%x \n", flash_capacity);
lic_ptr = (u8 *)sdfile_flash_addr2cpu_addr(flash_addr);
//head length check
head = (_flash_of_lic_para_head *)lic_ptr;
if (head->string_len >= 0xff) {
printf("license length error !!! \n");
return NULL;
}
////crc check
if (license_para_head_check(lic_ptr) == (false)) {
printf("license head check fail\n");
return NULL;
}
//put_buf(lic_ptr, 128);
lic_ptr += sizeof(_flash_of_lic_para_head);
return lic_ptr;
}
static uint8_t read_tuya_product_info_from_flash(uint8_t *read_buf, u16 buflen)
{
uint8_t *rp = read_buf;
const uint8_t *tuya_ptr = (uint8_t *)tuya_get_license_ptr();
//printf("tuya_ptr:");
//put_buf(tuya_ptr, 69);
if (tuya_ptr == NULL) {
return FALSE;
}
int data_len = 0;
data_len = tuya_get_one_info(tuya_ptr, rp);
//put_buf(rp, data_len);
if (data_len != 16) {
printf("read uuid err, data_len:%d", data_len);
put_buf(rp, data_len);
return FALSE;
}
tuya_ptr += 17;
rp = read_buf + 16;
data_len = tuya_get_one_info(tuya_ptr, rp);
//put_buf(rp, data_len);
if (data_len != 32) {
printf("read key err, data_len:%d", data_len);
put_buf(rp, data_len);
return FALSE;
}
tuya_ptr += 33;
rp = read_buf + 16 + 32;
data_len = tuya_get_one_info(tuya_ptr, rp);
//put_buf(rp, data_len);
if (data_len != 12) {
printf("read mac err, data_len:%d", data_len);
put_buf(rp, data_len);
return FALSE;
}
return TRUE;
}
static u8 ascii_to_hex(u8 in)
{
if (in >= '0' && in <= '9') {
return in - '0';
} else if (in >= 'a' && in <= 'f') {
return in - 'a' + 0x0a;
} else if (in >= 'A' && in <= 'F') {
return in - 'A' + 0x0a;
} else {
printf("tuya ascii to hex error, data:0x%x", in);
return 0;
}
}
static void parse_mac_data(u8 *in, u8 *out)
{
for (int i = 0; i < 6; i++) {
out[i] = (ascii_to_hex(in[2 * i]) << 4) + ascii_to_hex(in[2 * i + 1]);
}
}
void tuya_ble_app_init(void)
{
device_param.device_id_len = 16; //If use the license stored by the SDK,initialized to 0, Otherwise 16 or 20.
uint8_t read_buf[16 + 32 + 6 + 1] = {0};
int ret = 0;
device_param.use_ext_license_key = 1;
if (device_param.device_id_len == 16) {
#if TUYA_INFO_TEST
memcpy(device_param.auth_key, (void *)auth_key_test, AUTH_KEY_LEN);
memcpy(device_param.device_id, (void *)device_id_test, DEVICE_ID_LEN);
memcpy(device_param.mac_addr.addr, mac_test, 6);
#else
ret = read_tuya_product_info_from_flash(read_buf, sizeof(read_buf));
if (ret == TRUE) {
uint8_t mac_data[6];
memcpy(device_param.device_id, read_buf, 16);
memcpy(device_param.auth_key, read_buf + 16, 32);
parse_mac_data(read_buf + 16 + 32, mac_data);
memcpy(device_param.mac_addr.addr, mac_data, 6);
}
#endif
device_param.mac_addr.addr_type = TUYA_BLE_ADDRESS_TYPE_RANDOM;
}
printf("device_id:");
put_buf(device_param.device_id, 16);
printf("auth_key:");
put_buf(device_param.auth_key, 32);
printf("mac:");
put_buf(device_param.mac_addr.addr, 6);
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;
printf("HJY:12345\n");
tuya_ble_sdk_init(&device_param);
ret = tuya_ble_callback_queue_register(tuya_cb_handler);
y_printf("tuya_ble_callback_queue_register,ret=%d\n", ret);
//tuya_ota_init();
//TUYA_APP_LOG_INFO("demo project version : "TUYA_BLE_DEMO_VERSION_STR);
TUYA_APP_LOG_INFO("app version : "TY_APP_VER_STR);
}
@@ -0,0 +1,48 @@
#ifndef TUYA_BLE_APP_DEMO_H_
#define TUYA_BLE_APP_DEMO_H_
#ifdef __cplusplus
extern "C" {
#endif
#define APP_PRODUCT_ID "xqhyt364"
#define APP_BUILD_FIRMNAME "tuya_ble_sdk_app_demo_nrf52832"
//固件版本
#define TY_APP_VER_NUM 0x0100
#define TY_APP_VER_STR "1.0"
//硬件版本
#define TY_HARD_VER_NUM 0x0100
#define TY_HARD_VER_STR "1.0"
/*
typedef enum {
white,
colour,
scene,
music,
} tuya_light_mode;
*/
void tuya_ble_app_init(void);
#ifdef __cplusplus
}
#endif
#endif //
@@ -0,0 +1,207 @@
#include "tuya_ota.h"
#include "tuya_ble_type.h"
#include "tuya_ble_app_demo.h"
#include "dual_bank_updata_api.h"
#include "timer.h"
#include "asm/clock.h"
extern u8 dual_bank_update_verify_without_crc(void);
tuya_ble_status_t tuya_ble_ota_response(tuya_ble_ota_response_t *p_data);
#define OTA_WRITE_FLASH_SIZE (2048)
typedef struct {
u32 file_size;
u32 recv_len;
u32 file_crc;
u16 tuya_ota_packet_num;
u8 buff[OTA_WRITE_FLASH_SIZE];
u32 buff_size;
} tuya_ota_t;
tuya_ota_t tuya_ota;
__attribute__((weak))
u8 tuya_start_ota_check(void)
{
return 0;
}
void tuya_ota_reset(void *priv)
{
cpu_reset();
}
int tuya_ota_boot_info_cb(int err)
{
sys_timeout_add(NULL, tuya_ota_reset, 2000);
return 0;
}
int tuya_ota_file_end_response(void *priv)
{
tuya_ble_ota_response_t response;
tuya_ota_end_response_t ota_end_response;
ota_end_response.reserve = 0;
int old_sys_clk = clk_get("sys");
clk_set("sys", 120 * 1000000L); //提升系统时钟提高校验速度
if (dual_bank_update_verify_without_crc() == 0) {
printf("UPDATE SUCCESS");
ota_end_response.state = 0;
dual_bank_update_burn_boot_info(tuya_ota_boot_info_cb);
} else {
printf("UPDATE FAILURE");
ota_end_response.state = 2;
}
clk_set("sys", old_sys_clk); //恢复时钟
response.type = TUYA_BLE_OTA_END;
response.p_data = &ota_end_response;
response.data_len = 2;
return tuya_ble_ota_response(&response);
}
int tuya_ota_data_response()
{
tuya_ble_ota_response_t response;
tuya_ota_data_response_t ota_data_response;
response.type = TUYA_BLE_OTA_DATA;
ota_data_response.reserve = 0;
ota_data_response.state = TUYA_OTA_DATA_SUCC;
response.p_data = &ota_data_response;
response.data_len = 2;
tuya_ble_ota_response(&response);
return 0;
}
int tuya_update_write_cb(void *priv)
{
tuya_ota_data_response();
return 0;
}
void tuya_ota_proc(u16 type, u8 *recv_data, u32 recv_len)
{
tuya_ble_ota_response_t response;
static bool first_packet_come = 0;
static u32 current_file_size = 0;
switch (type) {
case TUYA_BLE_OTA_REQ:
printf("TUYA_BLE_OTA_REQ\n");
dual_bank_passive_update_exit(NULL); //tuya APP退到后台会中断发数,重新开始REQ要退出上一次的任务
tuya_ota_req_response_t ota_req_response;
ota_req_response.flag = tuya_start_ota_check();
ota_req_response.ota_version = 3;
ota_req_response.reserve = 0;
ota_req_response.frame_version = TY_APP_VER_NUM;
ota_req_response.max_pkt_len = OTA_MAX_DATA_LEN;
first_packet_come = 0;
current_file_size = 0;
response.p_data = &ota_req_response;
response.data_len = 9;
memset(&tuya_ota, 0, sizeof(tuya_ota));
break;
case TUYA_BLE_OTA_FILE_INFO:
printf("TUYA_BLE_OTA_FILE_INFO\n");
tuya_ota_file_info_response_t ota_file_info_response;
ota_file_info_response.reserve = 0;
tuya_ota.file_size = READ_BIG_U32(recv_data + 29);
uint32_t file_version = READ_BIG_U32(recv_data + 9);
printf("TUYA_BLE_OTA_FILE_INFO file_size%d file_version%d", tuya_ota.file_size, file_version);
dual_bank_passive_update_init(0, tuya_ota.file_size, OTA_WRITE_FLASH_SIZE, NULL);
if (dual_bank_update_allow_check(tuya_ota.file_size) != 0) {
dual_bank_passive_update_exit(NULL);
ota_file_info_response.state = TUYA_OTA_STATE_FILE_SIZE_TOO_LARGE;
} else if (file_version <= TY_APP_VER_NUM) {
dual_bank_passive_update_exit(NULL);
ota_file_info_response.state = TUYA_OTA_STATE_VER_LOW;
} else {
ota_file_info_response.state = TUYA_OTA_STATE_NORMAL;
}
response.p_data = &ota_file_info_response;
response.data_len = 26;
break;
case TUYA_BLE_OTA_FILE_OFFSET_REQ:
printf("TUYA_BLE_OTA_FILE_OFFSET_REQ\n");
uint8_t data[5] = {0};
response.type = TUYA_BLE_OTA_FILE_OFFSET_REQ;
u32 offset_addr = READ_BIG_U32(recv_data + 1);
data[1] = (u8)(offset_addr >> 24);
data[2] = (u8)(offset_addr >> 16);
data[3] = (u8)(offset_addr >> 8);
data[4] = (u8)(offset_addr >> 0);
printf("offset_addr = 0x%x", offset_addr);
response.data_len = 5;
response.p_data = data;
tuya_ble_ota_response(&response);
return;
/* tuya_ota_file_offset_response_t ota_file_offset_response; */
/* ota_file_offset_response.reserve = 0; */
/* ota_file_offset_response.offset = recv_data[1] << 24 | recv_data[2] << 16 | recv_data[3] << 8 | recv_data[4]; */
/* printf("offset:%d\n", ota_file_offset_response.offset); */
/* response.p_data = &ota_file_offset_response; */
/* response.data_len = 2; */
break;
case TUYA_BLE_OTA_DATA:
printf("TUYA_BLE_OTA_DATA\n");
tuya_ota_data_response_t ota_data_response;
ota_data_response.reserve = 0;
u16 remote_packet_num = (recv_data[1] << 8) + recv_data[2];
u32 cur_frame_size = (recv_data[3] << 8) + recv_data[4];
if (remote_packet_num == 0 && first_packet_come == 1) {
printf("OTA ERROR packet num error, num = %d", remote_packet_num);
ota_data_response.state = TUYA_OTA_DATA_PKT_NUM_ERR;
response.p_data = &ota_data_response;
response.data_len = 2;
response.type = TUYA_BLE_OTA_DATA;
tuya_ble_ota_response(&response);
return;
}
current_file_size += cur_frame_size;
printf("OTA DATA info:");
put_buf(recv_data, 7);
printf("file_size:%d remote_packet_num:%d, last_packet_num = %d, frame_size:%d\n", current_file_size, remote_packet_num, tuya_ota.tuya_ota_packet_num, recv_len - 7);
first_packet_come = 1;
if (remote_packet_num && remote_packet_num != tuya_ota.tuya_ota_packet_num + 1) {
printf("OTA ERROR packet num error");
ota_data_response.state = TUYA_OTA_DATA_PKT_NUM_ERR;
response.p_data = &ota_data_response;
response.data_len = 2;
tuya_ble_ota_response(&response);
//dual_bank_passive_update_exit(NULL);
return;
} else {
tuya_ota.recv_len += recv_len - 7;
memcpy(tuya_ota.buff + tuya_ota.buff_size, recv_data + 7, recv_len - 7);
tuya_ota.buff_size += recv_len - 7;
if (tuya_ota.buff_size >= OTA_WRITE_FLASH_SIZE) {
dual_bank_update_write(tuya_ota.buff, OTA_WRITE_FLASH_SIZE, tuya_update_write_cb);
tuya_ota.buff_size -= OTA_WRITE_FLASH_SIZE;
} else {
tuya_ota_data_response();
tuya_ota.tuya_ota_packet_num = remote_packet_num;
return;
}
}
tuya_ota.tuya_ota_packet_num = remote_packet_num;
break;
case TUYA_BLE_OTA_END:
printf("TUYA_BLE_OTA_END\n");
if (tuya_ota.buff_size != 0) { //把剩余的数据写入flash
dual_bank_update_write(tuya_ota.buff, tuya_ota.buff_size, tuya_ota_file_end_response);
} else {
tuya_ota_file_end_response(NULL);
}
break;
}
response.type = type;
tuya_ble_ota_response(&response);
}
@@ -0,0 +1,58 @@
#ifndef __TUYA_OTA_H__
#define __TUYA_OTA_H__
#include "typedef.h"
#define OTA_MAX_DATA_LEN 128
enum {
TUYA_OTA_STATE_NORMAL = 0,
TUYA_OTA_STATE_PID_NO_MATCH,
TUYA_OTA_STATE_VER_LOW,
TUYA_OTA_STATE_FILE_SIZE_TOO_LARGE,
};
enum {
TUYA_OTA_DATA_SUCC = 0,
TUYA_OTA_DATA_PKT_NUM_ERR,
TUYA_OTA_DATA_LEN_ERR,
TUYA_OTA_DATA_CRC_FAILED,
TUYA_OTA_DATA_OTHER_ERR,
};
#define READ_BIG_U32(a) ((*((u8*)(a)) <<24) + (*((u8*)(a)+1)<<16) + (*((u8*)(a)+2)<<8) + *((u8*)(a)+3))
typedef struct tuya_ota_req_response {
u8 flag;
u8 ota_version;
u8 reserve;
u32 frame_version;
u16 max_pkt_len;
} tuya_ota_req_response_t;
typedef struct tuya_ota_file_info_response {
u8 reserve;
u8 state;
u32 store_file_len; //用于断点续传,目前不支持
u32 store_crc;
u8 md5[16]; //目前不使用
} tuya_ota_file_info_response_t;
typedef struct tuya_ota_file_offset_response {
u8 reserve;
u32 offset;
} tuya_ota_file_offset_response_t;
typedef struct tuya_ota_data_response {
u8 reserve;
u8 state;
} tuya_ota_data_response_t;
typedef struct tuya_ota_end_response {
u8 reserve;
u8 state;
} tuya_ota_end_response_t;
void tuya_ota_proc(u16 type, u8 *recv_data, u32 recv_len);
#endif
@@ -0,0 +1,100 @@
/**
* \file tuya_ble_app_production_test.h
*
* \brief
*/
/*
* Copyright (C) 2014-2019, Tuya Inc., All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of tuya ble sdk
*/
#ifndef _TUYA_BLE_APP_PRODUCTION_TEST_H_
#define _TUYA_BLE_APP_PRODUCTION_TEST_H_
#include <stdint.h>
#include "tuya_ble_internal_config.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TUYA_BLE_AUC_CMD_ENTER 0x00
#define TUYA_BLE_AUC_CMD_QUERY_HID 0x01
#define TUYA_BLE_AUC_CMD_GPIO_TEST 0x02
#define TUYA_BLE_AUC_CMD_WRITE_AUTH_INFO 0x03
#define TUYA_BLE_AUC_CMD_QUERY_INFO 0x04
#define TUYA_BLE_AUC_CMD_RESET 0x05
#define TUYA_BLE_AUC_CMD_QUERY_FINGERPRINT 0x06
#define TUYA_BLE_AUC_CMD_WRITE_HID 0x07
#define TUYA_BLE_AUC_CMD_RSSI_TEST 0x08
#define TUYA_BLE_AUC_CMD_WRITE_OEM_INFO 0x09
#define TUYA_BLE_AUC_CMD_WRITE_SUBPKG_START 0x0C
#define TUYA_BLE_AUC_CMD_WRITE_SUBPKG_END 0x0D
#define TUYA_BLE_AUC_CMD_WRITE_COMM_CFG 0x12 // ADD
#define TUYA_BLE_AUC_CMD_READ_MAC 0x13
#define TUYA_BLE_AUC_CMD_EXIT 0x14
#define TUYA_BLE_AUC_CMD_EXTEND 0xF0
#define TUYA_BLE_SDK_TEST_CMD_EXTEND 0xF2
#define TUYA_BLE_AUC_FINGERPRINT_VER 1
#if ( TUYA_BLE_PROD_SUPPORT_OEM_TYPE == TUYA_BLE_PROD_OEM_TYPE_0_5 )
#define TUYA_BLE_AUC_WRITE_PID 1
#else
#define TUYA_BLE_AUC_WRITE_PID 0
#endif
#define TUYA_BLE_AUC_WRITE_DEV_CERT 1
enum {
TUYA_BLE_AUC_FW_FINGERPRINT_POS = 0,
TUYA_BLE_AUC_WRITE_PID_POS = 1,
TUYA_BLE_AUC_WRITE_DEV_CERT_POS = 5,
};
/*channel: 0-uart ,1 - ble.*/
void tuya_ble_app_production_test_process(uint8_t channel, uint8_t *p_in_data, uint16_t in_len);
#if (TUYA_BLE_DEVICE_REGISTER_FROM_BLE&&TUYA_BLE_DEVICE_AUTH_DATA_STORE)
tuya_ble_status_t tuya_ble_prod_beacon_scan_start(void);
tuya_ble_status_t tuya_ble_prod_beacon_scan_stop(void);
tuya_ble_status_t tuya_ble_prod_beacon_get_rssi_avg(int8_t *rssi);
tuya_ble_status_t tuya_ble_prod_gpio_test(void);
void tuya_ble_internal_production_test_with_ble_flag_clear(void);
uint8_t tuya_ble_internal_production_test_with_ble_flag_get(void);
#endif
#ifdef __cplusplus
}
#endif
#endif // _TUYA_BLE_APP_PRODUCTION_TEST_H_
@@ -0,0 +1,813 @@
/**
* \file tuya_ble_app_uart_common_handler.c
*
* \brief
*/
/*
* Copyright (C) 2014-2019, Tuya Inc., All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of tuya ble sdk
*/
#include "tuya_ble_stdlib.h"
#include "tuya_ble_type.h"
#include "tuya_ble_heap.h"
#include "tuya_ble_mem.h"
#include "tuya_ble_api.h"
#include "tuya_ble_port.h"
#include "tuya_ble_main.h"
#include "tuya_ble_internal_config.h"
#include "tuya_ble_data_handler.h"
#include "tuya_ble_mutli_tsf_protocol.h"
#include "tuya_ble_utils.h"
#include "tuya_ble_secure.h"
#include "tuya_ble_main.h"
#include "tuya_ble_storage.h"
#include "tuya_ble_app_uart_common_handler.h"
#include "tuya_ble_log.h"
#define TUYA_BLE_OTA_MCU_TEST 0
#define TUYA_BLE_UART_COMMON_MCU_OTA_DATA_LENGTH_MAX 200
#define TUYA_BLE_OTA_MCU_TYPE 1
#define TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST 0xEA
#define TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO 0xEB
#define TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET 0xEC
#define TUYA_BLE_UART_COMMON_MCU_OTA_DATA 0xED
#define TUYA_BLE_UART_COMMON_MCU_OTA_END 0xEE
#if (!TUYA_BLE_OTA_MCU_TEST)
void tuya_ble_uart_common_mcu_ota_data_from_ble_handler(uint16_t cmd, uint8_t *recv_data, uint32_t recv_len)
{
static uint8_t uart_data_temp[42];
uint8_t *uart_data_buffer = NULL;
uint8_t uart_data_len = 0;
if (cmd == FRM_OTA_DATA_REQ) {
uart_data_buffer = (uint8_t *)tuya_ble_malloc(recv_len + 7);
if (uart_data_buffer == NULL) {
TUYA_BLE_LOG_ERROR("uart_data_buffer malloc failed.");
return;
}
} else {
uart_data_buffer = uart_data_temp;
}
uart_data_buffer[0] = 0x55;
uart_data_buffer[1] = 0xAA;
uart_data_buffer[2] = 0x00;
switch (cmd) {
case FRM_OTA_START_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 2;
uart_data_buffer[6] = TUYA_BLE_UART_COMMON_MCU_OTA_DATA_LENGTH_MAX >> 8;
uart_data_buffer[7] = (uint8_t)TUYA_BLE_UART_COMMON_MCU_OTA_DATA_LENGTH_MAX;
uart_data_len = 8;
break;
case FRM_OTA_FILE_INFOR_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 35;
memcpy(uart_data_buffer + 6, recv_data, 8);
uart_data_buffer[14] = recv_data[9];
uart_data_buffer[15] = recv_data[10];
uart_data_buffer[16] = recv_data[11];
memcpy(&uart_data_buffer[17], recv_data + 12, 24);
uart_data_len = 41;
break;
case FRM_OTA_FILE_OFFSET_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 4;
memcpy(uart_data_buffer + 6, recv_data, 4);
uart_data_len = 10;
break;
case FRM_OTA_DATA_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_DATA;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = recv_len;
memcpy(uart_data_buffer + 6, recv_data, recv_len);
uart_data_len = 6 + recv_len;
break;
case FRM_OTA_END_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_END;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 0;
uart_data_len = 6;
break;
default:
break;
}
uart_data_buffer[uart_data_len] = tuya_ble_check_sum(uart_data_buffer, uart_data_len);
tuya_ble_common_uart_send_data(uart_data_buffer, uart_data_len + 1);
TUYA_BLE_LOG_HEXDUMP_DEBUG("mcu ota uart send data : ", uart_data_buffer, uart_data_len + 1);
if (cmd == FRM_OTA_DATA_REQ) {
tuya_ble_free(uart_data_buffer);
}
}
static void tuya_ble_uart_common_mcu_ota_data_from_uart_handler(uint8_t cmd, uint8_t *data_buffer, uint16_t data_len)
{
static uint8_t ble_data_buffer[30];
static uint8_t ble_data_len = 0;
uint16_t ble_cmd = 0;
tuya_ble_connect_status_t currnet_connect_status;
memset(ble_data_buffer, 0, sizeof(ble_data_buffer));
ble_data_len = 0;
switch (cmd) {
case TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST:
ble_data_buffer[0] = data_buffer[0];
ble_data_buffer[1] = 3;
ble_data_buffer[2] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[3] = 0;
memcpy(&ble_data_buffer[4], data_buffer + 1, 5);
ble_data_len = 9;
ble_cmd = FRM_OTA_START_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
memcpy(&ble_data_buffer[1], data_buffer, 25);
ble_data_len = 26;
ble_cmd = FRM_OTA_FILE_INFOR_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
memcpy(&ble_data_buffer[1], data_buffer, 4);
ble_data_len = 5;
ble_cmd = FRM_OTA_FILE_OFFSET_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_DATA:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[1] = data_buffer[0];
ble_data_len = 2;
ble_cmd = FRM_OTA_DATA_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_END:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[1] = data_buffer[0];
ble_data_len = 2;
ble_cmd = FRM_OTA_END_RESP;
break;
default:
break;
};
currnet_connect_status = tuya_ble_connect_status_get();
if (currnet_connect_status != BONDING_CONN) {
TUYA_BLE_LOG_ERROR("tuya_ble_uart_common_mcu_ota_process FAILED.");
return;
}
if (ble_data_len > 0) {
tuya_ble_commData_send(ble_cmd, 0, ble_data_buffer, ble_data_len, ENCRYPTION_MODE_SESSION_KEY);
}
}
__TUYA_BLE_WEAK void tuya_ble_custom_app_uart_common_process(uint8_t *p_in_data, uint16_t in_len)
{
uint8_t cmd = p_in_data[3];
uint16_t data_len = (p_in_data[4] << 8) + p_in_data[5];
uint8_t *data_buffer = p_in_data + 6;
switch (cmd) {
default:
break;
};
}
void tuya_ble_uart_common_process(uint8_t *p_in_data, uint16_t in_len)
{
uint8_t cmd = p_in_data[3];
uint16_t data_len = (p_in_data[4] << 8) + p_in_data[5];
uint8_t *data_buffer = p_in_data + 6;
switch (cmd) {
case TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST:
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO:
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET:
case TUYA_BLE_UART_COMMON_MCU_OTA_DATA:
case TUYA_BLE_UART_COMMON_MCU_OTA_END:
tuya_ble_uart_common_mcu_ota_data_from_uart_handler(cmd, data_buffer, data_len);
break;
default:
tuya_ble_custom_app_uart_common_process(p_in_data, in_len);
break;
};
}
#else
tuya_ble_timer_t tuya_ble_xtimer_heartbeat ;
static uint32_t tuya_ble_heartbeat_timeout_ms = 1000;
static uint8_t heartbeat_uart_buffer[10];
static uint8_t mcu_info_get = 0;
static void tuya_ble_common_uart_protocol_send(uint8_t cmd, uint8_t *pdata, uint8_t len)
{
static uint8_t alloc_buf[256];
uint8_t i = 0;
alloc_buf[0 + 1] = 0x55;
alloc_buf[1 + 1] = 0xaa;
alloc_buf[2 + 1] = 0x00;
alloc_buf[3 + 1] = cmd;
alloc_buf[4 + 1] = 0;
alloc_buf[5 + 1] = len;
memcpy(alloc_buf + 6 + 1, pdata, len);
alloc_buf[7 + len] = tuya_ble_check_sum(alloc_buf + 1, 6 + len);
tuya_ble_common_uart_send_data(alloc_buf + 1, 7 + len);
}
static void tuya_ble_vtimer_heartbeat_callback(tuya_ble_timer_t timer)
{
heartbeat_uart_buffer[0] = 0x55;
heartbeat_uart_buffer[1] = 0xAA;
heartbeat_uart_buffer[2] = 0x00;
heartbeat_uart_buffer[3] = 0x00;
heartbeat_uart_buffer[4] = 0x00;
heartbeat_uart_buffer[5] = 0x00;
heartbeat_uart_buffer[6] = 0xFF;
tuya_ble_common_uart_send_data(heartbeat_uart_buffer, 7);
}
static void tuya_ble_heartbeat_timer_create(void)
{
if (tuya_ble_timer_create(&tuya_ble_xtimer_heartbeat, tuya_ble_heartbeat_timeout_ms, TUYA_BLE_TIMER_REPEATED, tuya_ble_vtimer_heartbeat_callback) != TUYA_BLE_SUCCESS) {
TUYA_BLE_LOG_ERROR("tuya_ble_xtimer_heartbeat creat failed");
}
}
static void tuya_ble_heartbeat_timer_start(void)
{
if (tuya_ble_timer_start(tuya_ble_xtimer_heartbeat) != TUYA_BLE_SUCCESS) {
TUYA_BLE_LOG_ERROR("tuya_ble_xtimer_heartbeat start failed");
}
}
static void tuya_ble_heartbeat_timer_restart(uint32_t ms)
{
if (tuya_ble_timer_restart(tuya_ble_xtimer_heartbeat, ms) != TUYA_BLE_SUCCESS) {
TUYA_BLE_LOG_ERROR("tuya_ble_xtimer_heartbeat restart failed");
}
}
static void tuya_ble_heartbeat_timer_stop(void)
{
if (tuya_ble_timer_stop(tuya_ble_xtimer_heartbeat) != TUYA_BLE_SUCCESS) {
TUYA_BLE_LOG_ERROR("tuya_ble_xtimer_heartbeat stop failed");
}
}
static void tuya_ble_heartbeat_timer_delete(void)
{
if (tuya_ble_timer_delete(tuya_ble_xtimer_heartbeat) != TUYA_BLE_SUCCESS) {
TUYA_BLE_LOG_ERROR("tuya_ble_xtimer_heartbeat delete failed");
}
}
static void tuya_ble_ota_data_process_test(uint8_t *p_data, uint16_t p_data_len);
void tuya_ble_uart_common_mcu_ota_data_from_ble_handler(uint16_t cmd, uint8_t *recv_data, uint32_t recv_len)
{
static uint8_t uart_data_temp[42];
uint8_t uart_cmd = 0xFF;
uint8_t *uart_data_buffer = NULL;
uint8_t uart_data_len = 0;
if (cmd == FRM_OTA_DATA_REQ) {
uart_data_buffer = (uint8_t *)tuya_ble_malloc(recv_len + 7);
if (uart_data_buffer == NULL) {
TUYA_BLE_LOG_ERROR("uart_data_buffer malloc failed.\n");
return;
}
} else {
uart_data_buffer = uart_data_temp;
}
uart_data_buffer[0] = 0x55;
uart_data_buffer[1] = 0xAA;
uart_data_buffer[2] = 0x00;
switch (cmd) {
case FRM_OTA_START_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 2;
uart_data_buffer[6] = TUYA_BLE_UART_COMMON_MCU_OTA_DATA_LENGTH_MAX >> 8;
uart_data_buffer[7] = (uint8_t)TUYA_BLE_UART_COMMON_MCU_OTA_DATA_LENGTH_MAX;
uart_data_len = 8;
break;
case FRM_OTA_FILE_INFOR_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 35;
memcpy(uart_data_buffer + 6, recv_data, 8);
uart_data_buffer[14] = recv_data[9];
uart_data_buffer[15] = recv_data[10];
uart_data_buffer[16] = recv_data[11];
memcpy(&uart_data_buffer[17], recv_data + 12, 24);
uart_data_len = 41;
break;
case FRM_OTA_FILE_OFFSET_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 4;
memcpy(uart_data_buffer + 6, recv_data, 4);
uart_data_len = 10;
break;
case FRM_OTA_DATA_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_DATA;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = recv_len;
memcpy(uart_data_buffer + 6, recv_data, recv_len);
uart_data_len = 6 + recv_len;
break;
case FRM_OTA_END_REQ:
uart_data_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_END;
uart_data_buffer[4] = 0;
uart_data_buffer[5] = 0;
uart_data_len = 6;
break;
default:
break;
}
uart_data_buffer[uart_data_len] = tuya_ble_check_sum(uart_data_buffer, uart_data_len);
tuya_ble_common_uart_send_data(uart_data_buffer, uart_data_len + 1);
TUYA_BLE_LOG_HEXDUMP_DEBUG("mcu ota uart send data : ", uart_data_buffer, uart_data_len + 1);
if (cmd == FRM_OTA_DATA_REQ) {
tuya_ble_free(uart_data_buffer);
}
}
static void tuya_ble_uart_common_mcu_ota_data_from_uart_handler(uint8_t cmd, uint8_t *data_buffer, uint16_t data_len)
{
static uint8_t ble_data_buffer[30];
static uint8_t ble_data_len = 0;
uint16_t ble_cmd = 0;
tuya_ble_connect_status_t currnet_connect_status;
memset(ble_data_buffer, 0, sizeof(ble_data_buffer));
ble_data_len = 0;
switch (cmd) {
case TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST:
ble_data_buffer[0] = data_buffer[0];
ble_data_buffer[1] = 3;
ble_data_buffer[2] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[3] = 0;
memcpy(&ble_data_buffer[4], data_buffer + 1, 5);
ble_data_len = 9;
ble_cmd = FRM_OTA_START_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
memcpy(&ble_data_buffer[1], data_buffer, 25);
ble_data_len = 26;
ble_cmd = FRM_OTA_FILE_INFOR_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
memcpy(&ble_data_buffer[1], data_buffer, 4);
ble_data_len = 5;
ble_cmd = FRM_OTA_FILE_OFFSET_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_DATA:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[1] = data_buffer[0];
ble_data_len = 2;
ble_cmd = FRM_OTA_DATA_RESP;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_END:
ble_data_buffer[0] = TUYA_BLE_OTA_MCU_TYPE;
ble_data_buffer[1] = data_buffer[0];
ble_data_len = 2;
ble_cmd = FRM_OTA_END_RESP;
break;
default:
break;
};
currnet_connect_status = tuya_ble_connect_status_get();
if (currnet_connect_status != BONDING_CONN) {
TUYA_BLE_LOG_ERROR("tuya_ble_uart_common_mcu_ota_process FAILED.");
return;
}
if (ble_data_len > 0) {
tuya_ble_commData_send(ble_cmd, 0, ble_data_buffer, ble_data_len, ENCRYPTION_MODE_SESSION_KEY);
}
}
void tuya_ble_uart_common_send_current_ble_state(void)
{
uint8_t ble_work_state = 0;
tuya_ble_connect_status_t ble_state;
ble_state = tuya_ble_connect_status_get();
if ((ble_state == UNBONDING_UNCONN) || (ble_state == UNBONDING_UNCONN) || (ble_state == UNBONDING_UNCONN)) {
ble_work_state = 1;
} else if ((ble_state == BONDING_UNCONN) || (ble_state == BONDING_UNAUTH_CONN)) {
ble_work_state = 2;
} else if (ble_state == BONDING_CONN) {
ble_work_state = 3;
} else {
ble_work_state = 0;
}
tuya_ble_common_uart_protocol_send(TUYA_BLE_UART_COMMON_REPORT_WORK_STATE_TYPE, (uint8_t *)&ble_work_state, 1);
}
void tuya_ble_uart_common_process(uint8_t *p_in_data, uint16_t in_len)
{
uint8_t cmd = p_in_data[3];
uint16_t data_len = (p_in_data[4] << 8) + p_in_data[5];
uint8_t *data_buffer = p_in_data + 6;
uint32_t mcu_firmware_version = 0, mcu_hardware_version = 0;
switch (cmd) {
case TUYA_BLE_UART_COMMON_HEART_MSG_TYPE:
if ((mcu_info_get == 0) || (data_buffer[0] == 0)) {
mcu_info_get = 1;
tuya_ble_common_uart_protocol_send(TUYA_BLE_UART_COMMON_SEARCH_PID_TYPE, NULL, 0);
}
break;
case TUYA_BLE_UART_COMMON_SEARCH_PID_TYPE:
if (memcmp(tuya_ble_current_para.pid, data_buffer, 8) != 0) {
TUYA_BLE_LOG_HEXDUMP_DEBUG("PID change to : ", data_buffer, 16);
tuya_ble_device_update_product_id(TUYA_BLE_PRODUCT_ID_TYPE_PID, 8, data_buffer);
}
tuya_ble_heartbeat_timer_restart(10000);
tuya_ble_common_uart_protocol_send(TUYA_BLE_UART_COMMON_CK_MCU_TYPE, NULL, 0);
tuya_ble_common_uart_protocol_send(TUYA_BLE_UART_COMMON_QUERY_MCU_VERSION, NULL, 0);
break;
case TUYA_BLE_UART_COMMON_CK_MCU_TYPE:
tuya_ble_uart_common_send_current_ble_state();
break;
case TUYA_BLE_UART_COMMON_QUERY_MCU_VERSION:
mcu_firmware_version = (data_buffer[0] << 16) | (data_buffer[1] << 8) | (data_buffer[2]);
mcu_hardware_version = (data_buffer[3] << 16) | (data_buffer[4] << 8) | (data_buffer[5]);
TUYA_BLE_LOG_DEBUG("reveived mcu_firmware_version : 0x%04x mcu_hardware_version : 0x%04x", mcu_firmware_version, mcu_hardware_version);
tuya_ble_device_update_mcu_version(mcu_firmware_version, mcu_hardware_version);
break;
case TUYA_BLE_UART_COMMON_MCU_SEND_VERSION:
mcu_firmware_version = (data_buffer[0] << 16) | (data_buffer[1] << 8) | (data_buffer[2]);
mcu_hardware_version = (data_buffer[3] << 16) | (data_buffer[4] << 8) | (data_buffer[5]);
TUYA_BLE_LOG_DEBUG("reveived mcu_firmware_version : 0x%04x mcu_hardware_version : 0x%04x", mcu_firmware_version, mcu_hardware_version);
tuya_ble_device_update_mcu_version(mcu_firmware_version, mcu_hardware_version);
break;
case TUYA_BLE_UART_COMMON_REPORT_WORK_STATE_TYPE:
break;
case TUYA_BLE_UART_COMMON_RESET_TYPE:
break;
case TUYA_BLE_UART_COMMON_SEND_CMD_TYPE:
break;
case TUYA_BLE_UART_COMMON_SEND_STATUS_TYPE:
break;
case TUYA_BLE_UART_COMMON_QUERY_STATUS:
break;
case TUYA_BLE_UART_COMMON_SEND_STORAGE_TYPE:
break;
case TUYA_BLE_UART_COMMON_SEND_TIME_SYNC_TYPE:
break;
case TUYA_BLE_UART_COMMON_MODIFY_ADV_INTERVAL:
break;
case TUYA_BLE_UART_COMMON_TURNOFF_SYSTEM_TIME:
break;
case TUYA_BLE_UART_COMMON_ENANBLE_LOWER_POWER:
break;
case TUYA_BLE_UART_COMMON_SEND_ONE_TIME_PASSWORD_TOKEN:
break;
case TUYA_BLE_UART_COMMON_ACTIVE_DISCONNECT:
break;
case TUYA_BLE_UART_COMMON_BLE_OTA_STATUS:
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST:
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO:
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET:
case TUYA_BLE_UART_COMMON_MCU_OTA_DATA:
case TUYA_BLE_UART_COMMON_MCU_OTA_END:
tuya_ble_uart_common_mcu_ota_data_from_uart_handler(cmd, data_buffer, data_len);
break;
default:
break;
};
}
static uint8_t mcu_ota_flag = 0;
#define MCU_OTA_MAX_DATA_SIZE 200
#define CURRENT_MCU_FIRMWARE_VERSION 0x010000
#define SUPPORT_MCU_OTA_FILE_MAX_LENGTH 102400
typedef struct {
uint32_t file_version;
uint8_t file_md5[16];
uint32_t file_length;
uint32_t file_crc32;
} mcu_ota_file_info_data_t;
static mcu_ota_file_info_data_t mcu_ota_file_data = {0};
static uint16_t current_package = 0;
static uint16_t last_package = 0;
static uint32_t current_image_crc_last;
static uint32_t current_image_write_offset;
static void mcu_ota_current_para_init(void)
{
current_package = 0;
last_package = 0;
mcu_ota_flag = 0;
current_image_crc_last = 0;
current_image_write_offset = 0;
}
void mcu_ota_test_init(void)
{
mcu_ota_current_para_init();
tuya_ble_heartbeat_timer_create();
tuya_ble_heartbeat_timer_start();
}
void mcu_ota_test_para_init_connect(void)
{
mcu_ota_current_para_init();
}
static void tuya_ble_ota_data_process_test(uint8_t *p_data, uint16_t p_data_len)
{
uint16_t len = 0;
uint16_t crc16_rev, crc16_temp;
static uint8_t ota_data_response_buffer[40];
uint8_t ota_data_response_len;
uint8_t cmd = p_data[3];
uint16_t ota_data_len = (p_data[4] << 8) + p_data[5];
uint8_t *ota_data_buffer = p_data + 6;
memset(ota_data_response_buffer, 0, sizeof(ota_data_response_buffer));
ota_data_response_buffer[0] = 0x55;
ota_data_response_buffer[1] = 0xaa;
ota_data_response_buffer[2] = 0x00;
switch (cmd) {
case TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST:
ota_data_response_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_REQUEST;
ota_data_response_buffer[4] = 0;
ota_data_response_buffer[5] = 6;
if (mcu_ota_flag == 0) {
mcu_ota_current_para_init();
ota_data_response_buffer[6] = 0;
ota_data_response_buffer[7] = ((uint32_t)CURRENT_MCU_FIRMWARE_VERSION >> 16);
ota_data_response_buffer[8] = ((uint32_t)CURRENT_MCU_FIRMWARE_VERSION >> 8);
ota_data_response_buffer[9] = ((uint32_t)CURRENT_MCU_FIRMWARE_VERSION);
ota_data_response_buffer[10] = ((uint16_t)MCU_OTA_MAX_DATA_SIZE >> 8);
ota_data_response_buffer[11] = ((uint16_t)MCU_OTA_MAX_DATA_SIZE);
mcu_ota_flag = 1;
memset(&mcu_ota_file_data, 0, sizeof(mcu_ota_file_data));
} else {
ota_data_response_buffer[6] = 1;
mcu_ota_flag = 0;
}
ota_data_response_len = 12;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO:
ota_data_response_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_INFO;
ota_data_response_buffer[4] = 0;
ota_data_response_buffer[5] = 25;
if (mcu_ota_flag != 1) {
ota_data_response_buffer[6] = 4;
mcu_ota_flag = 0;
} else {
if (memcmp(ota_data_buffer, tuya_ble_current_para.pid, 8)) {
ota_data_response_buffer[6] = 1;
mcu_ota_flag = 0;
} else {
mcu_ota_file_data.file_version = (ota_data_buffer[8] << 16) + (ota_data_buffer[9] << 8) + ota_data_buffer[10];
memcpy(mcu_ota_file_data.file_md5, ota_data_buffer + 11, 16);
mcu_ota_file_data.file_length = (ota_data_buffer[27] << 24) + (ota_data_buffer[28] << 16) + (ota_data_buffer[29] << 8) + ota_data_buffer[30];
mcu_ota_file_data.file_crc32 = (ota_data_buffer[31] << 24) + (ota_data_buffer[32] << 16) + (ota_data_buffer[33] << 8) + ota_data_buffer[34];
if (mcu_ota_file_data.file_version <= CURRENT_MCU_FIRMWARE_VERSION) {
ota_data_response_buffer[6] = 2;
mcu_ota_flag = 0;
} else if (mcu_ota_file_data.file_length > SUPPORT_MCU_OTA_FILE_MAX_LENGTH) {
ota_data_response_buffer[6] = 3;
mcu_ota_flag = 0;
} else {
ota_data_response_buffer[6] = 0;
mcu_ota_flag = 2;
}
}
}
ota_data_response_len = 31;
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET:
ota_data_response_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_FILE_OFFSET;
ota_data_response_buffer[4] = 0;
ota_data_response_buffer[5] = 4;
if (mcu_ota_flag == 2) {
memset(&ota_data_response_buffer[6], 0, 4);
mcu_ota_flag = 3;
ota_data_response_len = 10;
} else {
mcu_ota_flag = 0;
ota_data_response_len = 0;
}
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_DATA:
ota_data_response_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_DATA;
ota_data_response_buffer[4] = 0;
ota_data_response_buffer[5] = 1;
if ((mcu_ota_flag == 3) || (mcu_ota_flag == 4)) {
current_package = (ota_data_buffer[0] << 8) | ota_data_buffer[1];
len = (ota_data_buffer[2] << 8) | ota_data_buffer[3];
if ((current_package != (last_package + 1)) && (current_package != 0)) {
TUYA_BLE_LOG_ERROR("mcu ota received package number error.received package number : %d", current_package);
ota_data_response_buffer[6] = 1;
} else if ((len > MCU_OTA_MAX_DATA_SIZE) || ((len + 6) != (p_data_len - 7))) {
TUYA_BLE_LOG_ERROR("mcu ota received package data length error : len = %d,p_data_len = %d", len, p_data_len);
ota_data_response_buffer[6] = 2;
} else {
crc16_temp = (ota_data_buffer[4] << 8) | ota_data_buffer[5];
crc16_rev = tuya_ble_crc16_compute(&ota_data_buffer[6], len, NULL);
if (crc16_temp != crc16_rev) {
TUYA_BLE_LOG_ERROR("mcu ota received package data crc16 error,crc_16_cal = 0x%04x ; crc16_rev = 0x%04x", crc16_temp, crc16_rev);
ota_data_response_buffer[6] = 3;
}
}
if (ota_data_response_buffer[6] == 0) {
current_image_crc_last = tuya_ble_crc32_compute(&ota_data_buffer[6], len, &current_image_crc_last);
current_image_write_offset += len;
mcu_ota_flag = 4;
last_package = current_package;
} else {
mcu_ota_flag = 0;
mcu_ota_current_para_init();
}
ota_data_response_len = 7;
} else {
mcu_ota_flag = 0;
ota_data_response_len = 0;
}
break;
case TUYA_BLE_UART_COMMON_MCU_OTA_END:
ota_data_response_buffer[3] = TUYA_BLE_UART_COMMON_MCU_OTA_END;
ota_data_response_buffer[4] = 0;
ota_data_response_buffer[5] = 1;
if (mcu_ota_flag != 0) {
if (mcu_ota_file_data.file_length != current_image_write_offset) {
ota_data_response_buffer[6] = 1;
} else if (mcu_ota_file_data.file_crc32 != current_image_crc_last) {
ota_data_response_buffer[6] = 2;
} else {
ota_data_response_buffer[6] = 0;
mcu_ota_flag = 0;
TUYA_BLE_LOG_DEBUG("mcu ota test succeed.");
}
ota_data_response_len = 7;
} else {
mcu_ota_flag = 0;
ota_data_response_len = 0;
}
break;
default:
break;
};
if (ota_data_response_len > 0) {
ota_data_response_buffer[ota_data_response_len] = tuya_ble_check_sum(ota_data_response_buffer, ota_data_response_len);
ota_data_response_len++;
tuya_ble_common_uart_send_full_instruction_received(ota_data_response_buffer, ota_data_response_len);
}
}
#endif
@@ -0,0 +1,53 @@
/**
* \file tuya_ble_app_uart_common_handler.h
*
* \brief
*/
/*
* Copyright (C) 2014-2019, Tuya Inc., All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of tuya ble sdk
*/
#ifndef _TUYA_BLE_APP_UART_COMMON_HANDLER_H_
#define _TUYA_BLE_APP_UART_COMMON_HANDLER_H_
#include <stdint.h>
#include "tuya_ble_internal_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Function for transmit ble data from peer devices to tuya sdk.
*
* @note This function must be called from where the ble data is received.
*.
* */
void tuya_ble_uart_common_process(uint8_t *p_in_data, uint16_t in_len);
void tuya_ble_uart_common_mcu_ota_data_from_ble_handler(uint16_t cmd, uint8_t *recv_data, uint32_t recv_len);
#ifdef __cplusplus
}
#endif
#endif // _TUYA_BLE_APP_UART_COMMON_HANDLER_H_