所有无线协议都可以经常使用廉价的电池供电发射器进行干扰。该协议甚至不必像红外线 (IR) 那样基于射频 (RF),并且任何其他通过空气传播的通信介质都可能因在与协议相同的频谱中发出噪声而受到干扰。想象一个繁忙的街角,你和朋友正在交谈,一辆警笛声响起的救火车经过。你的谈话停止了,因为你的朋友根本听不到你的声音。同样的事情也可能发生在 Z-Wave 中,“坏演员”携带一个小型电池供电的发射器并在 Z-Wave 使用的相同频段内发射射频。在这篇文章中,我将解释如何干扰 Z-Wave,以及如何检测并通知用户发生了干扰。
安全系统要求
干扰主要应用于安全系统。毕竟,如果有人想阻止你的房子在晚上打开厨房的灯,除了当你把膝盖撞到桌子上时笑还有什么意义呢?Z-Wave 在安防系统市场上取得了巨大的成功。Z-Wave 是可互操作的、易于使用的、低功耗的,并且网状网络协议意味着用户或安装人员不必担心让所有内容与其他所有内容进行通信,因为该协议会自动处理(大部分)所有内容。然而,安全系统非常担心干扰,以至于 Underwriters Laboratory 对其有规范。UL1023是美国安全家用防盗报警系统标准。
安全系统的实际情况是,窃贼不太可能试图通过干扰您的安全系统来绕过它。窃贼根本不是那么精通技术。联邦调查局甚至不通过干扰来跟踪入室盗窃的数量——人们会假设,因为数量基本上为零。窃贼会简单地敲打窗户或门,或者更常见的是简单地走进未上锁的门。但是,如果它足够简单且足够便宜,窃贼可能会尝试!CNET展示了使用 3 美元的发射器绕过使用廉价射频发射器的流行安全系统是多么容易。不管实际情况如何,拥有一个容易堵塞的安全系统的坏消息可能会让一家公司陷入困境。
Z-Wave 中的抗干扰技术
Z-Wave 从一开始就设计为坚固可靠。稳健性的第一个要求是确认接收消息的设备确实收到了它。每个 Z-Wave 消息都会被确认 (ACK),否则发送者将使用不同的网状路由或其他 RF 频率再次尝试。多次重试后,协议将放弃,然后应用程序可以决定是否要尝试更多方式来传递消息。如果消息不是很重要(如电池电量报告),应用程序可以直接删除它。如果传感器检测到烟雾!然后应用程序将继续尝试尽可能长时间地通过各种可能的方式获取此生命安全信息。
Z-Wave 需要双向通信——所有消息都得到确认
以下是 Z-Wave 用于可靠传递消息的技术列表:
-
Z-Wave
-
所有帧均已确认
-
多个网状路由
-
跳频 – 两个频率 – 3 种不同的波特率(美国)
-
RSSI 测量表明干扰
-
监督 CC 确认解密和数据完整性
-
-
Z-Wave 远程
-
监督 CC 确认解密和数据完整性
-
所有帧均已确认
-
动态发射功率
-
跳频到备用频道
-
RSSI 测量表明干扰
-
即使采取了所有这些不同的措施,仍然有可能干扰 Z-Wave。但它并不便宜,也不容易。但是,让我们尝试一下吧!
干扰 Z-Wave
Jamming Z-Wave 从 Silicon Labs Z-Wave 开发人员套件和 Simplicity Studio 开始。然而,这些工具包并不便宜,至少要花 150 美元买一个。可能会找到便宜的 900MHz 发射器,但您需要其中两个,并且它们必须能够将它们调谐到美国的 908.4MHz 和 916MHz的特定Z-Wave 频率。这些不会是 3 美元的电池供电发射器,它们需要大量的技术知识。既不便宜也不容易,所以我认为我们对你典型的窃贼很安全。
Z-Wave 在美国使用两个频道(频率):908.4MH 用于 9.6 和 40Kbps,916MHz 用于 100Kbps。Z-Wave Long Range (ZWLR) 也有两个通道,但使用扩频编码,将信号扩展到以 912MHz 和 920MHz 为中心的频带上。通过使用两个通道,Z-Wave 具有频率敏捷性,这使得干扰更加困难,因为您需要两个发射器而不是一个。下面的频谱分析仪图显示了四个 DevKit 一次对所有 4 个通道进行爆破。
Z-Wave 干扰所有四个频率 - 912 和 920 是 Z-Wave 长距离
创建干扰器固件使用 Simplicity Studio V5 中的 RailTest 实用程序。在 Debug Adapters 窗口中选择 DevKit,单击 Example Projects & Demos 选项卡,然后选中 Proprietary 按钮。唯一的示例项目应该是“Flex (RAIL) – RAILtest application”。单击创建并使用默认值。默认频率将声明为 868,但忽略这一点,因为 Z-Wave 模式都内置在 RailTest 中,不需要配置。创建项目后,单击 Build,然后下载到 devkit。右键单击“调试适配器”窗口中的 devkit,然后单击“启动控制台”。单击 Serial 1 选项卡,然后单击底部的命令框并按 ENTER。您应该得到 > 的RailTest提示。
Once you're at the RailTest prompt, enter the following commands:
rx 0 -- disables the radio which must be done before changing the configuration
setzwavemode 1 3 -- Puts the radio into Z-Wave mode
setpower 24 raw -- 24=0dbm radio transmit power - valid range is 1 to 155 but is non-linear
setchannel 0 -- ch0=916 ch1=908.4 ch2=908.42 - ZWLR ch0=912 ch1=920
setzwaveregion 1 -- EU=0, 1=US, 13=US Long Range
Do one of the following 2 commands:
SetTxTone 1 -- narrow band Carrier Wave - unmodulated
SetTxStream 1 -- Pseudo-Random data - modulated and in ZWLR uses Spread Spectrum (DSSS)
Use the same command with a 0 to turn the radio off
Remember to "rx 0" before changing any other configuration values
RAILtest 是一个强大的实用程序,除了 Z-Wave 之外,它还可以做各种事情。Silicon Labs 芯片中的无线电是软件定义无线电,它们可以定制到许多常见的频段。很容易创建定制版本的 RAILtest,它可以在几乎任何频段传输载波 (CW) 或调制信号,而不仅仅是 Z-Wave。但这比我有时间在这里讨论的要复杂。
既然我们知道了如何干扰,我们如何检测它并通知用户干扰正在发生?检测干扰发生在 Z-Wave 网络的两端,即控制器和终端设备。让我们首先看看终端设备,它在安全系统中通常是运动传感器或门/窗传感器。
终端设备干扰检测
大多数终端设备都是电池供电的,因此它们大部分时间都在睡觉,完全不知道可能发生的任何射频干扰。只有当检测到运动或门打开时,传感器才会唤醒并发现无线电波被干扰。检查射频干扰的最佳方法是首先尝试发送消息。当消息未能被确认时,开始查看是否发生干扰。
Z-Wave 应用程序框架 (ZAF) 处理发送消息并最终调用回调来报告状态。回调来自 EventHandlerZwCommandStatus(),它将在发送消息几秒钟后被调用。该协议会尝试各种网状路由、功率级别和波特率,这需要时间,因此请确保保持足够长的时间以接收回调。回调返回 TxStatus 变量,该变量通常为 TRANSMIT_COMPLETE_OK (0x00),表示消息已传递。但是,如果发生干扰并且无线电无法通过它,您将获得 TRANSMIT_COMPLETE_FAIL (0x02)。此状态与 TRANSMIT_COMPLETE_NO_ACK (0x01) 不同,这意味着消息未得到确认,这通常是因为目的地离线,但也可能是由于干扰。
下一步是通过对 EZWAVECOMMANDTYPE_GET_BACKGROUND_RSSI 事件进行排队来获取当前接收信号强度指示器 (RSSI) 级别来验证干扰是否正在发生。RSSI 是无线电接收器在未主动接收帧时信号强度的一个简单值,以 dB 为单位。在正常操作中,这个值应该在 -100dB 左右。每个环境都是不同的,因此被干扰的无线电的阈值需要是一个明显高于平均值的值。这在像公寓这样的密集住宅中尤其困难,因为可能每个单元都有 Z-Wave 网络。这导致相对较高的 RSSI 平均值。这里的关键是你不能使用简单的硬编码阈值来进行基于 RSSI 的干扰检测。相反,您必须在较长的时间跨度(通常是几小时)内平均 RSSI 值。
Z-Wave 干扰通知
检测到干扰发生后的下一步是通知集线器。但是,如果干扰仍在进行中,通知如何通过?当干扰仍在发生时,您自然无法通过。诀窍是不断尝试并希望干扰是短期的。问题是电池供电的传感器无法不断尝试,因为它可能会在几分钟内耗尽电池电量。您必须管理电池电量,同时不断尝试,尝试之间的超时时间越来越长。在某个时候,干扰应该结束,也许在最初的闯入后几个小时,但干扰器最终会耗尽电池电量。
Z-Wave 通知命令类具有 RF 干扰的预定义值 - 家庭安全通知类型 (0x07) 以及 RF 干扰事件 (0x0C) 和当前平均 RSSI 级别。这个通知是一个关键通知,所以它应该被包裹在监督命令类中,以保证它已经被控制器传递和理解。
示例代码
下面的代码首先检查 TxStatus,如果不正常,则通过排队 GET_BACKGROUND_RSSI 事件来检查 RSSI 级别。对 RSSI 进行采样后,将再次调用该函数,并通过下面的 GET_BACKGROUND_RSSI 情况进行切换。这部分代码然后将当前 RSSI 级别与背景 RSSI 级别进行比较,如果当前级别高于它,则设置 SendRFJamNotificationPending 全局变量。当一帧能够通过时,将发送未决的射频干扰通知,因为干扰似乎已经结束。这确保集线器被告知存在干扰,因此集线器可以决定是否需要通知用户。算法的基础代码在这里编码:
...
static void EventHandlerZwCommandStatus(void)
...
switch (Status.eStatusType)
...
case EZWAVECOMMANDSTATUS_TX: // callback from attempted message delivery
...
if (pTxStatus->TxStatus != TRANSMIT_COMPLETE_OK) { // failed to deliver - check RSSI
EZwaveCommandType event = EZWAVECOMMANDTYPE_GET_BACKGROUND_RSSI;
QueueNotifyingSendToBack(g_pAppHandles->pZwCommandQueue, &event, 0); // Queue GET_RSSI
} else { // message delivered OK
// more cleanup happens here...
if (SendRfJamNotificationPending) { // Is there a pending Jam Notification?
SendRfJamNotificationPending=false; // Send it!
void * pData = PrepareNotifyJamReport(&zaf_tse_local_actuation);
ZAF_TSE_Trigger((void *)CC_NotifyJam_report_stx, pData, true);
}
}
...
case EZWAVECOMMANDSTATUS_GET_BACKGROUND_RSSI: // only called if failed to deliver a message
if (Status.Content.GetBackgroundRssiStatus.rssi > BackgroundRSSIThreshold) {
// Set a global to send an RF Jamming Notification which will be sent when jamming ends
SendRfJamNotificationPending=true;
SendRfJamNotifRSSI= Status.Content.GetBackgroundRssiStatus.rssi;
}
... // Not shown are application level retries and various other checking
现在我们在终端设备端启用了干扰检测,让我们看看通信的控制器端。
控制器干扰检测
显然,控制器需要做的主要事情是对来自终端设备的干扰通知做出反应。控制器执行的最终操作留给控制器开发人员,但显然应通知最终用户已检测到干扰。但是该通知需要有足够的关于平均 RSSI 噪声水平的信息来限定,以避免错误的干扰检测通知。
如果干扰器在 200 米以上的距离外,RSSI 水平可能不会像控制器测量的那样显着上升。因此,对终端设备的干扰通知做出反应很重要。但是,控制器必须定期轮询 RSSI 水平以确定附近是否发生干扰。问题是它应该多久轮询一次以及何时对 RSSI 水平的突然变化做出反应?除了“它取决于”之外,这个问题没有明确的答案,它取决于许多不同的因素。通常,RSSI 应该每分钟采样几次——也许每 30 秒一次。如果某个值看起来异常高,则可能以更快的速度再采样几次,以确认 RSSI 已经跳跃并且它没有出现故障。与终端设备案例一样,
ZW_GetBackgroundRSSI
SerialAPI 函数 ZW_GetBackgroundRSSI() (0x3B) 将为控制器支持的各种通道返回三个或四个字节的 RSSI 值。此功能可以经常发送到 Z-Wave 控制器,因为它不会导致无线电中的任何延迟。它确实使用 UART 带宽,因此不能过于频繁地调用它,否则它可能会干扰正常的 Z-Wave 流量。轮询功能应以低优先级编码,以便仅在 UART 空闲几秒钟时发送,以避免与 Z-Wave 无线电流量发生冲突。一字节的 RSSI 值编码如下表所示。
ZW_GetBackgroundRSSI() 返回的 RSSI 值:
十六进制 | 十进制 (2S COMP) | 描述 |
---|---|---|
0x80-0xFF | -128 – -1 | 以 dBm 为单位测量的 RSSI |
0x00-0x7C | 0 – 124 | 以 dBm 为单位测量的 RSSI |
0x7D | 125 | RSSI 低于灵敏度,无法测量 |
0x7E | 126 | 无线电饱和,无法测量,因为它太高了 |
0x7F | 127 | RSSI 不可用 |
通常,当电波相当安静时,700 系列 Z-Wave 控制器的测量值约为 -100dBm。在传输期间,当节点在控制器几米范围内时,RSSI 通常约为 -30dBm。
发送状态报告
TxStatusReport 在传输一帧后返回,该帧包括具有各种 RSSI 测量值的多个字段。发送方有一个本底噪声,接收方有一个本底噪声。RSSI 值可以在正常 Z-Wave 流量期间进行监控,无需轮询。最好在发生 Z-Wave 流量时使用这些值,并在 Z-Wave UART 繁忙时暂时暂停轮询。一旦 UART 空闲,恢复 RSSI 轮询。
缺少心跳
干扰的另一个方面是电池供电的设备通常每小时发送一个“心跳”消息,以便控制器确定设备在线并且工作(主要是电池没有耗尽)。控制器应该跟踪自上次电池供电节点签入以来已经过去了多长时间,如果它错过了两个或最多三个心跳,控制器应该通知用户(或安装者)设备是离线,无法交流。如果电池电量已经很低,那么电池可能已经没电了。如果电池没问题,那么设备可能被卡住了。