mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-07-03 18:41:43 +00:00
d320b6511d
* Unify PlatformIO and ESP-IDF around a shared UI/runtime shell
6.6 KiB
6.6 KiB
# Team Chat 协议方案(方案 C,v0.1)
本文件描述“队伍聊天”协议的最小可实施方案,用于承载结构化消息: Text / Location / Command,并与 Team 安全域绑定,支持地图与态势联动。
1. 目标与范围
- 目标:让队伍聊天成为“可解析、可执行”的结构化消息流。
- 覆盖媒体类型:
- Text:普通文本。
- Location:位置分享,可在 Chat/GPS 地图渲染。
- Command:指令类消息,可触发队伍行动提示与地图标注。
- 安全:仅队伍成员可解密,不依赖 Meshtastic 普通聊天频道。
前置条件(v0.2 调整):
- 建队/入队不再通过 LoRa 或 NFC。
- 组队只在 5 米内的近距离场景发生,使用 ESP‑NOW 完成建队与密钥分发。
- LoRa 仅用于队内日常通信(Team Chat/Position/Track),不参与组队流程。
非目标:
- 不替换现有的普通聊天/广播消息。
- 不实现复杂可靠传输(v0.1 先做 best-effort)。
2. 端口与加密
- 新增端口:
TEAM_CHAT_APP = 303(在modules/core_team/include/team/protocol/team_portnum.h中定义)
- 加密方式:
- 复用
TeamEncryptedenvelope(team_wire.h)。 - 从
team_psk派生team_chatkey。 - 建议在
TeamService::setKeysFromPsk()中新增:deriveKey(psk, "team_chat", keys.chat_key)
- 复用
这样可实现“队伍聊天协议层隔离”,非队伍成员无法解密。
3. Payload 结构(v0.1)
3.1 通用头部
使用简洁 TLV 或固定头 + 变长 payload。建议固定头:
struct TeamChatHeader {
uint8_t version; // =1
uint8_t type; // 1=Text 2=Location 3=Command
uint16_t flags; // 预留
uint32_t msg_id; // 本地生成,防重放/去重
uint32_t ts; // 发送时间(unix)
uint32_t from; // 发送者 node_id
};
3.2 Text
struct TeamChatText {
// UTF-8 text bytes
bytes text;
};
3.3 Location
struct TeamChatLocation {
int32_t lat_e7;
int32_t lon_e7;
int16_t alt_m; // optional, 0=unknown
uint16_t acc_m; // optional, 0=unknown
uint32_t ts; // optional, 0=use header.ts
uint8_t source; // 位置语义图标,见下方映射
bytes label; // optional short label
};
source 映射(与当前固件实现一致):
0:None / 普通位置(无语义图标)1:AreaCleared2:BaseCamp3:GoodFind4:Rally5:Sos
3.4 Command
v0.1 仅做最小指令集,不做撤销/过期语义。
enum TeamCommandType : uint8_t {
RallyTo = 1, // 集结到目标点
MoveTo = 2, // 前往目标点
Hold = 3 // 原地待命
};
struct TeamChatCommand {
uint8_t cmd_type;
int32_t lat_e7; // 可选:用于 Rally/Move
int32_t lon_e7;
uint16_t radius_m; // 可选:集合半径
uint8_t priority; // 0=normal 1=high
bytes note; // 可选:简短备注
};
4. 发送与接收流程
4.1 发送
- UI 产生
Text/Location/Command。 - 编码为
TeamChatHeader + payload。 - 通过
TeamService::sendTeamChat():- 使用
keys.chat_key加密封装为TeamEncrypted。 - 通过
TEAM_CHAT_APP发送(mesh_.sendAppData(...))。
- 使用
4.2 接收
TeamService::processIncoming()新增TEAM_CHAT_APP分支:- 解密
TeamEncrypted。 - 解析
TeamChatHeader。 - 触发
TeamChatEvent(新增 EventBus 类型)。
- 解密
- UI 接收到
TeamChatEvent:- 追加到
team_ui_chatlog(新增类型字段)。 - 若是 Location/Command,同步更新地图/GPS 页标注。
- 追加到
5. 与现有代码的改动点
最小改动清单(v0.1):
-
协议与端口
modules/core_team/include/team/protocol/team_portnum.h新增TEAM_CHAT_APP = 303- 新增
team_chat.h/.cpp(编码/解码)
-
密钥派生
TeamKeys增加chat_keyTeamService::setKeysFromPsk()中派生"team_chat"
-
TeamService
- 新增
sendTeamChat(...) processIncoming()处理TEAM_CHAT_APP
- 新增
-
事件总线
sys/event_bus.h新增TeamChatEvent
-
UI / 存储
team_ui_chatlog_append()扩展为结构化消息(type + payload)Contacts/Team聊天页改用 TeamChat 数据源渲染卡片
6. 兼容性与过渡
- 保留现有普通聊天:
- Primary/Secondary 继续用 TEXT_MESSAGE_APP
- Team Chat 作为独立通道:
- 不影响普通聊天历史与通知
- 可以逐步替换 Team 页的会话来源
Location.source兼容建议(PC/上位机):- 若收到未知
source(不在0..5),按普通Location渲染,不得丢弃整条消息 - 继续使用坐标与时间字段,
label存在时可用于展示 - 建议保留原始
source值,便于前向兼容
- 若收到未知
7. v0.1 已确定事项
- ACK/送达:不需要(尽力而为)。
- Command 撤销/过期:不支持。
- 地图交互:收到消息只弹系统通知;弹窗由 Chat 会话中选中地图标注后触发,显示该位置瓦片地图的裁剪图。
- 组队模式 GPS:从 posring.log 渲染队员位置。
8. 版本策略
TeamChatHeader.version= 1- 后续扩展通过
flags或新type兼容
附录 A:ESP‑NOW 建队与入队(v0.2)
目标:减少步骤与不稳定环节,近距离(≤5m)快速建队。
A1. 角色与约束
- 场景:所有人同一房间/范围 ≤5m。
- 介质:ESP‑NOW(2.4GHz),不再使用 LoRa/NFC。
- 结果:成员收到 team_psk + team_id + key_id + epoch,之后用 LoRa 收发 Team 协议。
A2. 简化流程
Leader
- Create Team → 打开 “Pairing (ESP‑NOW)” 窗口(默认 120s)。
- 接收成员 Join 请求(可“Auto‑accept”或手动 Accept)。
- 发送 KeyDist(ESP‑NOW)给新成员。
Member
- Join Team → Nearby Teams(ESP‑NOW 扫描)选择目标。
- 发送 Join 请求并等待 KeyDist。
- 收到 KeyDist 后进入已加入状态。
A3. ESP‑NOW 消息(建议)
PAIR_BEACON { team_id_short, team_id, epoch, key_id, leader_id, expires_at }
PAIR_JOIN { team_id, member_id, member_pub, nonce }
PAIR_ACCEPT { team_id, member_id, ok, nonce }
PAIR_KEY { team_id, key_id, epoch, team_psk_encrypted, nonce }
说明:
team_psk_encrypted可用临时会话密钥(由member_pub+ leader 私钥派生)加密。nonce用于关联请求与防重放。- 所有 ESP‑NOW 包都只在 Pairing 窗口内处理。
A4. 与 Team Chat 的关系
- ESP‑NOW 仅负责“建队/入队/密钥分发”。
- 完成后使用 LoRa 的 Team 协议(TEAM_CHAT / TEAM_POS / TEAM_TRACK / …)。