zoukankan      html  css  js  c++  java
  • LoRaWAN协议(五)--OTAA入网方式详述

    前言

    OTAA(Over-The-Air Activation),是LoRaWAN的一种空中入网方式。当node在上电的时候处于非入网状态时,需要先入网才能和服务器进行通信。其操作就是node发送join_request message,请求入网,然后服务器同意入网,并且返回Join-accept message,node再对信息进行解析,获取通信参数,之后就可以和服务器通信了。

    顺便分享几个工具网站给大家:

    1. HEX/字符串转换
    2. JSON校验
    3. BASE64编码/解码

    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

    样例数据:

    {
        "rxpk": [
            {
                "tmst": 532505620,
                "chan": 6,
                "rfch": 0,
                "freq": 471.9,
                "stat": 1,
                "modu": "LORA",
                "datr": "SF12BW125",
                "codr": "4/5",
                "lsnr": -17,
                "rssi": -81,
                "size": 23,
                "data": "AAEAACAAxSYsFhAWIAB3SgBUe0At4Zo="
            }
        ]
    }
    
    

    此处,将data进行base64解码,我们就可以看到MAC层数据了,因为join_request message数据是未加密的

    data部分的内容如下:

    x00 x01 x00 x00 x20 x00 xc5 x26 
    x2c x16 x10 x16 x20 x00 x77 x4a 
    x00 x54 x7b x40 x2d xe1 x9a 
    

    各部分的内容分别为:

    字段 内容
    MHDR x00
    AppEUI x01 x00 x00 x20 x00 xc5 x26 x2c
    DevEUI x16 x10 x16 x20 x00 x77 x4a x00
    DevNonce x54 x7b
    MIC x40 x2d xe1 x9a

    第三步

    3.NS向AS发送设备入网包

    样例数据:

    {
        "join": {
            "request": {
                "frame": "AAEAACAAxSYsFhAWIAB3SgBUe0At4Zo"
            }
        }
    }
    

    将join.frame进行base64 解码,得到的内容为:

    x00 x01 x00 x00 x20 x00 xc5 x26 
    x2c x16 x10 x16 x20 x00 x77 x4a 
    x00 x54 x7b x40 x2d xe1 x9a 
    

    可以看到,原先的MAC 层的data数据没有变化

    第四步

    4.AS同意入网并且向NS回复同意入网

    样例数据:

    {
        "join": {
            "moteeui": "4a770020161016",
            "accept": true
        }
    }
    

    第五步

    5.NS生成MoteAddr,并将node端的信息发送给AS

    样例数据:

    {
        "join": {
            "appeui": "2c26c50020000001",
            "moteeui": "4a770020161016",
            "details": {
                "moteaddr": "48000002",
                "devicenonce": 31572
            }
        }
    }
    

    第六步

    6.AS生成密钥,并将相关信息告诉NS

    样例数据:

    {
        "join": {
            "moteeui": "4a770020161016",
            "complete": {
                "frame": "IPqAKXQ7LS/CmYVCDy8K3k4",
                "networkkey": "de03331aeb4254e9727b6fafbf13db3d"
            }
        }
    }
    

    可以看到,networkkey直接发送给NS了,这也就是NwkSKey,之所以明文告诉NS,是因为:
    1.NS不做解密的工作,所以不能通过APPKEY解密负载得到
    2.networkkey在NS对上下行数据进行校验的时候会使用到

    第七步

    7.NS将数据告诉GW,GW再转换成MAC包,发送给node

    样例数据:

    {
        "txpk": {
            "tmst": 537505620,
            "freq": 471.9,
            "rfch": 0,
            "powe": 14,
            "modu": "LORA",
            "datr": "SF12BW125",
            "codr": "4/5",
            "ipol": true,
            "size": 17,
            "data": "IPqAKXQ7LS/CmYVCDy8K3k4"
        }
    }
    

    需要注意的是,此时的data部分是经过base64编码以及AES加密的,直接解码,看到的数据是无效的,需要再进行解密,解密需要使用APPKEY,也就是之前介绍的APPKEY.

    txpk.data部分就是LoRaWAN MAC的join_accept message.

    第八步

    8.node解析join_accept message 部分

    根据LoRaWAN specification 可知,join_accept message的格式如下:

    MHDR AppNonce NetID DevAddr DLSettings RxDelay CFList(pad16) MIC
    1字节 3字节 3字节 4字节 4字节 1字节 0/16字节 4字节

    其中

    字段 描述
    MHDR 数据包头,其中包含了数据包的类型,也就是说从这个包头可以知道,这是一个join_accept message
    AppNonce 3字节的unique ID,服务器生成的,产生AppSKey/NwkSKey 会用到
    NetID 网络ID,产生AppSKey/NwkSKey 会用到
    DevAddr 设备的短地址
    DLSettings 设置RX1和RX2的下行接受串口的速率
    RxDelay 从发送完成到打开RX1接受串口的事件
    CFList(pad16) 我也不知道是什么,目前看到的都是0个字节
    MIC 4字节的校验

    需要注意的是Join_accept message是加密的,需要使用APPKEY解密

    txpk.data:
    "data": "IPqAKXQ7LS/CmYVCDy8K3k4"

    base64解码:
    x20 xfa x80 x29 x74 x3b x2d x2f
    xc2 x99 x85 x42 x0f x2f x0a xde
    x4e

    这个数据是未解密的,我们还需要解密

    解密后为
    x20 x43 x75 xcb x24 x00 x00 x02
    x00 x00 x48 x03 x00 x82 xc9 xd0
    xf9

    具体的情况如下:

    字段 解密前 解密后
    MHDR x20 x20
    AppNonce xfa x80 x29 x43 x75 xcb
    NetID x74 x3b x2d x24 x0 x0
    DevAddr x2f xc2 x99 x85 x2 x0 x0 x48
    DLSettings x42 x3
    RxDelay x0f x0
    CFList
    MIC x2f x0a xde x4e x82 xc9 xd0 xf9

    可以看到,DevAddr为0x48000002,而AppSKey和NwkSKey无法直接看出来,需要再计算

    计算公式如下:

    • NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad16)
    • AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad16)

    下一篇文章,我会把这个解密的过程,以及NwkSKey/AppSKey的计算过程,配合C语言,再分析一下。

    **本期的LoRaWAN协议分析就到这里了,如果本文有什么错误,或者对LoRaWAN有什么不理解的,欢迎联系我,邮箱(454626653@qq.com),在左边也有链接,谢谢大家。
    **

  • 相关阅读:
    docker
    协程 gevent
    vue
    数据
    elk 配置
    iOS下架
    综合练习:词频统计
    组合数据类型综合练习
    Python基础综合练习
    熟悉常用的Linux操作
  • 原文地址:https://www.cnblogs.com/answerinthewind/p/6213529.html
Copyright © 2011-2022 走看看