Esempio n. 1
0
        /// <summary>
        /// Unmarshals and deallocates a OPCITEMRESULT structures.
        /// </summary>
        internal static int[] GetItemResults(ref IntPtr pInput, int count, bool deallocate)
        {
            int[] output = null;

            if (pInput != IntPtr.Zero && count > 0)
            {
                output = new int[count];

                IntPtr pos = pInput;

                for (int ii = 0; ii < count; ii++)
                {
                    OpcRcw.Da.OPCITEMRESULT result = (OpcRcw.Da.OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OpcRcw.Da.OPCITEMRESULT));

                    output[ii] = result.hServer;

                    if (deallocate)
                    {
                        if (result.pBlob != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(result.pBlob);
                            result.pBlob      = IntPtr.Zero;
                            result.dwBlobSize = 0;
                        }

                        Marshal.DestroyStructure(pos, typeof(OpcRcw.Da.OPCITEMRESULT));
                    }

                    pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT)));
                }

                if (deallocate)
                {
                    Marshal.FreeCoTaskMem(pInput);
                    pInput = IntPtr.Zero;
                }
            }

            return(output);
        }
Esempio n. 2
0
        /// <summary>
        /// IOPCItemMgt::ValidateItems - Determines if an item is valid.
        ///                              Also returns information about the item such as canonical datatype, etc.
        /// </summary>
		public void ValidateItems(
            int               dwCount, 
            OPCITEMDEF[]      pItemArray, 
            int               bBlobUpdate, 
            out System.IntPtr ppValidationResults,
            out System.IntPtr ppErrors)
		{
			lock (m_lock)
			{
				if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL);

				// validate arguments.
				if (dwCount == 0 || pItemArray == null || dwCount != pItemArray.Length)
				{
					throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
				}

				try
				{
                    int[] errors = new int[dwCount];                    
                    OPCITEMRESULT[] results = new OPCITEMRESULT[dwCount];

                    for (int ii = 0; ii < dwCount; ii++)
					{
						results[ii].hServer             = 0;
						results[ii].dwBlobSize          = 0;
						results[ii].pBlob               = IntPtr.Zero;
						results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY;
						results[ii].dwAccessRights      = 0;
						results[ii].wReserved           = 0;
                						
                        // parse node id.
                        NodeId nodeId = Server.ItemIdToNodeId(pItemArray[ii].szItemID);

                        if (nodeId == null)
                        {
                            errors[ii] = ResultIds.E_INVALIDITEMID;
                            continue;
                        }

                        // find node.
                        VariableNode variable = m_session.NodeCache.Find(nodeId) as VariableNode;
                        
                        if (variable == null)
                        {
                            errors[ii] = ResultIds.E_INVALIDITEMID;
                            continue;
                        }
                        
                        // validated the requested datatype.
                        if (pItemArray[ii].vtRequestedDataType != 0)
                        {
                            if (ComUtils.GetSystemType(pItemArray[ii].vtRequestedDataType) == null)
                            {
                                errors[ii] = ResultIds.E_BADTYPE;
                                continue;
                            }
                        }
                                
                        // fill in metadata.
                        results[ii].vtCanonicalDataType = (short)m_server.DataTypeToVarType(variable.DataType, variable.ValueRank);
                        results[ii].dwAccessRights      = ComUtils.GetAccessRights(variable.AccessLevel);

                        if (results[ii].vtCanonicalDataType == (short)VarEnum.VT_VARIANT)
                        {
                            results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY;
                        }

                        errors[ii] = ResultIds.S_OK;
                    }
                    
                    // marshal the results.
                    ppValidationResults = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMRESULT))*dwCount);
                    IntPtr pos = ppValidationResults;
                                        
                    for (int ii = 0; ii < dwCount; ii++)
                    {
                        Marshal.StructureToPtr(results[ii], pos, false);
                        pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT)));
                    }
                    
					// marshal error codes.
					ppErrors = ComUtils.GetInt32s(errors);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
Esempio n. 3
0
        /// <summary>
        /// IOPCItemMgt::AddItems - Adds one or more items to a group.
        /// </summary>
		public void AddItems(
            int dwCount, 
            OPCITEMDEF[] pItemArray, 
            out System.IntPtr ppAddResults, 
            out System.IntPtr ppErrors)
		{
			lock (m_lock)
			{
                if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL);

                // validate arguments.
                if (dwCount == 0 || pItemArray == null || dwCount != pItemArray.Length)
                {
                    throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                }

                try
                {
                    // compile set of item modifications.
                    int[] errors = new int[dwCount];
                    OPCITEMRESULT[] results = new OPCITEMRESULT[dwCount];

                    List<Item> itemsToAdd = new List<Item>();

                    for (int ii = 0; ii < dwCount; ii++)
                    {
                        OPCITEMDEF itemToAdd = pItemArray[ii];
                           
                        // initialize result structure.
                        results[ii].hServer             = 0;
                        results[ii].dwBlobSize          = 0;
                        results[ii].pBlob               = IntPtr.Zero;
                        results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY;
                        results[ii].dwAccessRights      = 0;
                        results[ii].wReserved           = 0;

                        // parse node id.
                        NodeId nodeId = Server.ItemIdToNodeId(itemToAdd.szItemID);

                        if (nodeId == null)
                        {
                            errors[ii] = ResultIds.E_INVALIDITEMID;
                            continue;
                        }

                        // find node.
                        VariableNode variable = m_session.NodeCache.Find(nodeId) as VariableNode;
                        
                        if (variable == null)
                        {
                            errors[ii] = ResultIds.E_INVALIDITEMID;
                            continue;
                        }

                        // validated the requested datatype.
                        if (itemToAdd.vtRequestedDataType != 0)
                        {
                            if (ComUtils.GetSystemType(itemToAdd.vtRequestedDataType) == null)
                            {
                                errors[ii] = ResultIds.E_BADTYPE;
                                continue;
                            }
                        }
                                                
                        // fill in metadata.
                        results[ii].vtCanonicalDataType = (short)m_server.DataTypeToVarType(variable.DataType, variable.ValueRank);
                        results[ii].dwAccessRights      = ComUtils.GetAccessRights(variable.AccessLevel);

                        if (results[ii].vtCanonicalDataType == (short)VarEnum.VT_VARIANT)
                        {
                            results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY;
                        }

                        // create an item.
                        Item item = new Item();

                        item.ItemId       = itemToAdd.szItemID;
                        item.ClientHandle = itemToAdd.hClient;
                        item.ServerHandle = ii; // save this temporarily to correlate response to request list.
                        item.Active       = itemToAdd.bActive != 0;
                        item.ReqType      = (VarEnum)itemToAdd.vtRequestedDataType;
                        item.Variable     = variable;

                        // check if the item supports deadband.
                        INode euRange = m_session.NodeCache.Find(nodeId, ReferenceTypeIds.HasProperty, false, true, Opc.Ua.BrowseNames.EURange);

                        if (euRange != null)
                        {
                            item.DeadbandSupported = true;
                        }

                        // create a monitored item.
                        MonitoredItem monitoredItem = new MonitoredItem();

                        monitoredItem.StartNodeId      = nodeId;
                        monitoredItem.AttributeId      = Attributes.Value;
                        monitoredItem.MonitoringMode   = (item.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled;
                        monitoredItem.SamplingInterval = m_updateRate;
                        monitoredItem.QueueSize        = 0;
                        monitoredItem.DiscardOldest    = true;
                        monitoredItem.Encoding         = null;
                        monitoredItem.Filter           = null;
                        monitoredItem.IndexRange       = null;
                        
                        if (m_deadband != 0 && item.DeadbandSupported)
                        {
                            DataChangeFilter filter = new DataChangeFilter();
                            
                            filter.DeadbandType  = (uint)(int)DeadbandType.Percent;
                            filter.DeadbandValue = m_deadband;
                            filter.Trigger       = DataChangeTrigger.StatusValue;

                            monitoredItem.Filter = filter;
                        }

                        item.MonitoredItem = monitoredItem;
                        itemsToAdd.Add(item); 

                        // update the subscription.
                        m_subscription.AddItem(monitoredItem);
                    }
                    
                    if (itemsToAdd.Count > 0)
                    {                    
                        // create monitored items on the UA server.
                        m_subscription.ApplyChanges();

                        foreach (Item item in itemsToAdd)
                        {
                            // check for error during add.
                            int index = item.ServerHandle;
                            MonitoredItem monitoredItem = item.MonitoredItem;

                            if (ServiceResult.IsBad(monitoredItem.Status.Error))
                            {
                                errors[index] = Server.MapReadStatusToErrorCode(monitoredItem.Status.Error.StatusCode);
                                m_subscription.RemoveItem(monitoredItem);
                                continue;
                            }

                            // save server handle.
                            results[index].hServer = item.ServerHandle = Utils.ToInt32(monitoredItem.ClientHandle);

                            // add an entry in the cache.
                            CreateCacheEntry(item);
                            
                            // index item.
                            m_items[item.ServerHandle] = item;
                        }
                    }
                        
                    // marshal the results.
                    ppAddResults = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMRESULT))*dwCount);
                    IntPtr pos = ppAddResults;
                                        
                    for (int ii = 0; ii < dwCount; ii++)
                    {
                        Marshal.StructureToPtr(results[ii], pos, false);
                        pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT)));
                    }
                    
                    // marshal error codes.
                    ppErrors = ComUtils.GetInt32s(errors);
                }
                catch (Exception e)
                {
                    throw ComUtils.CreateComException(e);
                }
            }
		}