Lorawan協(xié)議說(shuō)明書(shū)可編輯范本_第1頁(yè)
Lorawan協(xié)議說(shuō)明書(shū)可編輯范本_第2頁(yè)
Lorawan協(xié)議說(shuō)明書(shū)可編輯范本_第3頁(yè)
Lorawan協(xié)議說(shuō)明書(shū)可編輯范本_第4頁(yè)
Lorawan協(xié)議說(shuō)明書(shū)可編輯范本_第5頁(yè)
已閱讀5頁(yè),還剩78頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第1章介紹本文檔描述了LoRaWAN網(wǎng)絡(luò)協(xié)議,是針對(duì)電池供電的終端設(shè)備(不管移動(dòng)還是固定位置)進(jìn)行優(yōu)化的一套網(wǎng)絡(luò)協(xié)議.LoRaWAN網(wǎng)絡(luò)通常采用星型拓?fù)浣Y(jié)構(gòu),由拓?fù)渲械木W(wǎng)關(guān)來(lái)轉(zhuǎn)發(fā)終端與后臺(tái)網(wǎng)絡(luò)服務(wù)器間的消息。網(wǎng)關(guān)通過(guò)標(biāo)準(zhǔn)IP連接來(lái)接入網(wǎng)絡(luò)服務(wù)器,而終端則通過(guò)單跳的LoRa或者FSK來(lái)和一個(gè)或多個(gè)網(wǎng)關(guān)通訊。雖然主要傳輸方式是終端上行傳輸給網(wǎng)絡(luò)服務(wù)器,但所有的傳輸通常都是雙向的.終端和網(wǎng)關(guān)間的通訊被分散到不同的信道頻點(diǎn)和數(shù)據(jù)速率上。數(shù)據(jù)速率的選擇需要權(quán)衡距離和消息時(shí)長(zhǎng)兩個(gè)因素,使用不同數(shù)據(jù)速率的設(shè)備互不影響。LoRa的數(shù)據(jù)速率范圍可以從0。3kbps到50kbps.為了最大程度地延長(zhǎng)終端的電池壽命和擴(kuò)大網(wǎng)絡(luò)容量,LoRa網(wǎng)絡(luò)使用速率自適應(yīng)(ADR)機(jī)制來(lái)獨(dú)立管理每個(gè)終端的速率和RF輸出。雖然每個(gè)設(shè)備可以在任意信道,任意時(shí)間,發(fā)送任意數(shù)據(jù),但需要注意遵守如下規(guī)定:終端的每次傳輸都使用偽隨機(jī)方式來(lái)改變信道。頻率的多變使得系統(tǒng)具有更強(qiáng)的抗干擾能力。終端要遵守相應(yīng)頻段和本地區(qū)的無(wú)線電規(guī)定中的發(fā)射占空比要求。終端要遵守相應(yīng)頻段和本地區(qū)的無(wú)線電規(guī)定中的發(fā)射時(shí)長(zhǎng)要求.twowinter注:發(fā)射占空比,意思是發(fā)射時(shí)長(zhǎng)占總時(shí)長(zhǎng)的比例。按照無(wú)線電規(guī)定,每個(gè)設(shè)備不能瘋狂發(fā)射霸占信道,總得給別人一點(diǎn)機(jī)會(huì)。這份文檔主要講述協(xié)議細(xì)節(jié),一些基于各地區(qū)規(guī)定的操作參數(shù),例如發(fā)射占空比和發(fā)射時(shí)長(zhǎng)等,在另一份文檔[LoRaWAN地區(qū)參數(shù)]中做具體描述。將這份文檔分開(kāi),是為了加入新地區(qū)參數(shù)時(shí)不影響基礎(chǔ)的協(xié)議規(guī)范。1。1LoRaWANClasses所有的LoRaWAN設(shè)備都必須至少實(shí)現(xiàn)本文檔描述的ClassA功能。另外也可以實(shí)現(xiàn)本文檔中描述的ClassB和ClassC及后續(xù)將定義的可選功能。不管怎么樣,設(shè)備都必須兼容ClassA.1。2文檔約定MAC命令的格式寫(xiě)作

LinkCheckReq

(粗斜體),位和位域的格式寫(xiě)作

FRMPayload

(粗體),常量的格式寫(xiě)作RECEIVE_DELAY1,變量的格式寫(xiě)作N。在本文檔中,所有多字節(jié)字段的字節(jié)序均采用小端模式EUI是8字節(jié)字段,采用小端模式傳輸默認(rèn)所有RFU保留位都設(shè)為0第2章LoRaWANClasses類型介紹LoRa是由Semtech面向長(zhǎng)距離、低功耗、低速率應(yīng)用而開(kāi)發(fā)的無(wú)線調(diào)制技術(shù).本文檔中,將ClassA基礎(chǔ)上實(shí)現(xiàn)了更多功能的設(shè)備稱為“更高class終端”。2。1LoRaWANClassesLoRa網(wǎng)絡(luò)包含基礎(chǔ)LoRaWAN(稱之為ClassA)和可選功能(ClassB,ClassC):

?圖1。LoRaWANClasses雙向傳輸終端(ClassA):

ClassA的終端在每次上行后都會(huì)緊跟兩個(gè)短暫的下行接收窗口,以此實(shí)現(xiàn)雙向傳輸。傳輸時(shí)隙是由終端在有傳輸需要時(shí)安排,附加一定的隨機(jī)延時(shí)(即ALOHA協(xié)議)。這種ClassA操作是最省電的,要求應(yīng)用在終端上行傳輸后的很短時(shí)間內(nèi)進(jìn)行服務(wù)器的下行傳輸。服務(wù)器在其他任何時(shí)間進(jìn)行的下行傳輸都得等終端的下一次上行。劃定接收時(shí)隙的雙向傳輸終端(ClassB):

ClassB的終端會(huì)有更多的接收時(shí)隙。除了ClassA的隨機(jī)接收窗口,ClassB設(shè)備還會(huì)在指定時(shí)間打開(kāi)別的接收窗口。為了讓終端可以在指定時(shí)間打開(kāi)接收窗口,終端需要從網(wǎng)關(guān)接收時(shí)間同步的信標(biāo)Beacon。這使得服務(wù)器可以知道終端正在監(jiān)聽(tīng)。最大化接收時(shí)隙的雙向傳輸終端(ClassC):

ClassC的終端基本是一直打開(kāi)著接收窗口,只在發(fā)送時(shí)短暫關(guān)閉.ClassC的終端會(huì)比ClassA和ClassB

?更加耗電,但同時(shí)從服務(wù)器下發(fā)給終端的時(shí)延也是最短的。2.2文檔范圍這份LoRaWAN協(xié)議還描述了與ClassA不同的其他Class的額外功能。更高Class的終端必須滿足ClassA定義的所有功能。注意:物理層幀格式,MAC幀格式,以及協(xié)議中更高class和ClassA相同的內(nèi)容都寫(xiě)在了ClassA部分,避免內(nèi)容重復(fù).第3章PHY幀格式LoRa有上行消息和下行消息。3。1上行消息上行消息是由終端發(fā)出,經(jīng)過(guò)一個(gè)或多個(gè)網(wǎng)關(guān)轉(zhuǎn)發(fā)給網(wǎng)絡(luò)服務(wù)器。上行消息使用LoRa射頻幀的嚴(yán)格模式,消息中含有PHDR和PHDR_CRC。載荷有CRC校驗(yàn)來(lái)保證完整性。PHDR,PHDR_CRC及載荷CRC域都通過(guò)射頻收發(fā)器加入。上行PHY:PreamblePHDRPHDR_CRCPHYPayloadCRC圖2。上行PHY幀格式3。2下行消息下行消息是由網(wǎng)絡(luò)服務(wù)器發(fā)出,經(jīng)過(guò)單個(gè)網(wǎng)關(guān)轉(zhuǎn)發(fā)給單個(gè)終端。下行消息使用射頻幀的嚴(yán)格模式,消息中包含PHDR和PHDR_CRC.下行PHY:PreamblePHDRPHDR_CRCPHYPayload圖3。下行PHY幀格式3。3接收窗口每個(gè)上行傳輸后終端都要開(kāi)兩個(gè)短的接收窗口。接收窗口開(kāi)始時(shí)間的規(guī)定,是以傳輸結(jié)束時(shí)間為參考。

?圖4。終端接收時(shí)隙的時(shí)序圖3。3。1第一接收窗口的信道,數(shù)據(jù)速率和啟動(dòng)。第一接收窗口RX1使用的頻率和上行頻率有關(guān),使用的速率和上行速率有關(guān).RX1是在上行調(diào)制結(jié)束后的RECEIVE_DELAY1秒打開(kāi)。上行和RX1時(shí)隙下行速率的關(guān)系是按區(qū)域規(guī)定,詳細(xì)描述在[LoRaWAN地區(qū)參數(shù)]文件中。默認(rèn)第一窗口的速率是和最后一次上行的速率相同。3.3。2第二接收窗口的信道,數(shù)據(jù)速率和啟動(dòng)。第二接收窗口RX2使用一個(gè)固定可配置的頻率和數(shù)據(jù)速率,在上行調(diào)制結(jié)束后的RECEIVE_(tái)DELAY2秒打開(kāi)。頻率和數(shù)據(jù)速率可以通過(guò)MAC命令(見(jiàn)第5章).默認(rèn)的頻率和速率是按區(qū)域規(guī)定,詳細(xì)描述在[LoRaWAN地區(qū)參數(shù)]文件中.3。3.3接收窗口的持續(xù)時(shí)間接收窗口的長(zhǎng)度至少要讓終端射頻收發(fā)器有足夠的時(shí)間來(lái)檢測(cè)到下行的前導(dǎo)碼。3.3.4接收方在接收窗口期間的處理如果在任何一個(gè)接收窗口中檢測(cè)到前導(dǎo)碼,射頻收發(fā)器需要繼續(xù)激活,直到整個(gè)下行幀都解調(diào)完畢。如果在第一接收窗口檢測(cè)到數(shù)據(jù)幀,且這個(gè)數(shù)據(jù)幀的地址和MIC校驗(yàn)通過(guò)確認(rèn)是給這個(gè)終端,那終端就不必開(kāi)啟第二個(gè)接收窗口。3。3.5網(wǎng)絡(luò)發(fā)送消息給終端如果網(wǎng)絡(luò)想要發(fā)一個(gè)下行消息給終端,它會(huì)精確地在兩個(gè)接收窗口的起始點(diǎn)發(fā)起傳輸。3.3.6接收窗口的重要事項(xiàng)終端在第一或第二接收窗口收到下行消息后,或者在第二接收窗口階段,不能再發(fā)起另一個(gè)上行消息。3。3。7其他協(xié)議的收發(fā)處理節(jié)點(diǎn)在LoRaWAN收發(fā)窗口階段可以收發(fā)其他協(xié)議,只要終端能滿足當(dāng)?shù)匾笠约凹嫒軱oRaWAN協(xié)議.2梳理解析LoRaWAN第3章,主要是講了接收窗口這回事,只要記住張圖就行.目前RX1一般是在上行后1秒開(kāi)始,RX2是在上行后2秒開(kāi)始。3源碼分析3.1源碼流程在梳理這章節(jié)的對(duì)應(yīng)代碼時(shí),自己手動(dòng)做了張思維導(dǎo)圖。有時(shí)是這樣,代碼再有層次感,也不及一個(gè)圖.好,請(qǐng)收下。3.2發(fā)送完成就開(kāi)始RX1和RX2延時(shí)staticvoidOnRadioTxDone(void){。.。//Setuptimersif(IsRxWindowsEnabled==true){TimerSetValue(&RxWindowTimer1,RxWindow1Delay);TimerStart(&RxWindowTimer1);if(LoRaMacDeviceClass!=CLASS_C){TimerSetValue(&RxWindowTimer2,RxWindow2Delay);TimerStart(&RxWindowTimer2);}if((LoRaMacDeviceClass==CLASS_C)||(NodeAckRequested==true)){TimerSetValue(&AckTimeoutTimer,RxWindow2Delay+ACK_TIMEOUT+randr(-ACK_TIMEOUT_RND,ACK_TIMEOUT_RND));TimerStart(&AckTimeoutTimer);}}.。.}3。3接收窗口的射頻處理從上面一步,我們已經(jīng)清晰的知道,對(duì)應(yīng)的處理肯定是在OnRxWindow1TimerEvent和OnRxWindow2TimerEvent中。

這兩個(gè)接收窗口的處理,會(huì)對(duì)速率和信道進(jìn)行設(shè)置,按照HYPERLINK”http://blog.csdn。net/iotisan/article/details/55056092"\t”_blank”LoRaWAN協(xié)議中文版_配套文件地區(qū)參數(shù)(物理層)

中對(duì)各地區(qū)的要求分別進(jìn)行處理。比如這個(gè)470的處理,對(duì)上行信道對(duì)48取余得到下行信道.RxWindowSetup(LORAMAC_FIRST_RX1_CHANNEL+(Channel%48)*LORAMAC_STEPWIDTH_第4章MAC幀格式LoRa所有上下行鏈路消息都會(huì)攜帶PHY載荷,PHY載荷以1字節(jié)MAC頭(MHDR)開(kāi)始,緊接著MAC載荷(MACPayload),最后是4字節(jié)的MAC校驗(yàn)碼(MIC)。射頻PHY層:PreamblePHDRPHDR_CRCPHYPayloadCRC圖5。射頻PHY結(jié)構(gòu)(注意CRC只有上行鏈路消息中存在)PHY載荷:MHDRMACPayloadMIC或者M(jìn)HDRJoin—RequestMIC或者M(jìn)HDRJoin-ResponseMIC圖6.PHY載荷結(jié)構(gòu)MAC載荷:FHDRFPortFRMPayload圖7.MAC載荷結(jié)構(gòu)FHDR:DevAddrFCtrlFCntFOpts圖8.幀頭結(jié)構(gòu)圖9。LoRa幀格式元素(即圖5~8)4.1MAC層(PHYPayload)Size(bytes)11..M4PHYPayloadMHDRMACPayloadMICMACPayload字段的最大長(zhǎng)度M,在第6章有詳細(xì)說(shuō)明。4.2MAC頭(MHDR字段)Bit#7.。54。.21.。0MHDRbitsMTypeRFUMajorMAC頭中指定了消息類型(MType)和幀編碼所遵循的LoRaWAN規(guī)范的主版本號(hào)(Major)。4。2。1消息類型(MType位字段)LoRaWAN定義了六個(gè)不同的MAC消息類型:joinrequest,joinaccept,unconfirmeddataup/down,以及confirmeddat(yī)aup/down。MType描述000JoinRequest001JoinAccept010UnconfirmedDataUp011UnconfirmedDat(yī)aDown100ConfirmedDat(yī)aUp101ConfirmedDat(yī)aDown110RFU111Proprietary表1。MAC消息類型4。2。1.1Join—requestandjoin—accept消息join-request和join—accept都是用在空中激活流程中,具體見(jiàn)章節(jié)6。24.2.1.2DatamessagesDatamessages用來(lái)傳輸MAC命令和應(yīng)用數(shù)據(jù),這兩種命令也可以放在單個(gè)消息中發(fā)送。

Confirmed-dat(yī)amessage接收者需要應(yīng)答。

Unconfirmed—datamessage接收者則不需要應(yīng)答.

Proprietarymessages用來(lái)處理非標(biāo)準(zhǔn)的消息格式,不能和標(biāo)準(zhǔn)消息互通,只能用來(lái)和具有相同拓展格式的消息進(jìn)行通信。不同消息類型用不同的方法保證消息一致性,下面會(huì)介紹每種消息類型的具體情況。4。2.2數(shù)據(jù)消息的主版本(Major位字段)Major位字段描述00LoRaWANR101..11RFU表2.Major列表注意:Major定義了激活過(guò)程中(joinprocedure)使用的消息格式(見(jiàn)章節(jié)6.2)和MACPayload的前4字節(jié)(見(jiàn)第4章)。終端要根據(jù)不同的主版本號(hào)實(shí)現(xiàn)不同最小版本的消息格式。終端使用的最小版本應(yīng)當(dāng)提前通知網(wǎng)絡(luò)服務(wù)器。4.3MAC載荷(MACPayload)MAC載荷,也就是所謂的“數(shù)據(jù)幀”,包含:幀頭(FHDR)、端口(FPort)以及幀載荷(FRMPayload),其中端口和幀載荷是可選的.4.3。1幀頭(FHDR)FHDR是由終端短地址(DevAddr)、1字節(jié)幀控制字節(jié)(FCtrl)、2字節(jié)幀計(jì)數(shù)器(FCnt)和用來(lái)傳輸MAC命令的幀選項(xiàng)(FOpts,最多15個(gè)字節(jié))組成。Size(bytes)4120..15FHDRDevAddrFCtrlFCntFOptsFCtrl在上下行消息中有所不同,下行消息如下:Bit#7654[3。。0]FCtrlbitsADRADRACKReqACKFPendingFOptsLen上行消息如下:Bit#7654[3..0]FCtrlbitsADRADRACKReqACKRFUFOptsLen4。3。1。1幀頭中自適應(yīng)數(shù)據(jù)速率的控制(ADR,ADRACKReqinFCtrl)LoRa網(wǎng)絡(luò)允許終端采用任何可能的數(shù)據(jù)速率。LoRaWAN協(xié)議利用該特性來(lái)優(yōu)化固定終端的數(shù)據(jù)速率。這就是自適應(yīng)數(shù)據(jù)速率(AdaptiveDataRate(ADR)).當(dāng)這個(gè)使能時(shí),網(wǎng)絡(luò)會(huì)優(yōu)化使得盡可能使用最快的數(shù)據(jù)速率。移動(dòng)的終端由于射頻環(huán)境的快速變化,數(shù)據(jù)速率管理就不再適用了,應(yīng)當(dāng)使用固定的數(shù)據(jù)速率。如果ADR的位字段有置位,網(wǎng)絡(luò)就會(huì)通過(guò)相應(yīng)的MAC命令來(lái)控制終端設(shè)備的數(shù)據(jù)速率。如果ADR位沒(méi)設(shè)置,網(wǎng)絡(luò)則無(wú)視終端的接收信號(hào)強(qiáng)度,不再控制終端設(shè)備的數(shù)據(jù)速率。ADR位可以根據(jù)需要通過(guò)終端及網(wǎng)絡(luò)來(lái)設(shè)置或取消。不管怎樣,ADR機(jī)制都應(yīng)該盡可能使能,幫助終端延長(zhǎng)電池壽命和擴(kuò)大網(wǎng)絡(luò)容量。注意:即使是移動(dòng)的終端,可能在大部分時(shí)間也是處于非移動(dòng)狀態(tài)。因此根據(jù)它的移動(dòng)狀態(tài),終端也可以請(qǐng)求網(wǎng)絡(luò)使用ADR來(lái)幫助優(yōu)化數(shù)據(jù)速率。如果終端被網(wǎng)絡(luò)優(yōu)化過(guò)的數(shù)據(jù)速率高于自己默認(rèn)的數(shù)據(jù)速率,它需要定期檢查下網(wǎng)絡(luò)仍能收到上行的數(shù)據(jù)。每次上行幀計(jì)數(shù)都會(huì)累加(是針對(duì)于每個(gè)新的上行包,重傳包就不再增加計(jì)數(shù)),終端增加ADR_ACK_CNT計(jì)數(shù)。如果直到ADR_ACK_LIMIT次上行(ADR_ACK_CNT>=ADR_ACK_LIMIT)都沒(méi)有收到下行回復(fù),它就得置高ADR應(yīng)答請(qǐng)求位(ADRACKReq)。網(wǎng)絡(luò)必須在規(guī)定時(shí)間內(nèi)回復(fù)一個(gè)下行幀,這個(gè)時(shí)間是通過(guò)ADR_ACK_DELAY來(lái)設(shè)置,上行之后收到任何下行幀就要把ADR_ACK_CNT的計(jì)數(shù)重置。當(dāng)終端在接收時(shí)隙中的任何回復(fù)下行幀的ACK位字段不需要設(shè)置,表示網(wǎng)關(guān)仍在接收這個(gè)設(shè)備的上行幀。如果在下一個(gè)ADR_ACK_DELAY上行時(shí)間內(nèi)都沒(méi)收到回復(fù)(例如,在總時(shí)間ADR_ACK_LIMIT+ADR_ACK_DELAY之后),終端必須切換到下一個(gè)更低速率,使得能夠獲得更遠(yuǎn)傳輸距離來(lái)重連網(wǎng)絡(luò).終端如果在每次ADR_ACK_LIMIT到了之后依舊連接不上,就需要每次逐步降低數(shù)據(jù)速率.如果終端用它的默認(rèn)數(shù)據(jù)速率,那就不需要置位ADRACKReq,因?yàn)闊o(wú)法幫助提高鏈路距離。注意:不要ADRACKReq立刻回復(fù),這樣給網(wǎng)絡(luò)預(yù)留一些余量,讓它做出最好的下行調(diào)度處理。注意:上行傳輸時(shí),如果ADR_ACK_CNT〉=ADR_ACK_LIMIT并且當(dāng)前數(shù)據(jù)速率比設(shè)備的最小數(shù)據(jù)速率高,就要設(shè)置ADRACKReq,其它情況下不需要.4.3。1。2消息應(yīng)答位及應(yīng)答流程(ACKinFCtrl)收到confirmed類型的消息時(shí),接收端要回復(fù)一條應(yīng)答消息(應(yīng)答位ACK要進(jìn)行置位)。如果發(fā)送者是終端,網(wǎng)絡(luò)就利用終端發(fā)送操作后打開(kāi)的兩個(gè)接收窗口之一進(jìn)行回復(fù)。如果發(fā)送者是網(wǎng)關(guān),終端就自行決定是否發(fā)送應(yīng)答。

?應(yīng)答消息只會(huì)在收到消息后回復(fù)發(fā)送,并且不重發(fā)。注意:為了讓終端盡可能簡(jiǎn)單,盡可能減少狀態(tài),在收到confirmation類型需要確認(rèn)的數(shù)據(jù)幀,需要立即發(fā)送一個(gè)嚴(yán)格的應(yīng)答數(shù)據(jù)幀?;蛘?終端會(huì)延遲發(fā)送應(yīng)答,在它下一個(gè)數(shù)據(jù)幀中再攜帶.4。3。1。3重傳流程當(dāng)需要應(yīng)答卻沒(méi)收到應(yīng)答時(shí)就會(huì)進(jìn)行重發(fā),重發(fā)的個(gè)數(shù)由終端自己定,可能每個(gè)終端都不一樣,這個(gè)參數(shù)也可以由網(wǎng)絡(luò)服務(wù)器來(lái)設(shè)置調(diào)整。注意:一些應(yīng)答機(jī)制的示例時(shí)序圖在第18章中有提供。注意:如果終端設(shè)備重發(fā)次數(shù)到達(dá)了最大值,它可以降低數(shù)據(jù)速率來(lái)重連。至于后面是否再重發(fā)還是說(shuō)丟棄不管,都取決于終端自己。注意:如果網(wǎng)絡(luò)服務(wù)器重發(fā)次數(shù)到達(dá)了最大值,它就認(rèn)為該終端掉線了,直到它再收到終端的消息.一旦和終端設(shè)備的連接出現(xiàn)問(wèn)題時(shí),要不要重發(fā)都取決于網(wǎng)絡(luò)服務(wù)器自己。注意:在重傳期間的數(shù)據(jù)速率回退的建議策略在章節(jié)18。4中有描述.4。3。1.4幀掛起位(FPendinginFCtrl只在下行有效)幀掛起位(FPending)只在下行交互中使用,表示網(wǎng)關(guān)還有掛起數(shù)據(jù)等待下發(fā),需要終端盡快發(fā)送上行消息來(lái)再打開(kāi)一個(gè)接收窗口.FPending的詳細(xì)用法在章節(jié)18.3。4.3。1.5幀計(jì)數(shù)器(FCnt)每個(gè)終端有兩個(gè)計(jì)數(shù)器跟蹤數(shù)據(jù)幀的個(gè)數(shù),一個(gè)是上行鏈路計(jì)數(shù)器(FCntUp),由終端在每次上行數(shù)據(jù)給網(wǎng)絡(luò)服務(wù)器時(shí)累加;另一個(gè)是下行鏈路計(jì)數(shù)器(FCntDown),由服務(wù)器在每次下行數(shù)據(jù)給終端時(shí)累計(jì)。網(wǎng)絡(luò)服務(wù)器為每個(gè)終端跟蹤上行幀計(jì)數(shù)及產(chǎn)生下行幀計(jì)數(shù)。終端入網(wǎng)成功后,終端和服務(wù)端的上下行幀計(jì)數(shù)同時(shí)置0。每次發(fā)送消息后,發(fā)送端與之對(duì)應(yīng)的FCntUp或FCntDown就會(huì)加1。接收方會(huì)同步保存接收數(shù)據(jù)的幀計(jì)數(shù),對(duì)比收到的計(jì)數(shù)值和當(dāng)前保存的值,如果兩者相差小于MAX_FCNT_GAP(要考慮計(jì)數(shù)器滾動(dòng)),接收方就按接收的幀計(jì)數(shù)更新對(duì)應(yīng)值.如果兩者相差大于MAX_FCNY_GAP就說(shuō)明中間丟失了很多數(shù)據(jù),這條以及后面的數(shù)據(jù)就被丟掉。LoRaWAN的幀計(jì)數(shù)器可以用16位和32位兩種,節(jié)點(diǎn)上具體執(zhí)行哪種計(jì)數(shù),需要在帶外通知網(wǎng)絡(luò)側(cè),告知計(jì)數(shù)器的位數(shù)。

?如果采用16位幀計(jì)數(shù),F(xiàn)Cnt字段的值可以使用幀計(jì)數(shù)器的值,此時(shí)有需要的話通過(guò)在前面填充0(值為0)字節(jié)來(lái)補(bǔ)足;如果采用32位幀計(jì)數(shù),

?FCnt就對(duì)應(yīng)計(jì)數(shù)器32位的16個(gè)低有效位(上行數(shù)據(jù)使用上行FCnt,下行數(shù)據(jù)使用下行FCnt)。終端在相同應(yīng)用和網(wǎng)絡(luò)密鑰下,不能重復(fù)用相同的FCntUp數(shù)值,除非是重傳。4.3.1。6幀可選項(xiàng)(FOptsLeninFCtrl,FOpts)

?FCtrl字節(jié)中的FOptsLen位字段描述了整個(gè)幀可選項(xiàng)(FOpts)的字段長(zhǎng)度.FOpts字段存放MAC命令,最長(zhǎng)15字節(jié),詳細(xì)的MAC命令見(jiàn)章節(jié)4.4.如果FOptsLen為0,則FOpts為空.在FOptsLen非0時(shí),則反之。如果MAC命令在FOpts字段中體現(xiàn),port0不能用(FPort要么不體現(xiàn),要么非0)。MAC命令不能同時(shí)出現(xiàn)在FRMPayload和FOpts中,如果出現(xiàn)了,設(shè)備丟掉該組數(shù)據(jù)。4.3.2端口字段(FPort)如果幀載荷字段不為空,端口字段必須體現(xiàn)出來(lái)。端口字段有體現(xiàn)時(shí),若FPort的值為0表示FRMPayload只包含了MAC命令;具體見(jiàn)章節(jié)4。4中的MAC命令。FPort的數(shù)值從1到223(0x01..0xDF)都是由應(yīng)用層使用。FPort的值從224到255(0xE0..0xFF)是保留用做未來(lái)的標(biāo)準(zhǔn)應(yīng)用拓展。Size(bytes)7。.230..10..NMACPayloadFHDRFPortFRMPayloadN是應(yīng)用程序載荷的字節(jié)個(gè)數(shù)。N的有效范圍具體在第7章有定義。N應(yīng)該小于等于:

N<=M—1—(FHDR長(zhǎng)度)

?M是MAC載荷的最大長(zhǎng)度。4.3.3MAC幀載荷加密(FRMPayload)如果數(shù)據(jù)幀攜帶了載荷,F(xiàn)RMPayload必須要在MIC計(jì)算前進(jìn)行加密。

?加密機(jī)制是采用IEEE802.15。4/2006的AES128HYPERLINK"http://lib。csdn。net/base/datastructure”\o”算法與數(shù)據(jù)結(jié)構(gòu)知識(shí)庫(kù)"算法。默認(rèn)的,加密和加密由LoRaWAN層來(lái)給所有的FPort來(lái)執(zhí)行.如果加密/解密由應(yīng)用層來(lái)做更方便的話,也可以在LoRaWAN層之上給特定FPorts來(lái)執(zhí)行,除了端口0。具體哪個(gè)節(jié)點(diǎn)的哪個(gè)FPort在LoRaWAN層之外要做加解密,必須要和服務(wù)器通過(guò)out-of-band信道來(lái)交互(見(jiàn)第19章)。4。3.3.1LoRaWAN的加密密鑰K根據(jù)不同的FPort來(lái)使用:FPortK0NwkSKey1。.255AppSKey表3:FPort列表具體加密是這樣:

?pld=FRMPayload

對(duì)于每個(gè)數(shù)據(jù)幀,算法定義了一個(gè)塊序列Ai,i從1到k,k=ceil(len(pld)/16):Size(bytes)1414411Ai0x014x0x00DirDevAddrFCntUporFCntDown0x00i方向字段(Dir)在上行幀時(shí)為0,在下行幀時(shí)為1.

?塊Ai通過(guò)加密,得到一個(gè)由塊Si組成的序列S。Si=aes128_encrypt(K,Ai)fori=1..k

?S=S1|S2|..|Sk通過(guò)異或計(jì)算對(duì)payload進(jìn)行加解密:4。3。3.2LoRaWAN層之上的加密

如果LoRaWAN之上的層級(jí)在已選的端口上(但不能是端口0,這是給MAC命令保留的)提供了預(yù)加密的FRMPayload給LoRaWAN,LoRaWAN則不再對(duì)FRMPayload進(jìn)行修改,直接將FRMPayload從MACPayload傳到應(yīng)用層,以及從應(yīng)用層傳到MACPayload。4.4消息校驗(yàn)碼(MIC)消息檢驗(yàn)碼要計(jì)算消息中所有字段。

msg=MHDR|FHDR|FPort|FRMPayloadMIC是按照[RFC4493]來(lái)計(jì)算:cmac=aes128_cmac(NwkSKey,B0|msg)

?MIC=cmac[0。。3]塊B0的定義如下:Size(bytes)1414411B00x494x0x00DirDevAddrFCntUporFCntDown0x00l(fā)en(msg)方向字段(Dir)在上行幀時(shí)為0,在下行幀時(shí)為1.LoRaWAN第4章,主要講述了MAC幀格式,對(duì)所有涉及的字段都做了解釋。千言萬(wàn)語(yǔ)匯成一句話,哦不,匯成一個(gè)表。數(shù)據(jù)幀頭DevAddrFCtrlFCntFOpts數(shù)據(jù)幀PreamblePHDRPHDR_CRCMHDRFHDRFPortFRMPayloadMICCRCMAC層PreamblePHDRPHDR_CRCMHDRMACPayloadMICCRCPHY層PreamblePHDRPHDR_CRCPHYPayloadCRC好了,幀格式是大家隨手都能看到的東西,本尊作為IoT小能手,如果不能提出一些稍有深度的信息增量,就對(duì)不起這個(gè)稱號(hào)了.所以,有些協(xié)議設(shè)計(jì)層面的心得要分享下:特別酷的ADR(速率自適應(yīng))機(jī)制

這個(gè)章節(jié)中最亮眼的莫過(guò)于速率自適應(yīng)機(jī)制,簡(jiǎn)直是為LoRa網(wǎng)絡(luò)量身定做的:一旦使能了FCtrl中的ADR位,距離近信號(hào)好的節(jié)點(diǎn)用高速率,距離遠(yuǎn)信號(hào)弱的節(jié)點(diǎn)用低速率,不小心被調(diào)高了速率,則自動(dòng)降下來(lái)。這樣,盡可能地提高了傳輸速率,也有效提高了網(wǎng)絡(luò)容量.我已經(jīng)見(jiàn)過(guò)不少?gòu)S家,拿這個(gè)協(xié)議的公知特點(diǎn)當(dāng)產(chǎn)品賣點(diǎn)了.可同時(shí)攜帶數(shù)據(jù)和命令的MAC幀

一般來(lái)說(shuō),應(yīng)用除了數(shù)據(jù),出于管理需要,肯定還會(huì)涉及命令。比如基站要查詢節(jié)點(diǎn)狀態(tài),或者節(jié)點(diǎn)要請(qǐng)求變更信道等。所以LoRaWAN協(xié)議設(shè)計(jì)上利用FOpts把數(shù)據(jù)和命令揉在一個(gè)MAC幀里,這樣可以提高交互效率,有效地降低功耗。這在寸土寸金,哦不,寸庫(kù)侖(電量單位)寸金的物聯(lián)網(wǎng)應(yīng)用中,是一個(gè)很有必要的設(shè)計(jì).3源碼解析這章的處理基本都在\src\mac\LoRaMac.c中,下面按照MAC幀格式的字段逐個(gè)解析下.3.1MAC層MHDR在LoRaWAN的數(shù)據(jù)API中處理了MHDR,這個(gè)字段內(nèi)容比較少,就按需選擇了消息類型是confirm還是unconfirm.

另外在管理API中的Join—Req的消息類型。具體可見(jiàn)LoRaMacMcpsRequest()和LoRaMacMlmeRequest()這兩個(gè)函數(shù).3。2MACPayloadMACPayload的組幀都在PrepareFrame()這個(gè)函數(shù)中處理,將macHdr和macPayload的fCtrl、FPort、FRMPayload都傳遞進(jìn)去,完成整個(gè)MAC層的數(shù)據(jù)組幀。LoRaMacBuffer就存放了MACPayload的數(shù)據(jù),這個(gè)變量的組幀和協(xié)議字段定義是一一對(duì)應(yīng)。MACPayload的組幀處理,在大流程上是對(duì)join和數(shù)據(jù)兩種類型的幀分別處理,用兩個(gè)case分開(kāi)。為了方便閱覽,我把函數(shù)代碼框架提煉了出來(lái)。LoRaMacStatus_tPrepareFrame(LoRaMacHeader_t*macHdr,LoRaMacFrameCtrl_t*fCtrl,uint8_tfPort,void*fBuffer,uint16_tfBufferSize){switch(macHdr—>Bits.MType){caseFRAME_TYPE_(tái)JOIN_REQ:。.。//省略break;caseFRAME_TYPE_DATA_CONFIRMED_UP:NodeAckRequested=true;//IntentionalfalltroughcaseFRAME_TYPE_(tái)DATA_UNCONFIRMED_UP:。.。fCtrl—>Bits.AdrAckReq=AdrNextDr(fCtrl-〉Bits。Adr,true,&LoRaMacParams。ChannelsDatarat(yī)e);...if(SrvAckRequested==true){SrvAckRequested=false;fCtrl—>Bits。Ack=1;}LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr)&0xFF;LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr〉>8)&0xFF;LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr>>16)&0xFF;LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr〉>24)&0xFF;LoRaMacBuffer[pktHeaderLen++]=fCtrl-〉Value;LoRaMacBuffer[pktHeaderLen++]=UpLinkCounter&0xFF;LoRaMacBuffer[pktHeaderLen++]=(UpLinkCounter>〉8)&0xFF;//CopytheMACcommandswhichmustbere—otheMACcommandbuffermemcpy1(&MacCommandsBuffer[MacCommandsBufferIndex],MacCommandsBufferToRepeat(yī),MacCommandsBufferToRepeatIndex);MacCommandsBufferIndex+=MacCommandsBufferToRepeatIndex;if((payload!=NULL)&&(payloadSize〉0)){if((MacCommandsBufferIndex〈=LORA_MAC_COMMAND_MAX_LENGTH)&&(MacCommandsInNextTx==true)){fCtrl->Bits。FOptsLen+=MacCommandsBufferIndex;//UpdateFCtrlfieldwithnewvalueofOptionsLengthLoRaMacBuffer[0x05]=fCtrl->Value;for(i=0;i〈MacCommandsBufferIndex;i++){LoRaMacBuffer[pktHeaderLen++]=MacCommandsBuffer[i];}}}else{if((MacCommandsBufferIndex〉0)&&(MacCommandsInNextTx)){payloadSize=MacCommandsBufferIndex;payload=MacCommandsBuffer;framePort=0;}}MacCommandsInNextTx=false;//StoreMACcommandswhichmustbere—sendincasethedevicedoesnotreceiveadownlinkanymoreMacCommandsBufferToRepeatIndex=ParseMacCommandsToRepeat(MacCommandsBuffer,MacCommandsBufferIndex,MacCommandsBufferToRepeat(yī));if(MacCommandsBufferToRepeatIndex〉0){MacCommandsInNextTx=true;}MacCommandsBufferIndex=0;if((payload?。絅ULL)&&(payloadSize>0)){LoRaMacBuffer[pktHeaderLen++]=framePort;if(framePort==0){LoRaMacPayloadEncrypt((uint8_t*)payload,payloadSize,LoRaMacNwkSKey,LoRaMacDevAddr,UP_LINK,UpLinkCounter,LoRaMacPayload);}else{LoRaMacPayloadEncrypt((uint8_t*)payload,payloadSize,LoRaMacAppSKey,LoRaMacDevAddr,UP_LINK,UpLinkCounter,LoRaMacPayload);}memcpy1(LoRaMacBuffer+pktHeaderLen,LoRaMacPayload,payloadSize);}LoRaMacBufferPktLen=pktHeaderLen+payloadSize;LoRaMacComputeMic(LoRaMacBuffer,LoRaMacBufferPktLen,LoRaMacNwkSKey,LoRaMacDevAddr,UP_LINK,UpLinkCounter,&mic);LoRaMacBuffer[LoRaMacBufferPktLen+0]=mic&0xFF;LoRaMacBuffer[LoRaMacBufferPktLen+1]=(mic〉>8)&0xFF;LoRaMacBuffer[LoRaMacBufferPktLen+2]=(mic>>16)&0xFF;LoRaMacBuffer[LoRaMacBufferPktLen+3]=(mic〉>24)&0xFF;LoRaMacBufferPktLen+=LORAMAC_MFR_LEN;break;caseFRAME_TYPE_PROPRIETARY:。。.//省略break;default:returnLORAMAC_STATUS_SERVICE_UNKNOWN;}returnLORAMAC_STATUS_OK;}Join-request的組幀處理對(duì)應(yīng)協(xié)議第6章6.2.4Join—requestmessage。

數(shù)據(jù)幀的組幀處理則稍微復(fù)雜些,尤其是FHDR,下面逐個(gè)字段講解下FHDR。3。2。1MACPayload中的FHDR1.FHDR中的DevAddrLoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr)&0xFF;

LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr>>8)&0xFF;

?LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr>>16)&0xFF;

?LoRaMacBuffer[pktHeaderLen++]=(LoRaMacDevAddr〉〉24)&0xFF;2。FHDR中的FCtrl首先ADR位段是在傳入PrepareFrame()之前,就做了處理。

?fCtrl。Bits。Adr=AdrCtrlOn;接著AdrAckReq位段,在長(zhǎng)期失聯(lián)情況下會(huì)發(fā)送AdrAckReq確認(rèn)鏈路。

fCtrl—〉Bits.AdrAckReq=AdrNextDr(fCtrl—>Bits.Adr,true,&LoRaMacParams。ChannelsDatarat(yī)e);最后F0ptsLen位段,會(huì)在下面計(jì)算完FOpts之后更新。3。FHDR中的FCntLoRaMacBuffer[pktHeaderLen++]=UpLinkCounter&0xFF;

LoRaMacBuffer[pktHeaderLen++]=(UpLinkCounter>>8)&0xFF;這個(gè)UpLinkCounter會(huì)在物理層發(fā)送完成后會(huì)按照協(xié)議進(jìn)行累加??梢钥吹竭@是個(gè)32位計(jì)數(shù)器,按照協(xié)議規(guī)定,“如果采用32位幀計(jì)數(shù),FCnt就對(duì)應(yīng)計(jì)數(shù)器32位的16個(gè)低有效位”。這是上行的,另外下行的也類似。4。FHDR中的FOpts把MAC命令放入F0pts中,并且更新F0ptsLen。MAC命令,要么使用非零的FPort來(lái)和數(shù)據(jù)一起傳輸,要么使用FPort0來(lái)單獨(dú)傳輸。//CopytheMACcommandswhichmustbere—sendintotheMACcommandbuffermemcpy1(&MacCommandsBuffer[MacCommandsBufferIndex],MacCommandsBufferToRepeat,MacCommandsBufferToRepeat(yī)Index);MacCommandsBufferIndex+=MacCommandsBufferToRepeatIndex;if((payload!=NULL)&&(payloadSize>0)){if((MacCommandsBufferIndex<=LORA_MAC_COMMAND_MAX_LENGTH)&&(MacCommandsInNextTx==true)){fCtrl—>Bits.FOptsLen+=MacCommandsBufferIndex;//UpdateFCtrlfieldwithnewvalueofOptionsLengthLoRaMacBuffer[0x05]=fCtrl—>Value;for(i=0;i<MacCommandsBufferIndex;i++){LoRaMacBuffer[pktHeaderLen++]=MacCommandsBuffer[i];}}}else{if((MacCommandsBufferIndex>0)&&(MacCommandsInNextTx)){payloadSize=MacCommandsBufferIndex;payload=MacCommandsBuffer;framePort=0;}}3.2.2MACPayload中的FPort這個(gè)是在應(yīng)用層一直傳遞進(jìn)去的,協(xié)議棧默認(rèn)是用了端口2。這個(gè)是后期大家在應(yīng)用時(shí)要調(diào)整的,類似于IP端口,不同的端口對(duì)應(yīng)不同的服務(wù)。3.3MIC解析在函數(shù)PrepareFrame()的最后是調(diào)用LoRaMacComputeMic()計(jì)算出整個(gè)MAC層的校驗(yàn)碼。應(yīng)用層這邊基本不用改這邊就暫時(shí)不細(xì)究了。第5章MAC命令對(duì)網(wǎng)絡(luò)管理者而言,有一套專門(mén)的MAC命令用來(lái)在服務(wù)器和終端MAC層之間交互.這套MAC命令對(duì)應(yīng)用程序(不管是服務(wù)器端還是終端設(shè)備的應(yīng)用程序)是不可見(jiàn)的。單個(gè)數(shù)據(jù)幀中可以攜帶MAC命令,要么在FOpts字段中捎帶,要么在獨(dú)立幀中將FPort設(shè)成0后放在FRMPayload里。如果采用FOpts捎帶的方式,MAC命令是不加密并且不長(zhǎng)度超過(guò)15字節(jié)。如果采用獨(dú)立幀放在FRMPayload的方式,那就必須采用加密方式,并且不超過(guò)FRMPayload的最大長(zhǎng)度。注意:如果MAC命令不想被竊聽(tīng),那就必須以獨(dú)立幀形式放在FRMPayload中。每個(gè)MAC命令是由1字節(jié)CID跟著一段可能為空的字節(jié)序列組成的。CIDCommand由誰(shuí)發(fā)送描述終端網(wǎng)關(guān)0x02LinkCheckReqx終端利用這個(gè)命令來(lái)判斷網(wǎng)絡(luò)連接質(zhì)量0x02LinkCheckAnsxLinkCheckReq的回復(fù)。包含接收信號(hào)強(qiáng)度,告知終端接收質(zhì)量0x03LinkADRReqx向終端請(qǐng)求改變數(shù)據(jù)速率,發(fā)射功率,重傳率以及信道0x03LinkADRAnsxLinkADRReq的回復(fù).0x04DutyCycleReqx向終端設(shè)置發(fā)送的最大占空比.0x04DutyCycleAnsxDutyCycleReq的回復(fù)。0x05RXParamSetupReqx向終端設(shè)置接收時(shí)隙參數(shù).0x05RXParamSetupAnsxRXParamSetupReq的回復(fù).0x06DevStat(yī)usReqx向終端查詢其狀態(tài)。0x06DevStat(yī)usAnsx返回終端設(shè)備的狀態(tài),即電池余量和鏈路解調(diào)預(yù)算.0x07NewChannelReqx創(chuàng)建或修改1個(gè)射頻信道定義。0x07NewChannelAnsxNewChannelReq的回復(fù)。0x08RXTimingSetupReqx設(shè)置接收時(shí)隙的時(shí)間。0x08RXTimingSetupAnsxRXTimingSetupReq的回復(fù)。0x80~0xFF私有xx給私有網(wǎng)絡(luò)命令拓展做預(yù)留。表4:MAC命令表注意:MAC命令的長(zhǎng)度雖然沒(méi)有明確給出,但是MAC執(zhí)行層必須要知道.因此未知的MAC命令無(wú)法被忽略,且前面未知的MAC命令會(huì)終止MAC命令的處理隊(duì)列。所以建議按照LoRaWAN協(xié)議介紹的MAC命令來(lái)處理MAC命令.這樣所有基于LoRaWAN協(xié)議的MAC命令都可以被處理,即使是更高版本的命令.2梳理解析從LoRaWAN第4章的幀格式可以得到如下信息:MAC命令,要么使用FPort0來(lái)單獨(dú)傳輸,要么使用非零的FPort來(lái)和數(shù)據(jù)一起傳輸。LoRaWAN第5章,LoRaWAN出于網(wǎng)絡(luò)管理需要,提出了9條MAC命令,這個(gè)章節(jié)是對(duì)9條命令進(jìn)行具體的描述。說(shuō)個(gè)題外話,CLAA(中國(guó)LoRa應(yīng)用聯(lián)盟)在9條命令以外還擴(kuò)充了一些MAC命令?,F(xiàn)階段協(xié)議還不能公開(kāi),所以我就不多說(shuō)了.中興目前作為L(zhǎng)oRa聯(lián)盟董事會(huì)成員,也許以后會(huì)把這些拓展MAC命令引入到LoRaWAN協(xié)議也說(shuō)不準(zhǔn),大家暫且當(dāng)個(gè)課外知識(shí)了解下就好。3代碼位置MAC命令枚舉/*!*LoRaMACmoteMACcommands**LoRaWANSpecificationV1。0.1,chapter5,table4*/typedefenumeLoRaMacMoteCmd{/*!*LinkCheckReq*/MOTE_(tái)MAC_LINK_CHECK_REQ=0x02,/*!*LinkADRAns*/MOTE_MAC_LINK_ADR_ANS=0x03,/*!*DutyCycleAns*/MOTE_MAC_DUTY_CYCLE_ANS=0x04,/*!*RXParamSetupAns*/MOTE_MAC_RX_PARAM_SETUP_ANS=0x05,/*!*DevStatusAns*/MOTE_MAC_DEV_STATUS_ANS=0x06,/*!*NewChannelAns*/MOTE_MAC_NEW_CHANNEL_ANS=0x07,/*!*RXTimingSetupAns*/MOTE_M(jìn)AC_RX_TIMING_SETUP_ANS=0x08,}LoRaMacMoteCmd_t;/*!*LoRaMACserverMACcommands**LoRaWANSpecificationV1。0。1chapter5,table4*/typedefenumeLoRaMacSrvCmd{/*!*LinkCheckAns*/SRV_MAC_LINK_CHECK_ANS=0x02,/*!*LinkADRReq*/SRV_MAC_LINK_ADR_REQ=0x03,/*!*DutyCycleReq*/SRV_MAC_DUTY_CYCLE_REQ=0x04,/*!*RXParamSetupReq*/SRV_MAC_RX_PARAM_SETUP_REQ=0x05,/*?。狣evStatusReq*/SRV_MAC_DEV_STATUS_REQ=0x06,/*!*NewChannelReq*/SRV_MAC_NEW_CHANNEL_REQ=0x07,/*!*RXTimingSetupReq*/SRV_MAC_RX_TIMING_SETUP_REQ=0x08,}LoRaMacSrvCmd_t;MAC命令的接收處理OnRadioRxDone()攜帶著MAC幀進(jìn)來(lái),經(jīng)過(guò)層層篩選,最終到達(dá)ProcessMacCommands()來(lái)處理MAC命令.

這里代碼中涉及的兩種處理方式,可以跟協(xié)議對(duì)應(yīng)起來(lái):port=0時(shí),MAC命令放在FRMPayload中,需要先解密再處理;port非零時(shí),MAC命令放在fopts中。if(port==0){if(fCtrl.Bits。FOptsLen==0){LoRaMacPayloadDecrypt(payload+appPayloadStartIndex,frameLen,nwkSKey,address,DOWN_LINK,downLinkCounter,LoRaMacRxPayload);//DecodeframepayloadMACcommandsProcessMacCommands(LoRaMacRxPayload,0,frameLen,snr);}}else{if(fCtrl.Bits。FOptsLen〉0){//DecodeOptionsfieldMACcommands.OmitthefPort.ProcessMacCommands(payload,8,appPayloadStartIndex-1,snr);}}MAC命令的發(fā)送及回復(fù)MAC命令的發(fā)送及回復(fù)處理都在這個(gè)函數(shù)中,AddMacCommand()。協(xié)議棧對(duì)MAC命令發(fā)送的處理還是比較簡(jiǎn)單的,都是放在Fopts中來(lái)傳輸,都在這個(gè)15字節(jié)的MacCommandsBuffer中.LinkADR是LoRaWAN網(wǎng)絡(luò)管理中相當(dāng)重要的一個(gè)MAC命令,其解析占用了183行.索性專門(mén)寫(xiě)篇源碼解析,記錄下.閱讀此文前,最好再把第五章的這個(gè)命令好好翻一翻,代碼和協(xié)議才能對(duì)應(yīng)上。我正在陸續(xù)對(duì)協(xié)議的各個(gè)章節(jié)進(jìn)行翻譯,具體其他章節(jié)的譯文,以及譯文之外的代碼解析,可點(diǎn)此查看帖子HYPERLINK”http://blog。csdn.net/iotisan/article/details/53930458”\t"_blank”LoRa學(xué)習(xí)筆記_匯總。

?本文作者twowinter,轉(zhuǎn)載請(qǐng)注明作者:HYPERLINK”http://blog.csdn。net/iotisan/”\t”_blank”http://blog。csdn.net/iotisan/LinkADRReq的源碼解析按照代碼思路走一遍。1。解析DataRate_TXPower字段datarate=payload[macIndex++];txPower=datarate&0x0F;datarate=(datarate>〉4)&0x0F;if((AdrCtrlOn==false)&&((LoRaMacParams。ChannelsDatarate!=datarate)||(LoRaMacParams。ChannelsTxPower!=txPower))){//ADRdisableddon'thandleADRrequestsifservertriestochangedatarateortxpower//Answertheserverwithfailstat(yī)us//PowerACK=0//DatarateACK=0//Channelmask=0AddMacCommand(MOTE_MAC_LINK_ADR_ANS,0,0);macIndex+=3;//Skipovertheremainingbytesoftherequestbreak;}如果終端ADR沒(méi)開(kāi),那么就立即丟棄本命令處理。這里的macIndex+=3是對(duì)應(yīng)LinkADRReq的剩余命令長(zhǎng)度3而言的。2.解析ChMask字段chMask=(uint16_t)payload[macIndex++];chMask|=(uint16_t)payload[macIndex++]<〈8;3。解析Redundancy字段nbRep=payload[macIndex++];chMaskCntl=(nbRep〉〉4)&0x07;nbRep&=0x0F;if(nbRep==0){nbRep=1;}把字段中的chMaskCntl和nbRep都給解析了出來(lái)。4。按地區(qū)規(guī)定處理chMaskCntl,及判斷ChMask有效性#elifdefined(USE_BAND_470)if(chMaskCntl==6){//Enableall125kHzchannelsfor(uint8_ti=0,k=0;i<LORA_MAX_NB_CHANNELS;i+=16,k++){for(uint8_tj=0;j〈16;j++){if(Channels[i+j].Frequency!=0){channelsMask[k]|=1<〈j;}}}}elseif(chMaskCntl==7){status&=0xFE;//ChannelmaskKO}else{for(uint8_ti=0;i<16;i++){if(((chMask&(1<〈i))!=0)&&(Channels[chMaskCntl*16+i].Frequency==0)){//Tryingtoenableanundefinedchannelstatus&=0xFE;//ChannelmaskKO}}channelsMask[chMaskCntl]=chMask;}如果chMaskCntl為6,則所有信道都使能.如果chMaskCntl為7,則由于未定義返回失敗。

其他有效chMaskCntl情況下,先檢查是否有未定義的頻點(diǎn),如果沒(méi)問(wèn)題則更新對(duì)應(yīng)的channelsMask。5.判斷速率有效性if(Validat(yī)eDatarate(datarate,channelsMask)==false){status&=0xFD;//DatarateKO}6.判斷發(fā)射功率有效性if(ValueInRange(txPower,LORAMAC_M(jìn)AX_TX_POWER,LORAMAC_MIN_TX_POWER)==false){status&=0xFB;//TxPowerKO}7.全部判斷通過(guò)后更新參數(shù)if((status&0x07)==0x07){LoRaMacParams。ChannelsDatarate=datarate;LoRaMacParams。ChannelsTxPower=txPower;memcpy1((uint8_t*)LoRaMacParams.ChannelsMask,(uint8_t*)channelsMask,sizeof(LoRaMacParams.ChannelsMask));LoRaMacParams.ChannelsNbRep=nbRep;}8?;貜?fù)MAC命令LinkADRAnsAddMacCommand(MOTE_(tái)MAC_LINK_ADR_ANS,status,0);突然發(fā)現(xiàn)AddMacCommand的形參只有CID加2字節(jié)的回復(fù),我是太無(wú)聊,把終端所有MAC命令都翻了一遍,確認(rèn)所有payload確實(shí)是小于2字節(jié)。再次贊揚(yáng)LoRaWAN協(xié)議的精簡(jiǎn)作風(fēng)。第6章終端激活為了加入LoRaWAN網(wǎng)絡(luò),每個(gè)終端需要初始化及激活。終端的激活有兩種方式,一種是空中激活Over-The-AirActivation(OTAA),當(dāng)設(shè)備部署和重置時(shí)使用;另一種是獨(dú)立激活A(yù)ctivat(yī)ionByPersonalization(ABP),此時(shí)初始化和激活這兩步就在一個(gè)步驟內(nèi)完成。twowinter備注:ABP這個(gè)詞不太好翻譯,通常會(huì)翻成個(gè)性化激活,也就是通過(guò)獨(dú)立配置參數(shù)的方式激活。但總感覺(jué)少點(diǎn)味道,與空中激活擺在一起,感覺(jué)獨(dú)立激活這個(gè)詞在語(yǔ)義上更有并列感。當(dāng)然這是我的主觀感覺(jué),建議大家和同行交流時(shí),還是說(shuō)ABP激活吧.6。1終端激活后的數(shù)據(jù)存儲(chǔ)激活后,終端會(huì)存儲(chǔ)如下信息:設(shè)備地址(DevAddr),應(yīng)用ID(AppEUI),網(wǎng)絡(luò)會(huì)話密鑰(NwkSKey),應(yīng)用會(huì)話密鑰(AppSKey)。6。1。1終端地址(DevAddr)終端地址(DevAddr)由可標(biāo)識(shí)當(dāng)前網(wǎng)絡(luò)設(shè)備的32位ID所組成,具體格式如下:Bit#[31。.25][24。。0]DevAddrbitsNwkIDNwkAddr它的高7位是NwkId,用來(lái)區(qū)別同一區(qū)域內(nèi)的不同網(wǎng)絡(luò),另外也保證防止節(jié)點(diǎn)竄到別的網(wǎng)絡(luò)去.它的低25位是NwkAddr,是終端的網(wǎng)絡(luò)地址,可以由網(wǎng)絡(luò)管理者來(lái)分配.6.1.2應(yīng)用ID(AppEUI)

AppEUI是一個(gè)類似IEEEEUI64的全球唯一ID,標(biāo)識(shí)終端的應(yīng)用提供者。

APPEUI在激活流程開(kāi)始前就存儲(chǔ)在終端中。6。1.3網(wǎng)絡(luò)會(huì)話密鑰(NwkSKey)NwkSKey被終端和網(wǎng)絡(luò)服務(wù)器用來(lái)計(jì)算和校驗(yàn)所有消息的MIC,以保證數(shù)據(jù)完整性。也用來(lái)對(duì)單獨(dú)MAC的數(shù)據(jù)消息載荷進(jìn)行加解密。6。1.4應(yīng)用會(huì)話密鑰(AppSKey)AppSKey被終端和網(wǎng)絡(luò)服務(wù)器用來(lái)對(duì)應(yīng)用層消息進(jìn)行加解密。當(dāng)應(yīng)用層消息載荷有MIC時(shí),也可以用來(lái)計(jì)算和校驗(yàn)該應(yīng)用層MIC。6。2空中激活OTAA針對(duì)空中激活,終端必須按照加網(wǎng)流程來(lái)和網(wǎng)絡(luò)服務(wù)器進(jìn)行數(shù)據(jù)交互。如果終端丟失會(huì)話消息,則每次必須重新進(jìn)行一次加網(wǎng)流程。

?加網(wǎng)流程需要終端準(zhǔn)備好如下這三個(gè)參數(shù):DevEUI,AppEUI,AppKey.APPEUI在上面的6.1.2已經(jīng)做了描述。注意:對(duì)于空中激活,終端不會(huì)初始化任何網(wǎng)絡(luò)密鑰。只有當(dāng)終端加入網(wǎng)絡(luò)后,才會(huì)被分配一個(gè)網(wǎng)絡(luò)會(huì)話密鑰,用來(lái)加密和校驗(yàn)網(wǎng)絡(luò)層的傳輸。通過(guò)這樣,使得終端在不同網(wǎng)絡(luò)間的漫游處理變得方便.同時(shí)使用網(wǎng)絡(luò)和應(yīng)用會(huì)話密鑰,使得網(wǎng)絡(luò)服務(wù)器中的應(yīng)用數(shù)據(jù),不會(huì)被網(wǎng)絡(luò)提供者讀取或者篡改。6.2。1終端ID(DevEUI)

DevEUI是一個(gè)類似IEEEEUI64的全球唯一ID,標(biāo)識(shí)唯一的終端設(shè)備。6.2。2應(yīng)用密鑰(AppKey)

?AppKey是由應(yīng)用程序擁有者分配給終端,很可能是由應(yīng)用程序指定的根密鑰來(lái)衍生的,并且受提供者控制。當(dāng)終端通過(guò)空中激活方式加入網(wǎng)絡(luò),AppKey用來(lái)產(chǎn)生會(huì)話密鑰NwkSKey和AppSKey,會(huì)話密鑰分別用來(lái)加密和校驗(yàn)網(wǎng)絡(luò)層和應(yīng)用層數(shù)據(jù)。6。2.3加網(wǎng)流程

?從終端角度看,加網(wǎng)流程是由和服務(wù)器的兩個(gè)MAC命令交互組成的,分別是joinrequest和joinaccept。6.2.4Join-request消息

加網(wǎng)流程總是由終端發(fā)送join—request來(lái)發(fā)起。Size(bytes)882JoinRequestAppEUIDevEUIDevNoncejoin—request消息包含了AppEUI和DevEUI,后面還跟了2個(gè)字節(jié)的聲明DevNonce.DevNonce是一個(gè)隨機(jī)值。網(wǎng)絡(luò)服務(wù)器為每個(gè)終端記錄過(guò)去的DevNonce數(shù)值,如果相同設(shè)備發(fā)出相同的DevNonce的joinrequest就會(huì)忽略。join-request消息的MIC數(shù)值(見(jiàn)第4章MAC幀格式)按照如下公式計(jì)算:cmac=aes128_cmac(AppKey,MHDR|AppEUI|DevEUI|DevNonce)

MIC=cmac[0..3]join—request消息不用加密。6.2。5Join—accept消息

待補(bǔ)充.6.3獨(dú)立激活A(yù)BP在某些情況下,終端可以獨(dú)立激活.獨(dú)立激活是讓終端繞過(guò)joinrequest—joinaccept的加網(wǎng)流程,直接加入到指定網(wǎng)絡(luò)中.獨(dú)立激活終端,意味著DevAddr和兩個(gè)會(huì)話密鑰NwkSKey和AppSKey直接存儲(chǔ)在終端中,而不是DevEUI,AppEUI,AppKey。終端在一開(kāi)始就配置好了入網(wǎng)必要的信息。每個(gè)終端必須要有唯一的NwkSKey和AppSKey。這樣,一個(gè)設(shè)備的密鑰被破解也不會(huì)造成其他設(shè)備的安全性危險(xiǎn)。創(chuàng)建那些密鑰的過(guò)程中,密鑰不允許通過(guò)公開(kāi)可用信息獲得(例如節(jié)點(diǎn)地址)。2梳理解析LoRaWAN第6章,主要對(duì)節(jié)點(diǎn)加網(wǎng)做了描述,它有兩種方式.如果要用一句話來(lái)總結(jié)的話,那就是這一句了,請(qǐng)看:如果是空中激活,則需要準(zhǔn)備DevEUI,AppEUI,AppKey這三個(gè)參數(shù),即設(shè)備自身MAC地址和要使用的應(yīng)用(應(yīng)用ID和密鑰)。

如果是ABP激活,則直接配置DevAddr,NwkSKey,AppSKey這三個(gè)LoRaWAN最終通訊的參數(shù),不再需要join流程。在這種情況下,這個(gè)設(shè)備是可以直接發(fā)應(yīng)用數(shù)據(jù)的。這里插個(gè)題外話,商用的LoRaWAN網(wǎng)絡(luò)一般都是走OTAA流程,這樣安全性才得以保證。(twowinter,你數(shù)數(shù),這是一句話?)

(如果是空中激活,則需要準(zhǔn)備DevEUI,AppEUI,AppKey來(lái)join。如果是ABP激活,則直接配置DevAddr,NwkSKey,AppSKey.)3代碼位置3.1激活處理協(xié)議的第6章,相關(guān)的核心代碼是這么幾行,位于\src\mac\main。c。

?整個(gè)代碼結(jié)構(gòu)非常清晰,用一個(gè)宏(OVER_THE_AIR_ACTIVATION)分開(kāi)兩段,分別對(duì)應(yīng)兩種激活方式。caseDEVICE_STATE_JOIN:{#if(OVER_THE_AIR_ACTIVATION!=0)MlmeReq_tmlmeReq;//InitializeLoRaMacdeviceuniqueIDBoardGetUniqueId(DevEui);mlmeReq。Type=MLME_JOIN;mlmeReq.Req。Join。DevEui=DevEui;mlmeReq.Req.Join.AppEui=AppEui;mlmeReq。Req.Join.AppKey=AppKey;if(NextTx==true){LoRaMacMlmeRequest(&mlmeReq);}DeviceStat(yī)e=DEVICE_STATE_SLEEP;#else//ChoosearandomdeviceaddressifnotalreadydefinedinComissioning。hif(DevAddr==0){//Randomseedinitializat(yī)ionsrand1(BoardGetRandomSeed());//ChoosearandomdeviceaddressDevAddr=randr(0,0x01FFFFFF);}mibReq。Type=MIB_NET_ID;mibReq.Param.NetID=LORAWAN_NETWORK_ID;LoRaMacMibSetRequestConfirm(&mibReq);mibReq.Type=MIB_DEV_ADDR;mibReq。Param.DevAddr=DevAddr;LoRaMacMibSetRequestConfirm(&mibReq);mibReq。Type=MIB_NWK_SKEY;mibReq.Param.NwkSKey=NwkSKey;LoRaMacMibSetRequestConfirm(&mibReq);mibReq.Type=MIB_APP_SKEY;mibReq。Param。AppSKey=AppSKey;LoRaMacMibSetRequestConfirm(&mibReq);mibReq。Type=MIB_NETWORK_JOINED;mibReq.Param。IsNetworkJoined=true;LoRaMac

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論