if (curTime.tm_hour == 0 && curTime.tm_min == 0 && curTime.tm_sec == 0) {\r
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_EMOJI_REPORT_ALL, NULL, 0);\r
}\r
- //整点上报时间线状态\r
- if(curTime.tm_min == 0 && curTime.tm_sec == 0)\r
- {\r
- //获取是否绑定\r
- if(uapi_ln_is_device_bound()) \r
- {\r
- do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS, NULL, 0);\r
- }\r
+ //整点上报时间线状态(亮屏立即获取,息屏推迟到按键亮屏后补拉)\r
+ if (curTime.tm_min == 0 && curTime.tm_sec == 0) {\r
+ ln_timeline_scheduled_hourly_fetch();\r
}\r
//每天凌晨2点检查夜间更新状态\r
if(curTime.tm_hour == 2 && curTime.tm_min == 0 && curTime.tm_sec == 0)\r
}
if (OtaSuccessView::GetInstance()) {
OtaSuccessView::GetInstance()->UpdateDownloadSuccess("模组升级失败");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[ota]CheckOtaResult: Cat1 failed, update failed");
}
} else if (status == 4) {
#ifdef SUPPORT_CAT1_SERVICE
uint8_t min = 0;
const bool still_1047 = (uapi_get_fw_version(&maj, &mid, &min) == ERRCODE_SUCC && maj == 1 && mid == 0 &&
min == 47);
- const bool py_not_34 = (uapi_get_py_ver() != 34);
- if (still_1047 && py_not_34) {
+ char kv_mark[8] = {0};
+ (void)UtilsGetValue("cat1_py34_upgrade_done", kv_mark, sizeof(kv_mark));
+ const bool py34_prereq = (uapi_get_py_ver() >= 34) &&
+ ((strcmp(kv_mark, "1") == 0) || uapi_cat1_ota_is_py34_verified());
+ if (still_1047 && !py34_prereq) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
- "CheckOtaResult: Cat1 ok, sw still 1.0.47 py=%u(!=34), stay updating for next round",
- (unsigned)uapi_get_py_ver());
+ "[ota]CheckOtaResult: Cat1 round done but py34 prereq not met, py=%u kv=%s verified=%d, stay updating",
+ (unsigned)uapi_get_py_ver(), kv_mark, uapi_cat1_ota_is_py34_verified());
SetOtaStatus(OTA_UI_STATUS_CAT1_START);
ThunderBirdModel::GetInstance()->PrepareCat1NextRoundAfterSuccess();
if (OtaUpdatingView::GetInstance()) {
OtaSuccessView::GetInstance()->UpdateDownloadSuccess("模组升级成功");
}
#ifdef SUPPORT_CAT1_SERVICE
- /* 以 g_ln_last_package_url_new2/new1(getTask 写入)中的 PY_SRV_Vxx 为准 */
- if (status == 4 && ln_cat1_last_package_urls_target_py() == 34) {
+ /* 本次 Cat1 真升:URL 目标 V34 + 当前 py>=34 + OTA 前基线 < 34 */
+ if (status == 4 && ln_cat1_last_package_urls_target_py() == 34 && uapi_get_py_ver() >= 34 &&
+ uapi_cat1_ota_get_py_baseline() < 34) {
(void)UtilsSetValue("cat1_py34_upgrade_done", "1");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
- "CheckOtaResult: Cat1 success, URL target py=34, KV cat1_py34_upgrade_done=1");
+ "[ota]CheckOtaResult: Cat1 verified py34, baseline=%u->%u, KV cat1_py34_upgrade_done=1",
+ (unsigned)uapi_cat1_ota_get_py_baseline(), (unsigned)uapi_get_py_ver());
}
#endif
}
char mark[8] = {0};
(void)UtilsGetValue(kKvCat1Py34UpgradeDone, mark, sizeof(mark));
if (strcmp(mark, "1") == 0) {
- return false;
+ if (uapi_get_py_ver() >= 34) {
+ return false;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[ota]IsSoftwareVersion_1_0_47: KV py34 set but runtime py=%u, clear KV",
+ (unsigned)uapi_get_py_ver());
+ (void)UtilsDeleteValue(kKvCat1Py34UpgradeDone);
}
uint8_t major = 0;
uint8_t mid = 0;
set(PRIVATE_HEADER
${CMAKE_CURRENT_SOURCE_DIR}/include
+${ROOT_DIR}/zhihui/leiniao/imsl_ln/
)
set(SOURCES
#if defined(CUSTOM_UTILS) && defined(BOARD_LEINIAO)\r
#include "custom_utils.h"\r
#endif\r
+#if defined(BOARD_LEINIAO)\r
+#include "ln_api.h"\r
+#endif\r
/* GBL_CTL_M中SOFT_RST_4寄存器 */\r
#define DISPLAY_LOGIC_CRG_RESET 0x570000c0\r
/**\r
\r
int32_t action_display_execute_entry(uint16_t action_bitmap, uint16_t new_state, event_type_t type, uint32_t event)\r
{\r
- unused(type);\r
- unused(event);\r
\r
screen_context_t *sc = power_display_get_screen_context();\r
uint32_t ret;\r
return ret;\r
}\r
POWER_DISPLAY_PRINT_DEBUG(0, "turn on success.");\r
+#if defined(BOARD_LEINIAO)\r
+ /* 按键亮屏时补拉整点因息屏未获取的时间线 */\r
+ if (type == GUI_EVENT && (event & GUI_EVENT_TYPE_MASK) == KEY) {\r
+ ln_timeline_try_fetch_pending_on_wakeup();\r
+ }\r
+#endif\r
}\r
\r
if ((action_bitmap & GET_ACTION_MASK(SET_DISPLAY_TO_IDLE_MODE)) != 0) {\r
return g_py_ver;
}
+static uint8_t g_cat1_ota_py_baseline = 0;
+static uint8_t g_cat1_py34_session_verified = 0;
+
+void uapi_cat1_ota_begin(uint8_t baseline_py)
+{
+ g_cat1_ota_py_baseline = baseline_py;
+ g_cat1_py34_session_verified = 0;
+}
+
+uint8_t uapi_cat1_ota_get_py_baseline(void)
+{
+ return g_cat1_ota_py_baseline;
+}
+
+void uapi_cat1_ota_mark_py34_verified(void)
+{
+ g_cat1_py34_session_verified = 1;
+}
+
+int uapi_cat1_ota_is_py34_verified(void)
+{
+ return g_cat1_py34_session_verified ? 1 : 0;
+}
static osTimerId_t g_timer_time_answer = NULL;
#ifdef BOARD_LEINIAO
#include "ln_api_interface.h"
int cat1_model_oat_suc_flag = 0;//模组升级标志
+
+static uint8_t cat1_ota_resolve_target_py(void)
+{
+ int target = ln_cat1_last_package_urls_target_py();
+ if (target > 0 && target <= 255) {
+ return (uint8_t)target;
+ }
+ return 34;
+}
#endif
static void modem_ota_timer_CallBack(int data_tmp)
{
- printf("modem_ota_timer_CallBack %d old_model_ver %d g_py_ver %d\n",mode_ota_count,old_model_ver,uapi_get_py_ver());
- if(old_model_ver!=uapi_get_py_ver())
+ int cat1_ota_ok = 0;
+ printf("modem_ota_timer_CallBack %d old_model_ver %d g_py_ver %d baseline %u\n", mode_ota_count,
+ old_model_ver, uapi_get_py_ver(), (unsigned)uapi_cat1_ota_get_py_baseline());
+#ifdef BOARD_LEINIAO
{
+ uint8_t cur_py = uapi_get_py_ver();
+ uint8_t target_py = cat1_ota_resolve_target_py();
+ uint8_t baseline_py = uapi_cat1_ota_get_py_baseline();
+ cat1_ota_ok = (cur_py >= target_py && cur_py > baseline_py) ? 1 : 0;
+ }
+#else
+ cat1_ota_ok = (old_model_ver != uapi_get_py_ver()) ? 1 : 0;
+#endif
+ if (cat1_ota_ok) {
uint8_t TRANSMIT_DATA=TRANS_FREE;
#ifdef BOARD_LEINIAO
+ uapi_cat1_ota_mark_py34_verified();
push_ota_status(OTA_UI_STATUS_SUCCESS);
/* 不在 4G 模组 OTA 成功后立即重启,便于继续后续手表 OTA(原 shutdown_reboot_prejobs(REBOOT_TYPE)) */
- printf("[OTA] Cat1 OTA py_ver changed: skip immediate reboot\r\n");
+ printf("[OTA] Cat1 OTA ok: cur>baseline and >= target, skip immediate reboot\r\n");
#else
CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1);
#endif
modem_ota_timer = NULL;
}
- }
- else
- {
+ } else {
mode_ota_count++;
if(mode_ota_count>120 || g_py_ver_new==0)
{
uint8_t TRANSMIT_DATA=OTA_UPDATA_FAIL;
CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1);
+#ifdef BOARD_LEINIAO
+ push_ota_status(OTA_UI_STATUS_FAILED);
+ printf("[OTA] Cat1 OTA timeout/fail py=%u baseline=%u target=%u\r\n",
+ (unsigned)uapi_get_py_ver(), (unsigned)uapi_cat1_ota_get_py_baseline(),
+ (unsigned)cat1_ota_resolve_target_py());
+#endif
if(modem_ota_timer){
osTimerStop(modem_ota_timer);
CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1);
#endif
+ uapi_cat1_ota_begin(ver);
old_model_ver=ver;
* @return 返回Python服务版本号,例如:4, 16, 28, 29等
* */
uint8_t uapi_get_py_ver(void);
+
+/** Cat1 OTA 开始前记录 Py 基线(star_http_ota_updata 调用) */
+void uapi_cat1_ota_begin(uint8_t baseline_py);
+uint8_t uapi_cat1_ota_get_py_baseline(void);
+/** 本次会话 Cat1 已确认升到目标 Py(非仅口播已是高版本) */
+void uapi_cat1_ota_mark_py34_verified(void);
+int uapi_cat1_ota_is_py34_verified(void);
+
/**
* @brief 获取modem版本
* @return modem版本字符串,sdk当下版本唯一 EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_BETA0312
# 私有头文件路径(仅当前组件内部使用)
set(PRIVATE_HEADER
- # 如无特殊私有头文件,可留空
${CMAKE_CURRENT_SOURCE_DIR}/
)
return ERRCODE_SUCC;
}
+/* 整点时间线获取:息屏时置位,按键亮屏后补拉 */
+static uint8_t g_ln_timeline_fetch_pending = 0;
+
+
+static void ln_timeline_do_get_status(void)
+{
+ if (!uapi_ln_is_device_bound()) {
+ return;
+ }
+ do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS, NULL, 0);
+ g_ln_timeline_fetch_pending = 0;
+}
+
+void ln_timeline_scheduled_hourly_fetch(void)
+{
+ if (!uapi_ln_is_device_bound()) {
+ return;
+ }
+ /* uapi_get_screen_state: 0=亮屏, 1=息屏 */
+ if (uapi_get_screen_state() == 0) {
+ ln_timeline_do_get_status();
+ } else {
+ g_ln_timeline_fetch_pending = 1;
+ }
+}
+
+void ln_timeline_try_fetch_pending_on_wakeup(void)
+{
+ if (g_ln_timeline_fetch_pending == 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[时间线] g_ln_timeline_fetch_pending == 0");
+ return;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[时间线] g_ln_timeline_fetch_pending == 1");
+ ln_timeline_do_get_status();
+}
+
/* 获取设备业务忙状态(返回业务忙描述字符串,如果设备空闲则返回NULL) */
const char* uapi_ln_get_device_busy_status(void)
{
/* ============================== 公共宏与URL路径 ============================== */
#define LN_VOICE_CHAT_ENABLED 0 //声纹锁开启宏
-#define LN_ENV_PRODUCTION 1 //正式环境
+#define LN_ENV_PRODUCTION 0 //正式环境
/* 接口基础配置 - 如需切换环境/密钥,在此调整 */
#if LN_ENV_PRODUCTION
#define LN_BASE_URL "https://ambybox-o.api.leiniao.com/ambybox-device-api" //正式环境服务器地址
/* 查询时间线状态(GET /v1/timeline/getStatus)*/
uint32_t ln_timeline_get_status_http(const char *device_id,
const char *device_token);
+/* 整点获取时间线:亮屏立即拉取,息屏置待获取标志,按键亮屏后补拉 */
+void ln_timeline_scheduled_hourly_fetch(void);
+void ln_timeline_try_fetch_pending_on_wakeup(void);
/* ============================== 各接口函数声明 ============================== */
uint32_t ln_get_device_token_http(const char *device_id,
#include "cat1_pub_api.h"
#endif
#include "cat1_pub_api.h" /* 包含 uapi_get_py_ver() 函数声明 */
-
-// static int ln_ota_reject_1047_if_not_py34(const char *target);
-
+#include "ln_api_interface.h"
/* OTA下载状态枚举(对应时序图中的下载阶段)*/
typedef enum
return 0;
}
-/* 1.0.47 仅当 Cat1 已先升到 Py 版 34 后才允许,否则需先走 Py 升级再继续 */
+/* 1.0.47 手表 OTA:须满足 Py34 前置(KV 或本次 Cat1 会话真升),不能仅口播已是 V34 */
static int ln_ota_reject_1047_if_not_py34(const char *target)
{
- return ln_ota_target_is_1047(target) && (uapi_get_py_ver() <34 && uapi_get_py_ver() != 32);
+ return ln_ota_target_is_1047(target) && !ln_cat1_py34_prereq_met();
}
//解析 OTA 任务 JSON,决定是否触发下载
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"解析OTA升级任务JSON");
if (ln_ota_reject_1047_if_not_py34(uapi_ln_get_device_version()))
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[OTA] task rejected: 1.0.47 requires py version 34 first, current=%u",
- (unsigned int)uapi_get_py_ver());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[OTA] task rejected: 1.0.47 requires cat1 py34 (KV or verified session), py=%u kv=%d verified=%d",
+ (unsigned int)uapi_get_py_ver(), ln_kv_cat1_py34_upgrade_done(), uapi_cat1_ota_is_py34_verified());
return;
}
// 直接获取CAT1 modem版本(如果版本还未获取,会在后续处理中处理)
char *text = cat1_api_runtime_get_cat1_modemver();
if (!text || strlen(text) == 0) {
- printf("[OTA] cat1 modem版本为空,执行普通OTA升级\n");
+ if (!ln_cat1_py34_prereq_met()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[OTA] modem ver empty: py34 prereq not met, skip host OTA");
+ return;
+ }
+ printf("[OTA] cat1 modem版本为空且py34已确认,执行普通OTA升级\n");
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_OTA_GET_TASK, NULL, 0);
return;
}
char version[16] = {0};
if (get_modem_fw_version_c(text, version) != 0) {
- printf("[OTA] 无法解析modem版本,执行普通OTA升级\n");
+ if (!ln_cat1_py34_prereq_met()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[OTA] modem ver parse fail: py34 prereq not met, skip host OTA");
+ return;
+ }
+ printf("[OTA] 无法解析modem版本且py34已确认,执行普通OTA升级\n");
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_OTA_GET_TASK, NULL, 0);
return;
}
// 检查cat1模组升级url是否为空
if(strlen(g_ln_last_package_url_new1) == 0 || strlen(g_ln_last_package_url_new2) == 0) {
- printf("[OTA] cat1模组升级url为空,执行普通OTA升级\n");
+ if (!ln_cat1_py34_prereq_met()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "[OTA] cat1 url empty: py34 prereq not met, skip host OTA (py=%u kv=%d verified=%d)",
+ (unsigned)uapi_get_py_ver(), ln_kv_cat1_py34_upgrade_done(), uapi_cat1_ota_is_py34_verified());
+ return;
+ }
+ printf("[OTA] cat1模组升级url为空且py34已确认,执行普通OTA升级\n");
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_OTA_GET_TASK, NULL, 0);
} else {
printf("[OTA] cat1模组升级url不为空,触发CAT1升级\n");
set(PRIVATE_HEADER
+${ROOT_DIR}/open_source/openharmony/utils/native/lite/include
+${ROOT_DIR}/zhihui/4g/cat1Service/include
${ROOT_DIR}/middleware/services/media/foundation/audiomanager/interfaces/kits/audiomanager
${ROOT_DIR}/middleware/services/media/foundation/audiomanager/interfaces/kits/audiocommon
${ROOT_DIR}/middleware/services/media/foundation/audiomanager/frameworks/audiostream/include
#include <stdlib.h>
#include <cstdio>
+#include <cstring>
+#include "kv_store.h"
+#include "cat1_pub_api.h"
+
+#define LN_CAT1_PY34_MIN_VER 34
+#define LN_KV_CAT1_PY34_UPGRADE_DONE "cat1_py34_upgrade_done"
+
+int ln_kv_cat1_py34_upgrade_done(void)
+{
+ char mark[8] = {0};
+ (void)UtilsGetValue(LN_KV_CAT1_PY34_UPGRADE_DONE, mark, sizeof(mark));
+ return (strcmp(mark, "1") == 0) ? 1 : 0;
+}
+
+int ln_cat1_py34_prereq_met(void)
+{
+ uint8_t py = uapi_get_py_ver();
+ if (py < LN_CAT1_PY34_MIN_VER && py != 32) {
+ return 0;
+ }
+ return ln_kv_cat1_py34_upgrade_done() || uapi_cat1_ota_is_py34_verified();
+}
// 推送文本给ui
void push_text_to_ui(const char *text)
void push_bluetooth_connect_notification(const char *bluetoothAddress);
//获取UI中设置的音量值(未真正设置到系统的音量)
int32_t get_ui_volume(void);
+
+/* Cat1 OTA 双包 URL(ln_api_ota 写入,cat1 模块可读目标 Py 版本) */
+extern char g_ln_last_package_url_new1[256];
+extern char g_ln_last_package_url_new2[256];
+/** 从 URL 路径解析 PY_SRV_Vxx,优先 new2;失败返回 -1 */
+int ln_cat1_last_package_urls_target_py(void);
+/** KV cat1_py34_upgrade_done 是否为 1 */
+int ln_kv_cat1_py34_upgrade_done(void);
+/** Cat1 已真升到 Py34:KV 或本次 OTA verified */
+int ln_cat1_py34_prereq_met(void);
+
#ifdef __cplusplus
}
#endif