LoRaWAN实战 LinkADR命令的源码分析

前言

LinkADR是LoRaWAN网络管理中相当重要的一个MAC命令,其解析占用了183行。索性专门写篇源码解析,记录下。

阅读此文前,最好再把第五章的这个命令好好翻一翻,代码和协议才能对应上。

我正在陆续对协议的各个章节进行翻译,具体其他章节的译文,以及译文之外的代码解析,可点此查看帖子LoRa学习笔记_汇总
本文作者twowinter,转载请注明作者: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 ) ) )
{ // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
    // Answer the server with fail status
    // Power ACK     = 0
    // Data rate ACK = 0
    // Channel mask  = 0
    AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
    macIndex += 3;  // Skip over the remaining bytes of the request
    break;
}

如果终端ADR没开,那么就立即丢弃本命令处理。这里的macIndex += 3是对应LinkADRReq的剩余命令长度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 都给解析了出来。

4.按地区规定处理 chMaskCntl ,及判断 ChMask 有效性

#elif defined( USE_BAND_470 )
    if( chMaskCntl == 6 )
    {
        // Enable all 125 kHz channels
        for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
        {
            for( uint8_t j = 0; j < 16; j++ )
            {
                if( Channels[i + j].Frequency != 0 )
                {
                    channelsMask[k] |= 1 << j;
                }
            }
        }
    }
    else if( chMaskCntl == 7 )
    {
        status &= 0xFE; // Channel mask KO
    }
    else
    {
        for( uint8_t i = 0; i < 16; i++ )
        {
            if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
                ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) )
            {// Trying to enable an undefined channel
                status &= 0xFE; // Channel mask KO
            }
        }
        channelsMask[chMaskCntl] = chMask;
    }

如果 chMaskCntl 为6,则所有信道都使能。如果 chMaskCntl 为7,则由于未定义返回失败。
其他有效 chMaskCntl 情况下,先检查是否有未定义的频点,如果没问题则更新对应的channelsMask。

5.判断速率有效性

if( ValidateDatarate( datarate, channelsMask ) == false )
{
    status &= 0xFD; // Datarate KO
}

6.判断发射功率有效性

if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
{
    status &= 0xFB; // TxPower KO
}

7.全部判断通过后更新参数

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.回复MAC命令 LinkADRAns

AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );

突然发现 AddMacCommand 的形参只有CID加2字节的回复,我是太无聊,把终端所有MAC命令都翻了一遍,确认所有payload确实是小于2字节。再次赞扬LoRaWAN协议的精简作风。

End

说明:LPWA物联网应用站(LPWAP.com)通过公开互联网收集、整理并转载有关LPWA物联网应用解决方案,以供广大LPWA应用开发者和爱好者共同学习交流和参考运用到实际生产生活中。本站所有转载的文章、图片、音频、视频等资料的版权归版权所有人所有并衷心感谢您的付出,由于本站采纳的非本站原创文章及图片等内容无法一一联系确认版权者,如果本网所选内容的文章原创作者认为其作品不宜放在本站,请及时通过以下留言功能通知我们采取适当措施,避免给双方造成不必要的经济损失。如果您希望保留文章在本站,但希望文章末尾提供对作者的致谢或者产品、网站交换链接的,也请将需求写入以下留言栏中,谢谢您的支持。让我们共同努力,打造万物互联的未来美好生活!

您的留言或需求: