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

+211
View File
@@ -0,0 +1,211 @@
/* mp_ipc.c — IPC 帧读写 + meow_svc_perf/power/netmgr 客户端(单点 IPC 收发)。 */
#include "mp.h"
const char *g_sock_perf = PERF_SOCK;
const char *g_sock_power = POWER_SOCK;
const char *g_sock_launcher = LAUNCHER_SOCK;
const char *g_sock_audio = AUDIO_SOCK;
const char *g_sock_net = NET_SOCK;
const char *g_sock_pm = PM_SOCK;
int x_read_full(int fd, uint8_t *buf, size_t n)
{
size_t off = 0;
while (off < n) {
ssize_t r = read(fd, buf + off, n - off);
if (r <= 0) return -1;
off += (size_t)r;
}
return 0;
}
int x_write_full(int fd, const uint8_t *buf, size_t n)
{
size_t off = 0;
while (off < n) {
ssize_t w = write(fd, buf + off, n - off);
if (w <= 0) return -1;
off += (size_t)w;
}
return 0;
}
int send_frame(int fd, uint16_t type, uint32_t req_id, const void *payload, uint32_t len)
{
uint8_t hdr[MEOW_IPC_HDR_LEN];
uint32_t magic = MEOW_IPC_MAGIC, rl = len;
uint16_t ver = MEOW_IPC_VERSION, t = type;
memcpy(hdr + 0, &magic, 4);
memcpy(hdr + 4, &ver, 2);
memcpy(hdr + 6, &t, 2);
memcpy(hdr + 8, &req_id, 4);
memcpy(hdr + 12, &rl, 4);
if (x_write_full(fd, hdr, MEOW_IPC_HDR_LEN) < 0) return -1;
if (len && payload && x_write_full(fd, payload, len) < 0) return -1;
return 0;
}
int recv_frame(int fd, uint16_t *type, uint32_t *req_id, uint8_t *buf, uint32_t cap)
{
uint8_t hdr[MEOW_IPC_HDR_LEN];
if (x_read_full(fd, hdr, sizeof hdr) < 0) return -1;
uint32_t magic, rlen, rid;
uint16_t ver, t;
memcpy(&magic, hdr, 4);
memcpy(&ver, hdr + 4, 2);
memcpy(&t, hdr + 6, 2);
memcpy(&rid, hdr + 8, 4);
memcpy(&rlen, hdr + 12, 4);
if (magic != MEOW_IPC_MAGIC || ver != MEOW_IPC_VERSION) return -1;
if (rlen > MEOW_IPC_MAX) return -1;
if (type) *type = t;
if (req_id) *req_id = rid;
uint32_t n = (rlen < cap) ? rlen : cap;
if (n && x_read_full(fd, buf, n) < 0) return -1;
/* 若实际更长,丢弃剩余 */
for (uint32_t i = n; i < rlen; i++) { uint8_t c; if (x_read_full(fd, &c, 1) < 0) return -1; }
return (int)n;
}
int ipc_connect_tmo(const char *sock, int tmo_ms)
{
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) return -1;
struct sockaddr_un a;
memset(&a, 0, sizeof a);
a.sun_family = AF_UNIX;
strncpy(a.sun_path, sock, sizeof a.sun_path - 1);
int fl = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
int rc = connect(fd, (struct sockaddr *)&a, sizeof a);
if (rc < 0 && errno == EINPROGRESS) {
struct pollfd pf = { fd, POLLOUT, 0 };
int pr = poll(&pf, 1, tmo_ms);
if (pr <= 0) { close(fd); return -1; }
int soerr = 0;
socklen_t sl = sizeof soerr;
getsockopt(fd, SOL_SOCKET, SO_ERROR, &soerr, &sl);
if (soerr != 0) { close(fd); return -1; }
} else if (rc < 0) { close(fd); return -1; }
fcntl(fd, F_SETFL, fl);
/* 读/写超时兜底(正常服务应即时响应) */
struct timeval tv = { tmo_ms / 1000, (tmo_ms % 1000) * 1000 };
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
return fd;
}
int ipc_hello(int fd)
{
m_hello_t h;
memset(&h, 0, sizeof h);
strncpy(h.app_id, "os.meow.panel", sizeof h.app_id - 1);
h.version = 1;
if (send_frame(fd, MSG_HELLO, 1, &h, sizeof h) < 0) return -1;
uint8_t buf[64];
uint16_t type; uint32_t rid;
int n = recv_frame(fd, &type, &rid, buf, sizeof buf);
if (n < (int)sizeof(m_ack_t)) return -1;
if (type != MSG_ACK) return -1;
m_ack_t a;
memcpy(&a, buf, sizeof a);
return (a.code == MEOW_OK) ? 0 : -1;
}
const char *perf_code_str(int code)
{
switch (code) {
case MEOW_OK: return ""; /* 不应使用 */
case MEOW_ERR_INVAL: return "参数非法";
case MEOW_ERR_IO: return "读取失败";
case MEOW_ERR_NODEV: return "设备不存在";
default: return "服务端错误";
}
}
int perf_subset_for_path(const char *path)
{
if (!strcmp(path, "/api/perf")) return PERF_SUBSET_PERF;
if (!strcmp(path, "/api/system")) return 0; /* system 需 uptime/storage,取全量 */
return 0; /* /api/status */
}
int ipc_perf_query(int subset, char *out, int cap)
{
int fd = ipc_connect_tmo(g_sock_perf, IPC_TIMEOUT_MS);
if (fd < 0) return MEOW_ERR_NODEV;
int rc = MEOW_ERR_INTERNAL;
char msg[128] = "";
if (ipc_hello(fd) < 0) { rc = MEOW_ERR_INTERNAL; snprintf(msg, sizeof msg, "握手中断:性能服务未就绪"); goto done; }
m_perf_query_t q;
memset(&q, 0, sizeof q);
q.subset = (uint32_t)subset;
if (send_frame(fd, MSG_PERF_QUERY, 2, &q, sizeof q) < 0) { rc = MEOW_ERR_IO; snprintf(msg, sizeof msg, "发送查询失败"); goto done; }
uint8_t buf[MEOW_IPC_MAX + MEOW_IPC_HDR_LEN];
uint16_t type; uint32_t rid;
int n = recv_frame(fd, &type, &rid, buf, sizeof buf);
if (n < (int)sizeof(m_perf_result_t)) { rc = MEOW_ERR_IO; snprintf(msg, sizeof msg, "应答帧过短"); goto done; }
if (type != MSG_PERF_RESULT) { rc = MEOW_ERR_INVAL; snprintf(msg, sizeof msg, "非预期应答类型 0x%04x", type); goto done; }
m_perf_result_t r;
memcpy(&r, buf, sizeof r);
if (r.code != MEOW_OK) { rc = (int)r.code; snprintf(msg, sizeof msg, "性能服务错误: %s", perf_code_str((int)r.code)); goto done; }
uint16_t jl = r.json_len;
if (jl > sizeof r.json - 1) jl = (uint16_t)(sizeof r.json - 1);
if ((size_t)jl >= (size_t)cap) jl = (uint16_t)(cap - 1);
memcpy(out, r.json, jl);
out[jl] = 0;
rc = MEOW_OK;
done:
close(fd);
/* 服务不可达/非 OK 由调用方据此返回错误;绝不静默失败、绝不降级直连 /proc。 */
return rc;
}
const char *power_code_str(int code)
{
switch (code) {
case MEOW_OK: return "";
case MEOW_ERR_PERM: return "无权限(需 root)";
case MEOW_ERR_INVAL: return "未知命令";
case MEOW_ERR_NODEV: return "设备/能力不支持";
case MEOW_ERR_NOENT: return "缺少升级文件";
case MEOW_ERR_IO: return "读写失败";
default: return "电源服务错误";
}
}
int ipc_power_action(uint32_t cmd, uint32_t flag, const char *arg, m_power_status_t *out_st)
{
int fd = ipc_connect_tmo(g_sock_power, 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_power_action_t a;
memset(&a, 0, sizeof a);
a.cmd = cmd;
a.flag = flag;
if (arg) snprintf(a.arg, sizeof a.arg, "%s", arg);
if (send_frame(fd, MSG_POWER_ACTION, 3, &a, sizeof a) < 0) { rc = MEOW_ERR_IO; goto done; }
uint8_t buf[256];
uint16_t type; uint32_t rid;
int n = recv_frame(fd, &type, &rid, buf, sizeof buf);
if (n < (int)sizeof(m_power_status_t)) { rc = MEOW_ERR_IO; goto done; }
if (type != MSG_POWER_STATUS) { rc = MEOW_ERR_INVAL; goto done; }
m_power_status_t st;
memcpy(&st, buf, sizeof st);
if (out_st) *out_st = st;
rc = (int)st.code;
done:
close(fd);
return rc;
}
void svc_msg_kv(const char *msg, const char *key, char *out, size_t cap)
{
out[0] = 0;
if (!msg || !key) return;
size_t kl = strlen(key);
if (strncmp(msg, key, kl) == 0 && msg[kl] == '=' && msg[kl + 1])
snprintf(out, cap, "%s", msg + kl + 1);
}