UI 代码:补全 remo_handle/cp_draw 注释,拆分 cp_draw_cb 绘制函数
This commit is contained in:
@@ -139,12 +139,24 @@ static void remo_send_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:处理一帧完整的远端命令(客户端→设备)
|
||||
* 入口参数:f - 完整帧 [TAG][CMD][LEN][DATA][CRC];n - 帧总长度
|
||||
* 函数功能:处理一帧完整的远端命令(客户端→设备),校验通过后按命令分发执行
|
||||
* 入口参数:f - 完整帧 [TAG][CMD][LEN][DATA][CRC](数据段自偏移 4 起)
|
||||
* n - 帧总长度(字节)
|
||||
* 返回值:无
|
||||
* 限定条件:调用前帧已通过 CRC 与 TAG 校验
|
||||
* 函数说明:按命令分发:KEEPLIVE 回心跳 / INIT 回尺寸 / KEY 注入按键 /
|
||||
* LCDMEM 回送 1bpp 帧缓冲(经平台后端取帧);非法情况静默丢弃
|
||||
* 限定条件:f 指向至少 n 字节可读空间;由解析状态机 rm_parser_feed 在 CRC 通过后调用
|
||||
* 函数说明:1. 前置校验(任一失败即静默丢弃:不应答、不断连接):
|
||||
* a) n >= 5:最短合法帧 5 字节(LEN=0 时 TAG/CMD/LEN_H/LEN_LO/CRC)
|
||||
* b) 4+len+1 <= n:长度字段与帧长一致,防长度损坏引发越界读
|
||||
* c) CRC 与数据段逐字节异或一致(仅覆盖数据段,不含头与 CRC 自身)
|
||||
* d) TAG 必须为 TAG_CLIENT(0xAA):服务端只收客户端方向帧
|
||||
* 状态机已做过等价校验,此处复核使本函数自包含(可独立调用)
|
||||
* 2. 按命令分发:
|
||||
* KEEPLIVE(0) - 原样回显空心跳帧,维持连接保活
|
||||
* INIT(1) - 回送屏幕几何 [宽u16][高u16][帧字节数u32](大端,6 字节)
|
||||
* KEY(2) - 数据段首字节按键码经平台后端注入 UI,回空帧作确认
|
||||
* LCDMEM(3) - 数据段为 4B 大端偏移;偏移 0=整帧,经平台后端取 1bpp
|
||||
* 位图后回送 [偏移u32][位图 3200B],非 0 偏移暂不支持
|
||||
* 3. 未知命令码静默丢弃
|
||||
*/
|
||||
static void remo_handle(const uint8_t *f, int n)
|
||||
{
|
||||
@@ -154,49 +166,68 @@ static void remo_handle(const uint8_t *f, int n)
|
||||
const uint8_t *data;
|
||||
uint8_t crc;
|
||||
|
||||
/* a) 最小帧长:TAG+CMD+LEN_H+LEN_LO+CRC 共 5 字节,不足必是残帧/噪声 */
|
||||
if (n < 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 解析帧头:TAG=方向(0xAA 客户端帧 / 0xBB 服务端帧),CMD=命令码,
|
||||
* LEN=数据段长度(16 位大端),数据段自偏移 4 起 */
|
||||
tag = f[0];
|
||||
cmd = f[1];
|
||||
len = (uint16_t)(((uint16_t)f[2] << 8) | (uint16_t)f[3]);
|
||||
data = f + 4;
|
||||
|
||||
/* b) 长度一致性:整帧长须恰为 4+len+1,防长度字段损坏导致越界读帧缓冲 */
|
||||
if ((int)(4 + len + 1) > n) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* c) CRC 校验:数据段逐字节异或(LEN=0 时恒 0)须与帧尾一致,坏帧静默丢弃 */
|
||||
crc = f[4 + len];
|
||||
if (crc != remo_crc(data, len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* d) 方向校验:只接受客户端帧 0xAA;0xBB 为服务端→客户端方向,出现在收包路径即非法 */
|
||||
if (tag != TAG_CLIENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_KEEPLIVE:
|
||||
/* 心跳保活:原样回显一个空 KEEPLIVE 帧,维持连接活性 */
|
||||
remo_send(CMD_KEEPLIVE, NULL, 0);
|
||||
break;
|
||||
case CMD_INIT:
|
||||
/* 查询屏幕参数:回送 [宽u16][高u16][帧字节数u32](大端,共 6 字节) */
|
||||
remo_send_init();
|
||||
break;
|
||||
case CMD_KEY:
|
||||
/* 远端导航按键:数据段首字节为按键码,经平台后端注入 UI 按键队列 */
|
||||
if (len >= 1) {
|
||||
ui_net_sink_inject_key(data[0]);
|
||||
}
|
||||
/* 回空帧作“已接收”确认(LEN=0,CRC=0) */
|
||||
remo_send(CMD_KEY, NULL, 0);
|
||||
break;
|
||||
case CMD_LCDMEM: {
|
||||
/* 读取显存:数据段为 4 字节大端起始偏移,不足 4 字节判非法丢弃 */
|
||||
if (len < 4) {
|
||||
break;
|
||||
}
|
||||
{
|
||||
/* 偏移按大端 32 位拼装(协议约定多字节字段大端) */
|
||||
uint32_t off = ((uint32_t)data[0] << 24) |
|
||||
((uint32_t)data[1] << 16) |
|
||||
((uint32_t)data[2] << 8) |
|
||||
((uint32_t)data[3]);
|
||||
/* 目前仅支持偏移 0(整帧)请求;非 0 偏移暂不支持,静默忽略 */
|
||||
if (off == 0) {
|
||||
/* 整帧请求:经平台后端取 1bpp 位图后回送(失败则静默丢弃) */
|
||||
/* 整帧请求:经平台后端取 1bpp 位图(MCU: ui_port_get_framebuffer /
|
||||
* 模拟器: sim_port_get_screen_mono)写入应答缓冲尾部,失败则静默丢弃 */
|
||||
if (ui_net_sink_get_lcdmem(g_lcdmem_data + 4, UI_MEMSIZE) == 0) {
|
||||
/* 应答数据段 = [偏移u32(回填请求原值)] + [1bpp 位图 3200B] */
|
||||
memcpy(g_lcdmem_data, data, 4);
|
||||
remo_send(CMD_LCDMEM, g_lcdmem_data, (uint16_t)(4 + UI_MEMSIZE));
|
||||
}
|
||||
@@ -205,6 +236,7 @@ static void remo_handle(const uint8_t *f, int n)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* 未知命令码:静默丢弃,保持连接等待后续帧 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -374,7 +406,7 @@ int ui_net_sink_start(uint16_t port)
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:ui_net_sink_start() 已成功调用
|
||||
* 函数说明:1. 网络代次变化(重建)时关闭旧监听/客户端并重建
|
||||
* 函数说明: 1. 网络代次变化(重建)时关闭旧监听/客户端并重建
|
||||
* 2. 无监听(启动失败)时重试启动
|
||||
* 3. 无客户端时尝试 accept,成功则复位状态机
|
||||
* 4. 有客户端时非阻塞 recv 逐字节喂入状态机
|
||||
|
||||
Reference in New Issue
Block a user