Arduino LoRaMesh中CMACLib的cmac_generate_subkeys函数无法运行求助
解决LoRa Mesh中CMACLib初始化失败及RHMesh负载传输问题
一、CMACLib初始化失败的排查要点
- 内存冲突排查:RHMesh/RH_RF95初始化会占用片上内存,CMACLib的AES运算也需要缓冲区,大概率是内存溢出导致节点卡死。可以在调用
cmac_generate_subkeys(key)前后用freeMemory()打印剩余内存,观察是否有异常消耗。如果剩余内存低于100字节,建议优化代码(比如减少全局变量、使用动态内存分配)或更换内存更大的MCU。 - 初始化顺序修正:必须先完成RH_RF95/RHMesh的硬件初始化(调用
init()方法并确认返回值为true),再执行CMACLib的子密钥生成。Mesh网络的初始化涉及射频配置、节点地址注册等步骤,硬件未就绪时执行密码运算会触发底层异常。 - 密钥完整性校验:检查传入
cmac_generate_subkeys的密钥长度是否符合AES标准(16字节对应AES-128,24字节AES-192,32字节AES-256)。Mesh环境下变量易被内存覆盖,调用前可以打印密钥的十六进制值,确认没有被意外修改。
二、RHMesh::MeshApplicationMessage结构体详解与负载传输方案
RHMesh的MeshApplicationMessage是上层应用与Mesh网络层交互的核心结构体,源码定义简化后如下:
struct MeshApplicationMessage { uint8_t to; // 目标节点地址(0为广播) uint8_t from; // 当前节点的Mesh地址 uint8_t id; // 消息唯一ID,用于去重 uint8_t flags; // 控制标志位,如RH_MESH_FLAGS_ACK_REQUEST(需ACK) uint8_t len; // 负载数据总长度 uint8_t data[RH_MESH_MAX_MESSAGE_LEN]; // 负载缓冲区,默认最大60字节 };
用它传输带CMAC标签的负载步骤:
- 生成认证负载:先调用
cmac_generate_subkeys生成子密钥,再用CMAC算法计算负载的MACTag,将原始负载与MACTag拼接(比如负载在前,16字节的MACTag在后)。 - 填充结构体:
- 给
to赋值目标节点地址,from设为当前节点的Mesh地址(初始化时通过setThisAddress()设置)。 id用自增整数(比如静态变量static uint8_t msg_id = 0; msg_id++),避免重复消息被处理。flags根据需求设置,比如需要可靠传输就加RH_MESH_FLAGS_ACK_REQUEST。len设为原始负载长度+MACTag长度,注意不能超过RH_MESH_MAX_MESSAGE_LEN,如果负载过长需要分片传输。- 将拼接后的负载数据复制到
data数组中。
- 给
- 发送与解析:
- 发送时调用
sendtoWait(data, len, to),直接传入负载数据和目标地址即可(RHMesh内部会自动封装成MeshApplicationMessage)。 - 接收端收到消息后,先从
MeshApplicationMessage的data中分离出原始负载和MACTag,再用相同的密钥和子密钥重新计算CMAC,与收到的标签对比完成认证。
- 发送时调用
内容的提问来源于stack exchange,提问作者Rain1603
相关产品推荐
相关产品推荐

