LoRaWAN协议
时间:2023-02-22 12:30:00
本文采集了数据http://www.cnblogs.com/answerinthewind/category/925777.html:
LoRaWAN协议(一)--架构解析
LoRaWAN 分层
总体结构分为4部分:
LoRaWAN从底层到最终用户获取数据的通信过程大致可以分为三个部分:
1.MOTE <---> GW (MAC层)
2.GW <---> server
3.server <---> 用户
LoRa联盟 规定了 MAC层的通信协议只在设备中(GW、MOTE)共同遵守的MAC在层协议的前提下,不同硬件制造商的设备可以相互连接。
而GW <---> Server以及Server <---> 虽然用户的两层协议LoRa联盟是标准化的,但不同的制造商可能会有所不同。
Mote/Node
Mote/Node 是节点,在LoRaWAN节点通常与传感器连接,负责收集传感数据,然后通过LoRaMAC 协议传输给Gateway。
Gateway
Gateway即网关,主要负责向服务器传输节点数据,即完成数据LoRa从网络模式到网络模式的转换,包括Gateway不处理数据,只负责包装和包装数据,然后传输给数据server(服务器)。
Server
按照LoRaWAN的规定,Server又分为四部分--NS(Network server)、AS(Application server)、CS(Customer server)、NC(Network controller)
每个部分都有不同的分工和功能。相应地,我将在后续的文章中讨论。
用户
用户一般只的是直观使用这个数据的人,一般是APP从服务器或其他客户端获取数据。
应用分析
在这里我以LoRaWAN 实现农场土壤湿度检测的方法具体说明了各部分的差异:
检测农场土壤湿度主要分为几个步骤:
·sensor层)
· 将采集到的土壤湿度通过MOTE发送给GW(LoRaMac 层)
· GW将收到的数据发送给NS(GW<--->Server)
· NS再将数据发送给用户(Server<--->Customer)
· 用户通过APP或者其他方式可以看到土壤的湿度状态。(Display)
通过以上的几个步骤,就可以实现远程监控农场土壤湿度。
LoRaWAN协议(二)--LoRaWAN MAC数据包格式
名词解析
上行:终端的数据发送经过一个或多个网关中转到达网络服务器。
下行:由网络服务器发送给终端设备,每条消息对应的终端设备是唯一确定的,而且只通过一个网关中转。
LoRaWAN Classes
LoRaWAN Classes 一共分为3类:Class A,Class B,Class C
Class A:终端先发送,在发送后开启一段时间的接收窗口,终端只有在发送后才可以接收。也就是说上行没有限制,下行的数据只有在上行包发送上来的时候终端才可以接收到。(功耗最低)
Class B:终端和服务器协商好接收的窗口开启的时间以及何时开启,然后再约定的时间进行接收,可以一次接收多个包。(功耗次低)
Class C:终端在发送以外的其他时间都开启接收窗口。更耗能,但通讯延时最低。(功耗最高)
PHY/MAC 层数据链路
总的数据包结构:
注意preamble、PHDR、PHDR_CRC、CRC都是硬件生成,无需软件参与,需要软件参与的就是PHYPayload部分
PHY层数据
上行链路消息:
下行链路消息:
其中上行最后还有CRC校验,而下行没有CRC校验。其中PHDR PHDR_CRC CRC都是射频芯片用于校准数据的完整新和一致性用的,并非用户生成的数据。
MAC 层数据
由上图可以看到,MAC数据是是作为PHYPayload存在的
其中MAC 层的包有三个部分组成:
· MHDR(MAC层帧头)
· MACPayload(MAC层负载)
· MIC(4字节的校验)
而MACPayload又由三个部分组成:
· FHDR (MAC层负载头)
· FPORT(MAC 层数据的通道号)
· FRMPayload(MAC层负载,加密)
而FHDR又由由四个部分组成:
· DevAddr(终端的ID 4字节)
· FCtrl(帧的控制字 1个字节)
· FCnt (帧的序号 2个字节)
· FOpts(帧配置,字节数不定,大部分情况0个字节)
所以,由协议可知,一个上行包或者下行包中的数据内容有哪些,抛开控制命令不说,主要有终端的ID、包的序号、用户的加密负载。
例如我抓到的一个数据包:
\x40 \x7f \xf8 \x8a \x29 \x80 \x2a \x00 \x02 \x07 \x42 \x87 \x3f \xc7 \xb4 \x22 \x04 \x00 \x84 \x8d \x1b \x06 \x2f \x5b \xbc \x57 \xdb \xf2 \x31 \xde \x49 \x61 \x00 \x86 \x99 \xec \x08 \x61 \xf0 \xb7 \xda \x54 \x0a \xfa \xd1 \x31 \xac \xd0 \x44 \x1b \x4d \xfa \x48 \x77 \x19 \xee \x61 \x14 \xbf \x23 \x52 \xd1 \xe9 \x93 \x79 \x6e \x16 \xd7 \x13 \x2e \x58 \x06 \x54 \xc3 \xd2 \x04 \xba \x52 \xa7 \xc8 \x7a \x0b \x8e
这是一个MAC 层的帧,即完整的PHYPayload部分,注意,默认LoRaWAN都是按小端方式传输的。
其中
· MHDR:
\x40
· MACPayload-FHDR-DevAddr:
\x7f \xf8 \x8a \x29
· MACPayload-FHDR-FCtrl:
\x80
· MACPayload-FHDR-FCnt:
\x2a \x00
· MACPayload-FPORT:
\x02
· MACPayload-FRMPayload(加密):
\x07 \x42 \x87 \x3f \xc7 \xb4 \x22 \x04 \x00 \x84 \x8d \x1b \x06 \x2f \x5b \xbc \x57 \xdb \xf2 \x31 \xde \x49 \x61 \x00 \x86 \x99 \xec \x08 \x61 \xf0 \xb7 \xda \x54 \x0a \xfa \xd1 \x31 \xac \xd0 \x44 \x1b \x4d \xfa \x48 \x77 \x19 \xee \x61 \x14 \xbf \x23 \x52 \xd1 \xe9 \x93 \x79 \x6e \x16 \xd7 \x13 \x2e \x58 \x06 \x54 \xc3 \xd2 \x04 \xba \x52 \xa7
· MIC:
\xc8 \x7a \x0b \x8e
LoRaWAN协议(三)--Server端数据协议
LoRaWAN Server 端架构
LoRaWAN 的server包括 NS(Network server)、AS(application server)、CS(Custom server)....
其中NS和AS是比不可少的,是完成LoRaWAN协议的重要组成部分
NS 职责
NS是直接与GW通信的服务器,也是AS和GW之间的桥梁
我所知道的工作有如下几点:
1. 验证数据的合法性(校验MIC)
2. 从GW的信息中提取数据,整理成NS 的JSON数据包
3. 将校验合法的数据打包成新的JSON包上传至AS
4. OTAA入网时向AS发送请求入网消息,然后再将入网信息告诉AS,当获取AS传来的入网的信息,告诉GW
5. GW 和 AS之间的数据通道
有几点需要注意的是NS端的数据不进行AES解密工作。
AS 职责
AS是server端的数据处理中心
它的工作有如下几点:
1. 上行数据的解密
2. 下行数据的加密
3. OTAA入网请求的处理(同意入网/生成APPSKEY/NWKSKEY)
CS 职责
CS负责将AS给的数据处理成用户自定义的数据协议格式,也就是说,CS端必须是用户来完成的,因为上面运行的是用户的协议。这里也就不再多说了。
抓包分析
以下是我在本地服务器端通过抓到得来的数据,我们通过分析数据包来理解数据的走向已及现有的server端处理流程。抓包使用的是tcpdump。
1.NS->AS数据
这是一帧从NS->AS的数据,使用的是TCP方式,AS的数据端口为4000。从data部分我们可以看出来,这是一个未解密的数据。
15:30:53.662471 IP localhost.60795 > localhost.4000: Flags [P.], seq 13:328, ack 14, win 442, options [nop,nop,TS val 414153 ecr 414145], length 315
0x0000: 4500 016f aee3 4000 4006 8ca3 7f00 0001
0x0010: 7f00 0001 ed7b 0fa0 5505 b988 2261 4f1b
0x0020: 8018 01ba ff63 0000 0101 080a 0006 51c9
0x0030: 0006 51c1 7b22 6170 7022 3a7b 226d 6f74
0x0040: 6565 7569 223a 2234 6137 3730 3032 3031
0x0050: 3631 3031 3622 2c22 6469 7222 3a22 7570
0x0060: 222c 2273 6571 6e6f 223a 3532 332c 2275
0x0070: 7365 7264 6174 6122 3a7b 2270 6f72 7422
0x0080: 3a32 2c22 7061 796c 6f61 6422 3a22 5645
0x0090: 7666 6f56 2b72 6631 5838 4177 316e 6c52
0x00a0: 7077 227d 2c22 6d6f 7465 7478 223a 7b22
0x00b0: 6672 6571 223a 3437 312e 352c 2264 6174
0x00c0: 7222 3a22 5346 3132 4257 3132 3522 2c22
0x00d0: 636f 6472 223a 2234 2f35 222c 2261 6472
0x00e0: 223a 6661 6c73 657d 2c22 6777 7278 223a
0x00f0: 5b7b 2265 7569 223a 2266 6666 6562 3832
0x0100: 3765 6266 3231 6130 3722 2c22 7469 6d65
0x0110: 223a 2232 3031 362d 3131 2d32 3454 3135
0x0120: 3a33 303a 3533 5a22 2c22 7469 6d65 6672
0x0130: 6f6d 6761 7465 7761 7922 3a66 616c 7365
0x0140: 2c22 6368 616e 223a 342c 2272 6663 6822
0x0150: 3a30 2c22 7273 7369 223a 2d37 392c 226c
0x0160: 736e 7222 3a2d 3136 2e35 7d5d 7d7d 00
提取其中的数据部分为:
{
"app": {
"moteeui": "4a770020161016",
"dir": "up",
"seqno": 523,
"userdata": {
"port": 2,
"payload": "VEvfoV+rf1X8Aw1nlRpw"
},
"motetx": {
"freq": 471.5,
"datr": "SF12BW125",
"codr": "4/5",
"adr": false
},
"gwrx": [
{
"eui": "fffeb827ebf21a07",
"time": "2016-11-24T15:30:53Z",
"timefromgateway": false,
"chan": 4,
"rfch": 0,
"rssi": -79,
"lsnr": -16.5
}
]
}
}
再把app.userdata.payload 做base64解码之后,得到的payload内容是这个:
app.userdata.payload base64 decoded:
\x54 \x4b \xdf \xa1 \x5f \xab \x7f \x55
\xfc \x03 \x0d \x67 \x95 \x1a \x70
此时看到的payload因为是加密的,所以完全看不出来数据内容是什么。
不过在这里,我们可以看到,NS已经将GW上传的数据做了一定的解析,封装成了另外一种JSON格式,由此,我们不难得出,NS做的工作包括--base64解码/MIC校验/GW数据包的重新组包
2.AS->CS数据
这是一帧从AS->CS的数据,使用的是TCP方式,CS的数据端口为5000。从data部分我们可以看出来,这是一个已经解密完成的数据了。
15:30:53.663219 IP localhost.36774 > localhost.5000: Flags [P.], seq 13:328, ack 13, win 342, options [nop,nop,TS val 414153 ecr 414140], length 315
0x0000: 4500 016f 928b 4000 4006 a8fb 7f00 0001
0x0010: 7f00 0001 8fa6 1388 2a2a 93a0 9d70 4aae
0x0020: 8018 0156 ff63 0000 0101 080a 0006 51c9
0x0030: 0006 51bc 7b22 6170 7022 3a7b 226d 6f74
0x0040: 6565 7569 223a 2234 6137 3730 3032 3031
0x0050: 3631 3031 3622 2c22 6469 7222 3a22 7570
0x0060: 222c 2273 6571 6e6f 223a 3532 332c 2275
0x0070: 7365 7264 6174 6122 3a7b 2270 6f72 7422
0x0080: 3a32 2c22 7061 796c 6f61 6422 3a22 4151
0x0090: 4944 4241 5547 4277 674a 4367 734d 4451
0x00a0: 3450 227d 2c22 6d6f 7465 7478 223a 7b22
0x00b0: 6672 6571 223a 3437 312e 352c 2264 6174
0x00c0: 7222 3a22 5346 3132 4257 3132 3522 2c22
0x00d0: 636f 6472 223a 2234 2f35 222c 2261 6472
0x00e0: 223a 6661 6c73 657d 2c22 6777 7278 223a
0x00f0: 5b7b 2265 7569 223a 2266 6666 6562 3832
0x0100: 3765 6266 3231 6130 3722 2c22 7469 6d65
0x0110: 223a 2232 3031 362d 3131 2d32 3454 3135
0x0120: 3a33 303a 3533 5a22 2c22 7469 6d65 6672
0x0130: 6f6d 6761 7465 7761 7922 3a66 616c 7365
0x0140: 2c22 6368 616e 223a 342c 2272 6663 6822
0x0150: 3a30 2c22 7273 7369 223a 2d37 392c 226c
0x0160: 736e 7222 3a2d 3136 2e35 7d5d 7d7d 00
提取其中的数据部分为:
{
"app": {
"moteeui": "4a770020161016",
"dir": "up",
"seqno": 523,
"userdata": {
"port": 2,
"payload": "AQIDBAUGBwgJCgsMDQ4P"
},
"motetx": {
"freq": 471.5,
"datr": "SF12BW125",
"codr": "4/5",
"adr": false
},
"gwrx": [
{
"eui": "fffeb827ebf21a07",
"time": "2016-11-24T15:30:53Z",
"timefromgateway": false,
"chan": 4,
"rfch": 0,
"rssi": -79,
"lsnr": -16.5
}
]
}
}
再把app.userdata.payload 做base64解码之后,得到的payload内容是这个:
\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08
\x09 \x0a \x0b \x0c \x0d \x0e \x0f
而此时,数据已经完全解密了,可以看到数据就是在AS解密的,解密完再发送给CS,CS再做进一步用户协议的处理。
在这里,我们可以看到,AS已经将NS传输过来的JSON包的payload部分做了解密,然后再传给了CS。所以解密工作是在AS完成的。
邮箱地址:454626653@qq.com 欢迎咨询搭讪
LoRaWAN协议(四)--入网方式概述
前言
在LoRaWAN中,node最终和服务器能够正常数据交互,需要先入网,入网的本质,也就是获得一些通信相关的参数,有以下几个:
1. NwkSKey
2. AppSKey
3. DevAddr
4. DevEui
其中
· NwkSKey用于数据的校验,也就是说在MIC校验时会用到
· AppSKey用于负载的AES加密,也就是说在加密解密时会使用到
· DevAddr是node的短地址,在数据通讯时,使用的是node的短地址
· DevEUI 在ABP入网方式的通讯中不会使用,在OTAA方式中会使用到,是由设备在入网前就产生了。在入网时,node将DevEUI上传,然后服务器会将此DevEUI注册并返回一个DevAddr,也就是说DevAddr此时和DevEUI就建立了映射关系,在node后续的通讯中,使用DevAddr。
LoRaWAN入网方式有两种:
1. ABP (Activation By Personalization)
2. OTAA(Over-The-Air Activation)
下面就讲述一下这两种方式。
ABP 概述
ABP方式是事先将入网信息烧写在设备上,也就是说设备上电已经入网了,无需再特意去请求入网。
这种方式就不再多说了。
OTAA 概述
OTAA方式入网的node,在刚上电的时候,是不处于入网状态的,此时就需要进行入网操作。
如果我们简单的把服务器看做一个整体,那么入网操作的流程是这样的:
1. node 发送入网请求,即join_request message
2. GW 收到 node 的数据,上传给服务器
3. 服务器收到入网请求,同意入网,并且将设备在服务器注册,建立长地址与短地址之间的联系,生成通讯密钥,将通讯密钥的参数打包下发给GW,即 Join-accept message
4. GW 收到服务器的数据,下发给 node
5. node 根据下发的数据包,得到 DevAddr、APPSKEY、NWKSKEY
这篇文章先大概的描述一下两种入网方式
详细的关于OTAA的入网方式见下一篇文章,会有OTAA的抓包分析,以及APPSKEY/NWKSKEY的生成过程,并且有C语言的Example。
LoRaWAN协议(五)--OTAA入网方式详述
前言
OTAA(Over-The-Air Activation),是LoRaWAN的一种空中入网方式。当node在上电的时候处于非入网状态时,需要先入网才能和服务器进行通信。其操作就是node发送join_request message,请求入网,然后服务器同意入网,并且返回Join-accept message,node再对信息进行解析,获取通信参数,之后就可以和服务器通信了。
顺便分享几个工具网站给大家:
1. HEX/字符串转换 http://tool.lu/hexstr/
2. JSON校验 http://www.bejson.com/
3. BASE64编码/解码 http://www1.tc711.com/tool/BASE64.htm
OTAA方式入网步骤
准备工作
node端在做OTAA入网之前,需要先具备三个参数:
· APPEUI node自定义的8字节长地址
· APPKEY 服务器和node端都事先存好,用于对Join_acept message 做加解密处理
· DevNonce 2字节的随机数,用于生成随机的AppSKey和NwkSKey
这些参数可以通过程序固话在里面,或者通过串口或其他方式在入网操作前告诉node。
当这些准备工作都做好了之后,node设备就能够入网了。
第一步
1.node发起入网请求,也就是发送join_request message,
根据LoRaWAN specification 可知,join_request message的格式如下:
MHDR |
APPEUI |
DevEUI |
DevNonce |
MIC |
1字节 |
8字节 |
8字节 |
2字节 |
4字节 |
其中
字段 |
描述 |
MHDR |
数据包头,其中包含了数据包的类型,也就是说从这个包头可以知道,这是一个join_request message |
APPEUI |
应用EUI |
DevEUI |
node的长地址,由node自己定义 |
DevNonce |
一个随机数,用来生成密码 |
MIC |
4字节的校验 |
需要注意的是Join_request message是未加密的
第二步
2.GW将此数据上传至NS
GW对MAC层的数据不进行解析,而是直接将其进行base64编码之后,封装成JSON包上传至NS,MAC层的数据位于rxpk.data
样例数据:
{
{
"chan": 6,
&n