feat: refresh managed audio after OTA activation

This commit is contained in:
chenjintao
2026-10-12 16:47:58 +08:00
parent 886ea58419
commit 84ce54eeb0
8 changed files with 574 additions and 45 deletions
@@ -182,13 +182,12 @@ void app_file_check_download(void)
int index = 1;
char url_buff[128]={0x00};
char filename_buff[64]={0x00};
int ret = 0, cnt = 0;
int ret = 0;
for(index=1;index<20;index++){
int cnt = 0;
/* barge_in_cute.mp3 is shipped in customer_fs and is not hosted by the
* legacy prompt download service. */
if(index==4||index==5||index==6||index==7||index==8||index==19){
if(index==4||index==5||index==6||index==7||index==8){
continue;
}
@@ -213,9 +212,7 @@ void app_file_check_del(void)
for(index=1;index<20;index++){
/* Keep the bundled barge-in prompt across app-only FOTA. Unlike the
* server-managed prompts, it cannot be restored by the downloader. */
if(index==4||index==5||index==6||index==7||index==8||index==19){
if(index==4||index==5||index==6||index==7||index==8){
continue;
}
@@ -0,0 +1,7 @@
#ifndef BANBAN_HTTP_DOWNFILE_H
#define BANBAN_HTTP_DOWNFILE_H
void app_file_check_download(void);
void app_file_check_del(void);
#endif
@@ -0,0 +1,11 @@
#ifndef BANBAN_OTA_POST_UPDATE_H
#define BANBAN_OTA_POST_UPDATE_H
/*
* Prepare server-managed audio refresh only after the running APP version
* matches the persisted OTA target. Returns 1 when files were removed for
* refresh, 0 when no refresh is pending, and a negative value on error.
*/
int ota_prepare_post_update_audio_refresh(void);
#endif
@@ -21,7 +21,9 @@
#include "cJSON.h"
#include "build_macro.h"
#include "ql_log.h"
#include "http_downfile.h"
#include "ota_fullfota2.h"
#include "ota_post_update.h"
#include "ota_url_policy.h"
@@ -45,6 +47,7 @@
#define OTA_STATE_TMP_FILE "U:/ota_state.tmp"
#define OTA_STATE_MAGIC 0x4F544131U
#define OTA_STATE_FORMAT_VERSION 1U
#define OTA_STATE_FLAG_AUDIO_REFRESH_PREPARED 0x0001U
#define OTA_PROMPT_PLAY_TIMEOUT_MS 10000
#define OTA_PROMPT_POLL_MS 50
@@ -110,7 +113,7 @@ int xiaoice_get_play_counter(void);
typedef struct {
uint32_t magic;
uint16_t format_version;
uint16_t reserved;
uint16_t flags;
char previous_version[16];
char target_version[16];
uint32_t checksum;
@@ -147,12 +150,56 @@ static uint32_t ota_state_checksum(const ota_state_t *state)
return hash;
}
static int ota_state_write(const ota_state_t *state)
{
ota_state_t persisted;
QFILE *fp;
int ret;
if (state == NULL) {
return -1;
}
persisted = *state;
persisted.checksum = 0;
persisted.checksum = ota_state_checksum(&persisted);
fp = ql_fopen(OTA_STATE_TMP_FILE, "wb+");
if (fp == NULL) {
RLOGE("OTA state open failed: %s", OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_fwrite(&persisted, sizeof(persisted), 1, fp);
if (ret != (int)sizeof(persisted)) {
RLOGE("OTA state write failed: %d", ret);
ql_fclose(fp);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_fsync(fp);
ql_fclose(fp);
if (ret != 0) {
RLOGE("OTA state sync failed: %d", ret);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_rename(OTA_STATE_TMP_FILE, OTA_STATE_FILE);
if (ret != 0) {
RLOGE("OTA state rename failed: %d", ret);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
return 0;
}
static int ota_state_save(const char *previous_version, const char *target_version)
{
ota_state_t state;
QFILE *fp;
int ret;
if (previous_version == NULL || target_version == NULL) {
return -1;
@@ -163,38 +210,7 @@ static int ota_state_save(const char *previous_version, const char *target_versi
state.format_version = OTA_STATE_FORMAT_VERSION;
strncpy(state.previous_version, previous_version, sizeof(state.previous_version) - 1);
strncpy(state.target_version, target_version, sizeof(state.target_version) - 1);
state.checksum = ota_state_checksum(&state);
fp = ql_fopen(OTA_STATE_TMP_FILE, "wb+");
if (fp == NULL) {
RLOGE("OTA state open failed: %s", OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_fwrite(&state, sizeof(state), 1, fp);
if (ret != (int)sizeof(state)) {
RLOGE("OTA state write failed: %d", ret);
ql_fclose(fp);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_fsync(fp);
ql_fclose(fp);
if (ret != 0) {
RLOGE("OTA state sync failed: %d", ret);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
ret = ql_rename(OTA_STATE_TMP_FILE, OTA_STATE_FILE);
if (ret != 0) {
RLOGE("OTA state rename failed: %d", ret);
ql_remove(OTA_STATE_TMP_FILE);
return -1;
}
return 0;
return ota_state_write(&state);
}
static int ota_state_load(ota_state_t *state)
@@ -296,6 +312,39 @@ static int ota_compare_version(const char *left, const char *right, int *result)
return 0;
}
int ota_prepare_post_update_audio_refresh(void)
{
ota_state_t state;
char current_version[64] = {0};
int compare_result;
if (ota_state_load(&state) != 0) {
return 0;
}
hal_os_get_build_ver(current_version);
if (ota_compare_version(current_version, state.target_version,
&compare_result) != 0 ||
compare_result != 0) {
return 0;
}
if ((state.flags & OTA_STATE_FLAG_AUDIO_REFRESH_PREPARED) != 0) {
return 0;
}
printf("OTA target APP is running; refreshing managed audio files\r\n");
app_file_check_del();
state.flags |= OTA_STATE_FLAG_AUDIO_REFRESH_PREPARED;
if (ota_state_write(&state) != 0) {
RLOGE("mark post-update audio refresh prepared failed");
return -1;
}
return 1;
}
/* ==================== 解析函数 ==================== */
@@ -19,6 +19,8 @@
#include "ql_ping.h"
#include "ql_nw.h"
#include "ql_atcmd.h"
#include "http_downfile.h"
#include "ota_post_update.h"
//#define NTP_SERVER_DOMAIN "ntp.aliyun.com"
@@ -104,6 +106,7 @@ static void ql_data_call_cb(int profile_idx, int nw_status)
void ql_datacall_demo_thread(void *arvg)
{
int ret = 0;
int refresh_ret = 0;
int file_valid = 0;
char ip4_addr_str[16] = {0};
struct ql_data_call_info info;
@@ -155,7 +158,11 @@ void ql_datacall_demo_thread(void *arvg)
ql_set_lwip_dns(1, "223.5.5.5","114.114.114.144");
ip4_addr = info.v4.addr.ip;
refresh_ret = ota_prepare_post_update_audio_refresh();
if(refresh_ret < 0){
printf("post-update audio refresh preparation failed\r\n");
}
app_file_check_download();
if(g_file_valid==0){