Unleashed 固件 SubGHz 计数器实验模式(CounterMode)完全指南:协议支持、.sub 配置与源码原理
2026/9/13 16:35:52 网站建设 项目流程

Unleashed 固件 SubGHz 计数器实验模式(CounterMode)完全指南:协议支持、.sub 配置与源码原理

【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware

导读

SubGHz Counter Experimental Mode 是 Unleashed 固件为 Flipper Zero 提供的一项高级实验特性,它允许你自定义 SubGHz 滚动码信号发射时计数器的递增方式。其核心目标是:让克隆的遥控器与原装遥控器在滚动码(rolling code)系统中同时使用而不互相冲突、不失步(desync)——不同品牌的接收器对计数器序列的校验规则不同,通过切换不同的 CounterMode,可以让 Flipper 发送的计数器序列与特定接收器型号的预期行为对齐。读完本文,你将掌握如何手工编辑.sub文件启用 CounterMode、五个支持协议的完整模式对照表(含源码级验证),以及模式选择背后的实现原理与风险边界。

⚠️重要警告(原文保留)不要对你没有访问权限的设备做实验。如果你不确定哪种模式适合你的系统、且无法对接收器重新编程,不要使用这些模式!如果你有接收器访问权限并能进行测试,可以在这些模式中尝试并到 GitHub issues 或社区反馈结果。


一、什么是 CounterMode:实验模式的设计动机

滚动码(rolling code)协议每次按键都会改变发射数据中的计数器(counter)字段,接收器只接受"预期范围内的下一个计数值",以此防止重放攻击。Flipper 克隆了信号后,如果每次发送都简单地把计数器 +1,当原装遥控器也同时被使用时,两边会互相"抢占"计数器序列,导致接收器判定失步(desync),最终双方都失效。

Experimental Counter Mode 的思路是:改变 Flipper 发送时计数器的步进序列(sequence pattern),使其与特定接收器固件/型号实际校验的序列保持一致,从而让 Flipper 与原装遥控器可以在同一套滚动码系统里"井水不犯河水"地共存。

从源码看,这是纯粹在编码器(encoder)侧实现的特性:lib/subghz/protocols/下每个支持该特性的协议文件中,都有一个静态全局变量保存当前模式,例如nice_flors_counter_mode(nice_flor_s.c)、keeloq_counter_mode(keeloq.c)、came_atomo_counter_mode(came_atomo.c)、alutech_at4n_counter_mode(alutech_at_4n.c)、v2_phoenix_counter_mode(phoenix_v2.c)。该变量在反序列化.sub文件时通过flipper_format_read_uint32(flipper_format, "CounterMode", ...)读取(缺失时置 0),随后在生成发射波形时决定计数器如何递增。


二、如何启用 CounterMode:手工编辑 .sub 文件

启用某个计数器模式,需要手工编辑你的.sub文件并添加一行CounterMode配置。

操作步骤

  1. 在 Flipper Zero 的 SD 卡上找到你的.sub文件(位于/ext/subghz/目录);
  2. 用文本编辑器打开该文件;
  3. 在文件末尾添加如下一行:
CounterMode: X

其中X是模式编号(0、1、2……),具体取值范围取决于协议,详见下文模式对照表。

完整示例 .sub 文件

Filetype: Flipper SubGhz Key File Version: 1 Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: Nice FloR-S Bit: 52 Key: AA AA AA AA AA AA AA CounterMode: 1

源码层面的读取逻辑

在固件源码中,这一行的解析路径是:编码器/解码器的*_deserialize()函数调用flipper_format_read_uint32()读取CounterMode,读取失败则回退到模式 0(标准模式)。以 KeeLoq 为例(keeloq.c):

uint32_t tmp_counter_mode; if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) { keeloq_counter_mode = (uint8_t)tmp_counter_mode; } else { keeloq_counter_mode = 0; }

因此语法上要求CounterMode:后紧跟空格再写数字,且模式号必须在该协议支持范围内。如果你使用无效的模式号,根据 SubGHzCounterMode.md 的 FAQ,最后一个模式会被采用——从源码看,这正是各协议if/else链末端兜底分支的行为(例如 KeeLoq 中keeloq_counter_mode == 7之外的任何值都会落入else的 Mode 7 分支)。


三、无需手动编辑文件:Signal Settings 菜单中的 CounterMode 选项

除了手工编辑.sub,固件还在 SubGHz 应用的信号设置场景中提供了图形化配置入口。场景代码 subghz_scene_signal_settings.c 中定义了 8 个可选项("System" 即模式 0,以及 Mode 1~Mode 7),并根据协议动态限制可选数量:

协议名(源码中的字符串)可用模式数
Nice FloR-S3(模式 0~2)
CAME Atomo4(模式 0~3)
Alutech AT-4N3(模式 0~2)
KeeLoq8(模式 0~7)
Phoenix_V23(模式 0~2)

该场景通过flipper_format_insert_or_update_uint32()把所选模式写回.sub文件;如果文件中的协议不在上表内,该项会被锁定并提示 "Not available for this protocol"(对应源码中counter_mode == 0xff的状态)。


四、支持协议与计数器模式对照表(附源码验证)

以下所有模式均已在对应协议源码的计数器递增逻辑中逐一确认。五种协议的模式 0(默认)行为完全一致:

模式 0(默认 / 标准模式)

  • 行为与普通遥控器一致;
  • 使用全局设置中的滚动计数器乘数(rolling counter multiplier,默认 +1)递增;
  • 计数器溢出(> 0xFFFF)时归零重置。

该乘数由 HAL 层维护:furi_hal_subghz.crolling_counter_mult默认值为 1,furi_hal_subghz_get_rolling_counter_mult()返回当前值(furi_hal_subghz.c)。标准模式下的递增逻辑形如(以 Nice Flor-S 为例,nice_flor_s.c):

if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); }

此外,五种协议还共享一个隐藏分支:当全局滚动计数器乘数被设置为-0x7FFFFFFF(即 OFEX / overflow experimental 溢出实验模式)时,模式 0 会退化为0x0001 / 0xFFFE交替序列。


1. Nice Flor-S(源码:lib/subghz/protocols/nice_flor_s.c)

模式计数器序列适用场景
0(默认)标准递增(+乘数),溢出归零普通遥控器模拟
1(floxi2r)0x0001 / 0xFFFE交替适用于 floxi2r 型号接收器
2(ox2)0x0000 / 0x0001交替适用于 ox2 型号接收器

源码实现位于 nice_flor_s.c:Mode 1 在计数器为0xFFFE时置回0x0001,否则强制置为0xFFFE;Mode 2 在计数器 ≥ 1 时归零,否则 +1。

2. Came Atomo(源码:lib/subghz/protocols/came_atomo.c)

模式计数器序列适用场景
0(默认)标准递增(+乘数),溢出归零普通遥控器模拟
10x0000 / 0x0001 / 0xFFFE / 0xFFFF循环兼容外置 CAME RE432 接收器,可能兼容其他接收器
20x807B / 0x807C / 0x007B / 0x007C循环兼容外置 CAME RE432 接收器,可能兼容其他接收器
3计数器冻结(不递增)固定计数值发送

源码实现位于 came_atomo.c。需要说明的是,CAME Atomo 的发射报文里还包含一个独立的"按键按住周期计数器"(8-bit,0~0x7F),这与我们讨论的 16-bit 滚动计数器是两回事,详见源码注释 came_atomo.c。

3. Alutech AT-4N(源码:lib/subghz/protocols/alutech_at_4n.c)

模式计数器序列适用场景
0(默认)标准递增(+乘数),溢出归零普通遥控器模拟
10x0000 / 0x0001 / 0xFFFE / 0xFFFF循环适用于 MCSW-3.3M 接收器
20x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004 / 0x0005循环适用于其他接收器板

源码实现位于 alutech_at_4n.c:Mode 2 在计数器 ≥ 0x0005 时归零,否则 +1,实现 0~5 循环。

4. KeeLoq(源码:lib/subghz/protocols/keeloq.c)

模式计数器序列适用场景
0(默认)标准递增(+乘数),溢出归零普通遥控器模拟
10x0000 / 0x0001 / 0xFFFE / 0xFFFF循环可能兼容某些系统(欢迎反馈)
2增量模式:每次发射 +0x3333(十进制 13107),溢出归零可能兼容 Doorhan,常见于某些"万能遥控器"
30x8006 / 0x8007 / 0x0006 / 0x0007循环可能兼容 Hormann EcoStar 等系统
40x807B / 0x807C / 0x007B / 0x007C循环可能兼容 Nice Smilo 等系统
50x0000 / 0xFFFF交替(在 0 与最大值 65535 之间跳变)可能兼容某些系统(欢迎反馈)
6计数器冻结(不递增)固定计数值发送
7对当前计数器连续做 5 次 +0x3333,然后恢复原值依次 +1 两次,一包共 7 条信号可能兼容 Doorhan,常见于某些"万能遥控器"

KeeLoq 的 Mode 2 实现位于 keeloq.c:(cnt + 0x3333) > 0xFFFF时归零,否则cnt += 0x3333。Mode 7 则是一个多信号序列:在 keeloq.c 中可以看到,它循环 7 次生成上传序列——前 4 次以计数器 +0x3333 递增(counter_up = true),第 3 次固定为0x0000,最后两次分别用原计数器和原计数器 +1 各发射一帧。

文档特别提示:Mode 7 下在 Flipper 上单击一次 Send 按钮即可发射整包 7 条信号,可能绕过接收器的计数器校验窗口,请等待完整传输结束

5. V2 Phoenix(Phox)(源码:lib/subghz/protocols/phoenix_v2.c)

模式计数器序列适用场景
0(默认)标准递增(+乘数),溢出归零普通遥控器模拟
1(类 ofex)0x0000 / 0x0001 / 0xFFFE / 0xFFFF循环已验证可用
2(0~4)0x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004循环可能可用(欢迎反馈)

源码实现位于 phoenix_v2.c:Mode 1 与 OFEX 序列一致;Mode 2 在计数器 ≥ 0x0004 时归零,否则 +1。与 KeeLoq 类似,Phoenix V2 的计数器在写入波形前还会经过subghz_protocol_phoenix_v2_encrypt_counter()加密处理。


五、重要注意事项与故障排查

关键考量

  1. 默认行为:如果.sub文件中未指定CounterMode,固件默认使用普通遥控器模拟(计数器 +1),这是标准模式,在大多数场景下都能正常工作;
  2. 协议兼容性:并非所有协议都支持所有计数器模式。使用不支持的编号可能导致意外行为(如落入最后一个模式的兜底分支);
  3. 务必先测试:在依赖某个配置之前,始终先验证其行为。

故障排查

如果你的文件在添加CounterMode后不工作:

  1. 复查语法:CounterMode: X(冒号后必须有空格);
  2. 确认该模式编号对当前协议是有效的(对照上文模式表)。

安全与合规边界

  • 根据原文档 FAQ:该功能可能会损坏你的遥控器或接收器——取决于接收器实现,它可能导致你的原装遥控器失步;不要对你没有访问权限的设备做实验;
  • 不确定该用哪个模式时,不要使用这些模式
  • CounterMode不是必须逐文件添加的:只有需要非默认行为时才需要加,未指定时自动使用模式 0(SubGHzCounterMode.md)。

一个值得注意的源码细节:bypass 机制

在所有五个协议实现中,都存在一个bypass标志:当你在 Signal Settings 菜单中通过界面直接修改了 Counter 或 Button 时,固件会置位bypass,从而跳过 CounterMode 序列逻辑,按你手动指定的计数值直接生成信号(例如 nice_flor_s.c 注释:"if we change counter/button in SignalSettings menu then we must bypass counter_modes, just gen and save signal file")。这意味着界面手动改计数与 CounterMode 序列是互斥的两条路径,理解这一点有助于解释"为什么我改了计数但 CounterMode 好像没生效"。


六、完整配置示例

示例 1:Nice Flor-S 使用模式 1(floxi2r)

Filetype: Flipper SubGhz Key File Version: 1 Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: Nice FloR-S Bit: 52 Key: 01 23 45 67 89 AB CD CounterMode: 1

示例 2:KeeLoq 使用模式 2(+0x3333,Doorhan)

Filetype: Flipper SubGhz Key File Version: 1 Frequency: 433920000 Preset: FuriHalSubGhzPresetOok650Async Protocol: KeeLoq Bit: 64 Key: DE AD BE EF CA FE BA BE Manufacture: Doorhan CounterMode: 2

提示:KeeLoq 协议的.sub文件通常还包含Manufacture(厂商)字段,编码器会根据厂商名选择不同的学习方式与加密密钥(keeloq.c),CounterMode 与该字段相互独立、可组合使用。


七、FAQ 速查

Q: 这会损坏我的遥控器或接收器吗?A: 可能会。取决于接收器实现,它可能导致你的遥控器失步。请注意风险,不要对你没有访问权限的设备做实验。

Q: 我应该用哪个模式?A: 如果你不确定,就不要使用这些模式。

Q: 如果我用了无效的模式编号会怎样?A: 会采用列表中的最后一个模式(源码中即if/else链的兜底分支)。

Q: 我需要给每个 .sub 文件都加 CounterMode 吗?A: 不需要。只有需要非默认行为时才加;未指定时自动使用模式 0。


本文基于 Unleashed 固件仓库中的 SubGHzCounterMode.md 撰写,并结合 lib/subghz/protocols/ 下五个协议的编码器实现、furi_hal_subghz.c 的全局计数器乘数实现以及 subghz_scene_signal_settings.c 的界面配置逻辑进行了源码级验证。引用时请注明出处。

【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询