示例#1
0
        /// <summary>
        /// Helper method to resolve FcntDown in case one was not yet acquired
        /// </summary>
        /// <returns>0 if the resolution failed or > 0 if a valid frame count was acquired</returns>
        async ValueTask <uint> EnsureHasFcntDownAsync(
            LoRaDevice loRaDevice,
            uint?fcntDown,
            uint payloadFcnt,
            ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
        {
            if (fcntDown > 0)
            {
                return(fcntDown.Value);
            }

            var newFcntDown = await frameCounterStrategy.NextFcntDown(loRaDevice, payloadFcnt);

            // Failed to update the fcnt down
            // In multi gateway scenarios it means the another gateway was faster than using, can stop now
            if (newFcntDown <= 0)
            {
                Logger.Log(loRaDevice.DevEUI, "another gateway has already sent ack or downlink msg", LogLevel.Debug);
            }
            else
            {
                Logger.Log(loRaDevice.DevEUI, $"down frame counter: {loRaDevice.FCntDown}", LogLevel.Debug);
            }

            return(newFcntDown);
        }
示例#2
0
        public ILoRaADRManager Create(ILoRaADRStrategyProvider strategyProvider,
                                      ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy,
                                      LoRaDevice loRaDevice)
        {
            if (loRaDevice is null)
            {
                throw new ArgumentNullException(nameof(loRaDevice));
            }

            return(!string.IsNullOrEmpty(loRaDevice.GatewayID)
                    ? new LoRaADRDefaultManager(CurrentInMemoryStore, strategyProvider, frameCounterStrategy, loRaDevice, this.loggerFactory.CreateLogger <LoRaADRDefaultManager>())
                    : new LoRaADRMultiGatewayManager(loRaDevice, this.loRaDeviceAPIService, this.loggerFactory.CreateLogger <LoRaADRMultiGatewayManager>()));
        }
        /// <summary>
        /// Helper method to resolve FcntDown in case one was not yet acquired
        /// </summary>
        /// <returns>0 if the resolution failed or > 0 if a valid frame count was acquired</returns>
        async ValueTask <uint> EnsureHasFcntDownAsync(
            LoRaDevice loRaDevice,
            uint?fcntDown,
            uint payloadFcnt,
            ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
        {
            if (fcntDown.HasValue)
            {
                return(fcntDown.Value);
            }

            var newFcntDown = await frameCounterStrategy.NextFcntDown(loRaDevice, payloadFcnt);

            // Failed to update the fcnt down
            // In multi gateway scenarios it means the another gateway was faster than using, can stop now
            LogFrameCounterDownState(loRaDevice, newFcntDown);

            return(newFcntDown);
        }
        private async Task <bool> DetermineIfFramecounterIsFromNewlyStartedDeviceAsync(LoRaDevice loRaDevice, uint payloadFcnt, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
        {
            var isFrameCounterFromNewlyStartedDevice = false;

            if (payloadFcnt <= 1)
            {
                if (loRaDevice.IsABP)
                {
                    if (loRaDevice.IsABPRelaxedFrameCounter && loRaDevice.FCntUp >= 0 && payloadFcnt <= 1)
                    {
                        // known problem when device restarts, starts fcnt from zero
                        // We need to await this reset to avoid races on the server with deduplication and
                        // fcnt down calculations
                        await frameCounterStrategy.ResetAsync(loRaDevice, payloadFcnt, this.configuration.GatewayID);

                        isFrameCounterFromNewlyStartedDevice = true;
                    }
                }
                else if (loRaDevice.FCntUp == payloadFcnt && payloadFcnt == 0)
                {
                    // Some devices start with frame count 0
                    isFrameCounterFromNewlyStartedDevice = true;
                }
            }

            return(isFrameCounterFromNewlyStartedDevice);
        }
        private async Task <LoRaADRResult> PerformADR(LoRaRequest request, LoRaDevice loRaDevice, LoRaPayloadData loraPayload, uint payloadFcnt, LoRaADRResult loRaADRResult, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
        {
            var loRaADRManager = this.loRaADRManagerFactory.Create(this.loRaADRStrategyProvider, frameCounterStrategy, loRaDevice);

            var loRaADRTableEntry = new LoRaADRTableEntry()
            {
                DevEUI    = loRaDevice.DevEUI,
                FCnt      = payloadFcnt,
                GatewayId = this.configuration.GatewayID,
                Snr       = request.Rxpk.Lsnr
            };

            // If the ADR req bit is not set we don't perform rate adaptation.
            if (!loraPayload.IsAdrReq)
            {
                _ = loRaADRManager.StoreADREntryAsync(loRaADRTableEntry);
            }
            else
            {
                loRaADRResult = await loRaADRManager.CalculateADRResultAndAddEntryAsync(
                    loRaDevice.DevEUI,
                    this.configuration.GatewayID,
                    payloadFcnt,
                    loRaDevice.FCntDown,
                    (float)request.Rxpk.RequiredSnr,
                    request.Region.GetDRFromFreqAndChan(request.Rxpk.Datr),
                    request.Region.TXPowertoMaxEIRP.Count - 1,
                    request.Region.MaxADRDataRate,
                    loRaADRTableEntry);

                Logger.Log(loRaDevice.DevEUI, $"device sent ADR ack request, computing an answer", LogLevel.Debug);
            }

            return(loRaADRResult);
        }
 public ILoRaADRManager Create(ILoRaADRStrategyProvider strategyProvider, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy, LoRaDevice loRaDevice)
 {
     return(!string.IsNullOrEmpty(loRaDevice.GatewayID)
             ? new LoRaADRDefaultManager(CurrentInMemoryStore, strategyProvider, frameCounterStrategy, loRaDevice)
             : new LoRaADRMultiGatewayManager(loRaDevice, this.loRaDeviceAPIService));
 }
 public LoRaADRDefaultManager(ILoRaADRStore store, ILoRaADRStrategyProvider strategyProvider, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy, LoRaDevice loRaDevice, ILogger <LoRaADRDefaultManager> logger)
     : base(store, strategyProvider, logger)
 {
     LoRaDevice = loRaDevice;
     this.frameCounterStrategy = frameCounterStrategy;
 }
示例#8
0
        private static bool DetermineIfFramecounterIsFromNewlyStartedDevice(LoRaDevice loRaDevice, uint payloadFcnt, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
        {
            var isFrameCounterFromNewlyStartedDevice = false;

            if (payloadFcnt <= 1)
            {
                if (loRaDevice.IsABP)
                {
                    if (loRaDevice.IsABPRelaxedFrameCounter && loRaDevice.FCntUp >= 0 && payloadFcnt <= 1)
                    {
                        // known problem when device restarts, starts fcnt from zero
                        _ = frameCounterStrategy.ResetAsync(loRaDevice);
                        isFrameCounterFromNewlyStartedDevice = true;
                    }
                }
                else if (loRaDevice.FCntUp == payloadFcnt && payloadFcnt == 0)
                {
                    // Some devices start with frame count 0
                    isFrameCounterFromNewlyStartedDevice = true;
                }
            }

            return(isFrameCounterFromNewlyStartedDevice);
        }
示例#9
0
 public LoRaDeviceFrameCounterSession(LoRaDevice loRaDevice, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
 {
     this.loRaDevice           = loRaDevice;
     this.frameCounterStrategy = frameCounterStrategy;
 }
 protected override Task <LoRaADRResult> PerformADR(LoRaRequest request, LoRaDevice loRaDevice, LoRaPayloadData loraPayload, uint payloadFcnt, LoRaADRResult loRaADRResult, ILoRaDeviceFrameCounterUpdateStrategy frameCounterStrategy)
 => Task.FromResult(PerformADRAssert());