/// <summary> /// Get's the access control capabilities / restrictions for the specified device. /// </summary> /// <param name="deviceId">The internal id of the device.</param> public DeviceAccessControl GetDeviceAccessControlCapabilities(uint deviceId = 0) { // Make sure we haven't already processed the restrictions. if (_accessControl != null) { return(_accessControl.GetValueOrDefault(DeviceAccessControl.None)); } return(Connect(() => { _accessControl = DeviceAccessControl.None; string[] objectIds = Client.getObjects(SessionId, deviceId, USAGE_CONTROL_DEVICE); if ((objectIds != null) && (objectIds.Length > 0)) { Trace.TraceInformation("Retrieved the following objectIds for {0}", USAGE_CONTROL_DEVICE); // For each of the object ids (corresponding to copy, fax, printer, scanner, etc.), // get the capabilities for each. objectIds.AsParallel().ForAll((objectId) => { objectCapability capability = GetObjectCapability(deviceId, objectId); if (capability != null) { DeviceAccessControl deviceAccessControl = capability.ToDeviceAccessControl(); Trace.TraceInformation("Device supports {0} restrictions (ACLs).", deviceAccessControl); _accessControl |= deviceAccessControl; } }); } return (_accessControl.GetValueOrDefault(DeviceAccessControl.None)); })); }
/// <summary> /// Gets all of the external service names / identifiers from the specified access control. /// </summary> /// <param name="capability">The object capability to extract the name from</param> /// <returns>The collection of external names.</returns> internal static DeviceAccessControl ToDeviceAccessControl(this objectCapability capability) { if (capability == null) { return(DeviceAccessControl.None); } Type type = typeof(DeviceAccessControl); var names = Enum.GetNames(type); foreach (string name in names) { // Get the metadata FieldInfo field = type.GetField(name); if (field != null) { var attributes = (RicohDeviceCapabilityMetaDataAttribute[])field.GetCustomAttributes(typeof(RicohDeviceCapabilityMetaDataAttribute), true); if (attributes.Any(attribute => String.Equals(attribute.Name, capability.name, StringComparison.CurrentCultureIgnoreCase))) { return((DeviceAccessControl)Enum.Parse(type, name)); } } } Trace.TraceWarning("Unknown {0} received: {1}", DeviceManagement.USAGE_CONTROL_DEVICE, capability.name); return(DeviceAccessControl.None); }
/// <summary> /// The actual API queries the capabilities for each and every object which is /// very slow. Since the object properties should be mostly the same (???), /// we're only going to query the capabilities for the first item and then reuse it. /// </summary> /// <param name="deviceId">The internal id of the device.</param> /// <param name="objectIds">The object ids that were retrieved.</param> /// <returns>The first valid objectCapability that will be used as the default.</returns> private objectCapability GetDefaultObjectCapability(uint deviceId, string[] objectIds) { if ((objectIds == null) || (objectIds.Length == 0)) { return(null); } objectCapability capability = null; if (objectIds.Any(objectId => (capability = GetObjectCapability(deviceId, objectId)) != null)) { return(capability); } return(null); }
/// <summary> /// Clears all of the counters for the system to zero. /// </summary> /// <param name="deviceId">The internal id of the device to clear.</param> /// <remarks> /// For performance, if you previously called <see cref="GetUserCounters"/>, instead of /// calling this function, you should instead call <see cref="Clear(System.Collections.Generic.IEnumerable{Ricoh.Models.UserCounter})"/> passing /// in the results from the previous call. In order to avoid some of the overhead of /// retrieving each object, only the ids are sent and the default object capability is /// used to clear the counters for each user. /// </remarks> public void Clear(uint deviceId = 0) { Connect(() => { Trace.TraceInformation("Retrieving all objects for {0}", USAGE_COUNTER_USER); try { string[] objectIds = Client.getObjects(SessionId, deviceId, USAGE_COUNTER_USER); if ((objectIds != null) && (objectIds.Length > 0)) { // Get the "default" object capabilities // ------------------------------------------------------- // Instead of querying each object, we're just going to use the fields returned // for the first item for each of the objectIds that were retrieved. To do this // "correctly" (i.e. slowly), we should query each object capabilities, then do // the update. Once we have the fields, we just get back those that are updateable objectCapability capability = GetDefaultObjectCapability(deviceId, objectIds); field[] fields = capability.fieldList.GetUpdatableFields(IsUserCounterCapabilityUpdatable); objectIds.AsParallel().ForAll((i) => { uint objectId; if (UInt32.TryParse(i, out objectId)) { if (Update(deviceId, Convert.ToString(UserCounter.ExtractIndexFromObjectId(objectId)), objectId, fields, USAGE_COUNTER_USER, true)) { Trace.TraceInformation("Counters reset for object {0}. Counters: {1}", objectId, String.Join(",", fields.Select(f => f.name))); } else { Trace.TraceError("Reset counter for object {0} failed.", objectId, String.Join(",", fields.Select(f => f.name))); } } }); } } catch (Exception e) { Trace.TraceError(e.Message); Trace.TraceError(e.StackTrace); throw (new RicohOperationFailedException(this, "Clear", e)); } return(true); // Required to satisfy Func<T> }); }
/// <summary> /// Retrieves the current user counters from the system. /// </summary> /// <param name="deviceId">The internal id of the device.</param> /// <returns>The collection of user counters for the device.</returns> public IEnumerable <UserCounter> GetUserCounters(uint deviceId = 0) { return(Connect(() => { IList <UserCounter> counters = new List <UserCounter>(); Trace.TraceInformation("Retrieving all objects for {0}", USAGE_COUNTER_USER); try { string[] objectIds = Client.getObjects(SessionId, deviceId, USAGE_COUNTER_USER); if ((objectIds != null) && (objectIds.Length > 0)) { Trace.TraceInformation("{0} objects: {1}", USAGE_COUNTER_USER, String.Join(",", objectIds)); // Get the "default" object capabilities objectCapability capability = GetDefaultObjectCapability(deviceId, objectIds); // In parallel, retrieve the user counters. objectIds.AsParallel().ForAll((i) => { uint objectId; if (UInt32.TryParse(i, out objectId)) { UserCounter counter = GetUserCounter(deviceId, objectId, ref capability); if (counter != null) { OnUserCounterRetrieved(counter); counters.Add(counter); } else { Trace.TraceWarning("Failed to retrieve information for object {0}.", objectId); } } }); } } catch (Exception e) { Trace.TraceError(e.Message); Trace.TraceError(e.StackTrace); throw (new RicohOperationFailedException(this, "GetUserCounters", e)); } return (counters); })); }
/// <summary> /// Retrieves the user counter data for the specified object id. /// </summary> /// <param name="deviceId">The internal id of the device.</param> /// <param name="objectId">The objectId to retrieve.</param> /// <param name="capability">The capabilities of the object to query.</param> /// <param name="retry">Internal parameter used to keep track of the number of retries.</param> /// <returns>The user counter for the specified objectId.</returns> private UserCounter GetUserCounter(uint deviceId, uint objectId, ref objectCapability capability, uint retry = 0) { // The actual API queries the capabilities for each and every object which is // very slow. Since the object properties should be mostly the same, we're only // going to query the capabilities for the first item and then reuse it. // query the capabilities for the first item and then reuse them. lock (_mutex) { if (capability == null) { Trace.TraceInformation("Retrieving object capabilities for {0}.", objectId); capability = GetObjectCapability(deviceId, objectId); } } string[] fields = capability.fieldList.Select(f => f.name).ToArray(); Trace.TraceInformation("Retreiving object {0} attributes: {1}.", objectId, String.Join(",", fields)); try { var @object = Client.getObject(SessionId, deviceId, objectId, fields); if (@object != null) { Trace.TraceInformation("Data received for object {0}: {1}", objectId, String.Join(",", @object.fieldList.Select(f => String.Format("{0}[{1}]={2}", f.name, f.type, f.value)))); return(new UserCounter(@object.oid, @object.fieldList, capability != null ? capability.fieldList : null)); } } catch (Exception e) { // Device is too slow... not responding. Requeue the request. if ((e is EntryPointNotFoundException) || (e is CommunicationException)) { if (retry < MAX_RETRIES) { Trace.TraceWarning("Connection timed out for: {0}. Retry: {1}", Hostname, retry + 1); return(GetUserCounter(deviceId, objectId, ref capability, retry + 1)); } } Trace.TraceError(e.Message); Trace.TraceError(e.StackTrace); throw (new RicohOperationFailedException(this, "GetUserCounter", e)); } return(null); }
/// <summary> /// Retrieves all the current user restrictions / permissions from the system. /// </summary> /// <param name="deviceId">The internal id of the device.</param> /// <returns>The collection of user counters for the device.</returns> public IEnumerable <UserAccessControl> GetUserAccessControls(uint deviceId = 0) { IList <UserAccessControl> userAccessControls = new List <UserAccessControl>(); return(Connect(() => { Trace.TraceInformation("Retrieving all objects for {0}", USAGE_CONTROL_USER); try { string[] objectIds = Client.getObjects(SessionId, deviceId, USAGE_CONTROL_USER); if ((objectIds != null) && (objectIds.Length > 0)) { Trace.TraceInformation("{0} objects: {1}", USAGE_CONTROL_USER, String.Join(",", objectIds)); // Get the "default" object capabilities objectCapability capability = GetDefaultObjectCapability(deviceId, objectIds); // In parallel, retrieve the access controls for the user. objectIds.AsParallel().ForAll((i) => { uint objectId; if (UInt32.TryParse(i, out objectId)) { UserAccessControl accessControl = GetUserAccessControl(objectId, deviceId, ref capability); if (accessControl != null) { OnUserAccessControlRetrieved(accessControl); userAccessControls.Add(accessControl); } } }); } return (userAccessControls); } catch (Exception e) { Trace.TraceError(e.Message); Trace.TraceError(e.StackTrace); throw (new RicohOperationFailedException(this, "GetUserRestrictions", e)); } })); }