├── README.md
├── SUMMARY.md
├── Style.md
├── chapter
├── 1 Introduction.md
├── 10 Uplink frame in Class B mode.md
├── 11 Downlink Ping frame format.md
├── 12 Beacon acquisition and tracking.md
├── 13 Class B Downlink slot timing.md
├── 14 Class B MAC commands.md
├── 15 Beaconing[Class B option].md
├── 16 Class B unicast & multicast downlink channel frequencies.md
├── 17 Class C Continuously listening end-device.md
├── 2 Introduction on LoRaWAN options.md
├── 3 Physical Message Formats.md
├── 4 MAC Message Formats.md
├── 5 MAC Commands.md
├── 6 End-Device Activation.md
├── 7 Retransmissions back-off Activation.md
├── 8 Introduction to Class B.md
├── 9 Principle of synchronous network initiated downlink.md
├── CLASS A - ALL END-DEVICE.md
├── CLASS B - BEACON.md
└── CLASS C – CONTINUOUSLY LISTENING.md
└── img
├── Beacon_timing.png
├── Beacon_timing.vsd
├── beacon-less_temporary_operation.png
├── lorawan_ClassCed_reception_slot_timing.png
├── lorawan_classb_rx_ping_slot_timing.png
├── lorawan_classes.png
└── lorawan_ed_receive_slot_timing.png
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # LoRaWAN-Specification_ZH_CN
3 |
4 | ## 项目介绍
5 |
6 | 这是《LoRaWAN-Specification》的中文译本。
7 |
8 | 《LoRaWAN-Specification》是 LoRa 联盟规范的核心协议,由于国内LoRa从业者数量众多,难免有不少伙伴需要中文译本,所以诞生了这个小项目。
9 |
10 | 项目采用 gitbook 进行编写,地址在 [https://twowinter.gitbooks.io/lorawan-specification_zh_cn/content/](https://twowinter.gitbooks.io/lorawan-specification_zh_cn/content/)。
11 |
12 | 由于这是民间自发的翻译,一些地方翻译可能不够恰当。如果觉得协议的某处比较晦涩,请不要怀疑自己,大概率是翻译的问题。
13 |
14 | 非常欢迎朋友们反馈翻译问题,争取给行业伙伴们提供一份相对可靠的译本。
15 |
16 | ## 如何参与
17 |
18 | 为了保证文档格式和内容的统一,项目目录下有一份陆续更新的[翻译规范](https://github.com/twowinter/LoRaWAN-Specification_ZH_CN/blob/master/Style.md),想要参与进来的童鞋们可做参考。
19 |
20 | ## 项目进展
21 |
22 | LoRaWAN_V1.0.2 的中文版本经过1年半时间断断续续的调整,现已优先发布,可[点此下载](https://github.com/twowinter/LoRaWAN-Specification_ZH_CN/releases)。
23 | LoRaWAN_V1.1 的中文版本正在分支中更新。
24 | 大家可关注[github 仓库地址](https://github.com/twowinter/LoRaWAN-Specification_ZH_CN)。
25 |
26 | 正在更新的记录如下:
27 | - Chapter 1,完善脚标,地区参数文件增加链接。
28 | - Chapter 2,完善少量格式细节。
29 |
30 | ## 贡献者介绍
31 |
32 | - [IoT小能手 twowinter](https://blog.csdn.net/iotisan/)
33 |
34 | - [厦门四信的小伙伴](http://www.four-faith.com/html/procenter/lora/)
35 |
36 | > 厦门四信的几个小伙伴在业余时间对协议的部分内容做了校对,尤其是 kevin 同学贡献了 CLASS B 等主要章节的翻译,在此表示感谢。
37 | >
38 | > 四信是 LoRa 联盟成员,阿里云金牌合作伙伴,CLAA 钻石合作伙伴,一直致力于为行业伙伴提供稳定可靠的 LoRa 模组、终端、网关系列产品,同时还提供消防、电力、水利等多个垂直行业解决方案。
39 |
40 | - [lioneie](https://github.com/lioneie)
41 |
42 | - 其他积极反馈问题或者提交修改的伙伴,如果你愿意,你的信息将会展示在这。
43 |
44 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | * [前言](README.md)
4 |
5 | * [第1章 介绍](chapter/1 Introduction.md)
6 | * [1.1 LoRaWAN Classes](chapter/1 Introduction.md#1.1)
7 | * [1.2 文档约定](chapter/1 Introduction.md#1.2)
8 |
9 | * [第2章 LoRaWAN Classes 类型介绍](chapter/2 Introduction on LoRaWAN options.md)
10 | * [2.1 LoRaWAN Classes](chapter/2 Introduction on LoRaWAN options.md#2.1)
11 | * [2.2 文档范围](chapter/2 Introduction on LoRaWAN options.md#2.2)
12 |
13 | * [CLASS A - ALL END-DEVICE 所有终端](chapter/CLASS A - ALL END-DEVICE.md)
14 |
15 | * [第3章 PHY 帧格式](chapter/3 Physical Message Formats.md)
16 | * [3.1 上行消息](chapter/3 Physical Message Formats.md#3.1)
17 | * [3.2 下行消息](chapter/3 Physical Message Formats.md#3.2)
18 | * [3.3 接收窗口](chapter/3 Physical Message Formats.md#3.3)
19 | * [3.3.1 第一接收窗口的信道,数据速率和启动](chapter/3 Physical Message Formats.md#3.3.1)
20 | * [3.3.2 第二接收窗口的信道,数据速率和启动](chapter/3 Physical Message Formats.md#3.3.2)
21 | * [3.3.3 接收窗口的持续时间](chapter/3 Physical Message Formats.md#3.3.3)
22 | * [3.3.4 接收方在接收窗口期间的处理](chapter/3 Physical Message Formats.md#3.3.4)
23 | * [3.3.5 网络发送消息给终端](chapter/3 Physical Message Formats.md#3.3.5)
24 | * [3.3.6 接收窗口的重要事项](chapter/3 Physical Message Formats.md#3.3.6)
25 |
26 | * [第4章 MAC帧格式](chapter/4 MAC Message Formats.md)
27 | * [4.1 MAC层](chapter/4 MAC Message Formats.md#4.1)
28 | * [4.2 MAC头(MHDR字段)](chapter/4 MAC Message Formats.md#4.2)
29 | * [4.2.1 第一接收窗口的信道,数据速率和启动](chapter/4 MAC Message Formats.md#4.2.1)
30 | * [4.2.2 数据消息的主版本(Major位字段)](chapter/4 MAC Message Formats.md#4.2.2)
31 | * [4.3 MAC载荷(MACPayload)](chapter/4 MAC Message Formats.md#4.3)
32 | * [4.3.1 帧头(FHDR)](chapter/4 MAC Message Formats.md#4.3.1)
33 | * [4.3.2 端口字段(FPort)](chapter/4 MAC Message Formats.md#4.3.2)
34 | * [4.3.3 MAC帧载荷加密(FRMPayload)](chapter/4 MAC Message Formats.md#4.3.3)
35 | * [4.4 消息校验码(MIC)](chapter/4 MAC Message Formats.md#4.4)
36 |
37 | * [第5章 MAC命令](chapter/5 MAC Commands.md)
38 | * [5.1 Link Check 命令 (LinkCheckReq, LinkCheckAns)](chapter/5 MAC Commands.md#5.1)
39 | * [5.2 Link ADR 命令(LinkADRReq, LinkADRAns)](chapter/5 MAC Commands.md#5.2)
40 | * [5.3 终端发射占空比(DutyCycleReq, DutyCycleAns)](chapter/5 MAC Commands.md#5.3)
41 | * [5.4 接收窗口参数(RXParamSetupReq,RXParamSetupAns)](chapter/5 MAC Commands.md#5.4)
42 | * [5.5 终端状态(DevStatusReq, DevStatusAns)](chapter/5 MAC Commands.md#5.5)
43 | * [5.6 信道的创建和修改(NewChannelReq, NewChannelAns, DlChannelReq, DlChannelAns)](chapter/5 MAC Commands.md#5.6)
44 | * [5.7 TX 和 RX 之间的延时设置(RXTimingSetupReq, RXTimingSetupAns)](chapter/5 MAC Commands.md#5.7)
45 | * [5.8 终端发送参数(TxParamSetupReq, TxParamSetupAns)](chapter/5 MAC Commands.md#5.8)
46 |
47 | * [第6章 终端激活](chapter/6 End-Device Activation.md)
48 | * [6.1 终端激活后的数据存储](chapter/6 End-Device Activation.md#6.1)
49 | * [6.2 空中激活 OTAA](chapter/6 End-Device Activation.md#6.2)
50 | * [6.2.1 终端 ID (DevEUI)](chapter/6 End-Device Activation.md#6.2.1)
51 | * [6.2.2 应用密钥(AppKey)](chapter/6 End-Device Activation.md#6.2.2)
52 | * [6.2.3 加网流程](chapter/6 End-Device Activation.md#6.2.3)
53 | * [6.2.4 Join-request 消息](chapter/6 End-Device Activation.md#6.2.4)
54 | * [6.2.5 Join-accept 消息](chapter/6 End-Device Activation.md#6.2.5)
55 | * [6.3 独立激活 ABP](chapter/6 End-Device Activation.md#6.3)
56 |
57 | * [第7章 重传退避](chapter/7 Retransmissions back-off Activation.md)
58 |
59 | * [CLASS B – BEACON 信标](chapter/CLASS B - BEACON.md)
60 |
61 | * [第8章 Class B 介绍](chapter/8 Introduction to Class B.md)
62 |
63 | * [第9章 下行同步网络的原理](chapter/9 Principle of synchronous network initiated downlink.md)
64 |
65 | * [第10章 Class B 模式的上行帧](chapter/10 Uplink frame in Class B mode.md)
66 |
67 | * [第11章 Class B 模式的下行帧(Class B选项)](chapter/11 Downlink Ping frame format.md)
68 |
69 | * [第12章 信标的获得和追踪](chapter/12 Beacon acquisition and tracking.md)
70 |
71 | * [第13章 Class B下行时隙时序](chapter/13 Class B Downlink slot timing.md)
72 | * [13.1 定义](chapter/13 Class B Downlink slot timing.md#13.1)
73 | * [13.2 时隙随机化](chapter/13 Class B Downlink slot timing.md#13.2)
74 |
75 | * [第14章 Class B MAC命令](chapter/14 Class B MAC commands.md)
76 | * [14.1 PingSlotInfoReq MAC命令](chapter/14 Class B MAC commands.md#14.1)
77 | * [14.2 BeaconFreReq MAC命令](chapter/14 Class B MAC commands.md#14.2)
78 | * [14.3 PingSlotChannelReq MAC命令](chapter/14 Class B MAC commands.md#14.3)
79 | * [14.4 BeaconTimingReq MAC命令](chapter/14 Class B MAC commands.md#14.4)
80 | * [14.5 BeaconTimingAns MAC命令](chapter/14 Class B MAC commands.md#14.5)
81 |
82 | * [第15章 信标(Class B选项)](chapter/15 Beaconing[Class B option].md)
83 | * [15.1 信标物理层](chapter/15 Beaconing[Class B option].md#15.1)
84 | * [15.2 信标物理帧格式](chapter/15 Beaconing[Class B option].md#15.2)
85 | * [15.3 信标 GwSpecific 域格式](chapter/15 Beaconing[Class B option].md#15.3)
86 | * [15.4 信标准确的时隙](chapter/15 Beaconing[Class B option].md#15.4)
87 | * [15.5 网络下行链路路由更新要求](chapter/15 Beaconing[Class B option].md#15.5)
88 |
89 | * [第16章 Class B单播/多播下行信道频率](chapter/16 Class B unicast & multicast downlink channel frequencies.md)
90 | * [16.1 欧盟 863-870MHz ISM 频段](chapter/16 Class B unicast & multicast downlink channel frequencies.md#16.1)
91 | * [16.2 美国 902-928MHz ISM 频段](chapter/16 Class B unicast & multicast downlink channel frequencies.md#16.2)
92 |
93 | * [CLASS C - CONTINUOUSLY LISTENING 持续接收](chapter/CLASS C – CONTINUOUSLY LISTENING.md)
94 |
95 | * [第17章 持续接收的终端](chapter/17 Class C Continuously listening end-device.md)
96 | * [17.1 Class C 的第二接收窗口持续时间](chapter/17 Class C Continuously listening end-device.md#17.1)
97 | * [17.2 Class C 对多播下行的处理](chapter/17 Class C Continuously listening end-device.md#17.2)
98 |
99 |
--------------------------------------------------------------------------------
/Style.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 文档格式
4 |
5 | 文档格式主要参考 [中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines)。
6 |
7 | - 中文中混杂英文词语和数字时,需要补充空格。
8 | // 这点没严格执行,有章节更新的话,会逐步完善这一块。
9 | > "本文档描述了 LoRaWAN 网络协议" // 前后都有汉字时在前后补充空格。
10 | > "LoRaWAN 网络通常采用星型拓扑结构" // 句首已经有明显分割,可以不补充空格。
11 | > “终端设备又称为 motes。” // 句末已经有明显分割,可以不补充空格。
12 | > “使用速率自适应(ADR)机制” // 分隔符号出现的周围,已经有明显分割,可以不补充空格。
13 |
14 | - 非协议内容的个人注解插入,使用代码块样式进行引用,和普通文本做区别。
15 |
16 | ```
17 | twowinter注:
18 | 发射占空比定义:发射时长占总时长的比例。按照无线电规定,每个设备不能持续占用信道,通过最大发射占空比来限制终端占用信道的时间。
19 | 例如某终端发送某数据时的发射时长为 1s,当地无线电规定中的最大发射占空比为1%,则该终端需要等候 99s 才能进行下一次的发射。
20 | ```
21 |
22 | -
23 |
24 | ## 术语翻译约定
25 |
26 | maximum transmit duty cycle | 最大发射占空比
27 | dwell time | 空中停留时间
--------------------------------------------------------------------------------
/chapter/1 Introduction.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## **第1章 介绍**
4 |
5 | 本文档描述了 LoRaWAN 网络协议,是针对电池供电的终端设备(不管移动还是固定位置)进行优化的一套网络协议。
6 |
7 | LoRaWAN 网络通常采用星型拓扑结构,其中**网关(gateway)**[^1]转发**终端设备(end-devices)**[^2]和后台**网络服务器(Network Server)**之间的消息。**网关**通过标准 IP 连接来接入**网络服务器**,而**终端**则通过单跳的 LoRa 或者 FSK 来和一个或多个**网关**通讯[^3]。虽然主要传输方式是**终端**上行传输给**网络服务器**,但所有的传输通常都是双向的。
8 |
9 | 终端和网关间的通讯被分散到不同的**信道频点(frequency channels)**和**数据速率(data rates)**上。数据速率的选择需要权衡通信距离和消息时长两个因素,使用不同数据速率的设备互不影响。LoRa 的数据速率范围可以从 0.3kbps 到 50kbps。为了最大程度地延长终端的电池寿命和扩大网络容量,LoRa 网络使用速率自适应(ADR)机制来独立管理每个终端的速率和 RF 输出。
10 |
11 | 每个设备可以在任意可用的信道,任意时间,使用任意数据速率发送数据,只要遵守如下规定:
12 |
13 | - 终端的每次传输都使用伪随机方式来改变信道。频率的多变使得系统具有更强的抗干扰能力。
14 | - 终端要遵守相应频段和本地区的无线电规定中的**最大发射占空比**要求。
15 | - 终端要遵守相应频段和本地区的无线电规定中的**最大发射时长**要求。
16 |
17 | 本文件规定了协议细节,另外的基于区域规则的各种操作参数是在单独的文件([LoRaWAN 区域参数[PARAMS]](https://lora-alliance.org/resource-hub/lorawantm-regional-parameters-v102rb))中进行描述,例如最大发射占空比和每个子频带的停留时间。 此文档分离开来,是的可以在无需修改基本协议规范的情况下,添加新的区域参数。
18 |
19 | ```
20 | twowinter注:
21 | 发射占空比定义:发射时长占总时长的比例。按照无线电规定,每个设备不能持续占用信道,通过最大发射占空比来限制终端占用信道的时间。
22 | 例如某终端发送某数据时的发射时长为 1s,当地无线电规定中的最大发射占空比为 1%,则该终端需要等候 99s 才能进行下一次的发射。
23 | ```
24 |
25 | ### 1.1 LoRaWAN Classes
26 |
27 | 所有的 LoRaWAN 设备都必须至少实现本文档描述的 Class A 功能。另外也可以实现本文档中描述的 Class B 和 Class C 及后续将定义的可选功能。但是在任何情况下,设备都必须兼容 Class A。
28 |
29 | ### 1.2 文档约定
30 |
31 | MAC命令的格式为 ***LinkCheckReq***(粗斜体),位和位域的格式为 **FRMPayload** (粗体),常量的格式为 RECEIVE_DELAY1(非粗非斜体),变量的格式为 *N*(斜体)。
32 |
33 | 在本文档中,
34 |
35 | - 所有多字节字段的字节序均采用小端模式
36 | - EUI 是8字节字段,采用小端模式传输
37 | - 默认情况下,所有 RFU 保留位都设为0
38 |
39 | ---
40 | [^1] 网关也被称作集中器或基站。
41 | [^2] 终端设备又称为 motes。
42 | [^3] 文档中没有描述对中间元素(中继器)的支持,但是对于封装开销的有效负载限制体现在本规范中。中继器要求使用LoRaWAN作为回程机制。
--------------------------------------------------------------------------------
/chapter/10 Uplink frame in Class B mode.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## **第10章 Class B 模式的上行帧**
4 |
5 | Class B 模式的上行帧和 Class A 的基本一样,除了帧头Fctrl字段的RFU位域有所不同。在 Class A 上行帧中这个位没有使用(RFU),而在 Class B 中有使用。
6 |
7 |
8 |
9 | Bit# |
10 | 7 |
11 | 6 |
12 | 5 |
13 | 4 |
14 | [3..0] |
15 |
16 |
17 | FCtrl bits |
18 | ADR |
19 | ADRACKReq |
20 | ACK |
21 | Class B |
22 | FOptsLen |
23 |
24 |
25 |
26 | 上行帧中的 Class B 位域置为1,用于通知network server设备已切换到 Class B 模式,准备好接收下行ping包。
27 |
28 | 下行帧的FPending位域的定义是不变的,仍然和Class A的定义一样,表示server有多个下行帧要下发,设备应当继续接收。
29 |
30 |
--------------------------------------------------------------------------------
/chapter/11 Downlink Ping frame format.md:
--------------------------------------------------------------------------------
1 | ## 第11章 Class B 模式的下行帧(Class B选项)
2 |
3 | ### 11.1 物理层帧格式
4 |
5 | 下行 Ping 帧使用和 Class A 下行帧相同的格式,但可能会采用不同的信道频率规划。
6 |
7 | ### 11.2 单播和多播 MAC消息
8 |
9 | 信息的传播方式可以是“单播”或者“多播”。单播是指将信息传递给一个指定的终端,多播是指将信息传递给多个终端。多播组内的所有终端都必须共享一个相同的多播地址和相关的加密密钥。LoRaWAN Class B 协议中并没有明确规定如何去建立这样的多播组,以及如何安全地分配多播密钥。这必须通过 节点个性化设置 或者 应用层 来实现。
10 |
11 | #### 11.2.1 单播 MAC 消息格式
12 | 单播下行 Ping 帧的 MAC 载荷格式和 Class A 的定义一样。终端的处理也采用相同的方式。同时也采用相同的帧计数,在收到 Class B ping 时隙或者 Class A 应答时隙时都进行递增处理。
13 |
14 | #### 11.2.2 多播 MAC 消息格式
15 |
16 | 多播帧和单播帧大部分都一样,仅有一些区别:
17 |
18 | - 不允许携带 MAC 命令,既不能在 FOpt 字段里,也不能 port 0 时的载荷里携带,因为多播下行不像单播帧那样具备认证鲁棒性。
19 | - **ACK** 和 **ADRACKReq** 位必须为 0。**MType** 字段必须为 “Unconfirmed Data Down”。
20 | - FPending 位表示还有多播数据要传输。如果设置了这个位,将会在下个多播接收时隙里传输数据帧。如果没设置这个位,则不确定下个多播接收时隙是否会传输数据。这个位可以让终端来评估正在冲突的接收时隙的优先级。
21 |
--------------------------------------------------------------------------------
/chapter/12 Beacon acquisition and tracking.md:
--------------------------------------------------------------------------------
1 | ## 第12章 信标的获得和追踪
2 |
3 | 在从 Class A 切换到 Class B 之前,终端必须首先接收一个网络的信标来将它自身的时间基准与网络时间进行校准。
4 |
5 | 一旦处于 Class B 模式,终端必须定期地去搜索并且接收一个网络信标,以消除自身内部基准时间相对于网络时间的任何漂移。
6 |
7 | Class B 模式的设备也许会短暂性地无法接收信标(超出与网关的通信范围,存在干扰,...)在这种情况之下,终端必须考虑它内部时钟可能产生的漂移,逐步地加大信标和ping时隙的接收窗口时间。
8 |
9 | > 例如,一个设备精度为 10ppm 的内部时钟每个信标周期(128s)就会有+/-1.3ms的漂移。
10 |
11 | ### 12.1 最小 beacon-less 操作时间
12 |
13 | 在信标丢失的情况之下,一个终端需要在接收到最后一个信标节点时间开始算起保持2小时的 Class B 操作。这种短暂的没有信标的 Class B 操作就称之为 “beacon-less” 操作。这种情况之下就需要依赖终端自己的时钟来保持时间。
14 |
15 | 在 “beacon-less” 的情况下,单播、多播还有信标接收时隙都必须逐步地扩大接收窗口时间以容纳终端可能的时钟漂移。
16 |
17 | 
18 |
19 | ### 12.2 beacon-less 接收操作的延长
20 |
21 | 在120分钟的时间间隔之内,一旦终端接收到任何信标,就需要将 Class B 的 “beacon-less” 操作进一步延长120分钟,使得终端可以校正时序漂移以及重置接收时隙持续时间。
22 |
23 | ### 12.3 减少时序漂移
24 |
25 | 终端可以使用信标的准确周期(当信标可用时)去校准他们的初始化时钟,这样可以减少初始化时钟频率的不准确性。由于定时振荡器会表示出可预知的温度漂移,因此使用温度传感器可以尽可能地减小时序漂移。
--------------------------------------------------------------------------------
/chapter/13 Class B Downlink slot timing.md:
--------------------------------------------------------------------------------
1 | ## 第13章 Class B下行时隙时序
2 |
3 | ### 13.1 定义
4 |
5 | 为了使 Class B模式能够正常运行,终端必须以信标规定的精准时刻打开接收时隙窗口。这章节定义了所需的时序操作。
6 |
7 | 两个连续的信标起始点之间的间隔称为信标周期。信标帧的传输以 **BEACON_RESERVED** 时间间隔的起始端对齐。每个信标都有一个保护时间间隔,在该时间间隔之内是没有 ping 时隙的。保护间隔的长度对应于允许帧在空中的最长时间。这样就能保证在保护时间之前的一个 ping 时隙内发起的下行数据帧总是有时间去完成传输而不与信标的传输发生冲突。因此用于ping时隙的时间间隔是从 **BEACON_RESERVED** 时间间隔的末尾节点到下一 **BEACON_GUARD** 时间间隔的起始节点。
8 |
9 | 
10 | 图 12 :信标时序
11 |
12 |
13 |
14 | Beacon_period |
15 | 128 s |
16 |
17 |
18 | Beacon_reserved |
19 | 2.120 s |
20 |
21 |
22 | Beacon_guard |
23 | 3.000 s |
24 |
25 |
26 | Beacon-window |
27 | 122.880 s |
28 |
29 |
30 |
31 | 表 12 :信标时序
32 |
33 |
34 | 信标帧在空中的时间实际上是远小于 **BEACON_RESERVED** 时间间隔的,目的是将来用于添加网络管理广播帧。
35 |
36 | **BEACON_WINDOW** 时间间隔被划分为2^12=4096个小时段,每一段时长为 30ms,所有时段的编号从0~4095。
37 |
38 | 每个使用时隙号**N**的终端必须在 **Beacon start** 开始之后的 **Ton** 秒打开它的接收窗口,**Ton**的计算公式如下:
39 |
40 | Ton = beacon_reserved + N * 30ms
41 |
42 | **N** 称为时隙编号。
43 |
44 | 最后一个 ping 时隙时段(编号为4095)的开始时间是在 beacon start 后的 beacon_reserved + 4095 * 30 ms = 124970ms 或者下一个信标开始前的 3030ms。
45 |
46 | ### 13.2 时隙随机化
47 |
48 | 为了避免系统冲突或者过载问题,所以时隙编号是随机的并且在每个信标周期都会改变。
49 |
50 | 使用以下参数:
51 |
52 |
53 |
54 | DevAddr |
55 | 设备32位网络单播或者多播地址 |
56 |
57 |
58 | pingNb |
59 | 每个信标周期的ping时隙数量。必须为2的整数幂:pingNb = 2^k,1<=k<=7 |
60 |
61 |
62 | pingPeriod |
63 | 设备唤醒接收所间隔的时隙周期,其单位是时隙数量:pingPeriod = 2^12 / pingNb |
64 |
65 |
66 | pingOffset |
67 | 在每个信标周期开始计算的随机偏移。值的范围为0到(pingPeriod-1) |
68 |
69 |
70 | beaconTime |
71 | 这个时间将会在BCNPayload中携带。前一个信标帧的时间 |
72 |
73 |
74 | slotLen |
75 | 一个单元ping时隙长度=30ms(就是前面所说的将ping时隙划分的时间段长度,4096段) |
76 |
77 |
78 |
79 | 在每个信标周期终端和服务器都会计算出一个新的伪随机偏移将接收时隙对齐。使用全零的固定密钥的AES加密去进行随机化:
80 |
81 | Key = 16 x 0x00
82 | Rand = aes128_encrypt(Key,beaconTime | DevAddr | pad16)
83 | pingOffset = (Rand[0] + Rand[1]x256) modulo pingPeriod
84 |
85 | 信标周期所使用的时隙是:
86 |
87 | pingOffset + N x pingPeriod with N = [0:pingNb-1]
88 |
89 | 因此节点打开接收时隙的时间是:
90 |
91 |
92 |
93 | First slot |
94 | Beacon_reserved + pingOffset x slotLen |
95 |
96 |
97 | Slot 2 |
98 | Beacon_reserved + (pingOffset + pingPeriod) x slotLen |
99 |
100 |
101 | Slot 3 |
102 | Beacon_reserved + (pingOffset + 2 x pingPeriod) x slotLen |
103 |
104 |
105 | ... |
106 | ... |
107 |
108 |
109 |
110 | 如果一个终端同时服务于单播和一个或多个多播时隙,则该计算将会在一个新的信标周期开始时执行多次。一次用于单播地址(节点网络地址),一次用于每个多播组地址。
111 |
112 | 当一个多播ping时隙和一个单播ping时隙发生了冲突并且终端接收窗口无法进行处理的情况之下,终端应该优先监听多播时隙的数据。如果多播接收时隙之间发生了冲突,则前一个多播帧的**FPending**位就可以用于设置优先级处理。
113 |
114 | 随机机制可以避免单播和多播时隙的系统冲突。如果在一个信标周期内发生了冲突,则下一个信标周期就不大可能发生。
115 |
--------------------------------------------------------------------------------
/chapter/14 Class B MAC commands.md:
--------------------------------------------------------------------------------
1 | ## 第14章 Class B Mac命令
2 |
3 | 所有在 Class A 协议中描述的命令都应该在 Class B 中实现。Class B 协议还额外添加了如下的 **MAC** 命令。
4 |
5 |
6 |
7 | CID |
8 | Command |
9 | 由谁传输 |
10 | 描述 |
11 |
12 |
13 | 终端 |
14 | 网关 |
15 |
16 |
17 | 0x10 |
18 | PingSlotInfoReq |
19 | x |
20 | |
21 | 终端设备用于将 ping 单播时隙数据速率和周期性传送给网络服务器 |
22 |
23 |
24 | 0x10 |
25 | PingSlotInfoAns |
26 | |
27 | x |
28 | 用于网络应答PingInfoSlotReq命令 |
29 |
30 |
31 | 0x11 |
32 | PingSlotChannelReq |
33 | |
34 | x |
35 | 用于网络服务器设置一个终端的单播 ping 通道 |
36 |
37 |
38 | 0x11 |
39 | PingSlotFreqAns |
40 | x |
41 | |
42 | 终端用于应答PingSlotChannelReq命令 |
43 |
44 |
45 | 0x12 |
46 | BeaconTimingReq |
47 | x |
48 | |
49 | 用于终端向网络请求下一个信标时间和信道 |
50 |
51 |
52 | 0x12 |
53 | BeaconTimingAns |
54 | |
55 | x |
56 | 用于网络应答BeaconTimingReq命令 |
57 |
58 |
59 | 0x13 |
60 | BeaconFreqReq |
61 | |
62 | x |
63 | 用于网络服务器修改终端希望接收信标广播的频率 |
64 |
65 |
66 | 0x13 |
67 | BeaconFreqAns |
68 | x |
69 | |
70 | 用于终端应答BeaconFreqReq命令 |
71 |
72 |
73 |
74 | ### 14.1 PingSlotInfoReq
75 |
76 | 终端可以使用**PingSlotInfoReq**命令来告知服务器它的单播 ping 时隙周期以及期望的数据速率。这个命令只能用于告知服务器单播 ping 时隙的参数。多播 ping 时隙完全由应用程序进行定义而不应该使用此命令设置。
77 |
78 |
79 |
80 | Size(bytes) |
81 | 1 |
82 |
83 |
84 | PingSlotInfoReq Payload |
85 | Periodicity & data rate |
86 |
87 |
88 |
89 |
90 |
91 |
92 | Bit# |
93 | 7 |
94 | [6:4] |
95 | [3:0] |
96 |
97 |
98 | Periodicity & data rate |
99 | RFU |
100 | Periodicity |
101 | Data rate |
102 |
103 |
104 |
105 | **Periodicity**字段是一个无符号3位整数,用于终端当前使用的 ping 时隙周期的编码,编码公式如下:
106 |
107 | pingSlotPeriod = 2^Periodicity(单位是s)
108 |
109 | - Periodicity = 0 表示终端每1s打开一个 ping 时隙。
110 | - Periodicity = 7 表示终端每128s打开一个 ping 时隙,这是 LoRaWAN Class B 协议中所支持的最大 ping 时隙周期。
111 |
112 | **Data rate** 字段表示终端期望收到 ping 时隙的数据率。它使用的编码方式与 Class A 协议中所描述的**LinkAdrReq**命令相同。
113 |
114 | 服务器需要知道终端的 ping 时隙周期或者期望的数据率,否则 Class B 的下行将不会成功。因此终端在 **PingSlotInfoReq** 命令发出之后必须收到 **PingSlotInfoAns** 命令的回复才能从 Class A 切换到 Class B。当终端需要改变 ping 时隙周期以及数据率时,需要先恢复到 Class A 模式,在发送 **PingSlotInfoReq** 命令并且收到服务器端的 **PinSlotInfoAns** 命令回复之后,就可以使用新的参数切换回 Class B模式。**PingSlotInfoReq** 命令可以和 **FHDRFOpt** 字段里的任何 MAC 命令进行连接,如 Class A 协议中的帧格式所述。
115 |
116 | ### 14.2 BeaconFreqReq
117 |
118 | 该命令由服务器发往终端,用于修改终端期望信标的频率。
119 |
120 |
121 |
122 | Octets |
123 | 3 |
124 |
125 |
126 | PingSlotChannelReq Payload |
127 | Frequency |
128 |
129 |
130 |
131 | Frequency字段和Class A协议中定义的 **NewChannelReq** MAC命令有着相同的编码方式。
132 |
133 | **Frequency**是24位的无符号整数。实际的信标信道频率是100 x Frequency,单位Hz。信标的信道以 100Hz 为基本单位,变化范围在 100MHz 到 1.67GHz 之间。终端必须检查该频率是不是射频硬件所允许的范围,不是则需要返回错误。
134 |
135 | 一个有效的非零频率将会强制终端以一个固定的频率信道去监听信标,即使默认是指定跳频信标(即美国ISM频段)。
136 |
137 | 若频率为0则表示终端使用“信标物理层”部分所定义的默认信标频率计划,在适用的情况之下恢复成跳频信标搜索。
138 |
139 | ### 14.3 PingSlotChannnelReq
140 |
141 | 该命令由服务器发往终端,用于修改终端期望下行 ping 的频率。
142 |
143 |
144 |
145 | Octets |
146 | 3 |
147 | 1 |
148 |
149 |
150 | PingSlotChannelReq Payload |
151 | Frequency |
152 | DrRange |
153 |
154 |
155 |
156 | Frequency 字段和Class A协议中定义的 **NewChannelReq** MAC 命令有着相同的编码方式。
157 |
158 | **Frequency**是24位的无符号整数。实际的信标信道频率是100 x Frequency,单位Hz。信标的信道以100Hz为基本单位,变化范围在100MHz到1.67GHz之间。终端必须检查该频率是不是射频硬件所允许的范围,不是则需要返回错误。
159 |
160 | 若频率为0则表示终端使用默认信标频率计划。
161 |
162 | **DrRange**是信道允许的数据率范围。这个字节被等分为两个4位。
163 |
164 |
165 |
166 | Bits |
167 | [7:4] |
168 | [3:0 |
169 |
170 |
171 | DrRange |
172 | Max data rate |
173 | Min data rate |
174 |
175 |
176 |
177 | 按照LoRaWAN地区参数文件[PARAMS]的定义,“Min data rate”字段指定了信道允许的最低数据率。例如0在欧盟物理层中指定DR0/125 kHz。类似的,“Max data rate”指定了最高数据率。例如在欧盟规范中,DrRange = 0x77 意味着在信道上只允许50 kpbs GFSK,DrRange = 0x50意味着支持 DR0/125kHz 到 DR5/125 kHz的数据率。
178 |
179 | 将终端接收到以上的命令之后,需要以**PingSlotFreqAns**命令进行回复。这个MAC命令的载荷包含了以下的信息:
180 |
181 |
182 |
183 | Size(bytes) |
184 | 1 |
185 |
186 |
187 | pingSlotChannelAns Payload |
188 | Status |
189 |
190 |
191 |
192 | **Status**的位段有以下含义:
193 |
194 |
195 |
196 | Bits |
197 | [7:2] |
198 | 1 |
199 | 0 |
200 |
201 |
202 | Statusd |
203 | RFU |
204 | Data rate range ok |
205 | Channel frequency ok |
206 |
207 |
208 |
209 |
210 |
211 | |
212 | Bit = 0 |
213 | Bit = 1 |
214 |
215 |
216 | Data rae range ok |
217 | 设置的数据率超过了该终端当前定义的范围,保持之前的数据率范围 |
218 | 数据率范围与终端兼容 |
219 |
220 |
221 | Channel frequency ok |
222 | 终端无法使用该频率,保持之前的频率 |
223 | 终端可以使用这个频率 |
224 |
225 |
226 |
227 | ### 14.4 BeaconTimingReq
228 |
229 | 终端使用该命令来请求下一个信标的时间以及信道,该MAC命令没有载荷。**BeaconTimingReq** & **BeaconTimingAns**机制仅仅用于加快刚开始的信标搜索以降低终端的能量需求。
230 |
231 | 网络在给定的时间周期内可能只应答有限数量的请求。终端不能期望在发出**BeaconTimingReq**命令之后立刻收到**BeaconTimingAns**命令的应答。想要切换到Class B模式的处于Class A模式的终端一小时之内不应该发送超过一个**BeaconTimingReq**命令。
232 |
233 | 需要快速锁定信标的终端必须实现自主信标查找算法。
234 |
235 | ### 14.5 BeaconTimingAns
236 |
237 | 网络用该命令来应答**BeaconTimingReq**命令的请求。
238 |
239 |
240 |
241 | Size(bytes) |
242 | 2 |
243 | 1 |
244 |
245 |
246 | BeaconInfoReqPayload |
247 | Delay |
248 | Channel |
249 |
250 |
251 |
252 | **"Delay"**字段是一个16位的无符号整数。如果当前下行帧的结束与下一个信标帧的开始之间的剩余时间记为 RTime:
253 |
254 | 30ms x (Delay+1) > RTime >= 30ms x Delay
255 |
256 | 在信标交替使用多个信道的网络中,**“Channel”**字段是下一个信标广播所使用的信道编号。对于信标广播频率固定的网络来说,这个字段值为0。
--------------------------------------------------------------------------------
/chapter/15 Beaconing[Class B option].md:
--------------------------------------------------------------------------------
1 | ## 第15章 信标(Class B选项)
2 |
3 | ### 15.1 信标物理层
4 |
5 | 所有网关除了可以为终端和网络服务器转发消息,还可以通过在可配置的固定时间间隔上发送信标(**BEACON_INTERVAL**)来参与提供一个时间同步机制。所有信标都以无线分组隐式模式进行发送,即没有 LoRa 物理帧头和 CRC 校验。
6 |
7 |
8 |
9 | PHY |
10 | Preamble |
11 | BCNPayload |
12 |
13 |
14 |
15 | 信标的 **Preamble** 开始于(长于默认)10个未调制符号。这允许终端实现低功耗占空比信标搜索。
16 |
17 | 信标的帧长度与无线电物理层紧密耦合。因此实际的帧长度可能从一个区域实现变为另一个区域实现。更改字段在下面的部分以粗体显示。
18 |
19 | #### 15.1.1 欧盟 863-870MHz ISM 频段
20 |
21 | 信标使用下面的设置进行传送:
22 |
23 |
24 |
25 | DR |
26 | 3 |
27 | 对应于125kHz带宽的SF9扩频因子 |
28 |
29 |
30 | CR |
31 | 1 |
32 | 编码率=4/5 |
33 |
34 |
35 | frequency |
36 | 869.525MHz |
37 | 这是推荐的允许+27 dBm EIRP的频率。 |
38 |
39 |
40 |
41 | 只要符合ETSI的要求,网络运营商也可以使用一个不同的频率。
42 |
43 | 信标帧的内容如下:
44 |
45 |
46 |
47 | Size(bytes) |
48 | 3 |
49 | 4 |
50 | 1 |
51 | 7 |
52 | 2 |
53 |
54 |
55 | BCNPayload |
56 | NetID |
57 | Time |
58 | CRC |
59 | GwSpecific |
60 | CRC |
61 |
62 |
63 |
64 | #### 15.1.2 美国 902-928 MHz ISM 频段
65 |
66 | 信标使用下面的设置进行传送:
67 |
68 |
69 |
70 | DR |
71 | 10 |
72 | 对应于500kHz带宽的SF10扩频因子 |
73 |
74 |
75 | CR |
76 | 1 |
77 | 编码率=4/5 |
78 |
79 |
80 | frequency |
81 | 923.3到927.5MHz(以600kHz为单位) |
82 | 信标的传送与Class A规范中定义的下行链路所使用的信道相同。 |
83 |
84 |
85 |
86 | 用于给定的信标所使用的下行链路信道是:
87 |
88 | Channel = [floor(beacon_time/beacon_preiod)] modulo 8
89 |
90 | - beacon_time是信标帧“Time”4字节字段的整数值。
91 |
92 | - beacon_period是信标帧的周期,128s
93 |
94 | - floor(x)意思是四舍五入到临近x的整数。
95 |
96 | > 例子:第一个信标在923.3MHz上进行传送,第二次在932.9MHz,第九次再一次在923.3MHz进行传送。
97 |
98 |
99 |
100 | Beacon channel nb |
101 | Frequency[MHz] |
102 |
103 |
104 | 0 |
105 | 923.3 |
106 |
107 |
108 | 1 |
109 | 923.9 |
110 |
111 |
112 | 2 |
113 | 924.5 |
114 |
115 |
116 | 3 |
117 | 925.1 |
118 |
119 |
120 | 4 |
121 | 925.7 |
122 |
123 |
124 | 5 |
125 | 926.3 |
126 |
127 |
128 | 6 |
129 | 926.9 |
130 |
131 |
132 | 7 |
133 | 927.5 |
134 |
135 |
136 |
137 | 信标帧的内容如下:
138 |
139 |
140 |
141 | Size(bytes) |
142 | 3 |
143 | 4 |
144 | 2 |
145 | 7 |
146 | 1 |
147 | 2 |
148 |
149 |
150 | BCNPayload |
151 | NetID |
152 | Time |
153 | CRC |
154 | GwSpecific |
155 | RFU |
156 | CRC |
157 |
158 |
159 |
160 | ### 15.2 信标帧内容
161 |
162 | 信标帧的**BCNPayload**载荷由一个网络的公共部分和一个网关的特定部分组成。
163 |
164 |
165 |
166 | Size(bytes) |
167 | 3 |
168 | 4 |
169 | 1/2 |
170 | 7 |
171 | 0/1 |
172 | 2 |
173 |
174 |
175 | BCNPayload |
176 | NetID |
177 | Time |
178 | CRC |
179 | GwSpecific |
180 | RFU |
181 | CRC |
182 |
183 |
184 |
185 | 网络的公共部分包含了一个网络的标识符**NetID**,用于唯一标识发送信标的网络还有一个时间戳**Time**(单位为s),这个时间戳是从1970年1月1日的[Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time)(UTC) 00:00:00开始计时的。信标网络的公共部分的完整性由8位或者16位的 CRC 校验码来进行保护,是8位还是16位取决于PHY层参数。CRC-16是在IEEE 802.15.4-2003 7.2.1.8部分所定义的NetID+Time字段上进行计算。当需要8位CRC时计算CRC-16的低8位就会被使用。
186 |
187 | 例如:这是一个有效的 EU868 信标帧:
188 |
189 | AA BB CC| 00 00 02 CC | 7E | 00 | 01 20 00 | 00 81 03 | DE 55
190 |
191 | 字节是从左向右进行传送。相对应字段的值是:
192 |
193 |
194 |
195 | Field |
196 | NetID |
197 | Time |
198 | CRC |
199 | InfoDesc |
200 | lat |
201 | long |
202 | CRC |
203 |
204 |
205 | Value Hex |
206 | CCBBAA |
207 | CC020000 |
208 | 7E |
209 | 0 |
210 | 002001 |
211 | 038100 |
212 | 55DE |
213 |
214 |
215 |
216 | NetID+Time字段的CRC-16校验码是0xC87E,但是在这种情况之下只使用低8位。
217 |
218 | **NetID**的7个最低有效位被称之为**NwkID** ,与终端短地址的7位最高有效位相匹配。相邻的或者重叠的网络必须有不同的**NwkID**。
219 |
220 | 网络的特定部分提供网关发送一个信标的额外信息,因此对于每个网关可能不同。当RFU字段适用时(区域特定)应该等于0。可选择的部分由GwSpecific+RFU字段计算出的CRC-16校验码进行保护。CRC-16的定义与强制部分相同。
221 |
222 | 例如:这是一个有效的 美国900 信标
223 |
224 |
225 |
226 | Field |
227 | NetID |
228 | Time |
229 | CRC |
230 | InfoDesc |
231 | lat |
232 | long |
233 | RFU |
234 | CRC |
235 |
236 |
237 | Value Hex |
238 | CCBBAA |
239 | CC020000 |
240 | C87E |
241 | 0 |
242 | 002001 |
243 | 038100 |
244 | 00 |
245 | D450 |
246 |
247 |
248 |
249 | 在空中,字节以以下顺序进行发送:
250 |
251 | AA BB CC| 00 00 02 CC | 7E C8 | 00 | 01 20 00 | 00 81 03 | 00 | 50 D4
252 |
253 | 监听和同步网络的公共部分足以在Class B模式去操作一个固定的终端。一个移动的终端也应该解调出信标的网关特定部分,以便信标在从一个网络移动到另一个网络时可以通知网络服务器。
254 |
255 | > **注意**:如前所述,所有的网关在同一个时间点(即时间同步)发送他们的信标,因此对于网络公共部分来说,即使一个终端同时从多个网关接收信标,监听的终端也不存在明显的空中冲突。至于网关的特定部分,当冲突发生时,位于多个网关附近的一个终端仍然有能力以高概率去解码最强的信标。
256 |
257 | ### 15.3 信标GwSpecific字段格式
258 |
259 | **GwSpecific**字段的内容如下所述:
260 |
261 |
262 |
263 | Size(bytes) |
264 | 1 |
265 | 6 |
266 |
267 |
268 | GwSpecific |
269 | InfoDesc |
270 | Info |
271 |
272 |
273 |
274 | **InfoDesc**描述符描述了如何解释**Info**字段信息。
275 |
276 |
277 |
278 | InfoDesc |
279 | Meaning |
280 |
281 |
282 | 0 |
283 | 网关第一天线的GPS坐标 |
284 |
285 |
286 | 1 |
287 | 网关第二天线的GPS坐标 |
288 |
289 |
290 | 2 |
291 | 网关第三天线的GPS坐标 |
292 |
293 |
294 | 3:127 |
295 | RFU |
296 |
297 |
298 | 128:255 |
299 | 为自定义网络特定广播预留 |
300 |
301 |
302 | |
303 | |
304 |
305 |
306 |
307 | 对于一个单一的全向天线网关,当广播GPS坐标时**InfoDesc**的值为0。例如,对于一个具有3扇区电线的站点,第一天线广播信标时**InfoDesc**的值为0,第二天线广播信标时**InfoDesc**的值为1,等等...
308 |
309 |
310 | #### 15.3.1 网关GPS坐标:InfoDesc = 0,1或者2
311 |
312 | 对于**InfoDesc**=0,1或者2,**Info**字段所包含的内容编码了天线广播信标的GPS坐标
313 |
314 |
315 |
316 | Size(bytes) |
317 | 3 |
318 | 3 |
319 |
320 |
321 | Info |
322 | Lat |
323 | Lng |
324 |
325 |
326 |
327 | 纬度和经度字段(分别对应于**Lat**和**Lng**)编码了网关的地理位置,如下:
328 |
329 | - 南北纬度使用24位字来进行编码,-2^23对应于南90°(南极点),2^23对应于北90°(北极点)。赤道对应于0。
330 |
331 | - 东西经度使用24位字来进行编码,-2^23对应于西180°,2^23对应于东180°。格林尼治子午线对应于0。
332 |
333 | ### 15.4 信标精确定时
334 |
335 | 信标从[Coordinated Universal Time(UTC)](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) ,1970年1月1日00:00:00 加上 NwkID 加 TBeaconDelay 开始,每128秒发送一次。因此信标是在 Coordinated Universal Time(UTC) 1970年1月1日00:00:00 之后
336 | Bt = k*128 + NwkID + TBeaconDelay
337 | 的时间点进行发送。
338 |
339 | 其中 k 是最小的整数: k*128 + NwkID > T
340 |
341 | 其中 T = 从1970年1月1日的 Coordinated Universal Time(UTC) 00:00:00 以后的秒数。
342 |
343 | > **注意**: T 不是 Unix 时间。类似于 GPS 时间,不像 Unix 时间,T 是严格单调递增的并且不受闰秒的影响。
344 |
345 |
346 | > **KevinCao注**:闰秒,是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中(也可能在季末)对协调世界时增加或减少1秒的调整。由于地球自转的不均匀性和长期变慢性(主要由潮汐摩擦引起的),会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把协调世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒); 闰秒一般加在公历年末或公历六月末。
347 |
348 | 其中**TBeaconDelay**是网络的特定延时,范围在0到50ms之间。**TBeaconDelay**在不同的网络之间可能不同,并且它意味着通信时允许网关有轻微的延时。**TBeaconDelay**对于给定的一个网络中的所有网关必须相同。**TBeaconDelay**必须小于50ms。所有终端的ping时隙使用信标传输时间作为定时基准。因此网络在调度Class B下行时需要将TBeaconDelay时间考虑在内。
349 |
350 | ### 15.5 网络下行路由更新要求
351 |
352 | 当网络使用Class B下行时隙去与终端进行通信时,当网络接收到最后一个上行数据帧之后,它会从最接近终端的一个网关进行下行数据发送。因此网络服务器需要追踪Class B终端的粗略位置。
353 |
354 | 只要一个Class B终端移动并且改变网络,它需要告知服务器以更新下行路由。可以通过发送“confirmed”类型或者“unconfirmed”类型的上行数据帧来完成更新,可能没有应用载荷。
355 |
356 | 终端可以在2个基础策略之间做出选择:
357 |
358 | - 系统周期上行:最简单的方式,不需要对信标的“gateway specific”字段解调。只适用于缓慢移动的或者固定的终端。对于这些周期性上行链路没有要求。
359 |
360 | - 网络改变的上行:终端对信标的“gateway specific”字段进行解调,检测到广播其解调的信标的网关的ID已经改变并且发送上行数据帧。在这种情况之下终端应当遵守信标解调和上行数据帧发送之间0~120s的伪随机延时。这用于确保当信标广播之后,同一个信标周期内进入或者离开网络的多个Class B设备的上行数据帧不会立即系统性地同时发生。
361 |
362 | 无法告知网络改变将会导致 Class B 的下行暂时性地无法运行。网络服务器可能必须等到下一个终端上行才能传输下行。
363 |
--------------------------------------------------------------------------------
/chapter/16 Class B unicast & multicast downlink channel frequencies.md:
--------------------------------------------------------------------------------
1 | ## 第16章 Class B单播/多播下行信道频率
2 |
3 | ### 16.1 欧盟 863-870MHz ISM 频段
4 |
5 | 所有的 Class B 的下行单播和多播都使用由 “**PingSLotChannelReq**” MAC 命令所定义的单频信道。默认的频率是 869.525MHz。
6 |
7 | ### 16.2 美国 902-928MHz ISM 频段
8 |
9 | 默认的,Class B的下行使用最后一个信标(鉴信标帧格式内容)的 **Time** 字段的信道函数和 **DevAddr**。
10 |
11 | Class B downlink channel = [DevAddr + floor(Beacon_Time/Beacon_period)] modulo 8
12 |
13 | - 其中 Beacon_Time 是当前信标周期的 32 位 **Time** 字段。
14 |
15 | - Beacon_period 是信标周期的长度(协议中定义的是128s)
16 |
17 | - Floor 指的是四舍五入到临近的较低整数值。
18 |
19 | - DevAddr 是终端的32位网络地址。
20 |
21 | 因此 Class B 的下行在 ISM 频段的 8 个信道进行跳跃并且所有的 Class B 终端平等地使用 8 个下行信道进行传输。
22 |
23 | 如果带有一个有效的非零参数的 “**PingSlotChannelReq**” 命令被用于设置 Class B 下行频率,则随后所有的 ping 时隙都应该只使用这个频率而不是上一个信标频率。
24 |
25 | 如果发送参数为零的 “**PingSlotChannelReq**” 命令,则终端应该恢复成默认的频率计划,同上所述,Class B ping 时隙在8个信道之间进行跳跃。
26 |
27 | 其基本思想是允许网络运营商在可行的情况之下配置终端使用一个专用的频段用于 Class B 下行,并且当 ISM 频段可用时尽可能地保持频率多样性。
28 |
--------------------------------------------------------------------------------
/chapter/17 Class C Continuously listening end-device.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## **第17章 持续接收的终端**
4 |
5 | 具备Class C 能力的终端,通常应用于供电充足的场景,因此不必精简接收时间。
6 |
7 | Class C 的终端不能执行 Class B 。
8 |
9 | Class C 终端会尽可能地使用 RX2 窗口来监听。按照 Class A 的规定,终端是在 RX1 无数据收发才进行 RX2 接收。为了满足这个规定,终端会在上行发送结束和 RX1 接收窗口开启之间,打开一个短暂的 RX2 窗口,一旦 RX1 接收窗口关闭,终端会立即切换到 RX2 接收状态; RX2 接收窗口会持续打开,除非终端需要发送其他消息。
10 |
11 | > 注意:没有规定节点必须要告诉服务端它是 Class C 节点。这完全取决于服务端的应用程序,它们可以在 join 流程通过协议交互来获知是否是 Class C 节点。
12 |
13 | ### 17.1 Class C 的第二接收窗口持续时间
14 |
15 | Class C 设备执行和 Class A 一样的两个接收窗口,但它们没有关闭 RX2 ,除非他们需要再次发送数据。因此它们几乎可以在任意时间用 RX2 来接收下行消息,包括MAC命令和ACK传输的下行消息。另外在发送结束和 RX1 开启之间还打开了一个短暂的RX2窗口。
16 |
17 | 
18 |
19 | 图13.Class C 终端的接收时隙时序图
20 |
21 | ### 17.2 Class C 对多播下行的处理
22 |
23 | 和 Class B 类似,Class C 设备也可以接收多播下行帧。多播地址和相关的 NWKSKEY 及 APPSKEY 都需要从应用层获取。Class C 多播下行帧也有相同的限制:
24 |
25 | - 不允许携带MAC命令,既不能放在FOpts域中,也不能放在 port 0 的 payload 中,因为多播下行无法像单播帧那样具备相同的鲁棒性。
26 |
27 | - ACK 和 ADRACKReq 位必须要为0。MType 域需要为 Unconfirmed Data Down 类型的数值。
28 |
29 | - FPending 位表明有更多的多播数据要发送。考虑到 Classs C 设备在大部分时间处于接收状态,FPending位不触发终端的任何特殊行为。
30 |
31 |
--------------------------------------------------------------------------------
/chapter/2 Introduction on LoRaWAN options.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## **第2章 LoRaWAN Classes 类型介绍**
5 |
6 | LoRa 是由 Semtech 面向长距离、低功耗、低速率应用而开发的无线调制技术。本文档中,将 Class A 基础上实现了更多功能的设备称为“更高 class 终端”。
7 |
8 | ### 2.1 LoRaWAN Classes
9 |
10 | LoRa网络包含基础 LoRaWAN (称之为 Class A) 和可选功能(Class B,Class C):
11 |
12 | 
13 | 图1.LoRaWAN Classes
14 |
15 | - **双向传输终端(Class A):** Class A 的终端在每次上行后都会紧跟两个短暂的下行接收窗口,以此实现双向传输。终端基于自身通信需求来安排传输时隙,在随机时间的基础上具有较小的变化(即ALOHA协议)。这种Class A 操作为应用提供了最低功耗的终端系统,只要求应用在终端上行传输后的很短时间内进行服务器的下行传输。服务器在其他任何时间进行的下行传输都得等终端的下一次上行。
16 |
17 | - **划定接收时隙的双向传输终端(Class B):** Class B 的终端会有更多的接收时隙。除了Class A 的随机接收窗口,Class B 设备还会在指定时间打开别的接收窗口。为了让终端可以在指定时间打开接收窗口,终端需要从网关接收**时间同步的信标(Beacon)**。这使得服务器可以知道终端何时处于监听状态。
18 |
19 | - **最大化接收时隙的双向传输终端(Class C):** Class C 的终端基本是一直打开着接收窗口,只在发送时短暂关闭。Class C 的终端会比 Class A 和 Class B
20 | 更加耗电,但同时从服务器下发给终端的时延也是最短的。
21 |
22 | ### 2.2 文档范围
23 |
24 | 这份LoRaWAN协议还描述了与 Class A 不同的其他 Class 的额外功能。更高 Class 的终端必须满足 Class A 定义的所有功能。
25 |
26 | > 注意:物理层帧格式,MAC 帧格式,以及协议中更高 class 和 Class A 相同的内容都写在了 Class A 部分,避免内容重复。
27 |
--------------------------------------------------------------------------------
/chapter/3 Physical Message Formats.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## **第3章 PHY 帧格式**
5 |
6 | LoRa 有上行消息和下行消息。
7 |
8 | ### 3.1 上行消息
9 |
10 | 上行消息是由终端发出,经过一个或多个网关转发给网络服务器。
11 |
12 | 上行消息使用 LoRa 射频帧的严格模式,消息中含有 PHDR 和 PHDR_CRC 。载荷有CRC校验来保证完整性。
13 |
14 | PHDR,PHDR_CRC 及载荷 CRC 域都通过射频收发器加入。
15 |
16 | 上行 PHY:
17 |
18 |
19 | Preamble |
20 | PHDR |
21 | PHDR_CRC |
22 | PHYPayload |
23 | CRC |
24 |
25 |
26 |
27 | 图2.上行PHY帧格式
28 |
29 | ### 3.2 下行消息
30 |
31 | 下行消息是由网络服务器发出,经过单个网关转发给单个终端。
32 |
33 | 下行消息使用射频帧的严格模式,消息中包含 PHDR 和 PHDR_CRC。
34 |
35 | 下行 PHY:
36 |
37 |
38 | Preamble |
39 | PHDR |
40 | PHDR_CRC |
41 | PHYPayload |
42 |
43 |
44 |
45 | 图3.下行PHY帧格式
46 |
47 |
48 | ### 3.3 接收窗口
49 |
50 | 每个上行传输后终端都要开两个短的接收窗口。接收窗口开始时间的规定,是以传输结束时间为参考。
51 |
52 | 
53 |
54 | 图4.终端接收时隙的时序图
55 |
56 | #### 3.3.1 第一接收窗口的信道,数据速率和启动
57 |
58 | 第一接收窗口 RX1 使用的频率和上行频率有关,使用的速率和上行速率有关。RX1 是在上行调制结束后的 RECEIVE_DELAY1秒(+/- 20微秒)打开。上行和 RX1 时隙下行速率的关系是按区域规定,详细描述在[LoRaWAN地区参数]文件中。默认第一窗口的速率是和最后一次上行的速率相同。
59 |
60 | #### 3.3.2 第二接收窗口的信道,数据速率和启动
61 |
62 | 第二接收窗口 RX2 使用一个固定可配置的频率和数据速率,在上行调制结束后的 RECEIVE_DELAY2秒(+/- 20微秒)打开。频率和数据速率可以通过 MAC 命令(见 第5章)。默认的频率和速率是按区域规定,详细描述在[LoRaWAN地区参数]文件中。
63 |
64 | #### 3.3.3 接收窗口的持续时间
65 |
66 | 接收窗口的长度至少要让终端射频收发器有足够的时间来检测到下行的前导码。
67 |
68 | #### 3.3.4 接收方在接收窗口期间的处理
69 |
70 | 如果在任何一个接收窗口中检测到前导码,射频收发器需要继续激活,直到整个下行帧都解调完毕。如果在第一接收窗口检测到数据帧,且这个数据帧的地址和MIC校验通过确认是给这个终端,那终端就不必开启第二个接收窗口。
71 |
72 | #### 3.3.5 网络发送消息给终端
73 |
74 | 如果网络想要发一个下行消息给终端,它会精确地在两个接收窗口的起始点发起传输。
75 |
76 | #### 3.3.6 接收窗口的重要事项
77 |
78 | 终端在第一或第二接收窗口中收完下行消息后,或者在第二接收窗口失效之后(第一或第二窗口均未收到下行消息),才能再发起另一个上行消息。
79 |
80 | #### 3.3.7 其他协议的收发处理
81 |
82 | 节点在LoRaWAN收发窗口阶段可以收发其他协议,只要终端能满足当地要求以及兼容LoRaWAN协议。
83 |
84 |
85 |
--------------------------------------------------------------------------------
/chapter/4 MAC Message Formats.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## **第4章 MAC帧格式**
5 |
6 | LoRa所有上下行链路消息都会携带PHY载荷,PHY载荷以1字节MAC头(MHDR)开始,紧接着MAC载荷(MACPayload),最后是4字节的MAC校验码(MIC)。
7 |
8 | 射频PHY层:
9 |
10 |
11 | Preamble |
12 | PHDR |
13 | PHDR_CRC |
14 | PHYPayload |
15 | CRC |
16 |
17 |
18 | 图5.射频PHY结构(注意 CRC只有上行链路消息中存在)
19 |
20 |
21 | PHY载荷:
22 |
23 |
24 | MHDR |
25 | MACPayload |
26 | MIC |
27 |
28 |
29 | 或者
30 |
31 |
32 | MHDR |
33 | Join-Request |
34 | MIC |
35 |
36 |
37 | 或者
38 |
39 |
40 | MHDR |
41 | Join-Response |
42 | MIC |
43 |
44 |
45 | 图6.PHY载荷结构
46 |
47 |
48 | MAC载荷:
49 |
50 |
51 | FHDR |
52 | FPort |
53 | FRMPayload |
54 |
55 |
56 | 图7.MAC载荷结构
57 |
58 |
59 | FHDR:
60 |
61 |
62 | DevAddr |
63 | FCtrl |
64 | FCnt |
65 | FOpts |
66 |
67 |
68 |
69 | 图8.帧头结构
70 |
71 |
72 | 图9.LoRa帧格式元素(即图5~8)
73 |
74 |
75 | ### 4.1 MAC层(PHYPayload)
76 |
77 |
78 | Size (bytes) |
79 | 1 |
80 | 1..M |
81 | 4 |
82 |
83 |
84 | PHYPayload |
85 | MHDR |
86 | MACPayload |
87 | MIC |
88 |
89 |
90 |
91 | MACPayload字段的最大长度M,在第6章有详细说明。
92 |
93 | ### 4.2 MAC头(MHDR字段)
94 |
95 |
96 | Bit# |
97 | 7..5 |
98 | 4..2 |
99 | 1..0 |
100 |
101 |
102 | MHDR bits |
103 | MType |
104 | RFU |
105 | Major |
106 |
107 |
108 |
109 | MAC头中指定了消息类型(MType)和帧编码所遵循的LoRaWAN规范的主版本号(Major)。
110 |
111 | #### 4.2.1 消息类型(MType位字段)
112 |
113 | LoRaWAN定义了六个不同的MAC消息类型:join request, join accept, unconfirmed data up/down, 以及 confirmed data up/down 。
114 |
115 |
116 |
117 | MType |
118 | 描述 |
119 |
120 |
121 | 000 |
122 | Join Request |
123 |
124 |
125 | 001 |
126 | Join Accept |
127 |
128 |
129 | 010 |
130 | Unconfirmed Data Up |
131 |
132 |
133 | 011 |
134 | Unconfirmed Data Down |
135 |
136 |
137 | 100 |
138 | Confirmed Data Up |
139 |
140 |
141 | 101 |
142 | Confirmed Data Down |
143 |
144 |
145 | 110 |
146 | RFU |
147 |
148 |
149 | 111 |
150 | Proprietary |
151 |
152 |
153 |
154 | 表1.MAC消息类型
155 |
156 |
157 | - 4.2.1.1 Join-request and join-accept 消息
158 |
159 | join-request和join-accept都是用在空中激活流程中,具体见章节6.2
160 |
161 | - 4.2.1.2 Data messages
162 |
163 | Data messages 用来传输MAC命令和应用数据,这两种命令也可以放在单个消息中发送。
164 | Confirmed-data message 接收者需要应答。
165 | Unconfirmed-data message 接收者则不需要应答。
166 | Proprietary messages 用来处理非标准的消息格式,不能和标准消息互通,只能用来和具有相同拓展格式的消息进行通信。
167 |
168 | 不同消息类型用不同的方法保证消息一致性,下面会介绍每种消息类型的具体情况。
169 |
170 |
171 | #### 4.2.2 数据消息的主版本(Major位字段)
172 |
173 |
174 |
175 | Major位字段 |
176 | 描述 |
177 |
178 |
179 | 00 |
180 | LoRaWAN R1 |
181 |
182 |
183 | 01..11 |
184 | RFU |
185 |
186 |
187 |
188 | 表2.Major列表
189 |
190 | > 注意:Major定义了激活过程中(join procedure)使用的消息格式(见章节6.2)和MAC Payload的前4字节(见第4章)。终端要根据不同的主版本号实现不同最小版本的消息格式。终端使用的最小版本应当提前通知网络服务器。
191 |
192 |
193 | ### 4.3 MAC载荷(MACPayload)
194 |
195 | MAC载荷,也就是所谓的“数据帧”,包含:帧头(FHDR)、端口(FPort)以及帧载荷(FRMPayload),其中端口和帧载荷是可选的。
196 |
197 |
198 | #### 4.3.1 帧头(FHDR)
199 |
200 | FHDR是由终端短地址(DevAddr)、1字节帧控制字节(FCtrl)、2字节帧计数器(FCnt)和用来传输MAC命令的帧选项(FOpts,最多15个字节)组成。
201 |
202 |
203 |
204 | Size(bytes) |
205 | 4 |
206 | 1 |
207 | 2 |
208 | 0..15 |
209 |
210 |
211 | FHDR |
212 | DevAddr |
213 | FCtrl |
214 | FCnt |
215 | FOpts |
216 |
217 |
218 |
219 | FCtrl在上下行消息中有所不同,下行消息如下:
220 |
221 |
222 | Bit# |
223 | 7 |
224 | 6 |
225 | 5 |
226 | 4 |
227 | [3..0] |
228 |
229 |
230 | FCtrl bits |
231 | ADR |
232 | ADRACKReq |
233 | ACK |
234 | FPending |
235 | FOptsLen |
236 |
237 |
238 |
239 | 上行消息如下:
240 |
241 |
242 | Bit# |
243 | 7 |
244 | 6 |
245 | 5 |
246 | 4 |
247 | [3..0] |
248 |
249 |
250 | FCtrl bits |
251 | ADR |
252 | ADRACKReq |
253 | ACK |
254 | RFU |
255 | FOptsLen |
256 |
257 |
258 |
259 | - 4.3.1.1 帧头中 自适应数据速率 的控制(ADR, ADRACKReq in FCtrl)
260 |
261 | LoRa网络允许终端采用任何可能的数据速率。LoRaWAN协议利用该特性来优化固定终端的数据速率。这就是自适应数据速率(Adaptive Data Rate (ADR))。当这个使能时,网络会优化使得尽可能使用最快的数据速率。
262 |
263 | 移动的终端由于射频环境的快速变化,数据速率管理就不再适用了,应当使用固定的数据速率。
264 |
265 | 如果**ADR**的位字段有置位,网络就会通过相应的MAC命令来控制终端设备的数据速率。如果**ADR**位没设置,网络则无视终端的接收信号强度,不再控制终端设备的数据速率。**ADR**位可以根据需要通过终端及网络来设置或取消。不管怎样,ADR机制都应该尽可能使能,帮助终端延长电池寿命和扩大网络容量。
266 |
267 | > 注意:即使是移动的终端,可能在大部分时间也是处于非移动状态。因此根据它的移动状态,终端也可以请求网络使用ADR来帮助优化数据速率。
268 |
269 | 如果终端被网络优化过的数据速率高于自己默认的数据速率,它需要定期检查下网络仍能收到上行的数据。每次上行帧计数都会累加(是针对于每个新的上行包,重传包就不再增加计数),终端增加 ADR_ACK_CNT 计数。如果直到ADR_ACK_LIMIT次上行(ADR_ACK_CNT >= ADR_ACK_LIMIT)都没有收到下行回复,它就得置高ADR应答请求位(**ADRACKReq**)。 网络必须在规定时间内回复一个下行帧,这个时间是通过ADR_ACK_DELAY来设置,上行之后收到任何下行帧就要把ADR_ACK_CNT的计数重置。当终端在接收时隙中的任何回复下行帧的ACK位字段不需要设置,表示网关仍在接收这个设备的上行帧。如果在下一个ADR_ACK_DELAY上行时间内都没收到回复(例如,在总时间ADR_ACK_LIMIT+ADR_ACK_DELAY之后),终端必须切换到下一个更低速率,使得能够获得更远传输距离来重连网络。终端如果在每次ADR_ACK_DELAY到了之后依旧连接不上,就需要每次逐步降低数据速率。如果终端用它的默认数据速率,那就不需要置位**ADRACKReq**,因为无法帮助提高链路距离。
270 |
271 | > 注意:不要ADRACKReq立刻回复,这样给网络预留一些余量,让它做出最好的下行调度处理。
272 |
273 | > 注意:上行传输时,如果 ADR_ACK_CNT >= ADR_ACK_LIMIT 并且当前数据速率比设备的最小数据速率高,就要设置 ADRACKReq,其它情况下不需要。
274 |
275 | - 4.3.1.2 消息应答位及应答流程(ACK in FCtrl)
276 |
277 | 收到confirmed类型的消息时,接收端要回复一条应答消息(应答位ACK要进行置位)。如果发送者是终端,网络就利用终端发送操作后打开的两个接收窗口之一进行回复。如果发送者是网关,终端就自行决定是否发送应答。
278 | 应答消息只会在收到消息后回复发送,并且不重发。
279 |
280 | > 注意:为了让终端尽可能简单,尽可能减少状态,在收到confirmation类型需要确认的数据帧,需要立即发送一个严格的应答数据帧。或者,终端会延迟发送应答,在它下一个数据帧中再携带。
281 |
282 | - 4.3.1.3 重传流程
283 |
284 | 当需要应答却没收到应答时就会进行重发,重发的个数由终端自己定,可能每个终端都不一样,这个参数也可以由网络服务器来设置调整。
285 |
286 | > 注意:一些应答机制的示例时序图在第18章中有提供。
287 |
288 | > 注意:如果终端设备重发次数到达了最大值,它可以降低数据速率来重连。至于后面是否再重发还是说丢弃不管,都取决于终端自己。
289 |
290 | > 注意:如果网络服务器重发次数到达了最大值,它就认为该终端掉线了,直到它再收到终端的消息。一旦和终端设备的连接出现问题时,要不要重发都取决于网络服务器自己。
291 |
292 | > 注意:在重传期间的数据速率回退的建议策略在章节18.4中有描述。
293 |
294 |
295 | - 4.3.1.4 帧挂起位(FPending in FCtrl 只在下行有效)
296 |
297 | 帧挂起位(FPending)只在下行交互中使用,表示网关还有挂起数据等待下发,需要终端尽快发送上行消息来再打开一个接收窗口。
298 |
299 | **FPending**的详细用法在章节18.3。
300 |
301 | - 4.3.1.5 帧计数器(FCnt)
302 |
303 | 每个终端有两个计数器跟踪数据帧的个数,一个是上行链路计数器(FCntUp),由终端在每次上行数据给网络服务器时累加;另一个是下行链路计数器(FCntDown),由服务器在每次下行数据给终端时累计。 网络服务器为每个终端跟踪上行帧计数及产生下行帧计数。 终端入网成功后,终端和服务端的上下行帧计数同时置0。 每次发送消息后,发送端与之对应的 FCntUp 或 FCntDown 就会加1。 如果收到的帧计数相比当前计数有增长,同时两者相差小于 MAX_FCNT_GAP(考虑了计数翻转),接收方就按接收的帧计数更新对应值。如果两者相差大于 MAX_FCNY_GAP 就说明中间丢失了很多数据,这条数据包就被丢掉。
304 |
305 | LoRaWAN的帧计数器可以用16位和32位两种,节点上具体执行哪种计数,需要在带外通知网络侧,告知计数器的位数。
306 | 如果采用16位帧计数,**FCnt**字段的值可以使用帧计数器的值,此时有需要的话通过在前面填充0(值为0)字节来补足;如果采用32位帧计数,
307 | **FCnt**就对应计数器32位的16个低有效位(上行数据使用上行FCnt,下行数据使用下行FCnt)。
308 |
309 | 终端在相同应用和网络密钥下,不能重复用相同的FCntUp数值,除非是重传。
310 |
311 | - 4.3.1.6 帧可选项(FOptsLen in FCtrl, FOpts)
312 | FCtrl 字节中的FOptsLen位字段描述了整个帧可选项(FOpts)的字段长度。
313 |
314 | FOpts字段存放MAC命令,最长15字节,详细的MAC命令见章节4.4。
315 |
316 | 如果FOptsLen为0,则FOpts为空。在FOptsLen非0时,则反之。如果MAC命令在FOpts字段中体现,port0不能用(FPort要么不体现,要么非0)。
317 |
318 | MAC命令不能同时出现在FRMPayload和FOpts中,如果出现了,设备丢掉该组数据。
319 |
320 |
321 | #### 4.3.2 端口字段(FPort)
322 |
323 | 如果帧载荷字段不为空,端口字段必须体现出来。端口字段有体现时,若FPort的值为0表示FRMPayload只包含了MAC命令;具体见章节4.4中的MAC命令。 FPort的数值从1到223(0x01..0xDF)都是由应用层使用。 FPort的值从224到255(0xE0..0xFF)是保留用做未来的标准应用拓展。
324 |
325 |
326 |
327 | Size(bytes) |
328 | 7..23 |
329 | 0..1 |
330 | 0..N |
331 |
332 |
333 | MACPayload |
334 | FHDR |
335 | FPort |
336 | FRMPayload |
337 |
338 |
339 |
340 | N是应用程序载荷的字节个数。N的有效范围具体在第7章有定义。
341 |
342 | N应该小于等于:
343 | N <= M - 1 - (FHDR长度)
344 | M是MAC载荷的最大长度。
345 |
346 | #### 4.3.3 MAC帧载荷加密(FRMPayload)
347 | 如果数据帧携带了载荷,FRMPayload必须要在MIC计算前进行加密。
348 | 加密机制是采用IEEE802.15.4/2006的AES128算法。
349 |
350 | 默认的,加密和解密由LoRaWAN层来给所有的FPort来执行。如果加密/解密由应用层来做更方便的话,也可以在LoRaWAN层之上给特定FPorts来执行,除了端口0。具体哪个节点的哪个FPort在LoRaWAN层之外要做加解密,必须要和服务器通过out-of-band信道来交互(见第19章)。
351 |
352 | - 4.3.3.1 LoRaWAN的加密
353 |
354 | 密钥K根据不同的FPort来使用:
355 |
356 |
357 |
358 | FPort |
359 | K |
360 |
361 |
362 | 0 |
363 | NwkSKey |
364 |
365 |
366 | 1..255 |
367 | AppSKey |
368 |
369 |
370 | 表3: FPort列表
371 |
372 | 具体加密是这样:
373 | pld = FRMPayload
374 | 对于每个数据帧,算法定义了一个块序列Ai,i从1到k,k = ceil(len(pld) / 16):
375 |
376 |
377 | Size(bytes) |
378 | 1 |
379 | 4 |
380 | 1 |
381 | 4 |
382 | 4 |
383 | 1 |
384 | 1 |
385 |
386 |
387 | Ai |
388 | 0x01 |
389 | 4 x 0x00 |
390 | Dir |
391 | DevAddr |
392 | FCntUp or FCntDown |
393 | 0x00 |
394 | i |
395 |
396 |
397 |
398 | 方向字段(**Dir**)在上行帧时为0,在下行帧时为1.
399 | 块Ai通过加密,得到一个由块Si组成的序列S。
400 | > Si = aes128_encrypt(K, Ai) for i = 1..k
401 | > S = S1 | S2 | .. | Sk
402 |
403 | 通过异或计算对payload进行加解密:
404 |
405 | - 4.3.3.2 LoRaWAN层之上的加密
406 |
407 | 如果LoRaWAN之上的层级在已选的端口上(但不能是端口0,这是给MAC命令保留的)提供了预加密的FRMPayload给LoRaWAN,LoRaWAN则不再对FRMPayload进行修改,直接将FRMPayload从MACPayload传到应用层,以及从应用层传到MACPayload。
408 |
409 | ## 4.4 消息校验码(MIC)
410 | 消息检验码要计算消息中所有字段。
411 | msg = MHDR | FHDR | FPort | FRMPayload
412 |
413 | MIC是按照[RFC4493]来计算:
414 | > cmac = aes128_cmac(NwkSKey, B0 | msg)
415 | > MIC = cmac[0..3]
416 |
417 | 块B0的定义如下:
418 |
419 |
420 |
421 | Size(bytes) |
422 | 1 |
423 | 4 |
424 | 1 |
425 | 4 |
426 | 4 |
427 | 1 |
428 | 1 |
429 |
430 |
431 | B0 |
432 | 0x49 |
433 | 4 x 0x00 |
434 | Dir |
435 | DevAddr |
436 | FCntUp or FCntDown |
437 | 0x00 |
438 | len(msg) |
439 |
440 |
441 |
442 | 方向字段(**Dir**)在上行帧时为0,在下行帧时为1。
443 |
444 |
--------------------------------------------------------------------------------
/chapter/5 MAC Commands.md:
--------------------------------------------------------------------------------
1 |
2 | ## **第5章 MAC命令**
3 |
4 | 对网络管理者而言,有一套专门的MAC命令用来在服务器和终端MAC层之间交互。这套MAC命令对应用程序或者应用服务器或者运行在终端设备上的应用程序是不可见的。
5 |
6 | 单个数据帧中可以包含MAC命令序列,要么在FOpts字段中捎带,要么作为独立帧将**FPort**设成0后放在FRMPayload里。如果采用FOpts捎带的方式,MAC命令不进行加密并且长度不能超过15字节。如果采用独立帧放在**FRMPayload**的方式,那就必须采用加密方式,并且不能超过**FRMPayload**的最大长度。
7 |
8 | > 注意:如果MAC命令不想被窃听,那就必须以独立帧形式放在FRMPayload中进行发送。
9 |
10 | 每个MAC命令是由 1字节命令码 (CID) 跟着一段可能为空的特定命令字节序列组成的。
11 |
12 |
13 |
14 | CID |
15 | Command |
16 | 由谁发送 |
17 | 描述 |
18 |
19 |
20 | 终端 |
21 | 网关 |
22 |
23 |
24 | 0x02 |
25 | LinkCheckReq |
26 | x |
27 | |
28 | 终端利用这个命令来判断网络连接质量 |
29 |
30 |
31 | 0x02 |
32 | LinkCheckAns |
33 | |
34 | x |
35 | LinkCheckReq的回复。包含接收信号强度,告知终端接收质量 |
36 |
37 |
38 | 0x03 |
39 | LinkADRReq |
40 | |
41 | x |
42 | 向终端请求改变数据速率,发射功率,重传率以及信道 |
43 |
44 |
45 | 0x03 |
46 | LinkADRAns |
47 | x |
48 | |
49 | LinkADRReq的回复。 |
50 |
51 |
52 | 0x04 |
53 | DutyCycleReq |
54 | |
55 | x |
56 | 向终端设置发送的最大占空比。 |
57 |
58 |
59 | 0x04 |
60 | DutyCycleAns |
61 | x |
62 | |
63 | DutyCycleReq的回复。 |
64 |
65 |
66 | 0x05 |
67 | RXParamSetupReq |
68 | |
69 | x |
70 | 向终端设置接收时隙参数。 |
71 |
72 |
73 | 0x05 |
74 | RXParamSetupAns |
75 | x |
76 | |
77 | RXParamSetupReq的回复。 |
78 |
79 |
80 | 0x06 |
81 | DevStatusReq |
82 | |
83 | x |
84 | 向终端查询其状态。 |
85 |
86 |
87 | 0x06 |
88 | DevStatusAns |
89 | x |
90 | |
91 | 返回终端设备的状态,即电池余量和链路解调预算。 |
92 |
93 |
94 | 0x07 |
95 | NewChannelReq |
96 | |
97 | x |
98 | 创建或修改 1个射频信道 定义。 |
99 |
100 |
101 | 0x07 |
102 | NewChannelAns |
103 | x |
104 | |
105 | NewChannelReq的回复。 |
106 |
107 |
108 | 0x08 |
109 | RXTimingSetupReq |
110 | |
111 | x |
112 | 设置接收时隙的时间。 |
113 |
114 |
115 | 0x08 |
116 | RXTimingSetupAns |
117 | x |
118 | |
119 | RXTimingSetupReq的回复。 |
120 |
121 |
122 | 0x09 |
123 | TxParamSetupReq |
124 | |
125 | x |
126 | 网络服务器用于设置基于当地规定的终端的最大允许驻留时间和最大EIRP |
127 |
128 |
129 | 0x09 |
130 | TxParamSetupAns |
131 | x |
132 | |
133 | TxParamSetupReq的回复。 |
134 |
135 |
136 | 0x0A |
137 | DlChannelReq |
138 | |
139 | x |
140 | 通过从上行链路频率移位下行链路频率(即创建非对称信道)来修改下行链路RX1无线电信道的定义 |
141 |
142 |
143 | 0x0A |
144 | DlChannelAns |
145 | x |
146 | |
147 | DlChannelReq的回复。 |
148 |
149 |
150 | 0x80~0xFF |
151 | 私有 |
152 | x |
153 | x |
154 | 给私有网络命令拓展做预留。 |
155 |
156 |
157 |
158 | 表4:MAC命令表
159 |
160 | > 注意:MAC命令的长度虽然没有明确给出,但是MAC执行层必须要知道。因此未知的MAC命令无法被忽略,且前面未知的MAC命令会终止MAC命令的处理队列。所以建议按照LoRaWAN协议介绍的MAC命令来处理MAC命令。这样所有基于LoRaWAN协议的MAC命令都可以被处理,即使是更高版本的命令。
161 |
162 | ---
163 |
164 | > 注意:由网络服务器调整的任何值(例如,RX2、新的或已调整的信道定义)仅在终端设备的下一次加网之前有效。因此,在每个成功加网之后,终端设备将再次使用默认参数,并由网络服务器根据需要重新调整值。
165 |
166 | ### 5.1 Link Check 命令 (LinkCheckReq, LinkCheckAns)
167 |
168 | 通过LinkCheckReq命令,终端可以知道是否已连接上服务器。该命令没有载荷。
169 |
170 | 当网络服务器通过一个或者多个网关接收到LinkCheckReq命令时,它会以LinkCheckAns命令进行回复。
171 |
172 |
173 |
174 | Size (bytes) |
175 | 1 |
176 | 1 |
177 |
178 |
179 | LinkCheckAns Payload |
180 | Margin |
181 | GwCnt |
182 |
183 |
184 |
185 | 解调预算(**Margin**)是一个范围为0~254的8位无符号整数,表示成功接收最新的**LinkCheckReq**命令的链路预算(单位为dB)。若 Margin 值为"0"则意味着数据帧是在解调水平上进行接收(0 dB或者没有预算),当 Margin 值为"20"时则意味着数据帧到达在解调水平之上20dB的网关。
186 |
187 | 网关计数(**GwCnt**)是成功接收最新的**LinkCheckReq**命令的网关个数。
188 |
189 | ### 5.2 Link ADR 命令(LinkADRReq, LinkADRAns)
190 |
191 | 通过 LinkADRReq 命令,NS(网络服务器)可以调整终端的数据速率。
192 |
193 |
194 |
195 | Size (bytes) |
196 | 1 |
197 | 2 |
198 | 1 |
199 |
200 |
201 | LinkADRReq Payload |
202 | DataRate_TXPower |
203 | ChMask |
204 | Redundancy |
205 |
206 |
207 |
208 |
209 |
210 | Bits |
211 | [7:4] |
212 | [3:0] |
213 |
214 |
215 | DataRate_TXPower |
216 | DataRate |
217 | TXPower |
218 |
219 |
220 |
221 | 所请求的数据速率(**DataRate**)和发射功率(**TXPower**)是根据区域规定,体现在[LoRaWAN协议中文版_配套文件 地区参数(物理层) ](http://blog.csdn.net/iotisan/article/details/55056092)中。命令中的发射功率字段指的是设备可操作的最大发射功率。如果命令中的发射功率高于终端实际发射功率的最大值,终端也要应答成功,这种情况下,将终端的发射功率尽可能提高到最大值。 信道掩码(ChMask)字段指示了上行链路的可用信道,从最低位bit0表示开始。
222 |
223 |
224 |
225 | Bit# |
226 | Usable channels |
227 |
228 |
229 | 0 |
230 | Channel 1 |
231 |
232 |
233 | 1 |
234 | Channel 2 |
235 |
236 |
237 | .. |
238 | .. |
239 |
240 |
241 | 15 |
242 | Channel 16 |
243 |
244 |
245 |
246 | 表5:信道状态表
247 |
248 | ChMask 字段的对应位如果设置为1,则表示对应的信道可以进行上行传输,只要该信道允许终端使用该数据速率。如果对应位设置为0,则表示相应信道不可用。
249 |
250 |
251 |
252 | Bits |
253 | 7 |
254 | [6:4] |
255 | [3:0] |
256 |
257 |
258 | Redundancy bits |
259 | RFU |
260 | ChMaskCntl |
261 | NbTrans |
262 |
263 |
264 |
265 | Redundancy 字段中的 **NbTrans** 位域,指的是每个上行消息的发送次数,这仅对 "unconfirmed" 消息有作用。这个字段的默认值为1,相对应的是每个数据帧只进行单次传输,有效范围是[1:15]。如果收到 **NbTrans** == 0,终端需要使用默认值。这个位域可以被NS(网络服务器)用来控制节点上行的 Redundancy 从而获得QOS(服务质量)。在重传帧时节点通常会跳频,每次重传需要等到接收窗口超时。只要在RX1期间收到下行消息,该上行消息则不再进行任何重传。对于 Class A 设备,RX2时隙的接收也是一样处理。
266 |
267 | ChMaskCntl 位域和之前定义的 ChMask 字段有关,它控制了ChMask所指定的16个信道块。也可以对所用信道进行全局的打开或关闭。这个位域的使用是根据区域规定,体现在[LoRaWAN协议中文版_配套文件 地区参数(物理层) ](http://blog.csdn.net/iotisan/article/details/55056092)中。
268 |
269 | NS(网络服务器)可能会在单个下行帧中包含多个 LinkAdrReq 命令。终端为了配置 channel mask ,将会按照下行消息中的命令块的顺序,逐一地处理所有的 LinkAdrReq 消息。 终端可能会接收或者拒绝命令块中所有 channel mask 的控制,在逐个 LinkAdrAns 命令块中体现连续的 Channel Mask ACK 状态,来指示相应的 channel mask 接受与否。 终端在连续命令块时只处理最后一个消息中的 DataRate, TXPower 和 NbTrans 字段,因为这些参数将会决定终端的全局状态。终端需要在每一个 LinkAdrAns 命令中体现 ACK 状态,来指示对这些最终设置的接受与否。
270 |
271 | 信道频点信息是按地区规定,在第6章中有定义。终端使用 LinkADRAns 命令来应答 LinkADRReq 命令。
272 |
273 |
274 |
275 | Size (bytes) |
276 | 1 |
277 |
278 |
279 | LinkADRAns Payload |
280 | Status |
281 |
282 |
283 |
284 |
285 |
286 |
287 | Bits |
288 | [7:3] |
289 | 2 |
290 | 1 |
291 | 0 |
292 |
293 |
294 | Status bits |
295 | RFU |
296 | Power ACK |
297 | Data rate ACK |
298 | Channel mask ACK |
299 |
300 |
301 |
302 | LinkADRAns 的 Status 位域按照如下定义:
303 |
304 |
305 |
306 | |
307 | Bit = 0 |
308 | Bit = 1 |
309 |
310 |
311 | Channel mask ACK |
312 | 所发的 channel mask 使能了未定义的信道或者禁用了所有信道。命令被丢弃,终端状态不变。 |
313 | 所发的 channel mask 已成功解析,已按照 mask 设置了当前的信道状态。 |
314 |
315 |
316 | Data rate ACK |
317 | 所请求的数据速率,终端无法识别,或者无法应用在当前信道中(不支持任何使能的信道)。命令被丢弃,终端状态不变。 |
318 | 数据速率成功设置。 |
319 |
320 |
321 | Power ACK |
322 | 所请求的发射功率不能在终端上执行。命令被丢弃,终端状态不变。 |
323 | 功率等级成功设置。 |
324 |
325 |
326 |
327 | 如果这三个位中有任何一位等于0,则**LinkADRReq**命令没有成功,节点保持之前的状态。
328 |
329 |
330 | ### 5.3 终端发射占空比(DutyCycleReq, DutyCycleAns)
331 | DutyCycleReq命令被网络协调者用来限制终端的**最大总计发射占空比**。**最大总计发射占空比**覆盖所有子频段上的发射占空比。
332 |
333 |
334 |
335 | Size (bytes) |
336 | 1 |
337 |
338 |
339 | DutyCycleReq Payload |
340 | DutyCyclePL |
341 |
342 |
343 |
344 |
345 |
346 | Bits |
347 | 7:4 |
348 | 3:0 |
349 |
350 |
351 | DutyCyclePL |
352 | RFU |
353 | MaxDCycle |
354 |
355 |
356 |
357 | 终端所允许的最大发射占空比为: aggregated duty cycle = 1/(2^MaxDcycle)
358 |
359 | **MaxDutyCycle**的有效范围为[0:15].MaxDutyCycle的值若为0则表示“无发射占空比限制”,除非各地区有对发射占空比进行限制。
360 |
361 | ### 5.4 接收窗口参数(RXParamSetupReq,RXParamSetupAns)
362 |
363 | **RXParamSetupReq**命令可以对每个上行消息之后的第二接收窗口(RX2)的频率以及数据速率进行改变。该命令还可以对上行数据速率和RX1下行数据速率的偏移量进行改变。
364 |
365 |
366 |
367 | Size (bytes) |
368 | 1 |
369 | 3 |
370 |
371 |
372 | RXParamSetupReq Payload |
373 | DLsettings |
374 | Frequency |
375 |
376 |
377 |
378 |
379 |
380 | Bits |
381 | 7 |
382 | 6:4 |
383 | 3:0 |
384 |
385 |
386 | DLsettins |
387 | RFU |
388 | RX1DRoffset |
389 | RX2DataRate |
390 |
391 |
392 |
393 | **RX1DRoffset**位域设置上行数据速率和RX1下行数据速率的偏移量。默认情况下偏移量为0(意思就是上行数据速率与下行数据速率相等)。偏移量用于考虑一些地区的基站最大功率密度限制和平衡上下行射频链路预算。
394 |
395 | **RX2DataRate**位域定义了第二接收窗口的下行链路数据速率,遵循与**LinkADRReq**命令相同的规则(例如,0表示DR0/125kHz)。**Frequency**位域所设置的是第二接收窗口所使用信道的频率,该频率按照与**NewChannelReq**命令相同的规则进行定义。
396 |
397 | 终端使用**RXParamSetupAns**命令对**RXParamSetupReq**命令进行应答。**RXParamSetupAns**命令应该添加在所有的上行链路数据帧的**Fopt**字段中直到终端接收到一个Class A类型的下行链路数据帧。这样就可以保证即使在上行链路帧丢失的情况之下,网络服务器总是可以知道终端所使用的下行链路参数。
398 |
399 | **RXParamSetupAns**命令的载荷为一个字节的状态信息。
400 |
401 |
402 |
403 | Size (bytes) |
404 | 1 |
405 |
406 |
407 | RXParamSetupAns Payload |
408 | Status |
409 |
410 |
411 |
412 | **Status**各位的含义如下:
413 |
414 |
415 | Bits |
416 | 7:3 |
417 | 2 |
418 | 1 |
419 | 0 |
420 |
421 |
422 | Status bits |
423 | RFU |
424 | RX1DRoffset ACK |
425 | RX2 Data Rate ACK |
426 | Channel ACK |
427 |
428 |
429 |
430 |
431 |
432 | |
433 | Bit = 0 |
434 | Bit = 1 |
435 |
436 |
437 | Channel ACK |
438 | 终端无法使用请求的频率 |
439 | RX2时隙信道频率设置成功 |
440 |
441 |
442 | RX2 Data rate ACK |
443 | 终端无法识别请求的数据速率 |
444 | RX2时隙数据速率设置成功 |
445 |
446 |
447 | RX1DRoffset ACK |
448 | 上行数据速率与RX1下行数据速率的偏移量不在允许的范围之内 |
449 | RX1DRoffset设置成功 |
450 |
451 |
452 |
453 | 如果3个位的任何一位为0,则**RXParamSetupReq**命令不成功,节点保持之前的状态。
454 |
455 |
456 | ### 5.5 终端状态(DevStatusReq, DevStatusAns)
457 |
458 | 通过 **DevStatusReq** 命令,NS(网络服务器)可以获取终端的状态信息。该命令无载荷。一旦终端收到 DevStatusReq 命令,则会回复 **DevStatusAns** 命令。
459 |
460 |
461 |
462 | Size (bytes) |
463 | 1 |
464 | 1 |
465 |
466 |
467 | DevStatusAns Payload |
468 | Battery |
469 | Margin |
470 |
471 |
472 |
473 | 报告电池电量(**Battery**)的编码如下:
474 |
475 |
476 |
477 | Battery |
478 | Description |
479 |
480 |
481 | 0 |
482 | 终端连接到外部电源 |
483 |
484 |
485 | 1..254 |
486 | 数值表示电池电量,1表示最低,254表示最高 |
487 |
488 |
489 | 255 |
490 | 终端无法测量电池电量 |
491 |
492 |
493 |
494 | 图8:电池电量码表
495 |
496 | **Margin**是最近一次成功接收**DevStatusReq**命令的解调信噪比(该值必须是四舍五入到最近的整数值,单位为dB)。它是6位的有符号整数(最小值为 -32,最大值为31)。
497 |
498 |
499 |
500 | Bits |
501 | 7:6 |
502 | 5:0 |
503 |
504 |
505 | Status bits |
506 | RFU |
507 | Margin |
508 |
509 |
510 |
511 |
512 | ### 5.6 信道的创建和修改(NewChannelReq, NewChannelAns, DlChannelReq, DlChannelAns)
513 |
514 | **NewChannelReq**命令可以用于修改现有的双向信道或者创建一个新的信道。这个命令设置了新信道的中心频率还有上行数据速率的可用范围:
515 |
516 |
517 |
518 | Size (bytes) |
519 | 1 |
520 | 3 |
521 | 1 |
522 |
523 |
524 | NewChannelReq Payload |
525 | Chlndex |
526 | Freq |
527 | DrRange |
528 |
529 |
530 |
531 | 信道索引**Chlndex**是正在创建或者正在修改的信道的索引。根据所使用的区域和频带,LoRaWAN规范强加了所有设备通用的默认信道,该信道不能被**NewChannelReq**命令修改(具体见章节6)。如果默认信道的个数为N,则默认信道的编号从0~(N-1),并且**Chlndex**的可接受范围为N~15。一个设备必须至少能处理16个 不同的信道定义。在某些特定的区域,设备可能必须存储超过16个信道定义。
532 |
533 | **Freq**位域是一个24位无符号整数。实际信道频率为(100×**Freq**),单位为HZ,其中表示低于100MHz的频率数值将会保留供将来使用。**Freq**可以设置从100MHz~1.67GHz之间的信道频率,但必须以100Hz为单位(因为实际信道频率为(100×**Freq**))。终端必须检测该频率是否能被射频硬件所使用,若不行则需返回错误。
534 |
535 | **DrRange**位域规定了这个信道所允许的上行数据速率范围。该位域被分为两个4位字段:
536 |
537 |
538 |
539 | Bits |
540 | 7:4 |
541 | 3:0 |
542 |
543 |
544 | DrRange |
545 | MaxDR |
546 | MinDR |
547 |
548 |
549 |
550 | 按照[章节5.2](#5.2)所定义的规则,最小数据速率**MinDR**字段规定了这个信道所允许的最低上行数据速率。例如0表示DR0/125kHz。类似的,最大数据速率**MaxDR**规定了最高上行数据速率。例如,若**DrRange**=0x77则表示一个信道只允许50kbps的GFSK;若**DrRange**=0x50表示一个信道支持DR0/125kHz到DR5/125kHZ的频率范围。
551 |
552 | 最近定义以及修改的信道被使能之后可以立刻用于通信。RX1的下行频率与上行频率相等。
553 |
554 | 终端以**NewChannelAns**命令对**NewChannelReq**进行应答。**NewChannelAns**命令的载荷包含了以下信息:
555 |
556 |
557 |
558 | Size (bytes) |
559 | 1 |
560 |
561 |
562 | NewChannelAns Payload |
563 | Status |
564 |
565 |
566 |
567 | **Status**位有以下含义:
568 |
569 |
570 |
571 | Bits |
572 | 7:2 |
573 | 1 |
574 | 0 |
575 |
576 |
577 | Status |
578 | RFU |
579 | Data rate range ok |
580 | Channel frequency ok |
581 |
582 |
583 |
584 |
585 |
586 | |
587 | Bit = 0 |
588 | Bit = 1 |
589 |
590 |
591 | Data rate range ok |
592 | 指定的数据速率超出了终端当前定义的范围 |
593 | 该数据速率与终端能够兼容 |
594 |
595 |
596 | Channel frequency ok |
597 | 终端无法使用该频率 |
598 | 终端能够使用该频率 |
599 |
600 |
601 |
602 | 如果以上两位其中之一为0,则**NewChannelReq**命令不成功,新的信道将不会产生。
603 |
604 | **DlChannelReq**命令允许服务器在RX1时隙使用不同的下行链路频率。这个命令可以适用于所有支持**NewChannelReq**命令的地理区域(例如欧盟和中国,但是不适用于美国和澳大利亚,具体详见《LoRaWAN Regional Parameters document [PARAMS]》。
605 |
606 | 该命令用于设置RX1时隙的下行消息中心频率,如下:
607 |
608 |
609 |
610 | Size (bytes) |
611 | 1 |
612 | 3 |
613 |
614 |
615 | DlChannelReq Payload |
616 | Chlndex |
617 | Freq |
618 |
619 |
620 |
621 | **Chlndex**是要修改下行频率的信道的索引。
622 |
623 | **Freq**位域是24位的无符号整数。实际信道频率为(100×**Freq**),单位为HZ,其中表示低于100MHz的频率数值将会保留供将来使用。终端必须检测该频率是否能被射频硬件所使用,若不行则需返回错误。
624 |
625 | 终端以**DlChannelAns**命令对**DlChannelReq**命令进行应答。**DlChannelAns**命令在终端没有接收到一个下行数据之前必须添加在所有的上行数据**FOpt**位域中。这样才能保证在上行数据包丢失的情况之下,网络服务器总是能够知道终端所使用的下行频率。
626 |
627 | 该命令的载荷有如下信息:
628 |
629 |
630 |
631 | Size (bytes) |
632 | 1 |
633 |
634 |
635 | DlChannelAns Payload |
636 | Status |
637 |
638 |
639 |
640 | **Status**位有以下的含义:
641 |
642 |
643 |
644 | Bits |
645 | 7:2 |
646 | 1 |
647 | 0 |
648 |
649 |
650 | Status |
651 | RFU |
652 | 上行频率可用 |
653 | 信道频率可用 |
654 |
655 |
656 |
657 |
658 |
659 | |
660 | Bit = 0 |
661 | Bit = 1 |
662 |
663 |
664 | Channel frequency ok |
665 | 终端无法使用该频率 |
666 | 终端无法使用该频率 |
667 |
668 |
669 | Channel frequency ok |
670 | 该信道无法使用此上行频率,只能为已经具有一个有效上行频率的信道设置下行频率 |
671 | 信道的上行频率有效 |
672 |
673 |
674 |
675 | ### 5.7 TX 和 RX 之间的延时设置(RXTimingSetupReq, RXTimingSetupAns)
676 |
677 | **RXTimingSetupReq**命令允许配置TX上行链路发送完毕之后与第一个接收窗口打开之间的延时。第二接收窗口在第一接收窗口打开之后的1秒打开。
678 |
679 |
680 |
681 | Size (bytes) |
682 | 1 |
683 |
684 |
685 | RXTimingSetupReq Payload |
686 | Settings |
687 |
688 |
689 |
690 | **Delay**位域指定了延时时间。这个位域被分为两个4位字段:
691 |
692 |
693 |
694 | Bits |
695 | 7:4 |
696 | 3:0 |
697 |
698 |
699 | Settings |
700 | RFU |
701 | Del |
702 |
703 |
704 |
705 | 延时时间的单位为秒。Del的值为0时对应的延时时间为1s。
706 |
707 |
708 |
709 | Del |
710 | Delay[s] |
711 |
712 |
713 | 0 |
714 | 1 |
715 |
716 |
717 | 1 |
718 | 1 |
719 |
720 |
721 | 2 |
722 | 2 |
723 |
724 |
725 | 3 |
726 | 3 |
727 |
728 |
729 | .. |
730 | .. |
731 |
732 |
733 | 15 |
734 | 15 |
735 |
736 |
737 |
738 | 图11:延时时间映射表
739 |
740 | 终端用于应答**RXTimingSetupReq**命令的**RXTimingSetupAns**命令没有载荷。
741 |
742 | **RXTimingSetupAns**命令在终端没有接收到一个下行数据之前必须添加在所有的上行数据**FOpt**位域中。这样才能保证在上行数据包丢失的情况之下,网络服务器总是能够知道终端所使用的下行频率。
743 |
744 | ### 5.8 终端发送参数(TxParamSetupReq, TxParamSetupAns)
745 |
746 | 该命令只需要在特定的可调节地区进行使用。具体请参考《LoRaWAN Regional Parameters document [PARAMS]》。
747 |
748 | **TxParamSetupReq**可以用于通知终端的最大允许驻留时间,换言之,一包数据在空中的最大持续传输时间,以及终端所允许的最大**等效全向辐射功率(EIRP)**。
749 |
750 | > KevinCao注:
751 | > **EIRP**解释:为无线电发射机供给天线的功率与在给定方向上天线绝对增益的乘积。各方向具有相同单位增益的理想全向天线,通常作为无线通信系统的参考天线。EIRP定义为:EIRP=Pt*Gt,它表示同全向天线相比,可由发射机获得的在最大天线增益方向上的 发射功率。Pt表示发射机的发射功率,Gt表示发射天线的天线增益。在无线通信工程中,通常用来衡量干扰的强度,以及发射机发射强信号的能力。
752 |
753 |
754 |
755 | Size (bytes) |
756 | 1 |
757 |
758 |
759 | TxParamSetup payload |
760 | EIRP_DwellTime |
761 |
762 |
763 |
764 | **EIRP_DwellTime**位域的结构如下所述:
765 |
766 |
767 |
768 | Bits |
769 | 7:6 |
770 | 5 |
771 | 4 |
772 | 3:0 |
773 |
774 |
775 | MaxDwellTime |
776 | RFU |
777 | DownlinkDwellTime |
778 | UplinkDwellTime |
779 | MaxEIRP |
780 |
781 |
782 |
783 | **TxParamSetupReq**命令的[0..3]位是用于表示**EIRP**的最大值,每个编码值对应的最大**EIRP**值的映射表如下。这张表中的最大**EIRP**的值的变化范围由各个地区来进行自行规定。
784 |
785 |
786 |
787 | Coded Value |
788 | 0 |
789 | 1 |
790 | 2 |
791 | 3 |
792 | 4 |
793 | 5 |
794 | 6 |
795 | 7 |
796 | 8 |
797 | 9 |
798 | 10 |
799 | 11 |
800 | 12 |
801 | 13 |
802 | 14 |
803 | 15 |
804 |
805 |
806 | Max EIRP(dBm) |
807 | 8 |
808 | 10 |
809 | 12 |
810 | 13 |
811 | 14 |
812 | 16 |
813 | 18 |
814 | 20 |
815 | 21 |
816 | 24 |
817 | 26 |
818 | 27 |
819 | 29 |
820 | 30 |
821 | 33 |
822 | 36 |
823 |
824 |
825 |
826 | 最大**EIRP**指的是设备无线电发射功率的上限。设备不需要使用该功率进行传输,但是绝不会辐射超过指定的EIRP。
827 |
828 | 第4位和第5位分别定义了上行链路和下行链路的驻留时间,驻留时间的映射编码表如下所示:
829 |
830 |
831 |
832 | Coded Value |
833 | Dwell Time |
834 |
835 |
836 | 0 |
837 | No Limit |
838 |
839 |
840 | 1> |
841 | 400 ms |
842 |
843 |
844 |
845 | 当该Mac命令生效时,(因区域而定)终端会以**TxParamSetupAns**命令对**TxParamSetupReq**命令进行回复。**TxParamSetupAns**命令不包含任何载荷。
846 |
847 | 当在某个区域内是不需要**TxParamSetupReq**命令时,则终端不会对该命令进行任何处理并且不会进行回复。
848 |
849 |
--------------------------------------------------------------------------------
/chapter/6 End-Device Activation.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## **第6章 终端激活**
4 |
5 | 为了加入LoRaWAN网络,每个终端需要初始化及激活。
6 |
7 | 终端的激活有两种方式,一种是空中激活 Over-The-Air Activation (OTAA),当设备部署和重置时使用; 另一种是独立激活 Activation By Personalization (ABP),此时初始化和激活这两步就在一个步骤内完成。
8 |
9 | > twowinter 备注: ABP 这个词不太好翻译,通常会翻成个性化激活,也就是通过独立配置参数的方式激活。但总感觉少点味道,与空中激活摆在一起,感觉独立激活这个词在语义上更有并列感。当然这是我的主观感觉,建议大家和同行交流时,还是说 ABP激活 吧。
10 |
11 | ### 6.1 终端激活后的数据存储
12 |
13 | 激活后,终端会存储如下信息:设备地址(DevAddr),应用ID(AppEUI),网络会话密钥(NwkSKey),应用会话密钥(AppSKey)。
14 |
15 | - 6.1.1 终端地址(DevAddr)
16 |
17 | 终端地址(DevAddr)由可标识当前网络设备的32位ID所组成,具体格式如下:
18 |
19 |
20 |
21 | Bit# |
22 | [31..25] |
23 | [24..0] |
24 |
25 |
26 | DevAddr bits |
27 | NwkID |
28 | NwkAddr |
29 |
30 |
31 |
32 | 它的高7位是NwkId,用来区别同一区域内的不同网络,另外也保证防止节点窜到别的网络去。它的低25位是NwkAddr,是终端的网络地址,可以由网络管理者来分配。
33 |
34 | - 6.1.2 应用ID(AppEUI)
35 |
36 | AppEUI是一个类似IEEE EUI64的全球唯一ID,标识终端的应用提供者。
37 | APPEUI在激活流程开始前就存储在终端中。
38 |
39 | - 6.1.3 网络会话密钥(NwkSKey)
40 |
41 | NwkSKey被终端和网络服务器用来计算和校验所有消息的MIC,以保证数据完整性。也用来对单独MAC的数据消息载荷进行加解密。
42 |
43 | - 6.1.4 应用会话密钥(AppSKey)
44 |
45 | AppSKey被终端和网络服务器用来对应用层消息进行加解密。当应用层消息载荷有MIC时,也可以用来计算和校验该应用层MIC。
46 |
47 | ### 6.2 空中激活 OTAA
48 |
49 | 针对空中激活,终端必须按照加网流程来和网络服务器进行数据交互。如果终端丢失会话消息,则每次必须重新进行一次加网流程。
50 | 加网流程需要终端准备好如下这三个参数:DevEUI,AppEUI,AppKey。
51 |
52 | APPEUI在上面的6.1.2已经做了描述。
53 |
54 | > 注意:对于空中激活,终端不会初始化任何网络密钥。只有当终端加入网络后,才会被分配一个网络会话密钥,用来加密和校验网络层的传输。通过这样,使得终端在不同网络间的漫游处理变得方便。同时使用网络和应用会话密钥,使得网络服务器中的应用数据,不会被网络提供者读取或者篡改。
55 |
56 | - 6.2.1 终端 ID (DevEUI)
57 | DevEUI 是一个类似IEEE EUI64的全球唯一ID,标识唯一的终端设备。
58 |
59 | - 6.2.2 应用密钥(AppKey)
60 |
61 | AppKey 是由应用程序拥有者分配给终端,很可能是由应用程序指定的根密钥来衍生的,并且受提供者控制。当终端通过空中激活方式加入网络,AppKey用来产生会话密钥NwkSKey和AppSKey,会话密钥分别用来加密和校验网络层和应用层数据。
62 |
63 | - 6.2.3 加网流程
64 |
65 | 从终端角度看,加网流程是由和服务器的两个MAC命令交互组成的,分别是 join request 和 join accept。
66 |
67 | - 6.2.4 Join-request 消息
68 |
69 | 加网流程总是由终端发送 join-request 来发起。
70 |
71 |
72 |
73 | Size (bytes) |
74 | 8 |
75 | 8 |
76 | 2 |
77 |
78 |
79 | Join Request |
80 | AppEUI |
81 | DevEUI |
82 | DevNonce |
83 |
84 |
85 |
86 | join-request 消息包含了AppEUI 和 DevEUI ,后面还跟了2个字节的声明 DevNonce。
87 |
88 | DevNonce 是一个随机值。网络服务器为每个终端记录过去的 DevNonce 数值,如果相同设备发出相同的 DevNonce 的join request就会忽略。
89 |
90 | join-request 消息的MIC数值(见第4章 MAC帧格式)按照如下公式计算:
91 |
92 | > cmac = aes128_cmac(AppKey, MHDR | AppEUI | DevEUI | DevNonce)
93 | > MIC = cmac[0..3]
94 |
95 | join-request 消息不用加密。
96 |
97 |
98 | - 6.2.5 Join-accept 消息
99 |
100 | 如果网络服务器准许终端加入网络,就会用 **join-accept** 对 **join-request** 进行应答。**join-accept** 是作为一个普通下行帧进行下发的,唯一的区别是它使用的是 JOIN_ACCEPT_DELAY1 或者 JOIN_ACCEPT_DELAY2 (分别代替 RECEIVE_DELAY1 和 RECEIVE_DELAY2 )但是它所使用的两个接收窗口的信道频率和数据率和 LoRaWAN 地区参数文件[PARAMS]"接收窗口"部分所描述的 RX1 和 RX2 接收窗口相同。
101 |
102 | 如果 **join-request** 不被接受,则终端不会收到回应。
103 |
104 | **join-accept** 消息的帧格式包括3字节的应用随机数(**AppNonce**),网络标识符(**NetID**),终端地址(**DevAddr**),TX和RX之间的延时(**RxDelay**),用于终端所加入的网络的可选信道频率列表(**CFList**)。**CFList** 的选择是由区域指定的,在 LoRaWAN 地区参数文件[PARAMS]中进行定义。
105 |
106 |
107 |
108 | Size (bytes) |
109 | 3 |
110 | 3 |
111 | 4 |
112 | 1 |
113 | 1 |
114 | (16)Optional |
115 |
116 |
117 | Join Accpet |
118 | AppNonce |
119 | NetID |
120 | DevAddr |
121 | DLSettings |
122 | RXDelay |
123 | CFList |
124 |
125 |
126 |
127 | **AppNonce**是由网络服务器所提供的一个随机值或者某些形式的唯一ID,用于终端得到两个会话密钥**NwkSKey**和**AppSKey**,如下:
128 |
129 | NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad 16 )
130 | AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad 16 )
131 |
132 | **join-accept**的 MIC 值由如下计算得到:
133 |
134 | cmac = aes128_cmac(AppKey,MHDR | AppNonce | NetID | DevAddr | DLSettings | RxDelay | CFList)
135 | MIC = cmac[0..3]
136 |
137 | **join-accept**消息是使用**AppKey**进行加密的,如下:
138 |
139 | aes128_decrypt(AppKey, AppNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | MIC)
140 |
141 | > 注意:网络服务器在 ECB 模式下使用一个 AES 解密操作去对 **join-accept** 消息进行加密,因此终端就可以使用一个 AES 加密操作去对消息进行解密。这样终端只需要去实现 AES 加密而不是 AES 解密。
142 |
143 | > 注意:建立这两个会话密钥使得 网络服务器 中的网络运营商无法窃听应用层数据。在这样的设置中,应用提供商必须支持网络运营商处理终端的加网以及为终端生成 NwkSkey。同时应用提供商向网络运营商承诺,它将承担终端所产生的任何流量费用并且保持用于保护应用数据的AppSKey的完全控制权。
144 |
145 | **NetID**的格式如下所述:**NetID**的7个最低有效位称为**NwkID**并且和之前所描述的终端的短地址的7个最高有效位相对应。保留的17个最高有效位可以由网络运营商进行自由选择。
146 |
147 | **DLsettings**字段包含了下行配置:
148 |
149 |
150 |
151 | Bits |
152 | 7 |
153 | 6:4 |
154 | 3:0 |
155 |
156 |
157 | DLsettings |
158 | RFU |
159 | RX1DRoffset |
160 | RX2 Data rate |
161 |
162 |
163 |
164 | **RX1DRoffset**位域设置上行数据速率和RX1下行数据速率的偏移量。默认情况下偏移量为0(意思就是上行数据速率与下行数据速率相等)。偏移量用于考虑一些地区的基站最大功率密度限制和平衡上下行射频链路预算。
165 |
166 | 上行和下行的数据率之间的实际关系是由区域指定的,在LoRaWAN地区参数文件[PARAM]中进行定义。
167 |
168 | 延时**RxDelay**和**RXTimingSetupReq**里的**Delay**字段有着相同的约定。
169 |
170 | ### 6.3 独立激活 ABP
171 |
172 | 在某些情况下,终端可以独立激活。独立激活是让终端绕过 join request - join accept的加网流程,直接加入到指定网络中。
173 |
174 | 独立激活终端,意味着 DevAddr 和两个会话密钥 NwkSKey 和 AppSKey 直接存储在终端中,而不是DevEUI,AppEUI,AppKey。终端在一开始就配置好了入网必要的信息。
175 |
176 | 每个终端必须要有唯一的 NwkSKey 和 AppSKey。这样,一个设备的密钥被破解也不会造成其他设备的安全性危险。创建那些密钥的过程中,密钥不允许通过公开可用信息获得(例如节点地址)。
--------------------------------------------------------------------------------
/chapter/7 Retransmissions back-off Activation.md:
--------------------------------------------------------------------------------
1 | ## **第7章 重传退避**
2 |
3 | 上行帧如下面这样:
4 |
5 | - 需要网络或者应用服务器进行确认或者应答时,如果超时没有接收到,终端需要进行重传。
6 |
7 | 同时,
8 |
9 | - 某些外部事件(断电,无线电干扰,网络断电,地震),将会导致大量的(>100)的设备出现同一时间上行的行为。
10 |
11 | 这样可能会引发灾难性的、持久的、射频网络过载的情况。
12 |
13 | > 注意:这种上行帧的一个典型例子是 JoinRequest,当发生网络中断时,一组终端将会复位 MAC 层。
14 |
15 | > 这一组的终端将会开始广播 JoinRequest 上行帧,只有当从网络中接收到 JoinResponse 命令时才会停止。
16 |
17 | 对于这些数据帧的重传,RX2时隙的末端和下一个上行帧的重传间隔应该是随机的,并且每个终端遵循不同的顺序(例如使用设备地址作为伪随机生成器的种子)。这些消息的发射占空比,要根据当地的参数要求,以及如下的限定,取二者中更严格的一个限定。
18 |
19 |
20 |
21 | 在上电或者复位后的第1个小时 |
22 | T0 < t < T0+1h |
23 | 发射时间 < 36秒 |
24 |
25 |
26 | 在接下来的10小时 |
27 | T0+1 < t < T0+11h |
28 | 发射时间 < 36秒 |
29 |
30 |
31 | 前11小时后的24小时 |
32 | T0+11+N < t < T0+35+N,N>=0 |
33 | 发射时间 < 8.7秒/24小时 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/chapter/8 Introduction to Class B.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## **第8章 Class B 介绍**
5 |
6 | 这章描述了LoRaWAN Class B层,这是为电池节点优化设计的,不管节点是移动的还是固定在某个位置。
7 |
8 | Class B 的终端必须执行如下操作,为了获得服务端发起的下行消息,终端必须按要求开启一个固定时间间隔的接收窗口。
9 |
10 | LoRaWAN Class B 就是在终端上增加一个经过同步的接收窗口。
11 |
12 | LoRaWAN Class A 的限制之一就是终端发送数据使用的Aloha算法;这使得客户应用程序或者服务端不能在确定时间内联系上终端。Class B 的目的就是在Class A 终端随机上行后的接收窗口之外,让终端也能在可预见的时间内开启接收。Class B 是让网关周期发送信标来同步网络中的所有终端,以便终端能够在周期时隙的确定时间点打开一个短的接收窗口(叫做“ping slot”)。
13 |
14 | > 注意:是否要从Class A 切换到 Class B,这个要在终端的应用层进行处理。如果打算从网络端将Class A 切换到 Class B,客户程序只能利用终端 Class A的上行包来反馈一个下行包给节点,需要应用层上处理来识别这个请求 - 这个处理不在LoRaWAN层面。
15 |
16 |
--------------------------------------------------------------------------------
/chapter/9 Principle of synchronous network initiated downlink.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## **第9章 下行同步网络的原理**
4 |
5 | 对于一个支持ClassB的网络,所有网关必须同步广播一个信标,以给所有终端提供一个参考时间。基于这个时间参考,终端可以周期性地打开接收窗口,下文称之为“ping slot”,这个“ping slot”被网络建设者用于发起下行通信。网络使用ping slots其中之一来发起下行通讯的行为,称之为“ping”。用来发起下行通讯的网关,是network server根据终端最近一次上行包的信号传输质量来选择的。基于此,如果终端根据广播的信标帧发现网络发生了切换(通信的网关发生了变化),它必须发出上行帧给network server,以使server端更新下行路径的数据库。
6 |
7 | 所有终端启动后,以Class A来加入网络。之后终端应用层可以切换到Class B。通过以下步骤来实现:
8 |
9 | - 终端应用层请求LoRaWAN层切换到Class B模式。终端的LoRaWAN层搜索信标帧,如果搜索到并且锁定了信标帧,那么就向应用层返回BEACON_LOCKED的服务原语,反之则返回BEACON_NOT_FOUND的服务原语。为了促进信标帧的搜索,LoRaWAN层可以使用稍后介绍的 “BeaconTimingReq” 消息。
10 |
11 | - 基于信标的强度和电池寿命,终端的应用层选择ping slot所需的数据速率和周期,这可以从LoRaWAN层获取到。
12 |
13 | - 一旦处于Class B模式,MAC层需要在所有上行帧的FCTRL字段中,将Class B的位域置为1。这个位用来通知server,设备已经切换到Class B模式。MAC层会给每个beacon和ping时隙安排接收时隙。当成功接收信标,终端的LoRaWAN层将会转发beacon内容给应用层,同时携带测量的射频信号强度。终端的LoRaWAN层在安排beacon和ping时隙时,需要考虑可能的最大时钟偏移。当在ping时隙成功解调出下行帧,它的处理和Class A 的方式一样。
14 |
15 | - 移动的终端,必须周期性地通知network server其位置信息,以便确定下行路径。这是通过发送普通的(可能是空包)“unconfirmed”或者“confirmed”上行包来实现。终端的LoRaWAN层需要将Class B的位域置为1。如果应用程序通过解析beacon内容来判断节点移动,那将会使得这个事情变得更高效。这种情况下终端需要在beacon接收后随机延时一段时间(具体见章节15.5)再上行,避免上行帧冲突。
16 |
17 | - 如果在指定周期内没有接收到beacon(具体见章节12.2),则意味着网络同步丢失。MAC层必须通知应用层切换回Class A。随后终端在上行帧的LoRaWAN层中将不再设置Class B的位域,用以通知network server终端不再处于 Class B 模式。终端的应用程序可以周期性地尝试切换回 Class B。在做这个处理时要先探寻下beacon。
18 |
19 | 下面这张图展示了beacon接收时隙和ping时隙。
20 |
21 | 
22 |
23 | 在这个示例中,指定beacon周期是128秒,ping接收时隙的周期是32秒。大部分时候server并没有使用ping时隙,因此终端可以在接入信道时监听下是否有前导码,如果没有则立即关闭接收窗口。如果监测到前导码,则射频会持续接收,直到下行帧解调完毕。MAC层随后处理数据帧,检查确认地址域匹配和MIC校验有效之后再转发给应用层。
24 |
--------------------------------------------------------------------------------
/chapter/CLASS A - ALL END-DEVICE.md:
--------------------------------------------------------------------------------
1 |
2 | # CLASS A - ALL END-DEVICE
3 |
4 | 所有的LoRaWAN终端都必须满足Class A的规定。
5 |
--------------------------------------------------------------------------------
/chapter/CLASS B - BEACON.md:
--------------------------------------------------------------------------------
1 |
2 | # CLASS B – BEACON
3 |
4 | Class B在当前协议版本中还仅作实验性参考。
5 |
--------------------------------------------------------------------------------
/chapter/CLASS C – CONTINUOUSLY LISTENING.md:
--------------------------------------------------------------------------------
1 |
2 | # CLASS C – CONTINUOUSLY LISTENING
3 |
4 |
--------------------------------------------------------------------------------
/img/Beacon_timing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/Beacon_timing.png
--------------------------------------------------------------------------------
/img/Beacon_timing.vsd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/Beacon_timing.vsd
--------------------------------------------------------------------------------
/img/beacon-less_temporary_operation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/beacon-less_temporary_operation.png
--------------------------------------------------------------------------------
/img/lorawan_ClassCed_reception_slot_timing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/lorawan_ClassCed_reception_slot_timing.png
--------------------------------------------------------------------------------
/img/lorawan_classb_rx_ping_slot_timing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/lorawan_classb_rx_ping_slot_timing.png
--------------------------------------------------------------------------------
/img/lorawan_classes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/lorawan_classes.png
--------------------------------------------------------------------------------
/img/lorawan_ed_receive_slot_timing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twowinter/LoRaWAN-Specification_ZH_CN/600a7c037afc910f0c7210f2b89ff329891378fe/img/lorawan_ed_receive_slot_timing.png
--------------------------------------------------------------------------------