public bool StoreInfo(DevAddrCacheInfo info, bool initialize = false) { if (info == null) { throw new ArgumentNullException("Required DevAddrCacheInfo argument was null"); } bool success = false; var serializedObjectValue = JsonConvert.SerializeObject(info); string cacheKeyToUse = GenerateKey(info.DevAddr); success = this.cacheStore.TrySetHashObject(cacheKeyToUse, info.DevEUI, serializedObjectValue); if (success) { this.logger.LogInformation($"Successfully saved dev address info on dictionary key: {cacheKeyToUse}, hashkey: {info.DevEUI}, object: {serializedObjectValue}"); } else { this.logger.LogError($"Failure to save dev address info on dictionary key: {cacheKeyToUse}, hashkey: {info?.DevEUI}, object: {serializedObjectValue}"); } return(success); }
public void StoreInfo(DevAddrCacheInfo info) { if (info is null) { throw new ArgumentNullException(nameof(info)); } var serializedObjectValue = JsonConvert.SerializeObject(info); var cacheKeyToUse = GenerateKey(info.DevAddr); var subKey = info.DevEUI is { } someDevEui?someDevEui.ToString() : string.Empty; this.cacheStore.SetHashObject(cacheKeyToUse, subKey, serializedObjectValue); this.logger.LogInformation($"Successfully saved dev address info on dictionary key: {cacheKeyToUse}, hashkey: {info.DevEUI}, object: {serializedObjectValue}"); }
public async Task <List <IoTHubDeviceInfo> > GetDeviceList(string devEUI, string gatewayId, string devNonce, string devAddr, ILogger log = null) { var results = new List <IoTHubDeviceInfo>(); if (devEUI != null) { var joinInfo = await this.TryGetJoinInfoAndValidateAsync(devEUI, gatewayId, log); // OTAA join using (var deviceCache = new LoRaDeviceCache(this.cacheStore, devEUI, gatewayId)) { var cacheKeyDevNonce = string.Concat(devEUI, ":", devNonce); var lockKeyDevNonce = string.Concat(cacheKeyDevNonce, ":joinlockdevnonce"); if (this.cacheStore.StringSet(cacheKeyDevNonce, devNonce, TimeSpan.FromMinutes(5), onlyIfNotExists: true)) { var iotHubDeviceInfo = new IoTHubDeviceInfo { DevEUI = devEUI, PrimaryKey = joinInfo.PrimaryKey }; results.Add(iotHubDeviceInfo); if (await deviceCache.TryToLockAsync()) { this.cacheStore.KeyDelete(devEUI); log?.LogDebug("Removed key '{key}':{gwid}", devEUI, gatewayId); } else { log?.LogWarning("Failed to acquire lock for '{key}'", devEUI); } } else { log?.LogDebug("dev nonce already used. Ignore request '{key}':{gwid}", devEUI, gatewayId); throw new DeviceNonceUsedException(); } } } else if (devAddr != null) { // ABP or normal message // TODO check for sql injection devAddr = devAddr.Replace('\'', ' '); var devAddrCache = new LoRaDevAddrCache(this.cacheStore, this.registryManager, log, gatewayId); if (await devAddrCache.TryTakeDevAddrUpdateLock(devAddr)) { try { if (devAddrCache.TryGetInfo(devAddr, out List <DevAddrCacheInfo> devAddressesInfo)) { for (int i = 0; i < devAddressesInfo.Count; i++) { if (!string.IsNullOrEmpty(devAddressesInfo[i].DevEUI)) { // device was not yet populated if (!string.IsNullOrEmpty(devAddressesInfo[i].PrimaryKey)) { results.Add(devAddressesInfo[i]); } else { // we need to load the primaryKey from IoTHub // Add a lock loadPrimaryKey get lock get devAddressesInfo[i].PrimaryKey = await this.LoadPrimaryKeyAsync(devAddressesInfo[i].DevEUI); results.Add(devAddressesInfo[i]); devAddrCache.StoreInfo(devAddressesInfo[i]); } // even if we fail to acquire the lock we wont enter in the next condition as devaddressinfo is not null } } } // if the cache results are null, we query the IoT Hub. // if the device is not found is the cache we query, if there was something, it is probably not our device. if (results.Count == 0 && devAddressesInfo == null) { if (await devAddrCache.TryTakeDevAddrUpdateLock(devAddr)) { try { var query = this.registryManager.CreateQuery($"SELECT * FROM devices WHERE properties.desired.DevAddr = '{devAddr}' OR properties.reported.DevAddr ='{devAddr}'", 100); int resultCount = 0; while (query.HasMoreResults) { var page = await query.GetNextAsTwinAsync(); foreach (var twin in page) { if (twin.DeviceId != null) { var device = await this.registryManager.GetDeviceAsync(twin.DeviceId); var iotHubDeviceInfo = new DevAddrCacheInfo { DevAddr = devAddr, DevEUI = twin.DeviceId, PrimaryKey = device.Authentication.SymmetricKey.PrimaryKey, GatewayId = twin.GetGatewayID(), NwkSKey = twin.GetNwkSKey(), LastUpdatedTwins = twin.Properties.Desired.GetLastUpdated() }; results.Add(iotHubDeviceInfo); devAddrCache.StoreInfo((DevAddrCacheInfo)iotHubDeviceInfo); } resultCount++; } } // todo save when not our devaddr if (resultCount == 0) { devAddrCache.StoreInfo(new DevAddrCacheInfo() { DevAddr = devAddr, DevEUI = string.Empty }); } } finally { devAddrCache.ReleaseDevAddrUpdateLock(devAddr); } } } } finally { devAddrCache.ReleaseDevAddrUpdateLock(devAddr); } } } else { throw new Exception("Missing devEUI or devAddr"); } return(results); }