/// <summary> /// Tries to obtain the device version ID (database key) for the given device version (or the highest available version if null). /// </summary> /// <param name="context">The device database context to extend.</param> /// <param name="deviceId">The device ID to search versions for.</param> /// <param name="version">The version number to return the device version ID for. If null, the ID for the highest available version will be retrieved.</param> /// <param name="deviceVersion">Returns the device version object if a device version of for given device ID and version range has been found.</param> /// <returns><c>true</c> if a device version of the given version has been found and the ID returned. Otherwise <c>false</c>.</returns> public static bool TryFindDeviceVersionId(this DeviceDatabaseContext context, int deviceId, SemanticVersion version, out DeviceVersion deviceVersion) { if (context == null) { throw new ArgumentNullException(nameof(context), "The context to search device version ID on is null"); } deviceVersion = null; var result = context.DeviceVersions.Where(d => d.DeviceId == deviceId).OrderByDescending(d => d.HigherOrEqualVersion).ToList(); if (result.Count == 0) { // no such device ID at all return(false); } if (version == null) { // no specific version requested, returns first entry (i.e. the one with the highest MinimumVersion) deviceVersion = result[0]; return(true); } // need to search for the best match of specified version: // we take the entry with the highest minimum version where the requested version is below maximum version foreach (DeviceVersion item in result) { if ((item.HigherOrEqualVersion <= version) && ((item.LowerThanVersion == null) || (item.LowerThanVersion > version))) { deviceVersion = item; return(true); } } log.Debug($"TryFindDeviceVersionId: No version range for device ID {deviceId} in database is applicable to requested version '{version}'"); return(false); }
/// <summary> /// Gets the OID lookup table for the specified device name and version. /// </summary> /// <param name="deviceName">The device name to look up.</param> /// <param name="version">The current version of the device.</param> /// <param name="deviceVersion">Returns the device version container matching this device.</param> /// <param name="deviceAddress">The IP address of the device (only used to include it with possible exceptions).</param> /// <returns>The OID lookup table for the specified device name and version.</returns> protected IDeviceSpecificOidLookup ObtainOidTable(string deviceName, SemanticVersion version, out DeviceVersion deviceVersion, IpAddress deviceAddress) { using (var database = DeviceDatabaseProvider.Instance.DeviceDatabase) { int foundDeviceId = -1; if (!database.TryFindDeviceId(deviceName, out foundDeviceId)) { var exception = new HamnetSnmpException($"Device name '{deviceName}' cannot be found in device database", deviceAddress?.ToString()); log.Error(exception.Message); this.CollectException("No OID lookup for device name", exception); throw exception; } deviceVersion = null; if (!database.TryFindDeviceVersionId(foundDeviceId, version, out deviceVersion)) { var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}) cannot be matched to any version range of device database", deviceAddress?.ToString()); log.Error(exception.Message); this.CollectException("No OID lookup for device version", exception); throw exception; } string foundOidMappingIds = string.Empty; if (!database.TryFindOidLookupId(deviceVersion.Id, out foundOidMappingIds)) { var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}, version ID {deviceVersion.Id}) cannot be matched to any OID mapping ID of device database", deviceAddress?.ToString()); log.Error(exception.Message); this.CollectException("No OID mapping for device version", exception); throw exception; } // need to convert the string containing a comma-separated list of OID lookup tables IDs into single, integer table IDs // Example: There are two lookups given in order "3,1" in the foundOidMappingIds string. // If a RetrievableValuesEnum has a value in lookup of ID 3 that value shall be used. Otherwise the value of lookup #1. string[] splitOidMappingIds = foundOidMappingIds.Split(new char[] { ',', ';', ':', ' ' }, StringSplitOptions.RemoveEmptyEntries); List <IDeviceSpecificOidLookup> orderedOidLookupsList = new List <IDeviceSpecificOidLookup>(splitOidMappingIds.Length); foreach (var sid in splitOidMappingIds) { int intId; if (!int.TryParse(sid, out intId)) { log.Warn($"OID mapping table ID '{sid}' as found for device '{deviceName}' v '{version}' (version ID {deviceVersion.Id}, mapping IDs '{foundOidMappingIds}') is not an integer value and will be ignored"); continue; } IDeviceSpecificOidLookup foundLookup = null; if (!database.TryFindDeviceSpecificOidLookup(intId, deviceVersion.MaximumSupportedSnmpVersion.ToSnmpVersion(), out foundLookup)) { var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}': Cannot find OID mapping ID table of ID {intId} in device database", deviceAddress?.ToString()); log.Error(exception.Message); this.CollectException("No OID mapping for mapping ID", exception); throw exception; } orderedOidLookupsList.Add(foundLookup); } return(new DeviceSpecificMultiLayerOidLookupProxy(orderedOidLookupsList)); } }