Beispiel #1
0
 public PreferredGatewayResult(string devEUI, uint fcntUp, LoRaDevicePreferredGateway preferredGateway)
 {
     this.DevEUI             = devEUI;
     this.RequestFcntUp      = fcntUp;
     this.CurrentFcntUp      = preferredGateway.FcntUp;
     this.PreferredGatewayID = preferredGateway.GatewayID;
     this.Conflict           = fcntUp != preferredGateway.FcntUp;
 }
        public PreferredGatewayResult(DevEui devEUI, uint fcntUp, LoRaDevicePreferredGateway preferredGateway)
        {
            if (preferredGateway is null)
            {
                throw new ArgumentNullException(nameof(preferredGateway));
            }

            DevEUI             = devEUI;
            RequestFcntUp      = fcntUp;
            CurrentFcntUp      = preferredGateway.FcntUp;
            PreferredGatewayID = preferredGateway.GatewayID;
            Conflict           = fcntUp != preferredGateway.FcntUp;
        }
Beispiel #3
0
 internal static bool SaveToCache(ILoRaDeviceCacheStore cacheStore, string devEUI, LoRaDevicePreferredGateway preferredGateway, bool onlyIfNotExists = false)
 {
     return(cacheStore.StringSet(PreferredGatewayCacheKey(devEUI), preferredGateway.ToCachedString(), null, onlyIfNotExists));
 }
        public async Task <IActionResult> SendCloudToDeviceMessageImplementationAsync(string devEUI, LoRaCloudToDeviceMessage c2dMessage)
        {
            if (string.IsNullOrEmpty(devEUI))
            {
                return(new BadRequestObjectResult($"Missing {nameof(devEUI)} value"));
            }

            if (c2dMessage == null)
            {
                return(new BadRequestObjectResult("Missing cloud to device message"));
            }

            if (!c2dMessage.IsValid(out var errorMessage))
            {
                return(new BadRequestObjectResult(errorMessage));
            }

            var cachedPreferredGateway = LoRaDevicePreferredGateway.LoadFromCache(this.cacheStore, devEUI);

            if (cachedPreferredGateway != null && !string.IsNullOrEmpty(cachedPreferredGateway.GatewayID))
            {
                return(await this.SendMessageViaDirectMethodAsync(cachedPreferredGateway.GatewayID, devEUI, c2dMessage));
            }

            var queryText = $"SELECT * FROM devices WHERE deviceId = '{devEUI}'";
            var query     = this.registryManager.CreateQuery(queryText, 1);

            if (query.HasMoreResults)
            {
                IEnumerable <Twin> deviceTwins;
                try
                {
                    deviceTwins = await query.GetNextAsTwinAsync();
                }
                catch (Exception ex)
                {
                    this.log.LogError(ex, "Failed to query devices with {query}", queryText);
                    return(new ObjectResult("Failed to query devices")
                    {
                        StatusCode = (int)HttpStatusCode.InternalServerError
                    });
                }

                var twin = deviceTwins.FirstOrDefault();

                if (twin != null)
                {
                    // the device must have a DevAddr
                    if (twin.Properties?.Desired?.GetTwinPropertyStringSafe(TwinProperty_DevAddr).Length == 0 && twin.Properties?.Reported?.GetTwinPropertyStringSafe(TwinProperty_DevAddr).Length == 0)
                    {
                        return(new BadRequestObjectResult("Device DevAddr is unknown. Ensure the device has been correctly setup as a LoRa device and that it has connected to network at least once."));
                    }

                    if (string.Equals("c", twin.Properties?.Desired?.GetTwinPropertyStringSafe(TwinProperty_ClassType), StringComparison.InvariantCultureIgnoreCase))
                    {
                        var gatewayID = twin.Properties?.Reported?.GetTwinPropertyStringSafe(TwinProperty_PreferredGatewayID);
                        if (string.IsNullOrEmpty(gatewayID))
                        {
                            gatewayID = twin.Properties?.Desired?.GetTwinPropertyStringSafe(TwinProperty_GatewayID);
                        }

                        if (!string.IsNullOrEmpty(gatewayID))
                        {
                            // add it to cache (if it does not exist)
                            var preferredGateway = new LoRaDevicePreferredGateway(gatewayID, 0);
                            LoRaDevicePreferredGateway.SaveToCache(this.cacheStore, devEUI, preferredGateway, onlyIfNotExists: true);

                            return(await this.SendMessageViaDirectMethodAsync(gatewayID, devEUI, c2dMessage));
                        }

                        // class c device that did not send a single upstream message
                        return(new BadRequestObjectResult("Class C devices must sent at least one message upstream. None has been received"));
                    }

                    // Not a class C device? Send message using sdk/queue
                    return(await this.SendMessageViaCloudToDeviceMessageAsync(devEUI, c2dMessage));
                }
            }

            return(new NotFoundObjectResult($"Device '{devEUI}' was not found"));
        }