1.0
LoRaWAN_APB入網參數設定
2.0 OTAA入網
OTAA(Over-The-Air Activation),是LoRaWAN的一種空中入網方式。當node在上電的時候處于非入網狀态時,需要先入網才能和伺服器進行通信。其操作就是node發送join_request message,請求入網,然後伺服器同意入網,并且傳回Join-accept message,node再對資訊進行解析,擷取通信參數,之後就可以和伺服器通信了。
APPEUI node自定義的8位元組長位址
APPKEY 伺服器和node端都事先存好,用于對Join_acept message 做加解密處理
DevNonce 2位元組的随機數,用于生成随機的AppSKey和NwkSKey
這些參數可以通過程式固話在裡面,或者通過序列槽或其他方式在入網操作前告訴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)