/// <remarks/> public ItemResult[] AddItems(Item[] items) { if (items == null) { throw new ArgumentNullException("items"); } lock (this) { // handle trivial case. if (items.Length == 0) { return(new ItemResult[0]); } // create item results. ItemResult[] results = new ItemResult[items.Length]; for (int ii = 0; ii < items.Length; ii++) { // initialize result with item. results[ii] = new ItemResult((ItemIdentifier)items[ii]); // check that the item is valid. if (items[ii].ItemName == null || items[ii].ItemName.Length == 0) { results[ii].ResultID = ResultID.Da.E_INVALID_ITEM_NAME; continue; } // check that the item exists. if (!m_cache.IsValidItem(items[ii].ItemName)) { results[ii].ResultID = ResultID.Da.E_UNKNOWN_ITEM_NAME; continue; } // check that requested datatype is valid. if (items[ii].ReqType == typeof(Opc.Type)) { results[ii].ResultID = ResultID.Da.E_BADTYPE; continue; } // create a new subscription item. SubscriptionItem item = new SubscriptionItem(items[ii].ItemName, m_cache); item.Active = (items[ii].ActiveSpecified)?items[ii].Active:true; item.ClientHandle = items[ii].ClientHandle; item.ReqType = items[ii].ReqType; item.Deadband = (items[ii].DeadbandSpecified)?items[ii].Deadband:-1; item.SamplingRate = (items[ii].SamplingRateSpecified)?items[ii].SamplingRate:-1; item.BufferEnabled = (items[ii].EnableBufferingSpecified)?items[ii].EnableBuffering:false; // update sampling rate. if (item.SamplingRate != -1) { item.SamplingRate = Cache.AdjustUpdateRate(item.SamplingRate); } // assign unique server handle. results[ii].ServerHandle = item.ServerHandle = AssignHandle(); // update result object. results[ii].Active = item.Active; results[ii].ActiveSpecified = true; results[ii].ClientHandle = item.ClientHandle; results[ii].ReqType = item.ReqType; results[ii].Deadband = (item.Deadband != -1)?item.Deadband:0; results[ii].DeadbandSpecified = item.Deadband != -1; results[ii].SamplingRate = (item.SamplingRate != -1)?item.SamplingRate:0; results[ii].SamplingRateSpecified = item.SamplingRate != -1; results[ii].EnableBuffering = item.BufferEnabled; results[ii].EnableBufferingSpecified = item.SamplingRate != -1; // save reference to new item. m_items[results[ii].ServerHandle] = item; } // return results. return(results); } }
/// <remarks/> public ItemResult[] ModifyItems(int masks, Item[] items) { if (items == null) { throw new ArgumentNullException("items"); } lock (this) { // handle trivial case. if (items.Length == 0) { return(new ItemResult[0]); } // create item results. ItemResult[] results = new ItemResult[items.Length]; for (int ii = 0; ii < items.Length; ii++) { // initialize result with item. results[ii] = new ItemResult(items[ii]); // check for invalid handle. if (items[ii].ServerHandle == null) { results[ii].ResultID = ResultID.Da.E_INVALIDHANDLE; continue; } // lookup existing item. SubscriptionItem item = (SubscriptionItem)m_items[items[ii].ServerHandle]; // check that the item is valid. if (m_items.Contains(items)) { results[ii].ResultID = ResultID.Da.E_INVALIDHANDLE; continue; } // update subscription item. System.Type reqType = item.ReqType; bool active = item.Active; object clientHandle = item.ClientHandle; float deadband = item.Deadband; int samplingRate = item.SamplingRate; bool enableBuffering = item.BufferEnabled; // requested data type. if ((masks & (int)StateMask.ReqType) != 0) { // check that requested datatype is valid. if (items[ii].ReqType == Type.ILLEGAL_TYPE) { results[ii].ResultID = ResultID.Da.E_BADTYPE; continue; } reqType = items[ii].ReqType; } // client handle. if ((masks & (int)StateMask.ClientHandle) != 0) { clientHandle = items[ii].ClientHandle; } // deadband. if ((masks & (int)StateMask.Deadband) != 0) { if (items[ii].DeadbandSpecified) { deadband = items[ii].Deadband; if (deadband < 0.0 || deadband > 100.0) { results[ii].ResultID = ResultID.E_INVALIDARG; continue; } } else { deadband = -1; } } // sampling rate. if ((masks & (int)StateMask.SamplingRate) != 0) { samplingRate = (items[ii].SamplingRateSpecified)?items[ii].SamplingRate:-1; int requestedSamplingRate = samplingRate; if (samplingRate != -1) { samplingRate = Cache.AdjustUpdateRate(requestedSamplingRate); } if (requestedSamplingRate != samplingRate) { results[ii].ResultID = ResultID.Da.S_UNSUPPORTEDRATE; } } if ((masks & (int)StateMask.EnableBuffering) != 0) { enableBuffering = (items[ii].EnableBufferingSpecified)?items[ii].EnableBuffering:false; } // active. if ((masks & (int)StateMask.Active) != 0) { active = (items[ii].ActiveSpecified)?items[ii].Active:item.Active; // ensure a callback is sent on the next update. if (active && !item.Active) { item.ResetLastUpdate(); } } // save new values. item.ReqType = reqType; item.Active = active; item.ClientHandle = clientHandle; item.Deadband = deadband; item.SamplingRate = samplingRate; item.BufferEnabled = enableBuffering; // update result object. results[ii].Active = item.Active; results[ii].ActiveSpecified = true; results[ii].ClientHandle = item.ClientHandle; results[ii].ReqType = item.ReqType; results[ii].Deadband = (item.Deadband != -1)?item.Deadband:0; results[ii].DeadbandSpecified = item.Deadband != -1; results[ii].SamplingRate = (item.SamplingRate != -1)?item.SamplingRate:0; results[ii].SamplingRateSpecified = item.SamplingRate != -1; results[ii].EnableBuffering = item.BufferEnabled; results[ii].EnableBufferingSpecified = item.BufferEnabled; } // return results. return(results); } }
/// <remarks/> public SubscriptionState ModifyState(int masks, SubscriptionState state) { if (state == null) { throw new ArgumentNullException("state"); } lock (this) { // save copy of current state. SubscriptionState modifiedState = (SubscriptionState)m_state.Clone(); // update subscription defaults. if ((masks & (int)StateMask.Name) != 0) { modifiedState.Name = state.Name; } if ((masks & (int)StateMask.ClientHandle) != 0) { modifiedState.ClientHandle = state.ClientHandle; } if ((masks & (int)StateMask.Active) != 0) { modifiedState.Active = state.Active; } if ((masks & (int)StateMask.UpdateRate) != 0) { modifiedState.UpdateRate = state.UpdateRate; } if ((masks & (int)StateMask.KeepAlive) != 0) { modifiedState.KeepAlive = state.KeepAlive; } if ((masks & (int)StateMask.Deadband) != 0) { modifiedState.Deadband = state.Deadband; } if ((masks & (int)StateMask.Locale) != 0) { modifiedState.Locale = Opc.Server.FindBestLocale(state.Locale, m_server.GetSupportedLocales()); } // check for unsupported update rate. modifiedState.UpdateRate = Cache.AdjustUpdateRate(modifiedState.UpdateRate); // check update rate chanegd. if ((masks & (int)StateMask.UpdateRate) != 0) { // resynch timebase but don't send an update. m_tickOffset = -2; } // check for unsupported keepalive rate. if (modifiedState.KeepAlive != 0) { modifiedState.KeepAlive = Cache.AdjustUpdateRate(modifiedState.KeepAlive); } // check if subscription deactivated. if (!m_state.Active && modifiedState.Active) { m_cache.ActivateSubscription(this); // force an update to be sent. m_tickOffset = -1; } // check if subscription deactivated. else if (m_state.Active && !modifiedState.Active) { m_cache.DeactivateSubscription(this); m_updateQueue.Clear(); } // replace existing state. m_state = modifiedState; // return new state. return(GetState()); } }