跳转到主要内容

LoRaWAN协议(五)--OTAA入网方式详述

<h2 id="前言">前言</h2>

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

<p>顺便分享几个工具网站给大家:</p>

<ol>
<li><a href="http://tool.lu/hexstr/">HEX/字符串转换</a></li&gt;
<li><a href="http://www.bejson.com/">JSON校验</a></li&gt;
<li><a href="http://www1.tc711.com/tool/BASE64.htm">BASE64编码/解码</a></li&gt;
</ol>

<h2 id="otaa方式入网步骤">OTAA方式入网步骤</h2>

<h3 id="准备工作">准备工作</h3>

<p>node端在做OTAA入网之前,需要先具备三个参数:</p>

<ul>
<li>APPEUI node自定义的8字节长地址</li>
<li>APPKEY 服务器和node端都事先存好,用于对Join_acept message 做加解密处理</li>
<li>DevNonce 2字节的随机数,用于生成随机的AppSKey和NwkSKey</li>
</ul>

<p>这些参数可以通过程序固话在里面,或者通过串口或其他方式在入网操作前告诉node。</p>

<p>当这些准备工作都做好了之后,node设备就能够入网了。</p>

<h3 id="第一步">第一步</h3>

<p>1.node发起入网请求,也就是发送join_request message,</p>

<p>根据LoRaWAN specification 可知,join_request message的格式如下:</p>

<p><img alt="join_request message的格式" data-entity-type="file" data-entity-uuid="6278876b-c0c5-4338-8a3d-ccd47c2ff0e1" src="/sites/default/files/inline-images/join_request%20message%E7%9A%84%E6%A0%BC%E5%BC%8F.JPG" /></p>

<p>其中</p>

<p><img alt="字段描述" data-entity-type="file" data-entity-uuid="393cabbf-60ec-4512-86ca-435c1ab8495b" src="/sites/default/files/inline-images/%E5%AD%97%E6%AE%B5%E6%8F%8F%E8%BF%B0.JPG" /></p>

<p>需要注意的是Join_request message是未加密的</p>

<h3 id="第二步">第二步</h3>

<p>2.GW将此数据上传至NS</p>

<p>GW对MAC层的数据不进行解析,而是直接将其进行base64编码之后,封装成JSON包上传至NS,MAC层的数据位于rxpk.data</p>

<p>样例数据:</p>

<p><img alt="样例数据" data-entity-type="file" data-entity-uuid="c4c2bf9d-9622-4e27-aaa1-846f1de9d3e5" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE.JPG" /></p>

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

<p>data部分的内容如下:</p>

<p>\x00 \x01 \x00 \x00 \x20 \x00 \xc5 \x26</p>

<p>\x2c \x16 \x10 \x16 \x20 \x00 \x77 \x4a</p>

<p>\x00 \x54 \x7b \x40 \x2d \xe1 \x9a</p>

<p>各部分的内容分别为:</p>

<p><img alt="各部分的内容分别为" data-entity-type="file" data-entity-uuid="7d044a07-799e-4c07-8a1c-bccda6257a0e" src="/sites/default/files/inline-images/%E5%90%84%E9%83%A8%E5%88%86%E7%9A%84%E5%86%85%E5%AE%B9%E5%88%86%E5%88%AB%E4%B8%BA.JPG" /></p>

<h3 id="第三步">第三步</h3>

<p>3.NS向AS发送设备入网包</p>

<p>样例数据:</p>

<p><img alt="样例数据2" data-entity-type="file" data-entity-uuid="0d57e66b-5395-4b21-a24c-9329fca6c18a" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE2.JPG" /></p>

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

<p>\x00 \x01 \x00 \x00 \x20 \x00 \xc5 \x26</p>

<p>\x2c \x16 \x10 \x16 \x20 \x00 \x77 \x4a</p>

<p>\x00 \x54 \x7b \x40 \x2d \xe1 \x9a</p>

<p>&nbsp;</p>

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

<h3 id="第四步">第四步</h3>

<p>4.AS同意入网并且向NS回复同意入网</p>

<p>样例数据:</p>

<p><img alt="样例数据3" data-entity-type="file" data-entity-uuid="f3c44aad-08a5-4b4f-86d9-f450bf98344c" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE3.JPG" /></p>

<h3 id="第五步">第五步</h3>

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

<p>样例数据:</p>

<p><img alt="样例数据4" data-entity-type="file" data-entity-uuid="acfc6ee8-e4d2-42bf-9755-dff760b71c64" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE4.JPG" /></p>

<h3 id="第六步">第六步</h3>

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

<p>样例数据:</p>

<p><img alt="样例数据5" data-entity-type="file" data-entity-uuid="648043c2-893c-41a7-b568-647751655b1d" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE5.JPG" /></p>

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

<h3 id="第七步">第七步</h3>

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

<p>样例数据:</p>

<p><img alt="样例数据6" data-entity-type="file" data-entity-uuid="be9ff732-0b74-4944-b561-babd2e138a66" src="/sites/default/files/inline-images/%E6%A0%B7%E4%BE%8B%E6%95%B0%E6%8D%AE6.JPG" /></p>

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

<p>txpk.data部分就是LoRaWAN MAC的join_accept message.</p>

<h3 id="第八步">第八步</h3>

<p>8.node解析join_accept message 部分</p>

<p>根据LoRaWAN specification 可知,join_accept message的格式如下:</p>

<p><img alt="join_accept message的格式" data-entity-type="file" data-entity-uuid="87e35e56-7988-4358-a2c8-1de3fb16178f" src="/sites/default/files/inline-images/join_accept%20message%E7%9A%84%E6%A0%BC%E5%BC%8F.JPG" /></p>

<p>其中</p>

<p><img alt="字段描述" data-entity-type="file" data-entity-uuid="705644e0-6163-4bcc-b3d0-4c16e8ca1b0d" src="/sites/default/files/inline-images/%E5%AD%97%E6%AE%B5%E6%8F%8F%E8%BF%B0_0.JPG" /></p>

<p>需要注意的是Join_accept message是加密的,需要使用APPKEY解密</p>

<p>txpk.data:<br />
"data": "IPqAKXQ7LS/CmYVCDy8K3k4"</p>

<p>base64解码:<br />
\x20 \xfa \x80 \x29 \x74 \x3b \x2d \x2f<br />
\xc2 \x99 \x85 \x42 \x0f \x2f \x0a \xde<br />
\x4e</p>

<p>这个数据是未解密的,我们还需要解密</p>

<p>解密后为<br />
\x20 \x43 \x75 \xcb \x24 \x00 \x00 \x02<br />
\x00 \x00 \x48 \x03 \x00 \x82 \xc9 \xd0<br />
\xf9</p>

<p>具体的情况如下:</p>

<p><img alt="字段解密" data-entity-type="file" data-entity-uuid="dd8fb888-a88d-40c7-9537-40661dfdfbcc" src="/sites/default/files/inline-images/%E5%AD%97%E6%AE%B5%E8%A7%A3%E5%AF%86.JPG" /></p>

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

<p>计算公式如下:</p>

<ul>
<li>NwkSKey = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad16)</li>
<li>AppSKey = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad16)</li>
</ul>

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

<p>文章来源:<a href="http://www.cnblogs.com/answerinthewind/&quot; id="Header1_HeaderTitle">AnswerInTheWind</a></p>