除了显示驱动,其余全部测试通过
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
#include "system/includes.h"
|
||||
|
||||
#include "app_log.h"
|
||||
#include "radar_report_service.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static struct radar_report_service_config report_config;
|
||||
|
||||
static struct radar_report_snapshot pending_snapshot;
|
||||
|
||||
static u8 report_service_initialized;
|
||||
static u8 report_pending;
|
||||
static u8 pending_reason;
|
||||
|
||||
static u32 last_report_ms;
|
||||
|
||||
|
||||
/*
|
||||
* 判断两个快照在“manager meaningful-change 关注的字段”上
|
||||
* 是否仍然一致。
|
||||
*
|
||||
* 不比较 position:
|
||||
* 当前 manager 的 meaningful-change 本来就不以 XYZ 作为
|
||||
* 上报变化条件,位置的持续抖动不应阻止 consumed baseline 推进。
|
||||
*
|
||||
* 不比较 last_update_ms/sample_age_ms:
|
||||
* 它们是时间信息,不是业务状态本身。
|
||||
*/
|
||||
static u8 radar_report_business_equal(
|
||||
const struct radar_report_snapshot *a,
|
||||
const struct radar_report_snapshot *b
|
||||
)
|
||||
{
|
||||
if (!a || !b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.presence != b->sensor.presence) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.motion != b->sensor.motion) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.sleep_state != b->sensor.sleep_state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.body_movement !=
|
||||
b->sensor.body_movement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.distance_cm !=
|
||||
b->sensor.distance_cm) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.heart_rate_x10 !=
|
||||
b->sensor.heart_rate_x10) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.breath_rate_x10 !=
|
||||
b->sensor.breath_rate_x10) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a->sensor.abnormal_state !=
|
||||
b->sensor.abnormal_state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int radar_report_service_init(
|
||||
const struct radar_report_service_config *config
|
||||
)
|
||||
{
|
||||
if (!config) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (config->max_age_ms == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
memset(
|
||||
&pending_snapshot,
|
||||
0,
|
||||
sizeof(pending_snapshot)
|
||||
);
|
||||
|
||||
report_config = *config;
|
||||
|
||||
report_pending = 0;
|
||||
pending_reason = RADAR_REPORT_REASON_NONE;
|
||||
last_report_ms = 0;
|
||||
|
||||
report_service_initialized = 1;
|
||||
|
||||
APP_LOG(
|
||||
"[RADAR_REPORT] init success max_age=%u periodic=%u\n",
|
||||
report_config.max_age_ms,
|
||||
report_config.periodic_interval_ms
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int radar_report_service_check(
|
||||
u32 now_ms,
|
||||
struct radar_report_snapshot *out,
|
||||
u8 *reason
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
u8 due_reason;
|
||||
struct radar_report_snapshot current;
|
||||
|
||||
if (!out || !reason) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!report_service_initialized) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 已经有一份等待真正发送成功的快照:
|
||||
* 始终返回同一份,避免发送失败重试时内容漂移。
|
||||
*/
|
||||
if (report_pending) {
|
||||
|
||||
memcpy(
|
||||
out,
|
||||
&pending_snapshot,
|
||||
sizeof(*out)
|
||||
);
|
||||
|
||||
*reason = pending_reason;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ret = radar_manager_get_report_snapshot(
|
||||
now_ms,
|
||||
report_config.max_age_ms,
|
||||
¤t
|
||||
);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 没有真正业务样本,或者样本已经过期:
|
||||
* 不把旧数据交给上层发送。
|
||||
*/
|
||||
if (current.sensor.last_update_ms == 0 ||
|
||||
!current.has_fresh_sample) {
|
||||
|
||||
*reason = RADAR_REPORT_REASON_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
due_reason = RADAR_REPORT_REASON_NONE;
|
||||
|
||||
|
||||
/*
|
||||
* 第一次成功上报之前,
|
||||
* 只要已经有 fresh sample 就先产生一份初始快照。
|
||||
*/
|
||||
if (last_report_ms == 0) {
|
||||
|
||||
due_reason =
|
||||
RADAR_REPORT_REASON_INITIAL;
|
||||
|
||||
} else if (current.has_meaningful_change) {
|
||||
|
||||
due_reason =
|
||||
RADAR_REPORT_REASON_CHANGE;
|
||||
|
||||
} else if (
|
||||
report_config.periodic_interval_ms != 0 &&
|
||||
(u32)(now_ms - last_report_ms) >=
|
||||
report_config.periodic_interval_ms
|
||||
) {
|
||||
|
||||
due_reason =
|
||||
RADAR_REPORT_REASON_PERIODIC;
|
||||
}
|
||||
|
||||
|
||||
if (due_reason == RADAR_REPORT_REASON_NONE) {
|
||||
|
||||
*reason = RADAR_REPORT_REASON_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
memcpy(
|
||||
&pending_snapshot,
|
||||
¤t,
|
||||
sizeof(pending_snapshot)
|
||||
);
|
||||
|
||||
report_pending = 1;
|
||||
pending_reason = due_reason;
|
||||
|
||||
|
||||
memcpy(
|
||||
out,
|
||||
&pending_snapshot,
|
||||
sizeof(*out)
|
||||
);
|
||||
|
||||
*reason = pending_reason;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int radar_report_service_mark_reported(
|
||||
u32 now_ms
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct radar_report_snapshot current;
|
||||
|
||||
if (!report_service_initialized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!report_pending) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 发送成功后重新看一次 manager 当前状态。
|
||||
*
|
||||
* 如果从生成 pending 到发送成功之间,
|
||||
* meaningful-change 相关业务字段没有变化,
|
||||
* 才安全推进 manager consumed baseline。
|
||||
*
|
||||
* 如果已经变化,则不消费:
|
||||
* 下一次 check 会继续看到 CHANGE,
|
||||
* 防止“发送旧快照却把新状态标记为已消费”。
|
||||
*/
|
||||
ret = radar_manager_get_report_snapshot(
|
||||
now_ms,
|
||||
report_config.max_age_ms,
|
||||
¤t
|
||||
);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (radar_report_business_equal(
|
||||
&pending_snapshot,
|
||||
¤t
|
||||
)) {
|
||||
|
||||
ret =
|
||||
radar_manager_mark_snapshot_consumed();
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
APP_LOG(
|
||||
"[RADAR_REPORT] state changed while pending, "
|
||||
"keep manager change for next report\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
last_report_ms = now_ms;
|
||||
|
||||
report_pending = 0;
|
||||
pending_reason = RADAR_REPORT_REASON_NONE;
|
||||
|
||||
memset(
|
||||
&pending_snapshot,
|
||||
0,
|
||||
sizeof(pending_snapshot)
|
||||
);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user