LoRaWAN GW NS代码

花了两天时间,根据 Semtech 公司的报文转发网关文档,我基于Twisted完成了相关原型开发,主要是用于之后的设备模拟设备交叉测试服务器压力测试,同时绘制了一下相关有限状态机。

FSM

Packet ID Enum Direction Header MAC Token Payload
PUSH_DATA 0 G>>S 12 Yes G(X) stat/rxpk[]
PUSH_ACK 1 G< 4 N/A S(X) N/A
PULL_DATA 2 G>>S 12 Yes G(Y) N/A
PULL_ACK 4 G< 4 N/A S(Y) N/A
PULL_RESP 3 G< 4 N/A S(Z) txpk
TX_ACK 5 G>>S 4 N/A G(Z) N/A

表1: LoRaWAN 协议有限状态机

RF->>GW: New Packet Received
GW->>NS: PUSH_DATA
NS->>GW: PUSH_ACK
NS->>DB: Packet Stored
GW->>NS: PULL_DATA
NS->>GW: PULL_ACK
DB->>NS: Packet Loaded
NS->>GW: PULL_RESP
GW->>NS: TX_ACK
GW->>RF: Packet Transmitted

图1: LoRaWAN流程

文档分析

在这个网络模型中,有两个角色:

  • GW即网关;
  • NS即网关服务器。

NS基本上可以投入实用,对接数据库和缓存即可。而目前的GW仅仅够做压测,另外一个MicroPython移植版本还在开发中。

相比NS,GW的开发需要增加多线程编程。在原始的MicroPython设计中,有以下线程:

  • UDP push data / pull data 的定时器线程,需要反复执行,其中push data对于服务器是异步事件,而pull data需要网关定时打开接受通道接受服务器下发;
  • RX/TX/Timeout 事件的ISR 回调函数,来自D0/D1和对应超时定时器;
  • LoRa Downlink 定时器线程,用于下发窗口空口通讯。

在多通道网关设计中,需要对多线程设计仔细规划,尤其在使用Python/Node.js这种多线程设计有缺陷的语言。相比之下,C++/Java/Lua之类的更加成熟。有必要拆解成为双通道网关,而每个双通道守护程序需要作为单独线程存在。

要淡化定制协议的存在

即便是IBM这种高大上的IT专业公司,和Semtech开发出来的这个协议,依然让我失望。这种协议的缺陷在于:

  • 二进制和ASCII JSON混合在一起;
  • 缺乏传输层安全,确切说安全是在应用层实现的;
  • 收发状态机有限,扩展困难;
  • 报文下发比较困难,尤其是GW在NAT之后时,需要GW定时发送Pull_data请求打开UDP接收端口。

虽说LoRaWANPktFwd协议在NS一侧设计比较简单,现在越来越多的LoRaWAN设计开始直接使用MQTT/TLS(也是IBM十年期的设计,但是通用性较强),并直接使用JSON作为序列化标准。即便是ESP8266这种SoC中也有足够资源来支持这些标准。一收一发,简单有效,扩展容易。

所以,在TTN接入协议中,LoRaWANPktFwd是作为Legacy(历史遗留)协议接入的。

你可能感兴趣的:(LoRaWAN GW NS代码)