コード例 #1
0
        protected static void AddEntryToTable(LoRaADRTable table, LoRaADRTableEntry entry)
        {
            var existing = table.Entries.FirstOrDefault(itm => itm.FCnt == entry.FCnt);

            if (existing == null)
            {
                // first for this framecount, simply add it
                entry.GatewayCount = 1;
                table.Entries.Add(entry);
            }
            else
            {
                if (existing.Snr < entry.Snr)
                {
                    // better SNR. Update
                    existing.Snr       = entry.Snr;
                    existing.GatewayId = entry.GatewayId;
                }

                existing.GatewayCount++;
            }

            if (table.Entries.Count > LoRaADRTable.FrameCountCaptureCount)
            {
                table.Entries.RemoveAt(0);
            }
        }
コード例 #2
0
 public Task <LoRaADRTable> AddTableEntry(LoRaADRTableEntry entry)
 {
     lock (this.cache)
     {
         var table = this.cache.GetOrCreate <LoRaADRTable>(entry.DevEUI, (cacheEntry) => new LoRaADRTable());
         AddEntryToTable(table, entry);
         return(Task.FromResult <LoRaADRTable>(table));
     }
 }
コード例 #3
0
        public virtual async Task StoreADREntryAsync(LoRaADRTableEntry newEntry)
        {
            if (newEntry == null)
            {
                return;
            }

            if (!newEntry.DevEUI.IsValid || string.IsNullOrEmpty(newEntry.GatewayId))
            {
                throw new ArgumentException("Missing Gateway ID or invalid DevEUI");
            }

            _ = await this.store.AddTableEntry(newEntry);
        }
コード例 #4
0
        public Task <LoRaADRTable> AddTableEntry(LoRaADRTableEntry entry)
        {
            if (entry is null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            lock (this.cache)
            {
                var table = this.cache.GetOrCreate(entry.DevEUI, (cacheEntry) => new LoRaADRTable());
                AddEntryToTable(table, entry);
                return(Task.FromResult(table));
            }
        }
コード例 #5
0
        public virtual async Task StoreADREntryAsync(LoRaADRTableEntry newEntry)
        {
            if (newEntry == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(newEntry.DevEUI) ||
                string.IsNullOrEmpty(newEntry.GatewayId))
            {
                throw new ArgumentException("Missing DevEUI or GatewayId");
            }

            await this.store.AddTableEntry(newEntry);
        }
コード例 #6
0
        public virtual async Task <LoRaADRResult> CalculateADRResultAndAddEntryAsync(DevEui devEUI, string gatewayId, uint fCntUp, uint fCntDown, float requiredSnr, DataRateIndex dataRate, int minTxPower, DataRateIndex maxDr, LoRaADRTableEntry newEntry = null)
        {
            var table = newEntry != null
                        ? await this.store.AddTableEntry(newEntry)
                        : await this.store.GetADRTable(devEUI);

            var currentStrategy = this.strategyProvider.GetStrategy();

            var result = currentStrategy.ComputeResult(table, requiredSnr, dataRate, minTxPower, maxDr);

            if (result == null)
            {
                // In this case we want to reset the device to default values as we have null values
                if (table == null ||
                    !table.CurrentNbRep.HasValue ||
                    !table.CurrentTxPower.HasValue ||
                    fCntUp > currentStrategy.MinimumNumberOfResult)
                {
                    result = ReturnDefaultValues(dataRate, currentStrategy.DefaultNbRep, currentStrategy.DefaultTxPower);
                }
                else
                {
                    result = await GetLastResultAsync(devEUI) ?? new LoRaADRResult();

                    result.NumberOfFrames = table.Entries.Count;
                    return(result);
                }
            }

            var nextFcntDown = await NextFCntDown(devEUI, gatewayId, fCntUp, fCntDown);

            result.CanConfirmToDevice = nextFcntDown > 0;

            if (result.CanConfirmToDevice)
            {
                if (table == null)
                {
                    // in a reset case, we may not have a table, but still want to store the default
                    // values that we sent to the client
                    table = new LoRaADRTable();
                }

                table.CurrentNbRep   = result.NbRepetition;
                table.CurrentTxPower = result.TxPower;
                await this.store.UpdateADRTable(devEUI, table);

                UpdateState(result);
                result.FCntDown = nextFcntDown;
            }

            result.NumberOfFrames = table.Entries.Count;
            this.logger.LogDebug($"calculated ADR: CanConfirmToDevice: {result.CanConfirmToDevice}, TxPower: {result.TxPower}, DataRate: {result.DataRate}");
            return(result);
        }