refactor(panel): 前后端按模块拆分+屏幕/控制合并页 — 后端meowpanel.c 6372行拆src/*.c+mp.h(235函数原型,20端点output byte-identical,0warning)+前端拆mp_shared/mp_pages/meowpanel三层;屏幕·遥控合并(左屏实时画面+右MD3 SVG矢量按钮无emoji);重编后热更TF卡

This commit is contained in:
AskaEth committed 2026-09-04 00:56:13 +08:00
1 parent f3ae06d7cd
commit 2dc4cad454
26 files changed
+9317 -2755

No files matched your search

+140
View File
@@ -0,0 +1,140 @@
/* mp_power.c — 功耗管理域:meow_powermgr IPC(/api/power*,policy,window,events)。 */
#include "mp.h"
int ipc_pm_query(uint32_t subset, char *out, int cap)
{
int fd = ipc_connect_tmo(g_sock_pm, IPC_TIMEOUT_MS);
if (fd < 0) return MEOW_ERR_NODEV;
int rc = MEOW_ERR_INTERNAL;
if (ipc_hello(fd) < 0) { rc = MEOW_ERR_INTERNAL; goto done; }
m_pm_query_t q;
memset(&q, 0, sizeof q);
q.subset = subset;
if (send_frame(fd, MSG_PM_QUERY, 0x31, &q, sizeof q) < 0) { rc = MEOW_ERR_IO; goto done; }
uint8_t buf[MEOW_IPC_MAX];
uint16_t type; uint32_t rid;
int n = recv_frame(fd, &type, &rid, buf, sizeof buf);
if (n < 12) { rc = MEOW_ERR_IO; goto done; } /* code(4)+subset(4)+json_len(2)+pad(2) */
if (type != MSG_PM_RESULT) { rc = MEOW_ERR_INVAL; goto done; }
uint32_t c; memcpy(&c, buf, 4);
if (c != MEOW_OK) { rc = (int)c; goto done; }
/* powermgr 发**紧凑**负载:json 从偏移 12 起(json_len 在偏移 8);同 m_pm_result_t 布局,兼容全量/紧凑。 */
uint16_t jl; memcpy(&jl, buf + 8, 2);
if (jl > MEOW_IPC_MAX - 12) jl = (uint16_t)(MEOW_IPC_MAX - 12);
if ((size_t)jl >= (size_t)cap) jl = (uint16_t)(cap - 1);
memcpy(out, buf + 12, jl);
out[jl] = 0;
rc = MEOW_OK;
done:
close(fd);
return rc;
}
int api_power(int sock)
{
char js[MEOW_IPC_MAX];
int rc = ipc_pm_query(0, js, sizeof js);
if (rc != MEOW_OK || !utf8_valid_n(js, strlen(js))) /* 上游坏字节 → 不返回,降级 */
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务不可用");
return send_json(sock, 200, js);
}
int ipc_pm_send(uint16_t req_type, const void *pl, uint32_t plen,
uint16_t *rtype, char *out, int cap)
{
int fd = ipc_connect_tmo(g_sock_pm, IPC_TIMEOUT_MS);
if (fd < 0) return MEOW_ERR_NODEV;
int rc = MEOW_ERR_INTERNAL;
if (rtype) *rtype = 0;
if (ipc_hello(fd) < 0) { rc = MEOW_ERR_INTERNAL; goto done; }
if (send_frame(fd, req_type, 0x41, pl, plen) < 0) { rc = MEOW_ERR_IO; goto done; }
uint8_t buf[MEOW_IPC_MAX];
uint16_t type; uint32_t rid;
int n = recv_frame(fd, &type, &rid, buf, sizeof buf);
if (n <= 0) { rc = MEOW_ERR_IO; goto done; }
if (rtype) *rtype = type;
if (type == MSG_ERR) {
m_err_t e; memcpy(&e, buf, sizeof e);
rc = (int)e.code; goto done;
}
if (n < 12) { rc = MEOW_ERR_IO; goto done; } /* code(4)+subset(4)+json_len(2)+pad(2) */
uint32_t c; memcpy(&c, buf, 4);
if (c != MEOW_OK) { rc = (int)c; goto done; }
uint16_t jl; memcpy(&jl, buf + 8, 2);
if (jl > MEOW_IPC_MAX - 12) jl = (uint16_t)(MEOW_IPC_MAX - 12);
if ((size_t)jl >= (size_t)cap) jl = (uint16_t)(cap - 1);
memcpy(out, buf + 12, jl); out[jl] = 0;
rc = (int)jl;
done:
close(fd);
return rc;
}
int api_power_policy_get(int sock)
{
char js[MEOW_IPC_MAX];
uint16_t rt = 0;
int rc = ipc_pm_send(MSG_PM_POLICY_GET, NULL, 0, &rt, js, sizeof js);
if (rc <= 0)
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务不可用(powermgr 未运行/IPC 不可达)");
if (rt != MSG_PM_RESULT || !utf8_valid_n(js, strlen(js)))
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务应答包含非法字节");
return send_json(sock, 200, js);
}
int api_power_policy_set(int sock, const char *body, size_t body_len)
{
if (!body || !body[0]) return send_err(sock, 400, "BAD_REQUEST", "缺少 body");
jv_t *root = jv_parse(body, (int)body_len);
if (!root) return send_err(sock, 400, "BAD_REQUEST", "body 非合法 JSON");
jv_t *ji = jv_obj_get(root, "item"), *jv = jv_obj_get(root, "value");
char item[20] = "", val[40] = "";
if (ji && ji->type == J_STR && ji->str) snprintf(item, sizeof item, "%s", ji->str);
if (jv && jv->type == J_STR && jv->str) snprintf(val, sizeof val, "%s", jv->str);
else if (jv && jv->type == J_NUM) snprintf(val, sizeof val, "%lld", jv->inum);
jv_free(root);
if (!item[0]) return send_err(sock, 422, "UNSUPPORTED", "缺 item(profile/low-pct/crit-pct/bri-cap/scr-cap)");
if (!val[0]) return send_err(sock, 422, "UNSUPPORTED", "缺 value");
m_pm_policy_set_t s; memset(&s, 0, sizeof s);
snprintf(s.item, sizeof s.item, "%.15s", item); /* item[16] 留一个 NUL;防越界截断告警 */
snprintf(s.val, sizeof s.val, "%.31s", val); /* val[32] 同理 */
char js[MEOW_IPC_MAX];
uint16_t rt = 0;
int rc = ipc_pm_send(MSG_PM_POLICY_SET, &s, sizeof s, &rt, js, sizeof js);
if (rc <= 0) {
if (rt == MSG_ERR) /* 权限不足:powermgr 拒绝(面板 root 仅当被白名单才放行;如实回传) */
return send_err(sock, 403, "FORBIDDEN", rc == MEOW_ERR_PERM ? "设备身份不允许写电源策略" : "电源策略写入被拒绝");
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务不可用(powermgr 未运行/IPC 不可达)");
}
if (rt != MSG_PM_RESULT || !utf8_valid_n(js, strlen(js)))
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务应答包含非法字节");
/* 服务端对非法值回 ok:false(HTTP 层 200,code 仍 OK);按其 why 映射 422。 */
if (strstr(js, "\"ok\":false")) {
char why[96] = "";
jv_t *jr = jv_parse(js, (int)strlen(js));
if (jr) { jv_t *w = jv_obj_get(jr, "why"); if (w && w->type == J_STR && w->str) snprintf(why, sizeof why, "%s", w->str); jv_free(jr); }
return send_err(sock, 422, "UNSUPPORTED", why[0] ? why : "非法电源策略值");
}
return send_json(sock, 200, js);
}
int api_power_window(int sock, uint16_t req_type, uint16_t want_type, const char *unavail)
{
uint32_t count = 0;
char js[MEOW_IPC_MAX];
uint16_t rt = 0;
int rc = ipc_pm_send(req_type, &count, sizeof count, &rt, js, sizeof js);
if (rc <= 0)
return send_err(sock, 503, "POWER_UNAVAILABLE", unavail);
if (rt != want_type || !utf8_valid_n(js, strlen(js)))
return send_err(sock, 503, "POWER_UNAVAILABLE", "电源管理服务应答包含非法字节");
return send_json(sock, 200, js);
}
int api_power_history(int sock)
{ return api_power_window(sock, MSG_PM_HISTORY, MSG_PM_HISTORY_RESULT, "电源历史采样不可用(powermgr 未运行)"); }
int api_power_events(int sock)
{ return api_power_window(sock, MSG_PM_EVENTS, MSG_PM_EVENTS_RESULT, "电源事件不可用(powermgr 未运行)"); }