public async Task <List <IoTHubDeviceInfo> > GetDeviceList(DevEui?devEUI, string gatewayId, DevNonce?devNonce, DevAddr?devAddr, ILogger log = null) { var results = new List <IoTHubDeviceInfo>(); if (devEUI is { } someDevEui) { var joinInfo = await TryGetJoinInfoAndValidateAsync(someDevEui, gatewayId, log); // OTAA join using var deviceCache = new LoRaDeviceCache(this.cacheStore, someDevEui, gatewayId); var cacheKeyDevNonce = string.Concat(devEUI, ":", devNonce); if (this.cacheStore.StringSet(cacheKeyDevNonce, devNonce?.ToString(), TimeSpan.FromMinutes(5), onlyIfNotExists: true)) { var iotHubDeviceInfo = new IoTHubDeviceInfo { DevEUI = someDevEui, PrimaryKey = joinInfo.PrimaryKey }; results.Add(iotHubDeviceInfo); if (await deviceCache.TryToLockAsync()) { deviceCache.ClearCache(); // clear the fcnt up/down after the join log?.LogDebug("Removed key '{key}':{gwid}", someDevEui, gatewayId); } else { log?.LogWarning("Failed to acquire lock for '{key}'", someDevEui); } } else { log?.LogDebug("dev nonce already used. Ignore request '{key}':{gwid}", someDevEui, gatewayId); throw new DeviceNonceUsedException(); } }
public async Task <IActionResult> NextFCntDownInvoke( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { if (req is null) { throw new ArgumentNullException(nameof(req)); } try { VersionValidator.Validate(req); } catch (IncompatibleVersionException ex) { return(new BadRequestObjectResult(ex.Message)); } string rawDevEui = req.Query["DevEUI"]; var fCntDown = req.Query["FCntDown"]; var fCntUp = req.Query["FCntUp"]; var gatewayId = req.Query["GatewayId"]; var abpFcntCacheReset = req.Query["ABPFcntCacheReset"]; if (!DevEui.TryParse(rawDevEui, EuiParseOptions.ForbidInvalid, out var devEui)) { return(new BadRequestObjectResult("Dev EUI is invalid.")); } if (!uint.TryParse(fCntUp, out var clientFCntUp)) { throw new ArgumentException("Missing FCntUp"); } if (abpFcntCacheReset != StringValues.Empty) { using (var deviceCache = new LoRaDeviceCache(this.deviceCache, devEui, gatewayId)) { if (await deviceCache.TryToLockAsync()) { if (deviceCache.TryGetInfo(out var deviceInfo)) { // only reset the cache if the current value is larger // than 1 otherwise we likely reset it from another device // and continued processing if (deviceInfo.FCntUp > 1) { log.LogDebug("Resetting cache for device {devEUI}. FCntUp: {fcntup}", devEui, deviceInfo.FCntUp); deviceCache.ClearCache(); } } } } return(new OkObjectResult(null)); } // validate input parameters if (!uint.TryParse(fCntDown, out var clientFCntDown) || StringValues.IsNullOrEmpty(gatewayId)) { var errorMsg = "Missing FCntDown or GatewayId"; throw new ArgumentException(errorMsg); } var newFCntDown = await GetNextFCntDownAsync(devEui, gatewayId, clientFCntUp, clientFCntDown); return(new OkObjectResult(newFCntDown)); }
public async Task <IActionResult> NextFCntDownInvoke( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { try { VersionValidator.Validate(req); } catch (IncompatibleVersionException ex) { return(new BadRequestObjectResult(ex.Message)); } string devEUI = req.Query["DevEUI"]; string fCntDown = req.Query["FCntDown"]; string fCntUp = req.Query["FCntUp"]; string gatewayId = req.Query["GatewayId"]; string abpFcntCacheReset = req.Query["ABPFcntCacheReset"]; uint newFCntDown = 0; EUIValidator.ValidateDevEUI(devEUI); if (!uint.TryParse(fCntUp, out uint clientFCntUp)) { string errorMsg = "Missing FCntUp"; throw new ArgumentException(errorMsg); } if (!string.IsNullOrEmpty(abpFcntCacheReset)) { using (var deviceCache = new LoRaDeviceCache(this.deviceCache, devEUI, gatewayId)) { if (await deviceCache.TryToLockAsync()) { if (deviceCache.TryGetInfo(out var deviceInfo)) { // only reset the cache if the current value is larger // than 1 otherwise we likely reset it from another device // and continued processing if (deviceInfo.FCntUp > 1) { log.LogDebug("Resetting cache. FCntUp: {fcntup}", deviceInfo.FCntUp); deviceCache.ClearCache(); } } } } return((ActionResult) new OkObjectResult(null)); } // validate input parameters if (!uint.TryParse(fCntDown, out uint clientFCntDown) || string.IsNullOrEmpty(gatewayId)) { string errorMsg = "Missing FCntDown or GatewayId"; throw new ArgumentException(errorMsg); } newFCntDown = await this.GetNextFCntDownAsync(devEUI, gatewayId, clientFCntUp, clientFCntDown); return((ActionResult) new OkObjectResult(newFCntDown)); }