AC695N-SoundBox-SDK/apps/common/third_party_profile/interface/app_protocol_ota.c
2026-08-09 00:00:00 +00:00

528 lines
16 KiB
C

#include "app_config.h"
#if AI_APP_PROTOCOL
#include "app_protocol_ota.h"
#include "app_protocol_api.h"
#include "fs.h"
#include "os/os_error.h"
#include "update_loader_download.h"
#include "dual_bank_updata_api.h"
#include "update.h"
#include "timer.h"
#include "debug.h"
#define LOG_TAG_CONST APP_OTA
#define LOG_TAG "[APP_OTA]"
int clk_set(const char *name, int clk);
update_op_tws_api_t *get_tws_update_api(void);
void tws_sync_update_crc_handler_register(void (*crc_init_hdl)(void), u32(*crc_calc_hdl)(u32 init_crc, u8 *data, u32 len));
#define APP_UPDATE_FAILED 0
#define APP_UPDATE_SUCC 1
#define APP_CHECK_CRC_SUCC 0
#define APP_CHECK_CRC_FAILED 1
typedef struct _app_protocol_ota_param_t {
u32 state;
u32 read_len;
u32 need_rx_len;
u8 *read_buf;
void (*resume_hdl)(void *priv);
int (*sleep_hdl)(void *priv);
app_protocol_ota_api ota_api;
u32 file_offset;
u8 seek_type;
u8 update_result;
u8 sync_update_first_packet;
u8 ota_cancle_flag;
u8 wait_app_reboot;
OS_SEM ota_sem;
} app_protocol_ota_param_t;
static app_protocol_ota_param_t app_protocol_ota_param;
static update_op_tws_api_t *app_protocol_update_tws_api = NULL;
#define __this (&app_protocol_ota_param)
enum {
BT_SEEK_SET = 0x01,
BT_SEEK_CUR = 0x02,
BT_SEEK_TYPE_UPDATE_LEN = 0x10,
};
typedef enum {
UPDATA_START = 0x00,
UPDATA_REV_DATA,
UPDATA_STOP,
} UPDATA_BIT_FLAG;
#define RETRY_TIMES 3
const app_protocol_ota_type_map ota_type_map[] = {
{.protocol_id = GMA_HANDLER_ID, .ota_type = PASSIVE_OTA},
{.protocol_id = MMA_HANDLER_ID, .ota_type = INITIATIVE_OTA},
{.protocol_id = DMA_HANDLER_ID, .ota_type = NO_SUPPORT_OTA},
{.protocol_id = TME_HANDLER_ID, .ota_type = INITIATIVE_OTA},
{.protocol_id = AMA_HANDLER_ID, .ota_type = NO_SUPPORT_OTA},
};
//根据protocol_id获取协议升级类型
u8 check_ota_type_by_protocol_id(int id)
{
u8 i = 0;
for (; i < sizeof(ota_type_map) / sizeof(app_protocol_ota_type_map); i++) {
if (id == ota_type_map[i].protocol_id) {
return ota_type_map[i].ota_type;
}
}
return NO_SUPPORT_OTA;
}
static void initiative_ota_resume_hdl_register(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
{
__this->resume_hdl = resume_hdl;
__this->sleep_hdl = sleep_hdl;
}
void app_protocol_ota_init(app_protocol_ota_api *api, u8 need_wait_app_reboot)
{
memcpy(&(__this->ota_api), api, sizeof(app_protocol_ota_api));
__this->wait_app_reboot = need_wait_app_reboot;
#if OTA_TWS_SAME_TIME_ENABLE
tws_sync_update_crc_handler_register(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl);
g_printf("crc_init_hdl:0x%x crc_calc_hdl:0x%x\n", __this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl);
#endif
}
void initiative_ota_init(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
{
os_sem_create(&(__this->ota_sem), 0);
initiative_ota_resume_hdl_register(resume_hdl, sleep_hdl);
}
u16 initiative_ota_f_open(void)
{
log_info(">>>initiative_ota_f_open\n");
__this->file_offset = 0;
__this->seek_type = BT_SEEK_SET;
return 1;
}
void initiative_ota_handle(u8 state, void *buf, int len)
{
/* log_info("R"); */
if (state != __this->state) {
log_info(">>>initiative state err\n");
return;
}
switch (state) {
case UPDATA_REV_DATA:
if (__this->read_buf) {
memcpy(__this->read_buf, buf, len);
__this->read_len = len;
__this->state = 0;
}
break;
case UPDATA_STOP:
__this->state = 0;
break;
}
if (__this->resume_hdl) {
__this->resume_hdl(NULL);
}
}
u16 initiative_ota_f_read(void *fp, u8 *buff, u16 len)
{
u8 retry_cnt = 0;
__this->need_rx_len = len;
__this->state = UPDATA_REV_DATA;
__this->read_len = 0;
__this->read_buf = buff;
__RETRY:
if (app_protocol_get_cur_handle_id() == 0) { //如果已经断开连接直接返回-1 */
return -1;
}
if (__this->ota_cancle_flag) {
return -1;
}
if (__this->ota_api.ota_request_data == NULL) {
return -1;
}
printf("initiative_ota_read\n");
__this->ota_api.ota_request_data(fp, __this->file_offset, len);
while (!((0 == __this->state) && (__this->read_len == len))) {
if (__this->sleep_hdl && app_protocol_get_cur_handle_id()) {
__this->sleep_hdl(NULL);
} else {
len = -1;
break;
}
if (!((0 == __this->state) && (__this->read_len == len))) {
if (retry_cnt++ > RETRY_TIMES) {
len = (u16) - 1;
break;
} else {
goto __RETRY;
}
}
}
if ((u16) - 1 != len) {
__this->file_offset += len;
}
return len;
}
int initiative_ota_f_seek(void *fp, u8 type, u32 offset)
{
if (type == SEEK_SET) {
__this->file_offset = offset;
__this->seek_type = BT_SEEK_SET;
} else if (type == SEEK_CUR) {
__this->file_offset += offset;
__this->seek_type = BT_SEEK_CUR;
}
return 0;//FR_OK;
}
static u16 initiative_ota_f_stop(u8 err)
{
//err = update_result_handle(err);
__this->state = UPDATA_STOP;
log_info(">>>initiative_ota_stop:%x err:0x%x\n", __this->state, err);
if (__this->ota_cancle_flag) {
return -1;
}
if (__this->ota_api.ota_request_data) {
__this->ota_api.ota_request_data(NULL, 0, 0);
}
while (!(0 == __this->state)) {
if (__this->sleep_hdl) { // && get_rcsp_connect_status()) {
if (__this->sleep_hdl(NULL) == OS_TIMEOUT) {
break;
}
} else {
break;
}
}
if (__this->ota_api.ota_report_result) {
__this->ota_api.ota_report_result(err);
}
return 1;
}
static int initiative_ota_notify_update_content_size(void *priv, u32 size)
{
int err;
u8 data[4];
/* WRITE_BIG_U32(data, size); */
/* user_change_ble_conn_param(0); */
log_info("send content_size:%x\n", size);
if (__this->ota_api.ota_notify_file_size) {
__this->ota_api.ota_notify_file_size(size);
}
/* err = JL_CMD_send(JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE, data, sizeof(data), JL_NEED_RESPOND); */
return err;
}
const update_op_api_t initiative_update_op = {
.ch_init = initiative_ota_init,
.f_open = initiative_ota_f_open,
.f_read = initiative_ota_f_read,
.f_seek = initiative_ota_f_seek,
.f_stop = initiative_ota_f_stop,
.notify_update_content_size = initiative_ota_notify_update_content_size,
};
void app_protocol_ota_update_success_reset(void *priv)
{
cpu_reset();
}
static void initiative_ota_state_cbk(int type, u32 state, void *priv)
{
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
if (ret_code) {
log_info("state:%x err:%x\n", ret_code->stu, ret_code->err_code);
}
switch (state) {
case UPDATE_CH_EXIT:
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
/* set_jl_update_flag(1); */
log_info(">>>initiative update succ\n");
update_result_set(UPDATA_SUCC);
__this->update_result = APP_UPDATE_SUCC;
#if !OTA_TWS_SAME_TIME_ENABLE
sys_timeout_add(NULL, app_protocol_ota_update_success_reset, 2000); //延时一段时间再reset保证命令已经发送
#endif
} else {
log_info(">>>initiative update failed\n");
update_result_set(UPDATA_DEV_ERR);
__this->update_result = APP_UPDATE_FAILED;
}
} else {
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
__this->update_result = APP_UPDATE_SUCC;
/* set_jl_update_flag(1); */
}
}
os_sem_post(&(__this->ota_sem));
break;
}
}
//被动升级请求下一帧数据
int passive_ota_write_callback(void *priv)
{
if (__this->ota_api.ota_request_data) {
__this->ota_api.ota_request_data(NULL, 0, 0);
}
return 0;
}
int passive_ota_set_boot_info_callback(int ret)
{
if (__this->ota_api.ota_report_result) {
__this->ota_api.ota_report_result(ret);
}
if (ret == 0) { //0表示boot info写成功
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_result_hdl && !__this->wait_app_reboot) {
app_protocol_update_tws_api->tws_ota_result_hdl(0);
}
#else
sys_timeout_add(NULL, app_protocol_ota_update_success_reset, 2000); //延时一段时间再reset保证命令已经发送
#endif
__this->update_result = APP_UPDATE_SUCC;
} else {
dual_bank_passive_update_exit(NULL);
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) {
app_protocol_update_tws_api->tws_ota_err(0);
}
__this->update_result = APP_UPDATE_FAILED;
#endif
}
return 0;
}
int passive_ota_crc_result_call_back(int crc_res)
{
if (crc_res) { //校验成功
log_info("crc check succ, write boot_info\n");
u8 update_boot_info_flag, verify_err;
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->exit_verify_hdl) {
if (app_protocol_update_tws_api->exit_verify_hdl(&verify_err, &update_boot_info_flag)) {
dual_bank_update_burn_boot_info((int (*)(int))passive_ota_set_boot_info_callback);
} else { //从机写boot_info失败
if (__this->ota_api.ota_report_result) {
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
}
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) { //通知从机升级失败
app_protocol_update_tws_api->tws_ota_err(0);
}
__this->update_result = APP_UPDATE_FAILED;
}
} else
#endif
{
dual_bank_update_burn_boot_info((int (*)(int))passive_ota_set_boot_info_callback);
}
} else { //校验失败
if (__this->ota_api.ota_report_result) {
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
}
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) { //通知从机升级失败
app_protocol_update_tws_api->tws_ota_err(0);
}
#endif
__this->update_result = APP_UPDATE_FAILED;
//app_protocol_reply_frame_check_result(crc_res);
dual_bank_passive_update_exit(NULL);
}
return 0;
}
int app_protocol_ota_interrupt_by_disconnect(int id)
{
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
} else {
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) {
app_protocol_update_tws_api->tws_ota_err(0);
}
#endif
dual_bank_passive_update_exit(NULL);
}
return 0;
}
int app_protocol_update_success_flag(void)
{
return __this->update_result;
}
int app_protocol_ota_message_handler(int id, int opcode, u8 *data, u32 len)
{
int err_code = UPDATE_RESULT_ERR_NONE;
int ret = 0;
switch (opcode) {
case APP_PROTOCOL_OTA_CHECK:
log_info("APP_PROTOCOL_OTA_CHECK\n");
ota_frame_info *frame_info = data;
dual_bank_passive_update_init(frame_info->frame_crc, frame_info->frame_size, frame_info->max_pkt_len, NULL);
ret = dual_bank_update_allow_check(frame_info->frame_size);
if (ret) {
err_code = UPDATE_RESULT_RESOURCE_LIMIT;
dual_bank_passive_update_exit(NULL);
} else { //for tws sync update init
#if OTA_TWS_SAME_TIME_ENABLE
app_protocol_update_tws_api = get_tws_update_api();
struct __tws_ota_para tws_update_para;
tws_update_para.fm_size = frame_info->frame_size;
tws_update_para.fm_crc16 = frame_info->frame_crc;
tws_update_para.max_pkt_len = frame_info->max_pkt_len;
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_start) {
if (app_protocol_update_tws_api->tws_ota_start(&tws_update_para)) {
err_code = UPDATE_RESULT_OTA_TWS_START_ERR;
dual_bank_passive_update_exit(NULL);
}
}
__this->sync_update_first_packet = 1;
#endif
}
break;
case APP_PROTOCOL_OTA_BEGIN:
update_mode_info_t info = {
.type = BLE_APP_UPDATA,
.state_cbk = initiative_ota_state_cbk,
.p_op_api = &initiative_update_op,
.task_en = 1,
};
__this->ota_cancle_flag = 0;
app_active_update_task_init(&info);
break;
case APP_PROTOCOL_OTA_TRANS_DATA:
log_info("APP_PROTOCOL_OTA_TRANS_DATA\n");
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
initiative_ota_handle(UPDATA_REV_DATA, data, len);
} else {
#if OTA_TWS_SAME_TIME_ENABLE
if (!__this->sync_update_first_packet) { //第一次传输不需要pend
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send_pend) {
if (app_protocol_update_tws_api->tws_ota_data_send_pend()) {
log_info(" UPDATE_ERR_WAIT_TWS_RESPONSE_TIMEOUT\n");
err_code = UPDATE_RESULT_OTA_TWS_NO_RSP;
break;
}
}
}
__this->sync_update_first_packet = 0;
#endif
dual_bank_update_write(data, len, passive_ota_write_callback);
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send) {
app_protocol_update_tws_api->tws_ota_data_send(data, len);
}
#endif
}
break;
case APP_PROTOCOL_OTA_GET_APP_VERSION:
u32 fm_version = app_protocol_get_version_by_id(id);
break;
case APP_PROTOCOL_OTA_CHECK_CRC:
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
os_sem_pend(&(__this->ota_sem), 0);
err_code = __this->update_result;
} else {
clk_set("sys", 120 * 1000000L); //提升主频加快CRC校验速度
#if OTA_TWS_SAME_TIME_ENABLE
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send_pend) { //pend 最后一包数据
if (app_protocol_update_tws_api->tws_ota_data_send_pend()) {
log_info(" UPDATE_ERR_WAIT_TWS_RESPONSE_TIMEOUT\n");
err_code = UPDATE_RESULT_OTA_TWS_NO_RSP;
break;
}
}
if (app_protocol_update_tws_api && app_protocol_update_tws_api->enter_verfiy_hdl) {
if (app_protocol_update_tws_api->enter_verfiy_hdl(NULL)) { //从机校验CRC
log_info("update enter verify err\n");
if (__this->ota_api.ota_report_result) {
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
}
} else {
log_info("update enter verify succ\n");
dual_bank_update_verify(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl, passive_ota_crc_result_call_back);
}
} else
#endif
{
dual_bank_update_verify(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl, passive_ota_crc_result_call_back);
}
}
break;
case APP_PROTOCOL_OTA_CANCLE:
__this->ota_cancle_flag = 1;
break;
case APP_PROTOCOL_OTA_REBOOT:
__this->state = 0;
/* #if OTA_TWS_SAME_TIME_ENABLE //同步升级在update lib里进行重启 */
/* g_printf("APP_PROTOCOL_OTA_REBOOT!!!\n"); */
/* #else */
/* cpu_reset(); */
/* #endif */
break;
case APP_PROTOCOL_OTA_PERCENT:
break;
case APP_PROTOCOL_OTA_END:
break;
case APP_PROTOCOL_OTA_SUCCESS:
break;
case APP_PROTOCOL_OTA_FAIL:
break;
}
return err_code;
}
#endif