Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data rate is not restored after periodical time synchronization #759

Closed
iotfreaks opened this issue Jul 8, 2019 · 1 comment
Closed

Comments

@iotfreaks
Copy link

Hi
We trying to use periodical time syncronization and have a little problem.
Configuration:

  • develop branch with latest commits
  • EU_868
  • ADR enabled

In according to LoRaWAN Application Layer Clock Synchronization Specification device shall temporarily disable ADR before transmitting DeviceTime message and restore previous state after sending it.

161 The AppTimeReq message is transmitted by the end-device to request a clock correction
162 from the application server. The message is meant to be transmitted periodically by the end163 device. The default periodicity is a function of the accuracy required by the application and
164 the maximum clock drift speed of the end-device.
165 This message SHALL only be transmitted a single time with a given DeviceTime payload, as
166 the network reception time stamp will be used by the application server to compute the
167 require clock correction. Therefore the “clock synchronization” package SHALL first
168 temporarily disable ADR and set NbTrans=1 before transmitting this message, then revert
169 the MAC layer to the previous state.

But after enabling ADR the previous data rate is not restored and device continues to work on lowest possible until the server increase it again.

Our test consequence is next:

  • Join
  • Periodical send some application packets
  • Server increase datarate to SF7
  • Launch periodical time sync by calling LmhpClockSyncAppTimeReq
  • ADR disabled inside LmhpClockSyncAppTimeReq and previous ADR (but not data rate) state is stored
    if( LmhpClockSyncState.AppTimeReqPending == false )
    {
        MibRequestConfirm_t mibReq;

        // Disable ADR
        mibReq.Type = MIB_ADR;
        LoRaMacMibGetRequestConfirm( &mibReq );
        LmhpClockSyncState.AdrEnabledPrev = mibReq.Param.AdrEnable;
        mibReq.Param.AdrEnable = false;
        LoRaMacMibSetRequestConfirm( &mibReq );

        // Set NbTrans = 1
        mibReq.Type = MIB_CHANNELS_NB_TRANS;
        LoRaMacMibGetRequestConfirm( &mibReq );
        LmhpClockSyncState.NbTransPrev = mibReq.Param.ChannelsNbTrans;
        mibReq.Param.ChannelsNbTrans = 1;
        LoRaMacMibSetRequestConfirm( &mibReq );

        // Add DeviceTimeReq MAC command.
        // In case the network server supports this more precise command
        // this package will use DeviceTimeAns answer as clock synchronization
        // mechanism.
        LmhpClockSyncPackage.OnDeviceTimeRequest( );
    }
  • Datarate is set to minimum possible inside LoRaMacMcpsRequest, because ADR is disabled now
    // Apply the minimum possible datarate.
    // Some regions have limitations for the minimum datarate.
    datarate = MAX( datarate, ( int8_t )phyParam.Value );
    if( readyToSend == true )
    {
        if( MacCtx.NvmCtx->AdrCtrlOn == false )
        {
            verify.DatarateParams.Datarate = datarate;
            verify.DatarateParams.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime;

            if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_DR ) == true )
            {
                MacCtx.NvmCtx->MacParams.ChannelsDatarate = verify.DatarateParams.Datarate;
            }
            else
            {
                return LORAMAC_STATUS_PARAMETER_INVALID;
            }
        }

  • Packet is sent and pervious ADR state is restored inside LmhpClockSyncOnMcpsConfirm
static void LmhpClockSyncOnMcpsConfirm( McpsConfirm_t *mcpsConfirm )
{
    MibRequestConfirm_t mibReq;

    if( LmhpClockSyncState.AppTimeReqPending == true )
    {
        // Revert ADR setting
        mibReq.Type = MIB_ADR;
        mibReq.Param.AdrEnable = LmhpClockSyncState.AdrEnabledPrev;
        LoRaMacMibSetRequestConfirm( &mibReq );

        // Revert NbTrans setting
        mibReq.Type = MIB_CHANNELS_NB_TRANS;
        mibReq.Param.ChannelsNbTrans = LmhpClockSyncState.NbTransPrev;
        LoRaMacMibSetRequestConfirm( &mibReq );

        LmhpClockSyncState.AppTimeReqPending = false;
    }
}
  • Device continues to send periodical application packets on SF12 until server increase DR again

It's not good, because periodical time syncronization requests decrease network capacity.

Patch below for LmhpClockSync.c solve the problem:

typedef struct LmhpClockSyncState_s
{
    bool Initialized;
    bool IsRunning;
    uint8_t DataBufferMaxSize;
    uint8_t *DataBuffer;
    union
    {
        uint8_t Value;
        struct
        {
            uint8_t TokenReq:    4;
            uint8_t AnsRequired: 1;
            uint8_t RFU:         3;
        }Fields;
    }TimeReqParam;
    bool AppTimeReqPending;
    bool AdrEnabledPrev;
    uint8_t NbTransPrev;
/*----------Added--------------------------*/
    uint8_t DataratePrev; 
/*--------------------------------------------*/        
}LmhpClockSyncState_t;
LmHandlerErrorStatus_t LmhpClockSyncAppTimeReq( void )
{
    if( LmHandlerIsBusy( ) == true )
    {
        return LORAMAC_HANDLER_ERROR;
    }

    if( LmhpClockSyncState.AppTimeReqPending == false )
    {
        MibRequestConfirm_t mibReq;

        // Disable ADR
        mibReq.Type = MIB_ADR;
        LoRaMacMibGetRequestConfirm( &mibReq );
        LmhpClockSyncState.AdrEnabledPrev = mibReq.Param.AdrEnable;
        mibReq.Param.AdrEnable = false;
        LoRaMacMibSetRequestConfirm( &mibReq );

        // Set NbTrans = 1
        mibReq.Type = MIB_CHANNELS_NB_TRANS;
        LoRaMacMibGetRequestConfirm( &mibReq );
        LmhpClockSyncState.NbTransPrev = mibReq.Param.ChannelsNbTrans;
        mibReq.Param.ChannelsNbTrans = 1;
        LoRaMacMibSetRequestConfirm( &mibReq );
/*----------Added--------------------------*/
        // Store data rate
        mibReq.Type = MIB_CHANNELS_DATARATE;
        LoRaMacMibGetRequestConfirm( &mibReq );  
        LmhpClockSyncState.DataratePrev = mibReq.Param.ChannelsDatarate;
/*--------------------------------------------*/        
        // Add DeviceTimeReq MAC command.
        // In case the network server supports this more precise command
        // this package will use DeviceTimeAns answer as clock synchronization
        // mechanism.
        LmhpClockSyncPackage.OnDeviceTimeRequest( );
    }
static void LmhpClockSyncOnMcpsConfirm( McpsConfirm_t *mcpsConfirm )
{
    MibRequestConfirm_t mibReq;

    if( LmhpClockSyncState.AppTimeReqPending == true )
    {
        // Revert ADR setting
        mibReq.Type = MIB_ADR;
        mibReq.Param.AdrEnable = LmhpClockSyncState.AdrEnabledPrev;
        LoRaMacMibSetRequestConfirm( &mibReq );

        // Revert NbTrans setting
        mibReq.Type = MIB_CHANNELS_NB_TRANS;
        mibReq.Param.ChannelsNbTrans = LmhpClockSyncState.NbTransPrev;
        LoRaMacMibSetRequestConfirm( &mibReq );
/*----------Added--------------------------*/
        // Revert data rate setting
        mibReq.Type = MIB_CHANNELS_DATARATE;
        mibReq.Param.ChannelsDatarate = LmhpClockSyncState.DataratePrev;
        LoRaMacMibSetRequestConfirm( &mibReq );        
/*--------------------------------------------*/        
        LmhpClockSyncState.AppTimeReqPending = false;
    }
}

Sorry for longread ;)

@iotfreaks iotfreaks changed the title Datarate is not restored after periodical time syncronization Data rate is not restored after periodical time syncronization Jul 8, 2019
@iotfreaks iotfreaks changed the title Data rate is not restored after periodical time syncronization Data rate is not restored after periodical time synchronization Jul 8, 2019
@mluis1
Copy link
Contributor

mluis1 commented Jul 8, 2019

Thanks for the feedback.

Disabling/Enabling the ADR is quite problematic (Mainly on the server side). That's why in newer version of the specification this has been removed and replaced by other mechanisms/rules to comply with.

Could you please provide a pull request with your proposition. But, please note that this will be completely suppressed once the newer version of the specification will be released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants